Domande dai principianti MQL5 MT5 MetaTrader 5 - pagina 990

 

Domanda: perché un Handel impostato su un periodo non passa valori aCopyBuffer su altri periodi. E cosa fare?

Se il problema fosse nello spostamento dell'elemento del buffer dell'array in tempi diversi, risolverei il problema. E quindi non è affatto chiaro.

 
kopeyka2:

Domanda: perché un Handel impostato su un periodo non passa valori aCopyBuffer su altri periodi. E cosa fare?

Se il problema fosse nello spostamento dell'elemento del buffer dell'array in tempi diversi, risolverei il problema. E quindi non è affatto chiaro.

Se l'handle è stato creato con successo, viene creato con i parametri che gli avete passato durante la sua creazione. E darà i dati dell'indicatore in qualsiasi timeframe. Tuttavia, darà i dati dell'intervallo di tempo che avete specificato durante la creazione. E per visualizzarli correttamente sul timeframe di lavoro, è necessario convertire i dati ricevuti dall'handle dell'indicatore nel timeframe in cui lavora il tuo indicatore.

 
kopeyka2:

Stavo solo controllando questo. Ma il PROBLEMA è che, fissando l'handel a un periodo permanente, in

Il valore di CopyBuffer su altri timeframe NON è TRASFERIBILE. Il valore era sul periodo di hendle impostato e 0,0 (zero) sui timeframe più piccoli. L'ho spostato intorno al buffer per cercarlo... zero. Perché non viene passato aCopyBuffer?

L'ho copiato...

//--- Подготовка данных
   int count=(limit>1 ? rates_total : 2),copied=0;
      ResetLastError();
   if(CopyBuffer(handle_ma,0,0,1,BufferPrice)<0)
     {
      PrintFormat("Failed to copy data from the handle_ma indicator, error code %d",GetLastError());
      return(0.0);
     }
//   copied=CopyBuffer(handle_ma,0,0,count,BufferPrice);
Print(BufferPrice[0]);

Un'altra domanda è cosa viene copiato :) Molto probabilmente stai richiedendo più barre da copiare di quante ce ne siano in quel TF, stampa

Print("count=",count," Bars=",Bars(Symbol(),Timeframes));
 
Artyom Trishkin:

Se l'handle è stato creato con successo, è stato creato con i parametri che gli avete dato quando lo avete creato. E darà i dati dell'indicatore in qualsiasi timeframe. Ma darà i dati del lasso di tempo che è stato impostato durante la creazione. E per visualizzarli correttamente sul timeframe di lavoro, è necessario convertire i dati ottenuti dall'handle dell'indicatore nel timeframe in cui lavora il tuo indicatore.

Ho fatto bene l'esperimento?

1) Ho creato un manico per il periodo D1.
2) Poi mettiamo i valori nel CopyBuffer secondo le istruzioni (da dove a dove).
Ho scritto da zero alla N-esima barra.
I valori delle maniglie dovrebbero essere scritti entro questo intervallo, in teoria. Anche quando si passa a un altro lasso di tempo i valori dovrebbero essere dal D1 impostato. Non lo vedo. O c'è qualcosa che non va? C'è qualcos'altro che dovrei aggiungere quando si imposta una maniglia? Poiché non c'è trasferimento di buffer.
 
kopeyka2:
Ho fatto bene l'esperimento?

1)Ho creato una maniglia sul periodo D1.
2)Poi, nel CopyBuffer mettiamo i valori secondo le istruzioni (da dove a dove).
Ho scritto da zero alla N-esima barra.
I valori delle maniglie dovrebbero essere scritti entro questo intervallo, in teoria. Anche quando si passa a un altro lasso di tempo i valori dovrebbero essere dal D1 impostato. Non lo vedo. O c'è qualcosa che non va? C'è qualcos'altro che dovrei aggiungere quando si imposta una maniglia? Perché non c'è trasferimento di buffer.

Ti ho dato una direzione...

Studiatelo:


//+------------------------------------------------------------------+
//|                                                     MTF_LRMA.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                                 https://mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com"
#property version   "1.00"
#property description "Multi Timeframe Linear Regression Moving Average with signal line"
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_plots   2
//--- plot LWMA
#property indicator_label1  "LRMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrLimeGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Signal
#property indicator_label2  "Signal"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- enums
enum ENUM_DRAW_MODE
  {
   DRAW_MODE_STEPS,  // Steps
   DRAW_MODE_SLOPE   // Slope
  };
