Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 919

 
Artyom Trishkin:

У вас расчёт индикатора идёт от начала к концу (от самых поздних исторических данных к самым свежим - к текущим). А это говорит об индексации как в таймсерии. Значит и массивы должны быть соответственно индексированы, что у вас и есть.

Что не так работает тогда?

да все работает один в один мой порт в MQL5 из MQL4, а вижу что код некрасивый из за ArraySetAsSeries() вот и спрашиваю

вот оба кода

ну научите образцово показательно написать этот индикатор под MT5 !!! - не красивый мой код и точка! )))

ЗЫ совсем не помню как под МТ5 писать индикаторы, сел и за 40 минут тупо переписал с помощью хелпа, но результат... имхо на троечку (((

Файлы:
PTL.mq4  8 kb
PTL.mq5  13 kb
 
Igor Makanu:

да все работает один в один мой порт в MQL5 из MQL4, а вижу что код некрасивый из за ArraySetAsSeries() вот и спрашиваю

вот оба кода

ну научите образцово показательно написать этот индикатор под MT5 !!! - не красивый мой код и точка! )))

При обратном цикле вам нужно обязательно делать массивы таймсериями иначе индексация буферов в цикле не будет совпадать с индексацией требуемых данных - индекс цикла в массиве буферов индикатора будет идти от начала к концу, а в open[], high[], low[], close[] и остальных - от конца к началу. Ну или переворачивайте цикл для соответствия его индексации массивов open[], high[], low[], close[] и остальных с индексацией буферов, что сложнее.

Если хотите аллегории, и будет понятнее, то вот вам аллегория:

Вы стоите у ж/д полотна и смотрите на два поезда. Они либо идут в одном направлении - оба слева-направо (ArraySetAsSeries(array,true) - первый поезд и цикл от limit до 0 - второй поезд),
либо идут навстречу друг-другу - (ArraySetAsSeries(array,false) - справа-налево - первый поезд, и цикл от limit до 0 - слева-направо- второй поезд)

И, да: код не глядел - не охота скачивать, сохранять у себя (и так очень много ненужных кодов с форума), сравнивать их промеж собою...

Проще вам было выложить их кодами в сообщение - один и второй - тогда было бы видно сразу что к чему.

 
Artyom Trishkin:

 Ну или переворачивайте цикл для соответствия его индексации массивов open[], high[], low[], close[] и остальных, что сложнее.

