В этой статье указан пример советника, который должен помещать ордер на покупку только в случае сигнала на покупку и отсутствия открытых длинных позиций. Аналогично в случае продажи - условия на продажу и отсутствие открытых коротких позиций.
При первом же тестировании выяснилось, что открывается не одна позиция, а несколько. Вопрос - почему?
Код советника читал, пытался понять и найти причину, но вроде всё ок.
Эта статья предназначена для начинающих, для тех, кто хочет научиться написанию простых советников на новом языке MQL5. Сначала мы определимся с тем, что требуется от нашего советника, а затем приступим к написанию того, каким образом он будет это делать. 1. Торговая стратегия Он будет следить за некоторыми индикаторами и при определенном...
В этой статье указан пример советника, который должен помещать ордер на покупку только в случае сигнала на покупку и отсутствия открытых длинных позиций. Аналогично в случае продажи - условия на продажу и отсутствие открытых коротких позиций.
При первом же тестировании выяснилось, что открывается не одна позиция, а несколько. Вопрос - почему?
Код советника читал, пытался понять и найти причину, но вроде всё ок.
Всем привет! Не могу сообразить как КОДОМ "нарисовать" трендовую, в будущее", параллельную колену зигзага. С контролем пересечения ценой этой трендовой в советнике. По сути Нужен сдвиг вправо Зигзага. Подскажите плз! Спасибо!
По двум точкам на прямой можно найти цену произвольной третьей точки на этой прямой, в том числе и в будущем (и наоборот).
//находит дату точки (координату X) на прямой, на заданную цену (координата Y)datetime GetPointTimeOnStraight(datetime eTime1, double ePrice1, datetime eTime2, double ePrice2, double ePrice3, string eSymbol, int eTimeFrame)
{
if(ePrice2-ePrice1==0) return(0.0);
//индекс бара соответствующий заданному времени, возможно задавать будующее времяint eIndex1=(eTime1>iTime(eSymbol,eTimeFrame,0))?(int)((iTime(eSymbol,eTimeFrame,0)-eTime1)/PeriodSeconds(eTimeFrame)):iBarShift(eSymbol,eTimeFrame,eTime1);
int eIndex2=(eTime2>iTime(eSymbol,eTimeFrame,0))?(int)((iTime(eSymbol,eTimeFrame,0)-eTime2)/PeriodSeconds(eTimeFrame)):iBarShift(eSymbol,eTimeFrame,eTime2);
int eIndex3=eIndex1+(int)((eIndex2-eIndex1)*(ePrice3-ePrice1)/(ePrice2-ePrice1));
return(iTime(eSymbol,eTimeFrame,eIndex3));
}
//находит цену точки (координату Y) на прямой, на заданное время (координата X)double GetPointPriceOnStraight(datetime eTime1, double ePrice1, datetime eTime2, double ePrice2, datetime eTime3, string eSymbol, int eTimeFrame)
{
//индекс бара соответствующий заданному времени, возможно задавать будующее времяint eIndex1=(eTime1>iTime(eSymbol,eTimeFrame,0))?(int)((iTime(eSymbol,eTimeFrame,0)-eTime1)/PeriodSeconds(eTimeFrame)):iBarShift(eSymbol,eTimeFrame,eTime1);
int eIndex2=(eTime2>iTime(eSymbol,eTimeFrame,0))?(int)((iTime(eSymbol,eTimeFrame,0)-eTime2)/PeriodSeconds(eTimeFrame)):iBarShift(eSymbol,eTimeFrame,eTime2);
if(eIndex2-eIndex1==0) return(0.0);
int eIndex3=(eTime3>iTime(eSymbol,eTimeFrame,0))?(int)((iTime(eSymbol,eTimeFrame,0)-eTime3)/PeriodSeconds(eTimeFrame)):iBarShift(eSymbol,eTimeFrame,eTime3);
return(ePrice1+(ePrice2-ePrice1)*(eIndex3-eIndex1)/(eIndex2-eIndex1));
}
Здравствуйте. Уделите пожалуйста внимание "Chechako ". Требуется указать на ошибки в коде, т.к. в тестере, советник не открывает ордера... При этом компилятор не выдает ошибок и предупреждений, в журнале аналогично - ошибок нет...
В этой статье указан пример советника, который должен помещать ордер на покупку только в случае сигнала на покупку и отсутствия открытых длинных позиций. Аналогично в случае продажи - условия на продажу и отсутствие открытых коротких позиций.
При первом же тестировании выяснилось, что открывается не одна позиция, а несколько. Вопрос - почему?
Код советника читал, пытался понять и найти причину, но вроде всё ок.
Здравствуйте, Иван! Никто новичков здесь не ругает, а наооборот, стараются помогать. Сам являюсь таким же новичком. Теперь, что касаемо Вашего вопроса. Несколько позиций открываются потому, что проверку на открытие позиции сделали, а прекратить выполнение проверки забыли. Оператор возврата return возвращает управление вызвавшей программе (взято из Справочника MQL5).
Нужно добавить return в код советника (выделен жёлтым шрифтом):
//--- есть ли открытые позиции?bool Buy_opened=false; // переменные, в которых будет храниться информация bool Sell_opened=false; // о наличии соответствующих открытых позицийif(PositionSelect(_Symbol)==true) // есть открытая позиция
{
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
{
Buy_opened=true; //это длинная позицияreturn;
}
elseif(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
{
Sell_opened=true; // это короткая позицияreturn;
}
}
Кроме того, чтобы компилятор не выдавал предупреждения, в условиях открытия позиций Buy и Sell необходимо добавить ещё одно условие для проверки OrderSend(mrequest,mresult). Это условие задается оператором if и будет выглядеть так:
И ещё необходимо учесть один момент. Бывает так, что при переходе с одного торгового дня на другой в 23:59:59 ранее открытая позиция закрывается и тут же в 00:00:00 открывается новая позиция. Это происходит так называемый rollover close и rollover open, который зависит от конкретного форекс-дилера и его условий торговли. Поищите на форуме, где-то была про это информация.
Всем привет. Люди нужна ваша помощь. Я соединил два зиг зага с разными параметрами в один индикатор (ошибок и предупреждений нет) Проблема вот в чём, неправильно прорисовывается 2 зигзаг.
Вот сам код (MQL5)
//+------------------------------------------------------------------+//| 6.mq5 |//| Copyright 2020, MetaQuotes Software Corp. |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright"2009-2017, MetaQuotes Software Corp."#property link"http://www.mql5.com"#property version"1.00"#property indicator_chart_window#property indicator_buffers6#property indicator_plots2//---- plot ZigZag 1#property indicator_label1"ZigZag1"#property indicator_type1DRAW_SECTION#property indicator_color1clrRed#property indicator_style1STYLE_SOLID#property indicator_width11//---- plot ZigZag 2#property indicator_label3"ZigZag2"#property indicator_type3DRAW_SECTION#property indicator_color3clrBlueViolet#property indicator_style3STYLE_SOLID#property indicator_width31//--- input parameters ZigZag 1inputint InpDepth =26;
inputint InpDeviation=12;
inputint InpBackstep =9;
//--- input parameters ZigZag 2inputint Inp_Depth =12;
inputint Inp_Deviation=5;
inputint Inp_Backstep =3;
//--- indicator buffers ZigZag 1double ZigZagBuffer[]; //double HighMapBuffer[]; //double LowMapBuffer[]; //int ExtRecalc=3; ////--- indicator buffers ZigZag 2double ZigZag_Buffer[]; // main bufferdouble HighMap_Buffer[]; // ZigZag high extremes (peaks)double LowMap_Buffer[]; // ZigZag low extremes (bottoms)int Ext_Recalc=3; // number of last extremes for recalculation//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- indicator buffers mappingSetIndexBuffer(0,ZigZagBuffer,INDICATOR_DATA);
SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);
//SetIndexBuffer(3,ZigZag_Buffer,INDICATOR_DATA);
SetIndexBuffer(4,HighMap_Buffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(5,LowMap_Buffer,INDICATOR_CALCULATIONS);
//--- set short name and digitsPlotIndexSetString(0,PLOT_LABEL,"ZigZag("+(string)InpDepth+","+(string)InpDeviation+","+(string)InpBackstep+")");
PlotIndexSetString(3,PLOT_LABEL,"ZigZag("+(string)Inp_Depth+","+(string)Inp_Deviation+","+(string)Inp_Backstep+")");
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- set an empty valuePlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(3,PLOT_EMPTY_VALUE,0.0);
//---return(0);
}
//+------------------------------------------------------------------+//| Search for the index of the highest bar |//+------------------------------------------------------------------+int Highest(constdouble &array[],int depth,int start)
{
//--- validation of the start indexif(start<0)
{
Print("Invalid parameter in the function Highest, start =",start);
return0;
}
int size=ArraySize(array);
//--- reduce depth to the available data if neededif(start-depth<0)
depth=start;
double max=array[start];
//--- start searchingint index=start;
for(int i=start; i>start-depth; i--)
{
if(array[i]>max)
{
index=i;
max=array[i];
}
}
//--- return index of the highest barreturn(index);
}
//+------------------------------------------------------------------+//| Search for the index of the lowest bar |//+------------------------------------------------------------------+int Lowest(constdouble &array[],int depth,int start)
{
//--- validation of the start indexif(start<0)
{
Print("Invalid parameter in the function iLowest, start =",start);
return0;
}
int size=ArraySize(array);
//--- reduce depth to the available data if neededif(start-depth<0)
depth=start;
double min=array[start];
//--- start searchingint index=start;
for(int i=start; i>start-depth; i--)
{
if(array[i]<min)
{
index=i;
min=array[i];
}
}
//--- return index of the lowest barreturn(index);
}
//--- auxiliary enumerationenum EnSearchMode
{
Peak=1, // searching for the next ZigZag peak
Bottom=-1// searching for the next ZigZag bottom
};
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+int zig(constint rates_total,
constint prev_calculated,
constdatetime &time[],
constdouble &open[],
constdouble &high[],
constdouble &low[],
constdouble &close[],
constlong &tick_volume[],
constlong &volume[],
constint &spread[])
{
int i=0;
int limit=0,extreme_counter=0,extreme_search=0;
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;
//--- initializingif(prev_calculated==0)
{
ArrayInitialize(ZigZag_Buffer,0.0);
ArrayInitialize(HighMap_Buffer,0.0);
ArrayInitialize(LowMap_Buffer,0.0);
}
//---if(rates_total<100)
//return(0);//--- set start position for calculationsif(prev_calculated==0)
limit=Inp_Depth;
//--- ZigZag was already calculated beforeif(prev_calculated>0)
{
i=rates_total-1;
//--- searching for the third extremum from the last uncompleted barwhile(extreme_counter<ExtRecalc && i>rates_total-100)
{
res=ZigZag_Buffer[i];
if(res!=0)
extreme_counter++;
i--;
}
i++;
limit=i;
//--- what type of exremum we search forif(LowMap_Buffer[i]!=0)
{
curlow=LowMap_Buffer[i];
extreme_search=Peak;
}
else
{
curhigh=HighMap_Buffer[i];
extreme_search=Bottom;
}
//--- clear indicator valuesfor(i=limit+1; i<rates_total && !IsStopped(); i++)
{
ZigZag_Buffer[i] =0.0;
LowMap_Buffer[i] =0.0;
HighMap_Buffer[i]=0.0;
}
}
//--- searching for high and low extremesfor(shift=limit; shift<rates_total && !IsStopped(); shift++)
{
//--- low
val=low[Lowest(low,Inp_Depth,shift)];
if(val==last_low)
val=0.0;
else
{
last_low=val;
if((low[shift]-val)>Inp_Deviation*_Point)
val=0.0;
else
{
for(back=1; back<=Inp_Backstep; back++)
{
res=LowMap_Buffer[shift-back];
if((res!=0) && (res>val))
LowMap_Buffer[shift-back]=0.0;
}
}
}
if(low[shift]==val)
LowMap_Buffer[shift]=val;
else
LowMap_Buffer[shift]=0.0;
//--- high
val=high[Highest(high,Inp_Depth,shift)];
if(val==last_high)
val=0.0;
else
{
last_high=val;
if((val-high[shift])>Inp_Deviation*_Point)
val=0.0;
else
{
for(back=1; back<=Inp_Backstep; back++)
{
res=HighMap_Buffer[shift-back];
if((res!=0) && (res<val))
HighMap_Buffer[shift-back]=0.0;
}
}
}
if(high[shift]==val)
HighMap_Buffer[shift]=val;
else
HighMap_Buffer[shift]=0.0;
}
//--- set last valuesif(extreme_search==0) // undefined values
{
last_low=0;
last_high=0;
}
else
{
last_low=curlow;
last_high=curhigh;
}
//--- final selection of extreme points for ZigZagfor(shift=limit; shift<rates_total && !IsStopped(); shift++)
{
res=0.0;
switch(extreme_search)
{
case0: // search for an extremumif(last_low==0 && last_high==0)
{
if(HighMap_Buffer[shift]!=0)
{
last_high=high[shift];
last_high_pos=shift;
extreme_search=Bottom;
ZigZag_Buffer[shift]=last_high;
res=1;
}
if(LowMap_Buffer[shift]!=0)
{
last_low=low[shift];
last_low_pos=shift;
extreme_search=Peak;
ZigZag_Buffer[shift]=last_low;
res=1;
}
}
break;
case Peak: // search for peakif(LowMap_Buffer[shift]!=0.0 && LowMap_Buffer[shift]<last_low && HighMap_Buffer[shift]==0.0)
{
ZigZag_Buffer[last_low_pos]=0.0;
last_low_pos=shift;
last_low=LowMap_Buffer[shift];
ZigZag_Buffer[shift]=last_low;
res=1;
}
if(HighMap_Buffer[shift]!=0.0 && LowMap_Buffer[shift]==0.0)
{
last_high=HighMap_Buffer[shift];
last_high_pos=shift;
ZigZag_Buffer[shift]=last_high;
extreme_search=Bottom;
res=1;
}
break;
case Bottom: // search for bottomif(HighMap_Buffer[shift]!=0.0 && HighMap_Buffer[shift]>last_high && LowMap_Buffer[shift]==0.0)
{
ZigZag_Buffer[last_high_pos]=0.0;
last_high_pos=shift;
last_high=HighMap_Buffer[shift];
ZigZag_Buffer[shift]=last_high;
}
if(LowMap_Buffer[shift]!=0.0 && HighMap_Buffer[shift]==0.0)
{
last_low=LowMap_Buffer[shift];
last_low_pos=shift;
ZigZag_Buffer[shift]=last_low;
extreme_search=Peak;
}
break;
default:
return(rates_total);
}
}
//--- return value of prev_calculated for next callreturn(rates_total);
}
//+------------------------------------------------------------------+intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime &time[],
constdouble &open[],
constdouble &high[],
constdouble &low[],
constdouble &close[],
constlong &tick_volume[],
constlong &volume[],
constint &spread[])
{
int i=0;
int limit=0,extreme_counter=0,extreme_search=0;
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;
//--- initializingif(prev_calculated==0)
{
ArrayInitialize(ZigZagBuffer,0.0);
ArrayInitialize(HighMapBuffer,0.0);
ArrayInitialize(LowMapBuffer,0.0);
}
//---if(rates_total<100)
return(0);
//--- set start position for calculationsif(prev_calculated==0)
limit=InpDepth;
//--- ZigZag was already calculated beforeif(prev_calculated>0)
{
i=rates_total-1;
//--- searching for the third extremum from the last uncompleted barwhile(extreme_counter<ExtRecalc && i>rates_total-100)
{
res=ZigZagBuffer[i];
if(res!=0)
extreme_counter++;
i--;
}
i++;
limit=i;
//--- what type of exremum we search forif(LowMapBuffer[i]!=0)
{
curlow=LowMapBuffer[i];
extreme_search=Peak;
}
else
{
curhigh=HighMapBuffer[i];
extreme_search=Bottom;
}
//--- clear indicator valuesfor(i=limit+1; i<rates_total && !IsStopped(); i++)
{
ZigZagBuffer[i] =0.0;
LowMapBuffer[i] =0.0;
HighMapBuffer[i]=0.0;
}
}
//--- searching for high and low extremesfor(shift=limit; 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 valuesif(extreme_search==0) // undefined values
{
last_low=0;
last_high=0;
}
else
{
last_low=curlow;
last_high=curhigh;
}
//--- final selection of extreme points for ZigZagfor(shift=limit; shift<rates_total && !IsStopped(); shift++)
{
res=0.0;
switch(extreme_search)
{
case0: // search for an extremumif(last_low==0 && last_high==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)
{
last_low=low[shift];
last_low_pos=shift;
extreme_search=Peak;
ZigZagBuffer[shift]=last_low;
res=1;
}
}
break;
case Peak: // search for peakif(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: // search for bottomif(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 callreturn(rates_total);
}
//+------------------------------------------------------------------+
Всем привет. Люди нужна ваша помощь. Я соединил два зиг зага с разными параметрами в один индикатор (ошибок и предупреждений нет) Проблема вот в чём, неправильно прорисовывается 2 зигзаг.
Вот сам код (MQL5)
всё у вас работает - немного сверху циферки поправьте
всё у вас работает - немного сверху циферки поправьте
Спасибо за помощь. Подскажите ещё один момент, почему у меня получилось так, что один зигзаг формируется как обычно (максимум, минимум), а второй формируется только по максимуму.
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Здравствуйте.
Я новичок, так что сильно не ругайте. )
https://www.mql5.com/ru/articles/100
В этой статье указан пример советника, который должен помещать ордер на покупку только в случае сигнала на покупку и отсутствия открытых длинных позиций. Аналогично в случае продажи - условия на продажу и отсутствие открытых коротких позиций.
При первом же тестировании выяснилось, что открывается не одна позиция, а несколько. Вопрос - почему?
Код советника читал, пытался понять и найти причину, но вроде всё ок.
Здравствуйте.
Я новичок, так что сильно не ругайте. )
https://www.mql5.com/ru/articles/100В этой статье указан пример советника, который должен помещать ордер на покупку только в случае сигнала на покупку и отсутствия открытых длинных позиций. Аналогично в случае продажи - условия на продажу и отсутствие открытых коротких позиций.
При первом же тестировании выяснилось, что открывается не одна позиция, а несколько. Вопрос - почему?
Код советника читал, пытался понять и найти причину, но вроде всё ок.
Попробуйте заменить
if(Buy_opened)на
Аналогично на продажу
Попробуйте заменить
на
Аналогично на продажу
Не поможет. Читайте чаще документацию.
"нарисовать" трендовую, в будущее"
По двум точкам на прямой можно найти цену произвольной третьей точки на этой прямой, в том числе и в будущем (и наоборот).
Здравствуйте.
Уделите пожалуйста внимание "Chechako ".
Требуется указать на ошибки в коде, т.к. в тестере, советник не открывает ордера...
При этом компилятор не выдает ошибок и предупреждений, в журнале аналогично - ошибок нет...
Здравствуйте.
Я новичок, так что сильно не ругайте. )
https://www.mql5.com/ru/articles/100
В этой статье указан пример советника, который должен помещать ордер на покупку только в случае сигнала на покупку и отсутствия открытых длинных позиций. Аналогично в случае продажи - условия на продажу и отсутствие открытых коротких позиций.
При первом же тестировании выяснилось, что открывается не одна позиция, а несколько. Вопрос - почему?
Код советника читал, пытался понять и найти причину, но вроде всё ок.
Здравствуйте, Иван! Никто новичков здесь не ругает, а наооборот, стараются помогать. Сам являюсь таким же новичком. Теперь, что касаемо Вашего вопроса. Несколько позиций открываются потому, что проверку на открытие позиции сделали, а прекратить выполнение проверки забыли. Оператор возврата return возвращает управление вызвавшей программе (взято из Справочника MQL5).
Нужно добавить return в код советника (выделен жёлтым шрифтом):
Кроме того, чтобы компилятор не выдавал предупреждения, в условиях открытия позиций Buy и Sell необходимо добавить ещё одно условие для проверки OrderSend(mrequest,mresult). Это условие задается оператором if и будет выглядеть так:
И ещё необходимо учесть один момент. Бывает так, что при переходе с одного торгового дня на другой в 23:59:59 ранее открытая позиция закрывается и тут же в 00:00:00 открывается новая позиция. Это происходит так называемый rollover close и rollover open, который зависит от конкретного форекс-дилера и его условий торговли. Поищите на форуме, где-то была про это информация.
С уважением, Владимир.
Всем привет. Люди нужна ваша помощь. Я соединил два зиг зага с разными параметрами в один индикатор (ошибок и предупреждений нет) Проблема вот в чём, неправильно прорисовывается 2 зигзаг.
Вот сам код (MQL5)
Всем привет. Люди нужна ваша помощь. Я соединил два зиг зага с разными параметрами в один индикатор (ошибок и предупреждений нет) Проблема вот в чём, неправильно прорисовывается 2 зигзаг.
Вот сам код (MQL5)
всё у вас работает - немного сверху циферки поправьте
всё у вас работает - немного сверху циферки поправьте
Спасибо за помощь. Подскажите ещё один момент, почему у меня получилось так, что один зигзаг формируется как обычно (максимум, минимум), а второй формируется только по максимуму.