//--- input parameters
input uint              InpPeriod      =  34;               // LRMA period
input uint              InpSignal      =  5;                // Signal period
input ENUM_TIMEFRAMES   InpTimeframe   =  PERIOD_H1;        // LRMA timeframe
input ENUM_DRAW_MODE    InpDrawMode    =  DRAW_MODE_STEPS;  // Drawing mode
//--- indicator buffers
double         BufferLRMA[];
double         BufferSignal[];
double         BufferLRMATmp[];
double         BufferSignalTmp[];
double         BufferLWMA[];
double         BufferSMA[];
//--- global variables
ENUM_TIMEFRAMES   timeframe1;
int               period_lrma;
int               signal;
int               handle_lwma;
int               handle_sma;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- timer
   EventSetTimer(90);
//--- set global variables
   period_lrma=int(InpPeriod<1 ? 1 : InpPeriod);
   signal=int(InpSignal<1 ? 1 : InpSignal);
   timeframe1=(InpTimeframe>Period() ? InpTimeframe : Period());
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferLRMA,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSignal,INDICATOR_DATA);
   SetIndexBuffer(2,BufferLRMATmp,INDICATOR_CALCULATIONS);
   SetIndexBuffer(3,BufferSignalTmp,INDICATOR_CALCULATIONS);
   SetIndexBuffer(4,BufferLWMA,INDICATOR_CALCULATIONS);
   SetIndexBuffer(5,BufferSMA,INDICATOR_CALCULATIONS);
//--- setting indicator parameters
   string label=TimeframeToString(timeframe1)+" LRMA("+(string)period_lrma+","+(string)signal+")";
   IndicatorSetString(INDICATOR_SHORTNAME,label);
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting plot buffer parameters
   PlotIndexSetString(0,PLOT_LABEL,TimeframeToString(timeframe1)+" LRMA("+(string)period_lrma+")");
   PlotIndexSetString(1,PLOT_LABEL,TimeframeToString(timeframe1)+" Signal("+(string)signal+")");
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferLRMA,true);
   ArraySetAsSeries(BufferSignal,true);
   ArraySetAsSeries(BufferLRMATmp,true);
   ArraySetAsSeries(BufferSignalTmp,true);
   ArraySetAsSeries(BufferLWMA,true);
   ArraySetAsSeries(BufferSMA,true);
//--- create handles
   ResetLastError();
   handle_lwma=iMA(NULL,timeframe1,period_lrma,0,MODE_LWMA,PRICE_CLOSE);
   if(handle_lwma==INVALID_HANDLE)
     {
      Print(__LINE__,": The ",TimeframeToString(timeframe1)," iMA(",(string)period_lrma,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
   handle_sma=iMA(NULL,timeframe1,period_lrma,0,MODE_SMA,PRICE_CLOSE);
   if(handle_sma==INVALID_HANDLE)
     {
      Print(__LINE__,": The ",TimeframeToString(timeframe1)," iMA(",(string)period_lrma,") object was not created: Error ",GetLastError());
      return INIT_FAILED;
     }
//--- get timeframe
   Time(NULL,timeframe1,1);
//---
   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[])
  {
//--- Проверка количества доступных баров
   if(rates_total<fmax(signal,4)) return 0;
//--- Проверка и расчёт количества просчитываемых баров
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-signal-2;
      ArrayInitialize(BufferLRMA,0);
      ArrayInitialize(BufferSignal,0);
      ArrayInitialize(BufferLRMATmp,0);
      ArrayInitialize(BufferSignalTmp,0);
      ArrayInitialize(BufferLWMA,0);
      ArrayInitialize(BufferSMA,0);
     }
//--- Подготовка данных
   if(Time(NULL,timeframe1,1)==0)
      return 0;
   int bars=(timeframe1==Period() ? rates_total : Bars(NULL,timeframe1));
   int count=(limit>1 ? fmin(bars,rates_total) : 1),copied=0;
   copied=CopyBuffer(handle_lwma,0,0,count,BufferLWMA);
   if(copied!=count) return 0;
   copied=CopyBuffer(handle_sma,0,0,count,BufferSMA);
   if(copied!=count) return 0;
      
//--- Расчёт индикатора
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      BufferLRMATmp[i]=3.0*BufferLWMA[i]-2.0*BufferSMA[i];
      BufferSignalTmp[i]=GetSMA(bars,i,signal,BufferLRMATmp);
     }
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      DataConversion(rates_total,NULL,timeframe1,i,BufferLRMATmp,BufferLRMA,InpDrawMode);
      DataConversion(rates_total,NULL,timeframe1,i,BufferSignalTmp,BufferSignal,InpDrawMode);
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Custom indicator timer function                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
   Time(NULL,timeframe1,1);
  }