я сегодня весь вечер переворачиваю, вот терпение закончилось (((

насколько я понял проблему:

- в МТ5 массивы которые назначаются индикаторными буферами по умолчанию индексируются слева на право;

- в МТ5 таймсерии  open[], high[], low[], close[]  доступные из OnCalculate() всегда передаются с индексацией справо на лево

- т..е исходя из пп 1 и 2, чтобы произвести расчет индикатора из конца истории к нулевому бару придется:

а) или переназначить индексацию буфферных массивов

б) или делать цикл в котором будет пересчет нумерации элементов массива слева на право, а в другом справо на лево: 

for(i=limit;i>=0;i--)
     {
      BufBarsBuffer1[limit - i] = open[i];
      ...
      }


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

исходники:

МТ5:

//+------------------------------------------------------------------+
//|                                          Perfect_Trend_Lines.mq5 |
//|                                                            IgorM |
//|                                                                  |
//+------------------------------------------------------------------+
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 9
#property indicator_plots   5
//--- plot BufBars
#property indicator_label1  "BufBars"
#property indicator_type1   DRAW_COLOR_BARS
#property indicator_color1  clrRed,clrAqua,clrNONE
#property indicator_style1  STYLE_SOLID
#property indicator_width1  3
//--- plot BufASELL
#property indicator_label2  "BufASELL"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrBlue
#property indicator_style2  STYLE_SOLID
#property indicator_width2  5
//--- plot BufABUY
#property indicator_label3  "BufABUY"
#property indicator_type3   DRAW_ARROW
#property indicator_color3  clrRed
#property indicator_style3  STYLE_SOLID
#property indicator_width3  5
//--- plot BufLSELL
#property indicator_label4  "BufLSELL"
#property indicator_type4   DRAW_LINE
#property indicator_color4  clrBlue
#property indicator_style4  STYLE_SOLID
#property indicator_width4  2
//--- plot BufLBUY
#property indicator_label5  "BufLBUY"
#property indicator_type5   DRAW_LINE
#property indicator_color5  clrRed
#property indicator_style5  STYLE_SOLID
#property indicator_width5  2
//--- input parameters
input int SlowLength         = 7; //Slow length
input int SlowPipDisplace    = 0; //Slow pip displace
input int FastLength         = 3; //Fast length
input int FastPipDisplace    = 0; //Fast pip displace
//--- indicator buffers
double         BufBarsBuffer1[];
double         BufBarsBuffer2[];
double         BufBarsBuffer3[];
double         BufBarsBuffer4[];
double         BufBarsColors[];
double         BufASELLBuffer[];
double         BufABUYBuffer[];
double         BufLSELLBuffer[];
double         BufLBUYBuffer[];
static int trend=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BufBarsBuffer1,INDICATOR_DATA);
   SetIndexBuffer(1,BufBarsBuffer2,INDICATOR_DATA);
   SetIndexBuffer(2,BufBarsBuffer3,INDICATOR_DATA);
   SetIndexBuffer(3,BufBarsBuffer4,INDICATOR_DATA);
   SetIndexBuffer(4,BufBarsColors,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(5,BufASELLBuffer,INDICATOR_DATA);
   SetIndexBuffer(6,BufABUYBuffer,INDICATOR_DATA);
   SetIndexBuffer(7,BufLSELLBuffer,INDICATOR_DATA);
   SetIndexBuffer(8,BufLBUYBuffer,INDICATOR_DATA);
   for(int i=0;i<9;i++)
     {
      PlotIndexSetInteger(i,PLOT_DRAW_BEGIN,FastLength+1);
      PlotIndexSetDouble(i,PLOT_EMPTY_VALUE,0.0);
     }
   ArraySetAsSeries(BufBarsBuffer1,true);
   ArraySetAsSeries(BufBarsBuffer2,true);
   ArraySetAsSeries(BufBarsBuffer3,true);
   ArraySetAsSeries(BufBarsBuffer4,true);
   ArraySetAsSeries(BufBarsColors,true);
   ArraySetAsSeries(BufABUYBuffer,true);
   ArraySetAsSeries(BufASELLBuffer,true);
   ArraySetAsSeries(BufLBUYBuffer,true);
   ArraySetAsSeries(BufLSELLBuffer,true);
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
   PlotIndexSetInteger(1,PLOT_ARROW,234);
   PlotIndexSetInteger(2,PLOT_ARROW,233);
   PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,-20);
   PlotIndexSetInteger(2,PLOT_ARROW_SHIFT,20);
   trend=0;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---
   int i,limit;
   double thigh1,tlow1,thigh2,tlow2,trendUp,trendDn;
   ArraySetAsSeries(open,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); ArraySetAsSeries(close,true);
   if(prev_calculated==0)
     {
      limit=rates_total-1;
      BufLSELLBuffer[limit]=high[limit];
      BufLBUYBuffer[limit]=low[limit];
      limit--;
     }
   else limit=rates_total-prev_calculated+1;
   for(i=limit;i>=0;i--)
     {
      thigh1= high[iHighest(NULL,0,MODE_HIGH,SlowLength,i)]+SlowPipDisplace * _Point;
      tlow1 = low[iLowest(NULL,0,MODE_LOW,SlowLength,i)]-SlowPipDisplace * _Point;
      thigh2= high[iHighest(NULL,0,MODE_HIGH,FastLength,i)]+FastPipDisplace * _Point;
      tlow2 = low[iLowest(NULL,0,MODE_LOW,FastLength,i)]-FastPipDisplace * _Point;
      if(close[i]>BufLBUYBuffer[i+1])  trendUp=tlow1;  else trendUp=thigh1;
      if(close[i]>BufLSELLBuffer[i+1]) trendDn=tlow2;  else trendDn=thigh2;
      BufLSELLBuffer[i]= trendDn;
      BufLBUYBuffer[i] = trendUp;
      BufBarsBuffer1[i] = 0.0;
      BufBarsBuffer2[i] = 0.0;
      BufBarsBuffer3[i] = 0.0;
      BufBarsBuffer4[i] = 0.0;
      BufBarsColors[i]  = 2;
      if(close[i]<trendUp && close[i]<trendDn)
        {
         BufBarsBuffer1[i] = open[i];
         BufBarsBuffer2[i] = high[i];
         BufBarsBuffer3[i] = low[i];
         BufBarsBuffer4[i] = close[i];
         BufBarsColors[i]  = 0;
        }
      if(close[i]>trendUp && close[i]>trendDn)
        {
         BufBarsBuffer1[i] = open[i];
         BufBarsBuffer2[i] = high[i];
         BufBarsBuffer3[i] = low[i];
         BufBarsBuffer4[i] = close[i];
         BufBarsColors[i]  = 1;
        }
      if(close[i]>trendUp && close[i]>trendDn && trend!=1)
        {
         BufABUYBuffer[i]=trendDn;
         BufASELLBuffer[i]=0.0;
         trend=1;
        }
      if(close[i]<trendUp && close[i]<trendDn && trend!=2)
        {
         BufASELLBuffer[i]=trendUp;
         BufABUYBuffer[i]=0.0;
         trend=2;
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

МТ4:

//+------------------------------------------------------------------+
//|                                            PerfecTrend Lines.mq4 |
//|                 Copyright © 2005-2007, MetaQuotes Software Corp. |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."

#property indicator_chart_window
#property indicator_buffers 6
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_color3 Red
#property indicator_color4 Aqua
#property indicator_color5 Blue
#property indicator_color6 Red

extern int SlowLength         = 7; // Slow length
extern int SlowPipDisplace    = 0; // Slow pip displace
extern int FastLength         = 3; // Fast length
extern int FastPipDisplace    = 0; // Fast pip displace

double Buf_NTLine1[],Buf_NTLine2[],Buf_NTBar1[],Buf_NTBar2[],Buf_NTSig1[],Buf_NTSig2[];
static int trend=0;
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(6);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2);
   SetIndexBuffer(0,Buf_NTLine1);
   SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2);
   SetIndexBuffer(1,Buf_NTLine2);
   SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_SOLID,2);
   SetIndexBuffer(2,Buf_NTBar1);
   SetIndexStyle(3,DRAW_HISTOGRAM,STYLE_SOLID,2);
   SetIndexBuffer(3,Buf_NTBar2);
   SetIndexStyle(4,DRAW_ARROW,STYLE_DASH,3);
   SetIndexArrow(4,108);
   SetIndexBuffer(4,Buf_NTSig1);
   SetIndexStyle(5,DRAW_ARROW,STYLE_DASH,3);
   SetIndexArrow(5,108);
   SetIndexBuffer(5,Buf_NTSig2);
   IndicatorShortName("NeuroTrend");
   SetIndexLabel(0,"NTLine1");
   SetIndexLabel(1,"NTLine2");
   SetIndexLabel(2,"NTBar1");
   SetIndexLabel(3,"NTBar2");
   SetIndexLabel(4,"NTSig1");
   SetIndexLabel(5,"NTSig2");
   SetIndexDrawBegin(0,FastLength+1);
   SetIndexDrawBegin(1,FastLength+1);
   SetIndexDrawBegin(2,FastLength+1);
   SetIndexDrawBegin(3,FastLength+1);
   SetIndexDrawBegin(4,FastLength+1);
   SetIndexDrawBegin(5,FastLength+1);
   trend=0;
   return (0);
  }
