Questions des débutants MQL5 MT5 MetaTrader 5 - page 990

 

Question : Pourquoi un Handel réglé sur une période ne transmet pas de valeurs àCopyBuffer sur d'autres périodes. Et que faire ?

Si le problème résidait dans le déplacement d'un élément de la mémoire tampon du tableau à différents moments, je résoudrais le problème. Et donc ce n'est pas clair du tout.

 
kopeyka2:

Question : Pourquoi un Handel réglé sur une période ne transmet pas de valeurs àCopyBuffer sur d'autres périodes. Et que faire ?

Si le problème résidait dans le déplacement d'un élément de la mémoire tampon du tableau à différents moments, je résoudrais le problème. Et donc ce n'est pas clair du tout.

Si le handle a été créé avec succès, il est créé avec les paramètres que vous lui avez passés lors de sa création. Et il donnera les données de l'indicateur à n'importe quel moment. Cependant, il donnera les données de la période que vous avez spécifiée lors de la création. Et pour les afficher correctement sur le cadre temporel de travail, vous devez convertir les données reçues de la poignée de l'indicateur au cadre temporel dans lequel votre indicateur travaille.

 
kopeyka2:

Je vérifiais juste ça. Mais le PROBLÈME est qu'en fixant la main à une période permanente, en

La valeur du CopyBuffer sur d'autres horizons temporels n'est PAS TRANSFÉRABLE. La valeur était sur la période d'hendle définie et 0.0 (zéro) sur les plus petites périodes. Je l'ai déplacé autour du tampon pour le chercher... zéro. Pourquoi n'est-il pas passé àCopyBuffer ?

Je l'ai copié...

//--- Подготовка данных
   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]);

Une autre question est de savoir ce qui est copié :) Il est fort probable que vous demandiez plus de barres à copier qu'il n'y en a sur cette TF, imprimez...

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

Si le handle a été créé avec succès, il a été créé avec les paramètres que vous lui avez donnés lors de sa création. Et il donnera les données de l'indicateur à n'importe quel moment. Mais il donnera les données de la période qui a été définie lors de la création. Et pour les afficher correctement sur le cadre temporel de travail, vous devez convertir les données obtenues de la poignée de l'indicateur au cadre temporel dans lequel votre indicateur travaille.

Est-ce que j'ai fait l'expérience correctement ?

1) J'ai créé un handle pour la période D1.
2) Ensuite, nous plaçons les valeurs dans CopyBuffer selon les instructions (d'où à où).
J'ai écrit de zéro à la Nième mesure.
Les valeurs des poignées devraient être écrites dans cet intervalle, en théorie. Même lorsque l'on passe à une autre période, les valeurs doivent être celles de l'ensemble D1. Je ne le vois pas. Ou quelque chose ne va pas ? Y a-t-il autre chose que je devrais ajouter lors de la définition d'une poignée ? Puisqu'il n'y a pas de transfert de tampon.
 
kopeyka2:
Est-ce que j'ai fait l'expérience correctement ?

1) J'ai créé une poignée sur la période D1.
2)Ensuite, dans le CopyBuffer nous mettons les valeurs selon les instructions (d'où à où).
J'ai écrit de zéro à la Nième mesure.
Les valeurs des poignées devraient être écrites dans cet intervalle, en théorie. Même lorsque l'on passe à une autre période, les valeurs doivent être celles de l'ensemble D1. Je ne le vois pas. Ou quelque chose ne va pas ? Y a-t-il autre chose que je devrais ajouter lors de la définition d'une poignée ? Parce qu'il n'y a pas de transfert de tampon.

Je vous ai donné une direction...

Étudiez-le:


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

Je l'ai copié...

Une autre question est de savoir ce qui est copié :) Il est fort probable que vous demandiez à copier plus de barres qu'il n'y en a sur cette TF, imprimez...