//+------------------------------------------------------------------+
//| Transfering data from the source timeframe to current timeframe  |
//+------------------------------------------------------------------+
void DataConversion(const int rates_total,
                    const string symbol_name,
                    const ENUM_TIMEFRAMES timeframe_src,
                    const int shift,
                    const double &buffer_src[],
                    double &buffer_dest[],
                    ENUM_DRAW_MODE mode=DRAW_MODE_STEPS
                   )
  {
   if(timeframe_src==Period())
     {
      buffer_dest[shift]=buffer_src[shift];
      return;
     }
   int bar_curr=BarToCurrent(symbol_name,timeframe_src,shift);
   if(bar_curr>rates_total-1)
      return;
   int bar_prev=BarToCurrent(symbol_name,timeframe_src,shift+1);
   int bar_next=(shift>0 ? BarToCurrent(symbol_name,timeframe_src,shift-1) : 0);
   if(bar_prev==WRONG_VALUE || bar_curr==WRONG_VALUE || bar_next==WRONG_VALUE)
      return;
   buffer_dest[bar_curr]=buffer_src[shift];
   if(mode==DRAW_MODE_STEPS)
      for(int j=bar_curr; j>=bar_next; j--)
         buffer_dest[j]=buffer_dest[bar_curr];
   else
     {
      if(bar_prev>rates_total-1) return;
      for(int j=bar_prev; j>=bar_curr; j--)
         buffer_dest[j]=EquationDirect(bar_prev,buffer_dest[bar_prev],bar_curr,buffer_dest[bar_curr],j);
      if(shift==0)
         for(int j=bar_curr; j>=0; j--)
            buffer_dest[j]=buffer_dest[bar_curr];
     }
  }
//+------------------------------------------------------------------+
//| Возвращает бар заданного таймфрейма как бар текущего таймфрейма  |
//+------------------------------------------------------------------+
int BarToCurrent(const string symbol_name,const ENUM_TIMEFRAMES timeframe_src,const int shift,bool exact=false)
  {
   datetime time=Time(symbol_name,timeframe_src,shift);
   return(time!=0 ? BarShift(symbol_name,Period(),time,exact) : WRONG_VALUE);
  }
//+------------------------------------------------------------------+
//| Возвращает смещение бара по времени                              |
//| https://www.mql5.com/ru/forum/743/page11#comment_7010041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |
//+------------------------------------------------------------------+
int BarShift(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const datetime time,bool exact=false)
  {
   int res=Bars(symbol_name,timeframe,time+1,UINT_MAX);
   if(exact) if((timeframe!=PERIOD_MN1 || time>TimeCurrent()) && res==Bars(symbol_name,timeframe,time-PeriodSeconds(timeframe)+1,UINT_MAX)) return(WRONG_VALUE);
   return res;
  }
//+------------------------------------------------------------------+
//| Возвращает Time                                                  |
//+------------------------------------------------------------------+
datetime Time(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const int shift)
  {
   datetime array[];
   ArraySetAsSeries(array,true);
   return(CopyTime(symbol_name,timeframe,shift,1,array)==1 ? array[0] : 0);
  }
//+------------------------------------------------------------------+
//| Уравнение прямой                                                 |
//+------------------------------------------------------------------+
double EquationDirect(const int left_bar,const double left_price,const int right_bar,const double right_price,const int bar_to_search)
  {
   return(right_bar==left_bar ? left_price : (right_price-left_price)/(right_bar-left_bar)*(bar_to_search-left_bar)+left_price);
  }
//+------------------------------------------------------------------+
//| Timeframe to string                                              |
//+------------------------------------------------------------------+
string TimeframeToString(const ENUM_TIMEFRAMES timeframe)
  {
   return StringSubstr(EnumToString(timeframe),7);
  }
//+------------------------------------------------------------------+
//| Simple Moving Average                                            |
//+------------------------------------------------------------------+
double GetSMA(const int rates_total,const int index,const int period,const double &price[],const bool as_series=true)
  {
//---
   double result=0.0;
//--- check position
   bool check_index=(as_series ? index<=rates_total-period-1 : index>=period-1);
   if(period<1 || !check_index)
      return 0;
//--- calculate value
   for(int i=0; i<period; i++)
      result+=(as_series ? price[index+i]: price[index-i]);
//---
   return(result/period);
  }
//+------------------------------------------------------------------+
 
Aleksey Vyazmikin:

L'ho copiato...

Un'altra domanda è cosa sia la copia :) Molto probabilmente stai chiedendo di copiare più barre di quante ce ne siano in quel TF, stampa

Tutto è più modesto. Non ne mettono un mucchio. Solo 1-2 barre su D1. Più precisamente int lm=IBarShift(NULL,PERIOD_D1, iTime(NULL, PERIOD_CURRENT, limit));
int bars=PeriodSeconds(PERIOD_D1/PeriodSecond(_Period);

int startbar=lm-(lm-bars);

Ho provato a fare il conteggio in CopyBuffer senza limite e rate_total.

In poche parole, sperimentare con CopyBuffer, cosa metterci dentro, che dovrebbe essere. Ma non c'è.
 

kopeyka2:
Верно ли я провел эксперемент.?

...

... Anche quando si passa a un altro timeframe i valori dovrebbero essere quelli del D1 impostato. È proprio questo che non vedo. O c'è qualcosa che non va? C'è qualcos'altro che dovrei aggiungere quando si imposta una maniglia? Poiché non c'è trasferimento di buffer.

In poche parole, sperimentare con CopyByffer , cosa metterci dentro dovrebbe essere. Ma non c'è.

Non hai controllato la disponibilità dei dati, ma stai cercando di copiare. Guardate il codice qui sopra - lì in secondo timer ogni minuto e mezzo si accede al timeframe non nativo - per mantenere i dati aggiornati. E la prima cosa nel codice è controllare se i dati richiesti sono disponibili. Se non sono pronti, allora restituisce zero per il prossimo tick e il calcolo completo dell'indicatore. E quando tutti i dati sono stati ricevuti e calcolati, e visualizzati, la quantità di dati calcolati viene restituita alla fine - per non fare il ricalcolo completo al prossimo tick.

 
Grazie. Ho letto tutto. Continuerò a cercare.
 
kopeyka2:
Grazie. Tutti leggono. Continuerò a cercare.

Cosa state cercando? Il codice di cui sopra è completamente funzionante. Potete sezionarlo come volete. Ho fatto notare il tuo errore: non controlli la disponibilità dei dati.

Anche su questa linea qui:

int lm=IBarShift(NULL,PERIOD_D1, iTime(NULL, PERIOD_CURRENT, limit));

Dov'è il controllo di ciò che iTime() ha restituito? Non c'è nessun controllo. Ma voi spingete un risultato sconosciuto proprio in iBarShift(). Sei sicuro che stai dando alla funzione quello che ti aspetti?

 
Artyom Trishkin:

Se l'handle è stato creato con successo, viene creato con i parametri che gli avete dato alla creazione. E passerà i dati dell'indicatore in qualsiasi timeframe. Tuttavia, darà i dati dell'intervallo di tempo che è stato impostato durante la creazione. E per visualizzarli correttamente sul timeframe di lavoro, è necessario convertire i dati ricevuti dall'handle dell'indicatore nel timeframe in cui lavora il tuo indicatore.

È esattamente quello che ho pensato. Il problema del malinteso è la parola "parametri". Così ho iniziato a guardare TUTTE le variabili che sono coinvolte nell'handle --> CopyBuffer

1) La mia domanda fin dall'inizio era quella di cambiare il timeframe SCREEN per salvare i dati della maniglia. Come è in MT4.

E infatti risulta così:

handle_ma=iMA(NULL,PERIOD_H1,period,0,MODE_SMA,PRICE_CLOSE); 

 Comment(handle_ma);  // ВСЕГДА 10

SEMPRE e su TUTTI i timeframe dà lo stesso valore di 10

Non avendo ottenuto nulla qui sono andato avanti.

2) E cito:"Ottiene i dati del buffer specificato dell'indicatore specificato nella quantità specificata nella matrice del buffer".

CopyBuffer(handle_ma,0,0,count,BufferPrice);  //

Cioè, impostandoil conteggio a mano dovremmo avere un INTERVALLO con i valori . Ed eccoli lì! MA!!!!!! Solo quando il periodo della maniglia corrisponde a

PERIOD_H1sullo schermo del monitor. Tutti i valori sono trasmessi chiaramente. Ma passando ad un altro timeframe, non ci sono dati sullo schermo.

NON vengono trasmessi in nessun modo!!!! E la mia domanda era esattamente questa. E il numero di barre non è così importante in questo caso se non sono lì!!!!


Ho guardato l'indicatore propostoMTF_LRMA.mq5 ma è lo stesso. Passa a un altro timeframe sullo schermo e i dati passano per il timeframe dello schermo. Ne ho bisogno su un palmare.

Per esempio: iClose(NULL, PERIOD_H1, 5); su tutti i timeframe darà lo stesso valore: chiusura su 5 barre su H1.

Finora tutti gli esempi erano sulla correzione delconteggio di CopyBuffer. Ma l'array è vuoto.


Motivazione: