Domande dai principianti MQL5 MT5 MetaTrader 5 - pagina 919

 
Artyom Trishkin:

Il calcolo del tuo indicatore è dall'inizio alla fine (dai dati storici più recenti ai dati attuali più recenti). Questa è un'indicazione di indicizzazione come nelle serie temporali. Quindi gli array devono essere indicizzati di conseguenza, che è quello che avete.

Cosa c'è che non va?

Funziona tutto come il mio porto in MQL5 da MQL4, ma vedo che il codice è brutto a causa diArraySetAsSeries(), ecco perché ho chiesto

Qui ci sono entrambi i codici

insegnami come scrivere questo indicatore per MT5! - Il mio codice non è bello, punto e basta! )))

ZSZ non ricordare come scrivere indicatori per MT5, seduto e riscritto in 40 minuti utilizzando la Guida, ma il risultato ... imho, non buono ((!)

File:
PTL.mq4  8 kb
PTL.mq5  13 kb
 
Igor Makanu:

Sì, tutto funziona esattamente come il mio porto in MQL5 da MQL4, ma vedo che il codice è brutto a causa diArraySetAsSeries(), così ho chiesto

Qui ci sono entrambi i codici

insegnami come scrivere questo indicatore per MT5! - Il mio codice non è bello, punto e basta! )))

Quando si inverte il ciclo, si deve necessariamente fare le serie temporali degli array, altrimenti l'indicizzazione dei buffer nel ciclo non coinciderà con l'indicizzazione dei dati richiesti - l'indice del ciclo nell'array dei buffer degli indicatori andrà dall'inizio alla fine, mentre in open[], high[], low[], close[] e altri - dalla fine all'inizio. Oppure, si può invertire il ciclo per far corrispondere la sua indicizzazione degli array open[], high[], low[], close[] e il resto con l'indicizzazione dei buffer, che è più complicato.

Se volete un'allegoria per renderlo più chiaro, ecco un'allegoria per voi:

Sei in piedi sui binari della ferrovia e guardi due treni. O vanno in una direzione - entrambi da sinistra a destra (ArraySetAsSeries(array,true) - primo treno e un ciclo da limite a 0 - secondo treno),
Oppure vanno uno verso l'altro - (ArraySetAsSeries(array,false) - da destra a sinistra - primo treno, e il ciclo dal limite a 0 - da sinistra a destra - secondo treno)

E, sì: non ho guardato il codice - non voglio scaricare, salvare (ho un sacco di codici inutili dal forum), confrontarli tra loro...

Sarebbe più facile metterli in codici nel messaggio - uno e secondo - poi sarebbe visibile subito cosa a cosa.

 
Artyom Trishkin:

O capovolgere il ciclo per far corrispondere la sua indicizzazione degli array open[], high[], low[], close[] e il resto, che è più difficile.

Ho fatto l'inversione tutta la notte oggi, la mia pazienza si è esaurita (((

Per quanto ho capito il problema:

- in MT5 gli array che sono assegnati ai buffer degli indicatori sono indicizzati da sinistra a destra per impostazione predefinita;

- in MT5 le serie temporaliopen[], high[], low[], close[] disponibili da OnCalculate() sono sempre passate indicizzate da destra a sinistra

- cioè in base ai passi 1 e 2, per calcolare l'indicatore dalla fine della storia alla barra zero

a) o riassegnare l'indicizzazione degli array di buffer

b) o per fare un ciclo in cui gli elementi dell'array saranno ricalcolati da sinistra a destra, e in un altro ciclo da destra a sinistra:

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


cioè,non c'è una bella soluzione alla mia domanda? opzione a) - nelle mie fonti è implementata, opzione b) - non vedo il punto di fare calcoli extra

fonti:

MT5:

//+------------------------------------------------------------------+
//|                                          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);
  }
//+------------------------------------------------------------------+

MT4:

//+------------------------------------------------------------------+
//|                                            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:

Ho girato tutta la notte stasera, ma la mia pazienza è finita (((

per quanto ho capito il problema:

- in MT5 gli array che sono assegnati ai buffer degli indicatori sono indicizzati da sinistra a destra per impostazione predefinita;

- in MT5 le serie temporaliopen[], high[], low[], close[] disponibili da OnCalculate() sono sempre passate indicizzate da destra a sinistra

- cioè in base ai passi 1 e 2, per calcolare l'indicatore dalla fine della storia alla barra zero

a) o riassegnare l'indicizzazione degli array di buffer

b) o per fare un ciclo in cui gli elementi dell'array saranno ricalcolati da sinistra a destra, e in un altro ciclo da destra a sinistra:


cioè,non c'è unabella soluzione alla mia domanda? variante a) - nel mio codice sorgente è implementato, variante b) - non vedo il punto di fare calcoli extra

Tutti gli array sono indicizzati da destra a sinistra. Quindi, per rispettare pienamente il ciclo da sinistra a destra (ed è da sinistra a destra - dal limite a 0), è necessario impostare tutti gli array usati sull'indicizzazione richiesta : i buffer in OnInit(), i timeserver usati - in OnCalculate().

Oppure, fare il ciclo da 0 a limite, che non è sempre facile da fare quando mql4 è portato a mql5.

Pertanto, l'opzione ArraySetAsSeries() è migliore in questo caso.

 
Artyom Trishkin:

Tutti gli array sono indicizzati da destra a sinistra. Pertanto, per rispettare pienamente il ciclo da sinistra a destra (ed è da sinistra a destra dal limite a 0), è necessario impostare tutti gli array usati sull'indicizzazione richiesta : i buffer in OnInit(), i timeserver usati - in OnCalculate().

Oppure, devi fare il ciclo da 0 a limite, che non è sempre facile da fare quando mql4 è portato a mql5.

Ecco perché in questo caso il metodo ArraySetAsSeries() funziona meglio.

Guarda, rimuovi tuttoArraySetAsSeries() dal tuo codice(sopra in Init() e OnCalculate() nelle prime righe) e correggi il ciclo:

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

In teoria, tutto dovrebbe combaciare, ma no, i grafici sono risultati diversi, questo è quello che non riesco a capire!

File:
1.jpg  747 kb
 
Igor Makanu:

Guarda, ho rimosso tuttoArraySetAsSeries() dal mio codice(in alto in Init() e in OnCalculate() nelle prime righe) e ho fissato il ciclo:

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

In teoria, tutto dovrebbe combaciare, ma no, i grafici sono risultati diversi, ed è questo che non riesco a capire!

Ti dico che è più complicato di così. Bisogna cambiare la logica. Non basta invertire il ciclo.

Ecco un piccolo esempio: nel codice c'è

Buf_NTLine1[i+1])

Dove andrà l'indice i+1 quando gli array sono indicizzati diversamente?

E ce n'è un sacco. IHighest() - inizio e numero. Dove inizia un'indicizzazione e dove un'altra?

E così via...

 
Artyom Trishkin:

e ce n'è un sacco. IHighest() - inizio e numero di... Dove inizia un'indicizzazione e l'altra?

Oh, cavolo, è vero! Ben fatto!!! sì, questa è la parte difficile!!!

Già... molte differenze in MT5, molti controlli e ogni sorta di precauzioni sulla testa del programmatore...

Quando ho visto questo messaggio qualche tempo fa, sembrava che in MT5 non sempre tuttoviene inizializzato correttamente inInit(), sembra cheInit() possa finire anche se i timeframes non sono pronti.

Ho visto un bug ieri: se questo indicatore in MT5 cambia timeframes, a volte i buffer degli indicatori potrebbero non essere vuoti - sembra che i vecchi valori rimangano se non per assegnare un valore specifico ad ogni elemento dell'array dell'indicatore in OnCalculate(), ho provatoa mettere ArrayInitialize(arr, 0.0) inInit()- funziona anche, poi no...

se ho capito bene:

- in MT5, all'inizializzazione inInit(), i buffer degli indicatori non vengono inizializzati automaticamente? (in MT4 non ricordo che sia rimasto qualcosa nei buffer)

- in MT5 inInit() le dimensioni degli array di buffer possono essere sconosciute se la storia non è caricata, ecco perchéanche ArrayInitialize(arr, 0.0) non sempre inizializza correttamente i buffer?

 
Igor Makanu:

Accidenti, è vero, ben fatto!!! Sì, questa è la parte divertente!!!

Già... Ci sono molte differenze in MT5, il programmatore ha un sacco di controlli e ogni sorta di precauzioni...

Quando ho visto questo messaggio qualche tempo fa, sembrava che in MT5 non sempre tuttoviene inizializzato correttamente inInit(), sembra cheInit() possa finire anche se i timeframes non sono pronti.

Ho visto un bug ieri: se questo indicatore in MT5 cambia timeframes, a volte i buffer degli indicatori potrebbero non essere vuoti - sembra che i vecchi valori rimangano se non per assegnare un valore specifico ad ogni elemento dell'array dell'indicatore in OnCalculate(), ho provatoa mettere ArrayInitialize(arr, 0.0) inInit()- funziona anche, poi no...

se ho capito bene:

- in MT5, all'inizializzazione inInit(), i buffer degli indicatori non vengono inizializzati automaticamente? (in MT4 non ricordo che sia rimasto qualcosa nei buffer)

- in MT5 inInit() le dimensioni degli array di buffer possono essere sconosciute se la storia non è caricata, ecco perchéanche ArrayInitialize(arr, 0.0) non sempre inizializza correttamente i buffer?

//+------------------------------------------------------------------+
//|                                            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);
  }
//+------------------------------------------------------------------+

Non è entrato nella logica della cosa.

 
Artyom Trishkin:

Non è entrato nella logica della cosa.

Questo è il modo giusto di procedere: non mettere punti di entrata al prezzo max/min - meglio al prezzo di apertura.

//+------------------------------------------------------------------+
//|                                            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);
  }
//+------------------------------------------------------------------+

E le linee dovrebbero essere rimosse - a cosa servono sul grafico? Se non altro per trascinare un arresto su di loro?

 

dichiarazione senza tipo

Se compilo un file include, non ci sono errori. Se compilo il file principale del programma dove includo questo file include, c'è una dichiarazione senza errore di tipo. Non vede l'oggetto dichiarato nel file include protected CSomeClass *object. Il file include ha la direttiva #include "SomeClass.mqh". E nel file principale, viene creato un oggetto della classe del file incluso e viene chiamato uno dei metodi.