Fragen von Anfängern MQL5 MT5 MetaTrader 5 - Seite 990

 

Frage: Warum ein Handel, der auf eine Periode eingestellt ist, keine Werte anCopyBuffer in anderen Zeitrahmen weitergibt.Und was ist zu tun?

Wenn das Problem in der Verschiebung der Array-Puffer-Element in verschiedenen Zeitrahmen war ich das Problem lösen würde. Es ist also überhaupt nicht klar.

 
kopeyka2:

Frage: Warum ein Handel, der auf eine Periode eingestellt ist, keine Werte anCopyBuffer in anderen Zeitrahmen weitergibt.Und was ist zu tun?

Wenn das Problem in der Verschiebung der Array-Puffer-Element in verschiedenen Zeitrahmen war, würde ich das Problem lösen. Es ist also überhaupt nicht klar.

Wenn das Handle erfolgreich erstellt wurde, wird es mit den Parametern erstellt, die Sie ihm bei der Erstellung übergeben haben. Außerdem werden die Indikatordaten in jedem beliebigen Zeitrahmen angezeigt. Es werden jedoch die Daten des Zeitraums angezeigt, den Sie bei der Erstellung angegeben haben. Und um sie korrekt auf dem Arbeits-Zeitrahmen anzuzeigen, müssen Sie die empfangenen Daten vom Indikator-Handle in den Zeitrahmen konvertieren, in dem Ihr Indikator arbeitet.

 
kopeyka2:

Ich habe mir das gerade angeschaut. Das PROBLEM ist jedoch, dass durch die Festlegung des Handbuchs auf einen ständigen Zeitraum, in

Der CopyBuffer-Wert in anderen Zeiträumen ist NICHT ÜBERTRAGBAR. Der Wert lag bei der eingestellten Zeitspanne und 0,0 (Null) bei den kleineren Zeitspannen. Ich habe ihn im Puffer herumgeschoben, um ihn zu suchen... Null. Warum wird er nicht anCopyBuffer übergeben?

Ich habe es kopiert...

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

Eine andere Frage ist, was kopiert wird :) Höchstwahrscheinlich fordern Sie mehr Takte zum Kopieren an, als auf der TF vorhanden sind, drucken

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

Wenn das Handle erfolgreich erstellt wurde, wurde es mit den Parametern erstellt, die Sie ihm bei der Erstellung übergeben haben. Außerdem werden die Indikatordaten in jedem beliebigen Zeitrahmen angezeigt. Es werden jedoch die Daten des Zeitraums angezeigt, der bei der Erstellung festgelegt wurde. Und um sie korrekt auf dem Arbeitszeitrahmen anzuzeigen, müssen Sie die vom Indikator-Handle erhaltenen Daten in den Zeitrahmen konvertieren, in dem Ihr Indikator arbeitet.

Habe ich das Experiment richtig durchgeführt?

1) Ich habe einen Griff für den Zeitraum D1 erstellt.
2) Dann legen wir die Werte in CopyBuffer entsprechend den Anweisungen ab (von wo nach wo).
Ich habe von Null bis zum N-ten Takt geschrieben.
Theoretisch sollten Handle-Werte innerhalb dieses Intervalls geschrieben werden. Auch beim Wechsel zu einem anderen Zeitrahmen sollten die Werte aus dem eingestellten D1 stammen. Ich kann es nicht sehen. Oder ist etwas nicht in Ordnung? Gibt es noch etwas, das ich beim Einstellen eines Griffs hinzufügen sollte? Da es keine Pufferübertragung gibt.
 
kopeyka2:
Habe ich das Experiment richtig durchgeführt?

1) Ich habe einen Griff für den Zeitraum D1 erstellt.
2) Als Nächstes werden im CopyBuffer Werte entsprechend den Anweisungen (von wo nach wo) eingetragen.
Ich habe von Null bis zum N-ten Takt geschrieben.
Theoretisch sollten Handle-Werte innerhalb dieses Intervalls geschrieben werden. Auch beim Wechsel zu einem anderen Zeitrahmen sollten die Werte aus dem eingestellten D1 stammen. Ich kann es nicht sehen. Oder ist etwas nicht in Ordnung? Gibt es noch etwas, das ich bei der Einstellung eines Griffs hinzufügen sollte? Denn es findet keine Pufferübertragung statt.

Ich habe dir eine Richtung gegeben...

Studieren Sie es:


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

Ich habe es kopiert...

Eine andere Frage ist, was ist Kopieren :) Höchstwahrscheinlich wollen Sie mehr Takte kopieren, als auf der TF vorhanden sind, drucken