//+------------------------------------------------------------------+
int deinit()
  {
   return (0);
  }
//+------------------------------------------------------------------+
int start()
  {
   int i,limit;
   double thigh1,tlow1,thigh2,tlow2,trendA,trendB,trendUP,trendDN;
   if(Bars <= FastLength) return (0);
   if(IndicatorCounted()==0) limit=Bars-1;
   if(IndicatorCounted()>0) limit=Bars-IndicatorCounted()-1;
   for(i=limit;i>=0;i--)
     {
      thigh1= High[iHighest(NULL,0,MODE_HIGH,SlowLength,i)]+SlowPipDisplace * Point;
      tlow1 = Low[iLowest(NULL,0,MODE_LOW,SlowLength,i)]-SlowPipDisplace * Point;
      thigh2= High[iHighest(NULL,0,MODE_HIGH,FastLength,i)]+FastPipDisplace * Point;
      tlow2 = Low[iLowest(NULL,0,MODE_LOW,FastLength,i)]-FastPipDisplace * Point;
      if(Close[i] > Buf_NTLine1[i+1]) trendA = tlow1; else trendA = thigh1;
      if(Close[i] > Buf_NTLine2[i+1]) trendB = tlow2; else trendB = thigh2;
      Buf_NTLine1[i] = trendA;
      Buf_NTLine2[i] = trendB;

      trendUP = 0.0;
      trendDN = 0.0;
      if(Close[i] < trendA && Close[i] < trendB) { trendUP = High[i]; trendDN = Low[i]; }
      if(Close[i] > trendA && Close[i] > trendB) { trendUP = Low[i];  trendDN = High[i];}
      Buf_NTBar1[i] = trendUP;
      Buf_NTBar2[i] = trendDN;
      if(Close[i] > trendB && Close[i] > trendA && trend != 1) { Buf_NTSig1[i] = trendB; Buf_NTSig2[i] = EMPTY_VALUE; trend = 1; }
      if(Close[i] < trendB && Close[i] < trendA && trend != 2) { Buf_NTSig2[i] = trendB; Buf_NTSig1[i] = EMPTY_VALUE; trend = 2; }
     }
   return (0);
  }