Tout est plus modeste. Ils ne mettent pas un tas. Seulement 1-2 barres sur D1. Plus précisément int lm=IBarShift(NULL,PERIOD_D1, iTime(NULL, PERIOD_CURRENT, limit)) ;
int bars=PeriodSeconds(PERIOD_D1/PeriodSecond(_Period) ;

int startbar=lm-(lm-bars) ;

J'ai essayé de faire le comptage dans CopyBuffer sans limite et rate_total.

Pour faire simple, expérimentez avec CopyBuffer, ce qu'il faut y mettre, cela devrait être. Mais il n'y en a pas.
 

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

...

... Même lorsque l'on passe à une autre période, les valeurs doivent être celles de l'ensemble D1. C'est exactement ce que je ne vois pas. Ou quelque chose ne va pas ? Y a-t-il autre chose que je devrais ajouter lors de la définition d'une poignée ? Puisqu'il n'y a pas de transfert de tampon.

Tout simplement, expérimenter avec CopyByffer , ce qu'il faut mettre dedans. Mais il n'est pas là.

Vous n'avez pas vérifié la disponibilité des données, mais vous essayez de copier. Regardez le code ci-dessus - il y a un second timer toutes les minutes et demie où l'on accède à l'image temporelle non native - pour garder les données à jour. Et la première chose dans le code est de vérifier si les données demandées sont disponibles. S'ils ne sont pas prêts, alors il retourne zéro pour le prochain tick et le calcul complet de l'indicateur. Et lorsque toutes les données ont été reçues, calculées et affichées, la quantité de données calculées est renvoyée à la fin - afin de ne pas avoir à effectuer un nouveau calcul complet au prochain tick.

 
Merci. J'ai tout lu. Je vais continuer à chercher.
 
kopeyka2:
Merci. J'ai tout lu. Je vais continuer à chercher.

Que cherchez-vous ? Le code ci-dessus fonctionne parfaitement. Vous pouvez le disséquer comme vous voulez. J'ai souligné votre erreur - vous ne vérifiez pas la disponibilité des données.

Même sur cette ligne ici :

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

Où est la vérification de ce que iTime() a retourné ? Il n'y a pas de contrôle. Mais tu pousses un résultat inconnu directement dans iBarShift(). Êtes-vous sûr de donner à la fonction ce que vous attendez ?

 
Artyom Trishkin:

Si le handle a été créé avec succès, il est créé avec les paramètres que vous lui avez donnés lors de la création. Et il transmettra les données de l'indicateur à n'importe quel moment. Cependant, il donnera les données de la période qui a été définie lors de la création. Et pour les afficher correctement sur le cadre temporel de travail, vous devez convertir les données reçues de la poignée de l'indicateur au cadre temporel dans lequel votre indicateur travaille.

C'est exactement ce que je pensais. La question du malentendu est le mot "paramètres". J'ai donc commencé à regarder TOUTES les variables qui sont impliquées dans le handle --> CopyBuffer

1) Ma question depuis le début était de basculer l'écran de l'horizon temporel pour sauvegarder les données de la poignée. Comme c'est le cas dans MT4.

Et en fait, c'est ce qui se passe :

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

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

TOUJOURS et sur TOUS les horizons temporels donne la même valeur de 10

N'ayant rien obtenu ici, je suis passé à autre chose.

2) Et je cite :"Obtient les données du tampon spécifié de l'indicateur spécifié dans la quantité spécifiée dans le tableau du tampon".

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

C'est-à-dire qu'en réglantle compte à la main, nous devrions avoir un INTERVALLE avec les valeurs . Et les voilà ! BUT !!!!!! Seulement lorsque la période de la poignée correspond à

PERIOD_H1sur l'écran du moniteur. Toutes les valeurs sont transmises clairement. Mais en passant à une autre période de temps, il n'y a PAS de données à l'écran.

Ils ne sont PAS transmis de quelque manière que ce soit. ! !!! Et ma question était exactement ça. Et le nombre de barres n'est pas si important ici s'il n'y en a PAS !!!!.


J'ai regardé l'indicateur proposéMTF_LRMA.mq5 mais c'est la même chose. Il passe à une autre période de l'écran et les données passent par la période de l'écran. J'en ai besoin sur un ordinateur de poche.

Par exemple : iClose(NULL, PERIOD_H1, 5) ; sur tous les horizons temporels, cela donnera la même valeur : clôture sur 5 barres sur H1.

Jusqu'à présent, tous les exemples concernaient la correction dunombre de CopyBuffer. Mais le tableau est vide.