Alles ist bescheidener. Sie legen kein Bündel ein. Nur 1-2 Takte auf D1. Genauer gesagt int lm=IBarShift(NULL,PERIOD_D1, iTime(NULL, PERIOD_CURRENT, limit));
int bars=PeriodSeconds(PERIOD_D1/PeriodSecond(_Period);

int startbar=lm-(lm-bars);

Ich habe versucht, in CopyBuffer ohne Limit und rate_total zu zählen.

Einfach ausgedrückt, experimentieren Sie mit CopyBuffer, was in ihm zu setzen, das sollte sein. Aber es gibt keine.
 

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

...

... Auch beim Wechsel zu einem anderen Zeitrahmen sollten die Werte aus dem eingestellten D1 übernommen werden. Das ist genau das, was ich nicht sehe. Oder ist etwas nicht in Ordnung? Gibt es noch etwas, das ich bei der Einstellung eines Griffs hinzufügen sollte? Da es keine Pufferübertragung gibt.

Einfach gesagt, experimentieren Sie mit CopyByffer , was in ihm stecken sollte. Aber sie ist nicht da.

Sie haben die Verfügbarkeit der Daten nicht überprüft, versuchen aber, sie zu kopieren. Sehen Sie sich den obigen Code an - dort wird im Sekundentakt alle anderthalb Minuten auf den nicht-nativen Zeitrahmen zugegriffen, um die Daten auf dem neuesten Stand zu halten. Als erstes wird im Code geprüft, ob die angeforderten Daten verfügbar sind. Wenn sie nicht bereit sind, wird für den nächsten Tick und die vollständige Berechnung des Indikators der Wert Null zurückgegeben. Und wenn alle Daten empfangen, berechnet und angezeigt wurden, wird am Ende die Menge der berechneten Daten zurückgegeben, um nicht beim nächsten Tick eine vollständige Neuberechnung vorzunehmen.

 
Ich danke Ihnen. Ich habe sie alle gelesen. Ich werde weiter suchen.
 
kopeyka2:
Ich danke Ihnen. Ich habe sie alle gelesen. Ich werde weiter suchen.

Wonach suchen Sie? Der obige Code ist voll funktionsfähig. Sie können es zerlegen, wie Sie wollen. Ich habe Sie auf Ihren Fehler hingewiesen - Sie prüfen nicht die Verfügbarkeit der Daten.

Auch auf dieser Linie hier:

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

Wo ist die Überprüfung, was iTime() zurückgegeben hat? Es gibt keine Kontrolle. Aber Sie schieben ein unbekanntes Ergebnis direkt in iBarShift(). Sind Sie sicher, dass Sie der Funktion das geben, was Sie erwarten?

 
Artyom Trishkin:

Wenn das Handle erfolgreich erstellt wurde, wurde es mit den Parametern erstellt, die ihm bei seiner Erstellung übergeben wurden. Und er wird die Indikatordaten in jedem Zeitrahmen weitergeben. Es werden jedoch die Daten des Zeitraums angezeigt, der bei der Erstellung festgelegt wurde. Und um sie korrekt auf dem Arbeits-Zeitrahmen anzuzeigen, müssen Sie die empfangenen Daten vom Indikator-Handle in den Zeitrahmen konvertieren, in dem Ihr Indikator arbeitet.

Das ist genau das, was ich dachte. Das Problem des Missverständnisses ist das Wort "Parameter". Also habe ich begonnen, ALLE Variablen zu betrachten, die an dem Handle --> CopyBuffer beteiligt sind

1) Meine Frage von Anfang an war, den Zeitrahmen SCREEN zu wechseln, um die Griffdaten zu speichern. Wie in MT4.

Und tatsächlich sieht es so aus:

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

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

IMMER und für ALLE Zeitrahmen ergibt sich der gleiche Wert von 10

Da ich hier nichts fand, ging ich weiter.

2) Und ich zitiere:"Holt die Daten des angegebenen Puffers des angegebenen Indikators in der angegebenen Menge in das Puffer-Array".

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

Das heißt, wenn wirden Zähler von Hand einstellen, sollten wir ein INTERVALL mit den Werten haben . Und da sind sie! BUT!!!!!! Nur wenn die Griffperiode der

PERIOD_H1Zeitrahmen auf dem Bildschirm. Alle Werte werden deutlich übertragen. Wechselt man jedoch zu einem anderen Zeitrahmen, werden KEINE Daten auf dem Bildschirm angezeigt.

Sie werden NICHT in irgendeiner Weise übertragen!!!! Und genau das war meine Frage. Und die Anzahl der Balken ist hier nicht so wichtig, wenn sie NICHT dort sind!!!!


Ich habe mir den vorgeschlagenen IndikatorMTF_LRMA.mq5 angesehen , aber er hat das gleiche Problem. Es wird zu einem anderen Zeitrahmen auf dem Bildschirm gewechselt, und die Daten gehen durch den Bildschirmzeitrahmen. Ich brauche es auf einem Handheld.

Zum Beispiel: iClose(NULL, PERIOD_H1, 5); auf allen Timeframes ergibt das den gleichen Wert: close on 5 bars on H1.

Bisher waren alle Beispiele auf CopyBuffer Zählerkorrektur. Aber das Feld ist leer.