//+------------------------------------------------------------------+
 
Igor Makanu:

я сегодня весь вечер переворачиваю, вот терпение закончилось (((

насколько я понял проблему:

- в МТ5 массивы которые назначаются индикаторными буферами по умолчанию индексируются слева на право;

- в МТ5 таймсерии  open[], high[], low[], close[]  доступные из OnCalculate() всегда передаются с индексацией справо на лево

- т..е исходя из пп 1 и 2, чтобы произвести расчет индикатора из конца истории к нулевому бару придется:

а) или переназначить индексацию буфферных массивов

б) или делать цикл в котором будет пересчет нумерации элементов массива слева на право, а в другом справо на лево: 


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

Массивы все индексируются справа-нелево. Поэтому, чтобы полностью соответствовать циклу слева-направо (а он от limit до 0 - именно слева-направо), то вам нужно всем используемым массивам задать нужную индексацию: буферам в OnInit(), используемым таймсериям - в OnCalculate().

Либо делать цикл от 0 до limit, что не всегда просто сделать при портации из mql4 в mql5

Поэтому вариант с ArraySetAsSeries() в данном случае выгодней.

 
Artyom Trishkin:

Массивы все индексируются справа-нелево. Поэтому, чтобы полностью соответствовать циклу слева-направо (а он от limit до 0 - именно слева-направо), то вам нужно всем используемым массивам задать нужную индексацию: буферам в OnInit(), используемым таймсериям - в OnCalculate().

Либо делать цикл от 0 до limit, что не всегда просто сделать при портации из mql4 в mql5

Поэтому вариант с ArraySetAsSeries() в данном случае выгодней.

ну вот смотри, убрал из своего кода все ArraySetAsSeries()  (вверху в Init() и в OnCalculate() в первых строках) и исправил цикл:

for(i=0;i<limit;i++)

 в теории все должно сойтись! но нет! графики то разные получились, вот что никак не могу понять!

Файлы:
1.jpg  747 kb
 
Igor Makanu:

ну вот смотри, убрал из своего кода все ArraySetAsSeries()  (вверху в Init() и в OnCalculate() в первых строках) и исправил цикл:

for(i=0;i<limit;i++)

 в теории все должно сойтись! но нет! графики то разные получились, вот что никак не могу понять!

Я ж говорю - сложнее. Логику менять нужно. Не достаточно просто цикл перевернуть.

Вот один маленький пример: в коде есть

Buf_NTLine1[i+1])

куда будет обращаться индекс i+1 при разных индексациях массивов?

и там много такого. IHighest() - начало и количество... Откуда начинает при одной индексации и при другой?

И т.д. ...

 
Artyom Trishkin:

и там много такого. IHighest() - начало и количество... Откуда начинает при одной индексации и при другой?

блин! точно! молодец!!! да, вот тут то и весь прикол!!!

нда... много отличий в МТ5, уж очень много на голову программиста ложится всяких проверок и всяких предусмотрительностей...

да, вот еще вопрос, вроде не давно видел сообщение, что в МТ5 не всегда все в Init() корректно инициализируется, вроде связано, что Init() может закончится даже если не готовы таймфреймы

вчера несколько раз видел баг: если этот индикатор под МТ5 переключать по ТФ, то иногда индикаторные буфера могут быть не пустыми - вроде старые значения остаются если в OnCalculate() не присваивать каждому элементу в индикаторном массиве конкретное значение, попробовал в Init() воткнуть ArrayInitialize(arr, 0.0) - тоже то работает то нет..

насколько я правильно понимаю:

- в МТ5 при инициализации в Init()  индикаторные буфера автоматически не инициализируются? (в МТ4 ну не помню чтобы в буферах что то оставалось)

- в МТ5 в Init()  размеры буферных массивов могут быть неизвестны если не подгрузилась история, поэтому ArrayInitialize(arr, 0.0) тоже не всегда корректно инициализирует буфера?

 
Igor Makanu:

блин! точно! молодец!!! да, вот тут то и весь прикол!!!

нда... много отличий в МТ5, уж очень много на голову программиста ложится всяких проверок и всяких предусмотрительностей...

да, вот еще вопрос, вроде не давно видел сообщение, что в МТ5 не всегда все в Init() корректно инициализируется, вроде связано, что Init() может закончится даже если не готовы таймфреймы

вчера несколько раз видел баг: если этот индикатор под МТ5 переключать по ТФ, то иногда индикаторные буфера могут быть не пустыми - вроде старые значения остаются если в OnCalculate() не присваивать каждому элементу в индикаторном массиве конкретное значение, попробовал в Init() воткнуть ArrayInitialize(arr, 0.0) - тоже то работает то нет..

насколько я правильно понимаю:

- в МТ5 при инициализации в Init()  индикаторные буфера автоматически не инициализируются? (в МТ4 ну не помню чтобы в буферах что то оставалось)

- в МТ5 в Init()  размеры буферных массивов могут быть неизвестны если не подгрузилась история, поэтому ArrayInitialize(arr, 0.0) тоже не всегда корректно инициализирует буфера?

//+------------------------------------------------------------------+
//|                                            PerfecTrend Lines.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 9
#property indicator_plots   5
//--- plot Top
#property indicator_label1  "Top"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Bottom
#property indicator_label2  "Bottom"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrBlue
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- plot Candles
#property indicator_label3  "Open;High;Low;Close"
#property indicator_type3   DRAW_COLOR_CANDLES
#property indicator_color3  clrDodgerBlue,clrOrangeRed,clrDarkGray
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1
//--- plot ArrowUP
#property indicator_label4  "ArrowUP"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  clrRed
#property indicator_style4  STYLE_SOLID
#property indicator_width4  1
//--- plot ArrowDN
#property indicator_label5  "ArrowDN"
#property indicator_type5   DRAW_ARROW
#property indicator_color5  clrBlue
#property indicator_style5  STYLE_SOLID
#property indicator_width5  1
//--- input parameters
input uint     InpPeriodSlow     =  7;    // Slow length
input uint     InpDistanceSlow   =  0;    // Slow pip displace
input uint     InpPeriodFast     =  3;    // Fast length
input uint     InpDistanceFast   =  0;    // Fast pip displace
//--- indicator buffers
double         BufferTop[];
double         BufferBottom[];
double         BufferCandlesOpen[];
double         BufferCandlesHigh[];
double         BufferCandlesLow[];
double         BufferCandlesClose[];
double         BufferColors[];
double         BufferArrowUP[];
double         BufferArrowDN[];
//--- global variables
int            period_slow;
int            period_fast;
int            period_max;
double         distance_slow;
double         distance_fast;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- set global variables
   period_fast=int(InpPeriodFast<1 ? 1 : InpPeriodFast);
   period_slow=int(InpPeriodSlow<1 ? 1 : InpPeriodSlow);
   period_max=fmax(period_fast,period_slow);
   distance_fast=InpDistanceFast*Point();
   distance_slow=InpDistanceSlow*Point();
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferTop,INDICATOR_DATA);
   SetIndexBuffer(1,BufferBottom,INDICATOR_DATA);
   SetIndexBuffer(2,BufferCandlesOpen,INDICATOR_DATA);
   SetIndexBuffer(3,BufferCandlesHigh,INDICATOR_DATA);
   SetIndexBuffer(4,BufferCandlesLow,INDICATOR_DATA);
   SetIndexBuffer(5,BufferCandlesClose,INDICATOR_DATA);
   SetIndexBuffer(6,BufferColors,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(7,BufferArrowUP,INDICATOR_DATA);
   SetIndexBuffer(8,BufferArrowDN,INDICATOR_DATA);
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
   PlotIndexSetInteger(3,PLOT_ARROW,108);
   PlotIndexSetInteger(4,PLOT_ARROW,108);
//--- setting indicator parameters
   IndicatorSetString(INDICATOR_SHORTNAME,"NeuroTrend");
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferTop,true);
   ArraySetAsSeries(BufferBottom,true);
   ArraySetAsSeries(BufferCandlesOpen,true);
   ArraySetAsSeries(BufferCandlesHigh,true);
   ArraySetAsSeries(BufferCandlesLow,true);
   ArraySetAsSeries(BufferCandlesClose,true);
   ArraySetAsSeries(BufferColors,true);
   ArraySetAsSeries(BufferArrowUP,true);
   ArraySetAsSeries(BufferArrowDN,true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//--- Установка массивов буферов как таймсерий
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);
//--- Проверка и расчёт количества просчитываемых баров
   if(rates_total<fmax(period_max,4)) return 0;
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-period_max-1;
      ArrayInitialize(BufferTop,EMPTY_VALUE);
      ArrayInitialize(BufferBottom,EMPTY_VALUE);
      ArrayInitialize(BufferCandlesOpen,EMPTY_VALUE);
      ArrayInitialize(BufferCandlesHigh,EMPTY_VALUE);
      ArrayInitialize(BufferCandlesLow,EMPTY_VALUE);
      ArrayInitialize(BufferCandlesClose,EMPTY_VALUE);
      ArrayInitialize(BufferArrowUP,EMPTY_VALUE);
      ArrayInitialize(BufferArrowDN,EMPTY_VALUE);
     }
