Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 2527

 
Artyom Trishkin:

В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти на MQL5 - языки очень похожи.

Здесь можно будет обсудить задачи, алгоритмы их решения, да и впрочем, любые вопросы, так или иначе касающиеся программирования для МТ.

Надеюсь, что к решению вопросов подтянутся другие опытные участники нашего форума, и ветка будет интересна всем.

Объясните ArraySetSeries, CopyRates, Copy(high, low и т.д.)

Как этим пользоваться. Ну или может у вас есть код, где вы это применили. Не очень понимаю данную тему. Заранее спасибо
Форум трейдеров - MQL5 community
Форум трейдеров - MQL5 community
  • www.mql5.com
MQL5: форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
 
Dojkged #:
Объясните ArraySetSeries, CopyRates, Copy(high, low и т.д.)

Как этим пользоваться. Ну или может у вас есть код, где вы это применили. Не очень понимаю данную тему. Заранее спасибо

Справку читали? Там же всё подробно и с примерами

ArraySetAsSeries

CopyRates

и всё остальное там же читайте.

Документация по MQL5: Операции с массивами / ArraySetAsSeries
Документация по MQL5: Операции с массивами / ArraySetAsSeries
  • www.mql5.com
Устанавливает флаг AS_SERIES указанному объекту динамического массива , индексация элементов массива будет производиться как в таймсериях ...
 
Игорь #:
Tretyakov Rostyslav #:

PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);

#property indicator_chart_window
#property indicator_buffers 6 // в оригинале было 3
#property indicator_plots   2 // в оригинале было 1
//---- plot ZigZag 1
#property indicator_label1  "ZigZag1"
#property indicator_type1   DRAW_SECTION
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//---- plot ZigZag 2
#property indicator_label2  "ZigZag2"
#property indicator_type2   DRAW_SECTION
#property indicator_color2  clrBlueViolet
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- input parameters ZigZag 1
input int      InpDepth    =26;
input int      InpDeviation=12;
input int      InpBackstep =9;
//--- input parameters ZigZag 2
input int      Ext_Depth    =12;
input int      Ext_Deviation=5;
input int      Ext_Backstep =3;
//--- indicator buffers ZigZag 1
double         ZigZagBuffer[];      //
double         HighMapBuffer[];     //
double         LowMapBuffer[];      //
int            ExtRecalc=3;         //
//--- indicator buffers ZigZag 2
double         Buffer1[];      // main buffer
double         Buffer2[];     // ZigZag high extremes (peaks)
double         Buffer3[];      // ZigZag low extremes (bottoms)
int            InpRecalc=3;         // nu

enum EnSearchMode
  {
   Extremum=0, // searching for the first extremum
   Peak=1,     // searching for the next ZigZag peak
   Bottom=-1   // searching for the next ZigZag bottom
  };
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ZigZagBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);
//
   SetIndexBuffer(3,Buffer1,INDICATOR_DATA);
   SetIndexBuffer(4,Buffer2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,Buffer3,INDICATOR_CALCULATIONS);
//--- set short name and digits
   //string short_name=StringFormat("ZigZag(%d,%d,%d)",InpDepth,InpDeviation,InpBackstep);
   //IndicatorSetString(INDICATOR_SHORTNAME,short_name);
   //PlotIndexSetString(0,PLOT_LABEL,short_name);
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- set an empty value
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
  }//+------------------------------------------------------------------+
//| ZigZag calculation                                               |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   OnCalculateOne(rates_total,prev_calculated,time,open,high,low,close,tick_volume,volume,spread);
//     OnCalculateTwo(rates_total,prev_calculated,time,open,high,low,close,tick_volume,volume,spread);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ZigZag calculation One                                           |
//+------------------------------------------------------------------+
//  /*
int OnCalculateOne(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(rates_total<100)
      return(0);
//---
   int    i=0;
   int    start=0,extreme_counter=0,extreme_search=Extremum;
   int    shift=0,back=0,last_high_pos=0,last_low_pos=0;
   double val=0,res=0;
   double curlow=0,curhigh=0,last_high=0,last_low=0;
//--- initializing
   if(prev_calculated==0)
     {
      ArrayInitialize(ZigZagBuffer,0.0);
      ArrayInitialize(HighMapBuffer,0.0);
      ArrayInitialize(LowMapBuffer,0.0);
      start=InpDepth;
     }

//--- ZigZag was already calculated before
   if(prev_calculated>0)
     {
      i=rates_total-1;
      //--- searching for the third extremum from the last uncompleted bar
      while(extreme_counter<ExtRecalc && i>rates_total-100)
        {
         res=ZigZagBuffer[i];
         if(res!=0.0)
            extreme_counter++;
         i--;
        }
      i++;
      start=i;

      //--- what type of exremum we search for
      if(LowMapBuffer[i]!=0.0)
        {
         curlow=LowMapBuffer[i];
         extreme_search=Peak;
        }
      else
        {
         curhigh=HighMapBuffer[i];
         extreme_search=Bottom;
        }
      //--- clear indicator values
      for(i=start+1; i<rates_total && !IsStopped(); i++)
        {
         ZigZagBuffer[i] =0.0;
         LowMapBuffer[i] =0.0;
         HighMapBuffer[i]=0.0;
        }
     }

//--- searching for high and low extremes
   for(shift=start; shift<rates_total && !IsStopped(); shift++)
     {
      //--- low
      val=low[Lowest(low,InpDepth,shift)];
      if(val==last_low)
         val=0.0;
      else
        {
         last_low=val;
         if((low[shift]-val)>InpDeviation*_Point)
            val=0.0;
         else
           {
            for(back=1; back<=InpBackstep; back++)
              {
               res=LowMapBuffer[shift-back];
               if((res!=0) && (res>val))
                  LowMapBuffer[shift-back]=0.0;
              }
           }
        }
      if(low[shift]==val)
         LowMapBuffer[shift]=val;
      else
         LowMapBuffer[shift]=0.0;
      //--- high
      val=high[Highest(high,InpDepth,shift)];
      if(val==last_high)
         val=0.0;
      else
        {
         last_high=val;
         if((val-high[shift])>InpDeviation*_Point)
            val=0.0;
         else
           {
            for(back=1; back<=InpBackstep; back++)
              {
               res=HighMapBuffer[shift-back];
               if((res!=0) && (res<val))
                  HighMapBuffer[shift-back]=0.0;
              }
           }
        }
      if(high[shift]==val)
         HighMapBuffer[shift]=val;
      else
         HighMapBuffer[shift]=0.0;
     }

//--- set last values
   if(extreme_search==0) // undefined values
     {
      last_low=0.0;
      last_high=0.0;
     }
   else
     {
      last_low=curlow;
      last_high=curhigh;
     }

//--- final selection of extreme points for ZigZag
   for(shift=start; shift<rates_total && !IsStopped(); shift++)
     {
      res=0.0;
      switch(extreme_search)
        {
         case Extremum:
            if(last_low==0.0 && last_high==0.0)
              {
               if(HighMapBuffer[shift]!=0)
                 {
                  last_high=high[shift];
                  last_high_pos=shift;
                  extreme_search=Bottom;
                  ZigZagBuffer[shift]=last_high;
                  res=1;
                 }
               if(LowMapBuffer[shift]!=0.0)
                 {
                  last_low=low[shift];
                  last_low_pos=shift;
                  extreme_search=Peak;
                  ZigZagBuffer[shift]=last_low;
                  res=1;
                 }
              }
            break;
         case Peak:
            if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<last_low && HighMapBuffer[shift]==0.0)
              {
               ZigZagBuffer[last_low_pos]=0.0;
               last_low_pos=shift;
               last_low=LowMapBuffer[shift];
               ZigZagBuffer[shift]=last_low;
               res=1;
              }
            if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
              {
               last_high=HighMapBuffer[shift];
               last_high_pos=shift;
               ZigZagBuffer[shift]=last_high;
               extreme_search=Bottom;
               res=1;
              }
            break;
         case Bottom:
            if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>last_high && LowMapBuffer[shift]==0.0)
              {
               ZigZagBuffer[last_high_pos]=0.0;
               last_high_pos=shift;
               last_high=HighMapBuffer[shift];
               ZigZagBuffer[shift]=last_high;
              }
            if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
              {
               last_low=LowMapBuffer[shift];
               last_low_pos=shift;
               ZigZagBuffer[shift]=last_low;
               extreme_search=Peak;
              }
            break;
         default:
            return(rates_total);
        }
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
// */
//+------------------------------------------------------------------+
//| ZigZag calculationTwo                                            |
//+------------------------------------------------------------------+
  /*
  int OnCalculateTwo(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int    i=0;
   int    start=0,extreme_counter=0,extreme_search=Extremum;
   int    shift=0,back=0,last_high_pos=0,last_low_pos=0;
   double val=0,res=0;
   double curlow=0,curhigh=0,last_high=0,last_low=0;
//--- initializing
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer1,0.0);
      ArrayInitialize(Buffer2,0.0);
      ArrayInitialize(Buffer3,0.0);
      start=Ext_Depth;
     }

//--- ZigZag was already calculated before
   if(prev_calculated>0)
     {
      i=rates_total-1;
      //--- searching for the third extremum from the last uncompleted bar
      while(extreme_counter<InpRecalc && i>rates_total-100)
        {
         res=Buffer1[i];
         if(res!=0.0)
            extreme_counter++;
         i--;
        }
      i++;
      start=i;

      //--- what type of exremum we search for
      if(Buffer3[i]!=0.0)
        {
         curlow=Buffer3[i];
         extreme_search=Peak;
        }
      else
        {
         curhigh=Buffer2[i];
         extreme_search=Bottom;
        }
      //--- clear indicator values
      for(i=start+1; i<rates_total && !IsStopped(); i++)
        {
         Buffer1[i] =0.0;
         Buffer3[i] =0.0;
         Buffer2[i]=0.0;
        }
     }

//--- searching for high and low extremes
   for(shift=start; shift<rates_total && !IsStopped(); shift++)
     {
      //--- low
      val=low[Lowest(low,Ext_Depth,shift)];
      if(val==last_low)
         val=0.0;
      else
        {
         last_low=val;
         if((low[shift]-val)>Ext_Deviation*_Point)
            val=0.0;
         else
           {
            for(back=1; back<=Ext_Backstep; back++)
              {
               res=Buffer3[shift-back];
               if((res!=0) && (res>val))
                  Buffer3[shift-back]=0.0;
              }
           }
        }
      if(low[shift]==val)
         Buffer3[shift]=val;
      else
         Buffer3[shift]=0.0;
      //--- high
      val=high[Highest(high,Ext_Depth,shift)];
      if(val==last_high)
         val=0.0;
      else
        {
         last_high=val;
         if((val-high[shift])>Ext_Deviation*_Point)
            val=0.0;
         else
           {
            for(back=1; back<=Ext_Backstep; back++)
              {
               res=Buffer2[shift-back];
               if((res!=0) && (res<val))
                  Buffer2[shift-back]=0.0;
              }
           }
        }
      if(high[shift]==val)
         Buffer2[shift]=val;
      else
         Buffer2[shift]=0.0;
     }

//--- set last values
   if(extreme_search==0) // undefined values
     {
      last_low=0.0;
      last_high=0.0;
     }
   else
     {
      last_low=curlow;
      last_high=curhigh;
     }

//--- final selection of extreme points for ZigZag
   for(shift=start; shift<rates_total && !IsStopped(); shift++)
     {
      res=0.0;
      switch(extreme_search)
        {
         case Extremum:
            if(last_low==0.0 && last_high==0.0)
              {
               if(Buffer2[shift]!=0)
                 {
                  last_high=high[shift];
                  last_high_pos=shift;
                  extreme_search=Bottom;
                  Buffer1[shift]=last_high;
                  res=1;
                 }
               if(Buffer3[shift]!=0.0)
                 {
                  last_low=low[shift];
                  last_low_pos=shift;
                  extreme_search=Peak;
                  Buffer1[shift]=last_low;
                  res=1;
                 }
              }
            break;
         case Peak:
            if(Buffer3[shift]!=0.0 && Buffer3[shift]<last_low && Buffer2[shift]==0.0)
              {
               Buffer1[last_low_pos]=0.0;
               last_low_pos=shift;
               last_low=Buffer3[shift];
               Buffer1[shift]=last_low;
               res=1;
              }
            if(Buffer2[shift]!=0.0 && Buffer3[shift]==0.0)
              {
               last_high=Buffer2[shift];
               last_high_pos=shift;
               Buffer1[shift]=last_high;
               extreme_search=Bottom;
               res=1;
              }
            break;
         case Bottom:
            if(Buffer2[shift]!=0.0 && Buffer2[shift]>last_high && Buffer3[shift]==0.0)
              {
               Buffer1[last_high_pos]=0.0;
               last_high_pos=shift;
               last_high=Buffer2[shift];
               Buffer1[shift]=last_high;
              }
            if(Buffer3[shift]!=0.0 && Buffer2[shift]==0.0)
              {
               last_low=Buffer3[shift];
               last_low_pos=shift;
               Buffer1[shift]=last_low;
               extreme_search=Peak;
              }
            break;
         default:
            return(rates_total);
        }
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
  
   */ 
//+------------------------------------------------------------------+
//|  Search for the index of the highest bar                         |
//+------------------------------------------------------------------+
int Highest(const double &array[],const int depth,const int start)
  {
   if(start<0)
      return(0);

   double max=array[start];
   int    index=start;
//--- start searching
   for(int i=start-1; i>start-depth && i>=0; i--)
     {
      if(array[i]>max)
        {
         index=i;
         max=array[i];
        }
     }
//--- return index of the highest bar
   return(index);
  }
//+------------------------------------------------------------------+
//|  Search for the index of the lowest bar                          |
//+------------------------------------------------------------------+
int Lowest(const double &array[],const int depth,const int start)
  {
   if(start<0)
      return(0);

   double min=array[start];
   int    index=start;
//--- start searching
   for(int i=start-1; i>start-depth && i>=0; i--)
     {
      if(array[i]<min)
        {
         index=i;
         min=array[i];
        }
     }
//--- return index of the lowest bar
   return(index);
  }
//+------------------------------------------------------------------+

Уже исправил. Всё равно косяк с буфером обмена. Интересная штука получается). Я нижний  зиг-заг за комментирую, то у меня красный зигзаг рисуется нормально, то синий зигзаг рисуется  по максимумам. Если я верхний зиг-заг за комментирую, то у меня красный зигзаг рисуется нормально, то синий зиг-заг формируется по минимумам.



 
Игорь #:
Всё равно косяк с буфером обмена.
#property indicator_chart_window
#property indicator_buffers 6 // в оригинале было 3
#property indicator_plots   2 // в оригинале было 1
//---- plot ZigZag 1
#property indicator_label1  "ZigZag1"
#property indicator_type1   DRAW_SECTION
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//---- plot ZigZag 2
#property indicator_label2  "ZigZag2"
#property indicator_type2   DRAW_SECTION
#property indicator_color2  clrBlueViolet
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- input parameters ZigZag 1
input int      InpDepth    =26;
input int      InpDeviation=12;
input int      InpBackstep =9;
//--- input parameters ZigZag 2
input int      Ext_Depth    =12;
input int      Ext_Deviation=5;
input int      Ext_Backstep =3;
//--- indicator buffers ZigZag 1
double         ZigZagBuffer[];      //
double         HighMapBuffer[];     //
double         LowMapBuffer[];      //
int            ExtRecalc=3;         //
//--- indicator buffers ZigZag 2
double         Buffer1[];      // main buffer
double         Buffer2[];     // ZigZag high extremes (peaks)
double         Buffer3[];      // ZigZag low extremes (bottoms)
int            InpRecalc=3;         // nu

enum EnSearchMode
  {
   Extremum=0, // searching for the first extremum
   Peak=1,     // searching for the next ZigZag peak
   Bottom=-1   // searching for the next ZigZag bottom
  };
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,ZigZagBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,Buffer1,INDICATOR_DATA);
//
   SetIndexBuffer(2,HighMapBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,LowMapBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,Buffer2,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,Buffer3,INDICATOR_CALCULATIONS);
//--- set short name and digits
   //string short_name=StringFormat("ZigZag(%d,%d,%d)",InpDepth,InpDeviation,InpBackstep);
   //IndicatorSetString(INDICATOR_SHORTNAME,short_name);
   //PlotIndexSetString(0,PLOT_LABEL,short_name);
   IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- set an empty value
   PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
   PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
  }//+------------------------------------------------------------------+
//| ZigZag calculation                                               |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   OnCalculateOne(rates_total,prev_calculated,time,open,high,low,close,tick_volume,volume,spread);
   OnCalculateTwo(rates_total,prev_calculated,time,open,high,low,close,tick_volume,volume,spread);
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ZigZag calculation One                                           |
//+------------------------------------------------------------------+
//  /*
int OnCalculateOne(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(rates_total<100)
      return(0);
//---
   int    i=0;
   int    start=0,extreme_counter=0,extreme_search=Extremum;
   int    shift=0,back=0,last_high_pos=0,last_low_pos=0;
   double val=0,res=0;
   double curlow=0,curhigh=0,last_high=0,last_low=0;
//--- initializing
   if(prev_calculated==0)
     {
      ArrayInitialize(ZigZagBuffer,0.0);
      ArrayInitialize(HighMapBuffer,0.0);
      ArrayInitialize(LowMapBuffer,0.0);
      start=InpDepth;
     }

//--- ZigZag was already calculated before
   if(prev_calculated>0)
     {
      i=rates_total-1;
      //--- searching for the third extremum from the last uncompleted bar
      while(extreme_counter<ExtRecalc && i>rates_total-100)
        {
         res=ZigZagBuffer[i];
         if(res!=0.0)
            extreme_counter++;
         i--;
        }
      i++;
      start=i;

      //--- what type of exremum we search for
      if(LowMapBuffer[i]!=0.0)
        {
         curlow=LowMapBuffer[i];
         extreme_search=Peak;
        }
      else
        {
         curhigh=HighMapBuffer[i];
         extreme_search=Bottom;
        }
      //--- clear indicator values
      for(i=start+1; i<rates_total && !IsStopped(); i++)
        {
         ZigZagBuffer[i] =0.0;
         LowMapBuffer[i] =0.0;
         HighMapBuffer[i]=0.0;
        }
     }

//--- searching for high and low extremes
   for(shift=start; shift<rates_total && !IsStopped(); shift++)
     {
      //--- low
      val=low[Lowest(low,InpDepth,shift)];
      if(val==last_low)
         val=0.0;
      else
        {
         last_low=val;
         if((low[shift]-val)>InpDeviation*_Point)
            val=0.0;
         else
           {
            for(back=1; back<=InpBackstep; back++)
              {
               res=LowMapBuffer[shift-back];
               if((res!=0) && (res>val))
                  LowMapBuffer[shift-back]=0.0;
              }
           }
        }
      if(low[shift]==val)
         LowMapBuffer[shift]=val;
      else
         LowMapBuffer[shift]=0.0;
      //--- high
      val=high[Highest(high,InpDepth,shift)];
      if(val==last_high)
         val=0.0;
      else
        {
         last_high=val;
         if((val-high[shift])>InpDeviation*_Point)
            val=0.0;
         else
           {
            for(back=1; back<=InpBackstep; back++)
              {
               res=HighMapBuffer[shift-back];
               if((res!=0) && (res<val))
                  HighMapBuffer[shift-back]=0.0;
              }
           }
        }
      if(high[shift]==val)
         HighMapBuffer[shift]=val;
      else
         HighMapBuffer[shift]=0.0;
     }

//--- set last values
   if(extreme_search==0) // undefined values
     {
      last_low=0.0;
      last_high=0.0;
     }
   else
     {
      last_low=curlow;
      last_high=curhigh;
     }

//--- final selection of extreme points for ZigZag
   for(shift=start; shift<rates_total && !IsStopped(); shift++)
     {
      res=0.0;
      switch(extreme_search)
        {
         case Extremum:
            if(last_low==0.0 && last_high==0.0)
              {
               if(HighMapBuffer[shift]!=0)
                 {
                  last_high=high[shift];
                  last_high_pos=shift;
                  extreme_search=Bottom;
                  ZigZagBuffer[shift]=last_high;
                  res=1;
                 }
               if(LowMapBuffer[shift]!=0.0)
                 {
                  last_low=low[shift];
                  last_low_pos=shift;
                  extreme_search=Peak;
                  ZigZagBuffer[shift]=last_low;
                  res=1;
                 }
              }
            break;
         case Peak:
            if(LowMapBuffer[shift]!=0.0 && LowMapBuffer[shift]<last_low && HighMapBuffer[shift]==0.0)
              {
               ZigZagBuffer[last_low_pos]=0.0;
               last_low_pos=shift;
               last_low=LowMapBuffer[shift];
               ZigZagBuffer[shift]=last_low;
               res=1;
              }
            if(HighMapBuffer[shift]!=0.0 && LowMapBuffer[shift]==0.0)
              {
               last_high=HighMapBuffer[shift];
               last_high_pos=shift;
               ZigZagBuffer[shift]=last_high;
               extreme_search=Bottom;
               res=1;
              }
            break;
         case Bottom:
            if(HighMapBuffer[shift]!=0.0 && HighMapBuffer[shift]>last_high && LowMapBuffer[shift]==0.0)
              {
               ZigZagBuffer[last_high_pos]=0.0;
               last_high_pos=shift;
               last_high=HighMapBuffer[shift];
               ZigZagBuffer[shift]=last_high;
              }
            if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0)
              {
               last_low=LowMapBuffer[shift];
               last_low_pos=shift;
               ZigZagBuffer[shift]=last_low;
               extreme_search=Peak;
              }
            break;
         default:
            return(rates_total);
        }
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
// 
//+------------------------------------------------------------------+
//| ZigZag calculationTwo                                            |
//+------------------------------------------------------------------+
  int OnCalculateTwo(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   int    i=0;
   int    start=0,extreme_counter=0,extreme_search=Extremum;
   int    shift=0,back=0,last_high_pos=0,last_low_pos=0;
   double val=0,res=0;
   double curlow=0,curhigh=0,last_high=0,last_low=0;
//--- initializing
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer1,0.0);
      ArrayInitialize(Buffer2,0.0);
      ArrayInitialize(Buffer3,0.0);
      start=Ext_Depth;
     }

//--- ZigZag was already calculated before
   if(prev_calculated>0)
     {
      i=rates_total-1;
      //--- searching for the third extremum from the last uncompleted bar
      while(extreme_counter<InpRecalc && i>rates_total-100)
        {
         res=Buffer1[i];
         if(res!=0.0)
            extreme_counter++;
         i--;
        }
      i++;
      start=i;

      //--- what type of exremum we search for
      if(Buffer3[i]!=0.0)
        {
         curlow=Buffer3[i];
         extreme_search=Peak;
        }
      else
        {
         curhigh=Buffer2[i];
         extreme_search=Bottom;
        }
      //--- clear indicator values
      for(i=start+1; i<rates_total && !IsStopped(); i++)
        {
         Buffer1[i] =0.0;
         Buffer3[i] =0.0;
         Buffer2[i]=0.0;
        }
     }

//--- searching for high and low extremes
   for(shift=start; shift<rates_total && !IsStopped(); shift++)
     {
      //--- low
      val=low[Lowest(low,Ext_Depth,shift)];
      if(val==last_low)
         val=0.0;
      else
        {
         last_low=val;
         if((low[shift]-val)>Ext_Deviation*_Point)
            val=0.0;
         else
           {
            for(back=1; back<=Ext_Backstep; back++)
              {
               res=Buffer3[shift-back];
               if((res!=0) && (res>val))
                  Buffer3[shift-back]=0.0;
              }
           }
        }
      if(low[shift]==val)
         Buffer3[shift]=val;
      else
         Buffer3[shift]=0.0;
      //--- high
      val=high[Highest(high,Ext_Depth,shift)];
      if(val==last_high)
         val=0.0;
      else
        {
         last_high=val;
         if((val-high[shift])>Ext_Deviation*_Point)
            val=0.0;
         else
           {
            for(back=1; back<=Ext_Backstep; back++)
              {
               res=Buffer2[shift-back];
               if((res!=0) && (res<val))
                  Buffer2[shift-back]=0.0;
              }
           }
        }
      if(high[shift]==val)
         Buffer2[shift]=val;
      else
         Buffer2[shift]=0.0;
     }

//--- set last values
   if(extreme_search==0) // undefined values
     {
      last_low=0.0;
      last_high=0.0;
     }
   else
     {
      last_low=curlow;
      last_high=curhigh;
     }

//--- final selection of extreme points for ZigZag
   for(shift=start; shift<rates_total && !IsStopped(); shift++)
     {
      res=0.0;
      switch(extreme_search)
        {
         case Extremum:
            if(last_low==0.0 && last_high==0.0)
              {
               if(Buffer2[shift]!=0)
                 {
                  last_high=high[shift];
                  last_high_pos=shift;
                  extreme_search=Bottom;
                  Buffer1[shift]=last_high;
                  res=1;
                 }
               if(Buffer3[shift]!=0.0)
                 {
                  last_low=low[shift];
                  last_low_pos=shift;
                  extreme_search=Peak;
                  Buffer1[shift]=last_low;
                  res=1;
                 }
              }
            break;
         case Peak:
            if(Buffer3[shift]!=0.0 && Buffer3[shift]<last_low && Buffer2[shift]==0.0)
              {
               Buffer1[last_low_pos]=0.0;
               last_low_pos=shift;
               last_low=Buffer3[shift];
               Buffer1[shift]=last_low;
               res=1;
              }
            if(Buffer2[shift]!=0.0 && Buffer3[shift]==0.0)
              {
               last_high=Buffer2[shift];
               last_high_pos=shift;
               Buffer1[shift]=last_high;
               extreme_search=Bottom;
               res=1;
              }
            break;
         case Bottom:
            if(Buffer2[shift]!=0.0 && Buffer2[shift]>last_high && Buffer3[shift]==0.0)
              {
               Buffer1[last_high_pos]=0.0;
               last_high_pos=shift;
               last_high=Buffer2[shift];
               Buffer1[shift]=last_high;
              }
            if(Buffer3[shift]!=0.0 && Buffer2[shift]==0.0)
              {
               last_low=Buffer3[shift];
               last_low_pos=shift;
               Buffer1[shift]=last_low;
               extreme_search=Peak;
              }
            break;
         default:
            return(rates_total);
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|  Search for the index of the highest bar                         |
//+------------------------------------------------------------------+
int Highest(const double &array[],const int depth,const int start)
  {
   if(start<0)
      return(0);

   double max=array[start];
   int    index=start;
//--- start searching
   for(int i=start-1; i>start-depth && i>=0; i--)
     {
      if(array[i]>max)
        {
         index=i;
         max=array[i];
        }
     }
//--- return index of the highest bar
   return(index);
  }
//+------------------------------------------------------------------+
//|  Search for the index of the lowest bar                          |
//+------------------------------------------------------------------+
int Lowest(const double &array[],const int depth,const int start)
  {
   if(start<0)
      return(0);

   double min=array[start];
   int    index=start;
//--- start searching
   for(int i=start-1; i>start-depth && i>=0; i--)
     {
      if(array[i]<min)
        {
         index=i;
         min=array[i];
        }
     }
//--- return index of the lowest bar
   return(index);
  }
//+------------------------------------------------------------------+
 
Artyom Trishkin:

В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти на MQL5 - языки очень похожи.

Здесь можно будет обсудить задачи, алгоритмы их решения, да и впрочем, любые вопросы, так или иначе касающиеся программирования для МТ.

Надеюсь, что к решению вопросов подтянутся другие опытные участники нашего форума, и ветка будет интересна всем.


Расскажите, как сделать перерыв в торговле. Например, чтобы робот не торговал с 8 до 9. И как сделать несколько таких периодов

 
Dojkged #:

Расскажите, как сделать перерыв в торговле. Например, чтобы робот не торговал с 8 до 9. И как сделать несколько таких периодов

Здесь помогают, а не делают за Вас.

Покажите что уже Вы сделали и Вам помогут.

 
Добрый день! 

Подскажите ребята какой функцией и в какой части кода мне прописать,  чтобы отображался комментарий для открытой сделки (именно в терминальной части,а не в журнале), на основании сигнала в коде для открытия SELL or BUY позиции?
Я пробовал использовать команду  string DEAL_COMMENT перед  ct.PositionOpen, но это не сработало.


// Check if the current low is the lowest among the last 12 candles
        if (IsLowestLow(rates, numCandles, rates[0].low)) {
            // The current low is the lowest among the last 12 candles
            double previousClose1 = rates[1].close;
            double previousClose2 = rates[2].close;

            // Determine if the trend is downward
            if (previousClose1 < previousClose2) {
                // Open a sell position towards the trend
                double currentPrice = SymbolInfoDouble(Symbol(), SYMBOL_BID);
                string DEAL_COMMENT = "Bearish trend signal";
                ct.PositionOpen(Symbol(), ORDER_TYPE_SELL, Lot, currentPrice, 0, 0);


Помогите, подскажите пожалуйста! Скриншот куда хочу комментарий прилагаю.
Заранее спасибо!
Файлы:
tbwsu8.JPG  37 kb
 
Sergei Tarasov #:
Подскажите ребята какой функцией и в какой части кода мне прописать,
bool  PositionOpen(
   const string     symbol,         // символ
   ENUM_ORDER_TYPE  order_type,     // тип торговой операции для открытия позиции
   double           volume,         // объем позиции
   double           price,          // цена исполнения
   double           sl,             // цена Stop Loss
   double           tp,             // цена Take Profit
   const string     comment=""      // комментарий
   )
PositionOpen(Symbol(), ORDER_TYPE_SELL, Lot, currentPrice, 0, 0,comment); 
 

Добрый день!

ПОдскажите еще пожалуйста в чем может быть причина не срабатывания trailing stop. У меня вот такой код для него, кусок ниже - активация происходит при достижении определенного уровня профита в USD ( TrailingStartProfit ), со стоп-лоссом на уровне Open price, потом стоп-лосс должен переместиться на уровень TrailingStopDistance от цены и дальше уже по нему работать.
Но почему-то при достижении установленного профита  Trailing не хочет активироваться. ((( 
ЧТо в коде не так? Подскажите пожалуйста! 

// Function to manage trailing stop

void ManageTrailingStop()

  {

   for(int i = 0; i < PositionsTotal(); i++)  // Loop through all open positions

     {

      ulong ticket = PositionGetTicket(i); // Get the ticket number of the position

      if(PositionSelectByTicket(ticket))  // Select the position by ticket

        {

         string symbol = PositionGetString(POSITION_SYMBOL);

         double currentPrice = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? SymbolInfoDouble(symbol, SYMBOL_BID) : SymbolInfoDouble(symbol, SYMBOL_ASK);

         double stopLoss = PositionGetDouble(POSITION_SL);

         double profit = PositionGetDouble(POSITION_PROFIT);

         double openingPrice = PositionGetDouble(POSITION_PRICE_OPEN); // Get the opening price of the position


         // Check if profit exceeds the defined trailing start profit

         if(profit >= TrailingStartProfit)

           {

            // For Buy positions: Set initial stop loss at opening price

            if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)

              {

               if(stopLoss < openingPrice)

                 {

                  stopLoss = openingPrice; // Set stop loss to opening price

                  ct.PositionModify(symbol, stopLoss, 0);

                  Print("Initial Stop Loss Set for BUY at Opening Price: ", stopLoss);

                 }

               double newStopLoss = currentPrice - TrailingStopDistance * _Point; // Calculate new stop loss

               if(newStopLoss > stopLoss)  // Update stop loss only if the new one is higher

                 {

                  ct.PositionModify(symbol, newStopLoss, 0);

                 }

              }

            // For Sell positions: Set initial stop loss at opening price

            else

               if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)

                 {

                  if(stopLoss > openingPrice)

                    {

                     stopLoss = openingPrice; // Set stop loss to opening price

                     ct.PositionModify(symbol, stopLoss, 0);

                     Print("Initial Stop Loss Set for SELL at Opening Price: ", stopLoss);

                    }

                  double newStopLoss = currentPrice + TrailingStopDistance * _Point; // Calculate new stop loss

                  if(newStopLoss < stopLoss)  // Update stop loss only if the new one is lower

                    {

                     ct.PositionModify(symbol, newStopLoss, 0);

                    }

                 }

           }

        }

     }

  } 

 
Tretyakov Rostyslav #:
Ростислав, спасибо за оперативаный ответ!
Я новичок в MQL5, как вы поняли, подскажите вот эту первую часть из вашего ответа в какую часть кода нужно прописать, типа сразу после CTrade ct; в начале или в другом каком-то блоке кода?
bool  PositionOpen(
   const string     symbol,         // символ
   ENUM_ORDER_TYPE  order_type,     // тип торговой операции для открытия позиции
   double           volume,         // объем позиции
   double           price,          // цена исполнения
   double           sl,             // цена Stop Loss
   double           tp,             // цена Take Profit
   const string     comment=""      // комментарий
   )