//---
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      int bhs=Highest(period_slow,i);
      int bls=Lowest(period_slow,i);
      int bhf=Highest(period_fast,i);
      int blf=Lowest(period_fast,i);
      if(bhs==WRONG_VALUE || bls==WRONG_VALUE || bhf==WRONG_VALUE || blf==WRONG_VALUE)
         continue;
      double thigh1=high[bhs]+distance_slow;
      double tlow1=low[bls]-distance_slow;
      double thigh2=high[bhf]+distance_fast;
      double tlow2=low[blf]-distance_fast;
      
      double trendA=(close[i]>BufferTop[i+1] ? tlow1 : thigh1);
      double trendB=(close[i]>BufferBottom[i+1] ? tlow2 : thigh2);
      BufferTop[i]=trendA;
      BufferBottom[i]=trendB;

      double trendUP=0;
      double trendDN=0;
      
      BufferCandlesOpen[i]=open[i];
      BufferCandlesHigh[i]=high[i];
      BufferCandlesLow[i]=low[i];
      BufferCandlesClose[i]=close[i];
      BufferColors[i]=2;
      if(close[i]<trendA && close[i]<trendB)
        {
         BufferColors[i]=1;
         trendUP=high[i];
         trendDN=low[i];
        }
      else if(close[i]>trendA && close[i]>trendB)
        {
         BufferColors[i]=0;
         trendUP=low[i];
         trendDN=high[i];
        }
      else
        {
         BufferCandlesOpen[i]=EMPTY_VALUE;
         BufferCandlesHigh[i]=EMPTY_VALUE;
         BufferCandlesLow[i]=EMPTY_VALUE;
         BufferCandlesClose[i]=EMPTY_VALUE;
        }
      static int trend=0;
      BufferArrowUP[i]=BufferArrowDN[i]=EMPTY_VALUE;
      if(close[i]>trendB && close[i]>trendA && trend!=1)
        {
         BufferArrowDN[i]=trendB;
         BufferArrowUP[i]=EMPTY_VALUE;
         trend=1;
        }
      if(close[i]<trendB && close[i]<trendA && trend!=2)
        {
         BufferArrowUP[i]=trendB;
         BufferArrowDN[i]=EMPTY_VALUE;
         trend=2;
        }
     }
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Возвращает индекс максимального значения таймсерии High          |
//+------------------------------------------------------------------+
int Highest(const int count,const int start,const bool as_series=true)
  {
   double array[];
   ArraySetAsSeries(array,as_series);
   return(CopyHigh(NULL,PERIOD_CURRENT,start,count,array)==count ? ArrayMaximum(array)+start : WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//| Возвращает индекс минимального значения таймсерии Low            |
//+------------------------------------------------------------------+
int Lowest(const int count,const int start,const bool as_series=true)
  {
   double array[];
   ArraySetAsSeries(array,as_series);
   return(CopyLow(NULL,PERIOD_CURRENT,start,count,array)==count ? ArrayMinimum(array)+start : WRONG_VALUE);
  }
//+------------------------------------------------------------------+

Особо не вникал в логику.

 
Artyom Trishkin:

Особо не вникал в логику.

Так правильнее будет: нечего ставить точки входа на макс/мин цены - лучше на цену открытия.

//+------------------------------------------------------------------+
//|                                            PerfecTrend Lines.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 9
#property indicator_plots   5
//--- plot Top
#property indicator_label1  "Top"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Bottom
#property indicator_label2  "Bottom"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrBlue
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- plot Candles
#property indicator_label3  "Open;High;Low;Close"
#property indicator_type3   DRAW_COLOR_CANDLES
#property indicator_color3  clrDodgerBlue,clrOrangeRed,clrDarkGray
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1
//--- plot ArrowUP
#property indicator_label4  "ArrowUP"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  clrRed
#property indicator_style4  STYLE_SOLID
#property indicator_width4  1
//--- plot ArrowDN
#property indicator_label5  "ArrowDN"
#property indicator_type5   DRAW_ARROW
#property indicator_color5  clrBlue
#property indicator_style5  STYLE_SOLID
#property indicator_width5  1
//--- input parameters
input uint     InpPeriodSlow     =  7;    // Slow length
input uint     InpDistanceSlow   =  0;    // Slow pip displace
input uint     InpPeriodFast     =  3;    // Fast length
input uint     InpDistanceFast   =  0;    // Fast pip displace
//--- indicator buffers
double         BufferTop[];
double         BufferBottom[];
double         BufferCandlesOpen[];
double         BufferCandlesHigh[];
double         BufferCandlesLow[];
double         BufferCandlesClose[];
double         BufferColors[];
double         BufferArrowUP[];
double         BufferArrowDN[];
//--- global variables
int            period_slow;
int            period_fast;
int            period_max;
double         distance_slow;
double         distance_fast;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- set global variables
   period_fast=int(InpPeriodFast<1 ? 1 : InpPeriodFast);
   period_slow=int(InpPeriodSlow<1 ? 1 : InpPeriodSlow);
   period_max=fmax(period_fast,period_slow);
   distance_fast=InpDistanceFast*Point();
   distance_slow=InpDistanceSlow*Point();
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferTop,INDICATOR_DATA);
   SetIndexBuffer(1,BufferBottom,INDICATOR_DATA);
   SetIndexBuffer(2,BufferCandlesOpen,INDICATOR_DATA);
   SetIndexBuffer(3,BufferCandlesHigh,INDICATOR_DATA);
   SetIndexBuffer(4,BufferCandlesLow,INDICATOR_DATA);
   SetIndexBuffer(5,BufferCandlesClose,INDICATOR_DATA);
   SetIndexBuffer(6,BufferColors,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(7,BufferArrowUP,INDICATOR_DATA);
   SetIndexBuffer(8,BufferArrowDN,INDICATOR_DATA);
//--- setting a code from the Wingdings charset as the property of PLOT_ARROW
   PlotIndexSetInteger(3,PLOT_ARROW,108);
   PlotIndexSetInteger(4,PLOT_ARROW,108);
//--- setting indicator parameters
   IndicatorSetString(INDICATOR_SHORTNAME,"NeuroTrend");
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferTop,true);
   ArraySetAsSeries(BufferBottom,true);
   ArraySetAsSeries(BufferCandlesOpen,true);
   ArraySetAsSeries(BufferCandlesHigh,true);
   ArraySetAsSeries(BufferCandlesLow,true);
   ArraySetAsSeries(BufferCandlesClose,true);
   ArraySetAsSeries(BufferColors,true);
   ArraySetAsSeries(BufferArrowUP,true);
   ArraySetAsSeries(BufferArrowDN,true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//--- Установка массивов буферов как таймсерий
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);
//--- Проверка и расчёт количества просчитываемых баров
   if(rates_total<fmax(period_max,4)) return 0;
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-period_max-1;
      ArrayInitialize(BufferTop,EMPTY_VALUE);
      ArrayInitialize(BufferBottom,EMPTY_VALUE);
      ArrayInitialize(BufferCandlesOpen,EMPTY_VALUE);
      ArrayInitialize(BufferCandlesHigh,EMPTY_VALUE);
      ArrayInitialize(BufferCandlesLow,EMPTY_VALUE);
      ArrayInitialize(BufferCandlesClose,EMPTY_VALUE);
      ArrayInitialize(BufferArrowUP,EMPTY_VALUE);
      ArrayInitialize(BufferArrowDN,EMPTY_VALUE);
     }
//---
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      int bhs=Highest(period_slow,i);
      int bls=Lowest(period_slow,i);
      int bhf=Highest(period_fast,i);
      int blf=Lowest(period_fast,i);
      if(bhs==WRONG_VALUE || bls==WRONG_VALUE || bhf==WRONG_VALUE || blf==WRONG_VALUE)
         continue;
      double thigh1=high[bhs]+distance_slow;
      double tlow1=low[bls]-distance_slow;
      double thigh2=high[bhf]+distance_fast;
      double tlow2=low[blf]-distance_fast;
      
      double trendA=(close[i]>BufferTop[i+1] ? tlow1 : thigh1);
      double trendB=(close[i]>BufferBottom[i+1] ? tlow2 : thigh2);
      BufferTop[i]=trendA;
      BufferBottom[i]=trendB;
      
      BufferCandlesOpen[i]=open[i];
      BufferCandlesHigh[i]=high[i];
      BufferCandlesLow[i]=low[i];
      BufferCandlesClose[i]=close[i];
      BufferColors[i]=2;
      if(close[i]<trendA && close[i]<trendB)
         BufferColors[i]=1;
      else if(close[i]>trendA && close[i]>trendB)
         BufferColors[i]=0;
      else
        {
         BufferCandlesOpen[i]=EMPTY_VALUE;
         BufferCandlesHigh[i]=EMPTY_VALUE;
         BufferCandlesLow[i]=EMPTY_VALUE;
         BufferCandlesClose[i]=EMPTY_VALUE;
        }
      static int trend=0;
      BufferArrowUP[i]=BufferArrowDN[i]=EMPTY_VALUE;
      if(close[i]>trendB && close[i]>trendA && trend!=1)
        {
         BufferArrowDN[i]=open[i];
         BufferArrowUP[i]=EMPTY_VALUE;
         trend=1;
        }
      if(close[i]<trendB && close[i]<trendA && trend!=2)
        {
         BufferArrowUP[i]=open[i];
         BufferArrowDN[i]=EMPTY_VALUE;
         trend=2;
        }
     }
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Возвращает индекс максимального значения таймсерии High          |
//+------------------------------------------------------------------+
int Highest(const int count,const int start,const bool as_series=true)
  {
   double array[];
   ArraySetAsSeries(array,as_series);
   return(CopyHigh(NULL,PERIOD_CURRENT,start,count,array)==count ? ArrayMaximum(array)+start : WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//| Возвращает индекс минимального значения таймсерии Low            |
//+------------------------------------------------------------------+
int Lowest(const int count,const int start,const bool as_series=true)
  {
   double array[];
   ArraySetAsSeries(array,as_series);
   return(CopyLow(NULL,PERIOD_CURRENT,start,count,array)==count ? ArrayMinimum(array)+start : WRONG_VALUE);
  }
//+------------------------------------------------------------------+

И линии убрать нужно - зачем они на графике? Если только стоп тащить по ним?

 

declaration without type

Если я компилирую включаемый файл, то ошибок нет. Если же я компилирую основной файл программы, в который включаю данный включаемый файл, то ошибка declaration without type. Он не видит объект, объявленный во включаемом файле protected CSomeClass *object. Во включаемом файле есть директива #include "SomeClass.mqh". А в основном файле создается объект класса включаемого файла и вызывается один из методов.
Причина обращения: