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

 
Im Prinzip schon, der Fehler lag wohl darin, dass mein Indikator-Handle in der OnTick-Funktion erstellt wird und die Daten sofort auf denselben Tick kopiert werden. Ich habe es in der Nacht verstanden, jetzt werde ich versuchen, die Indikator-Handles auf die OnInit-Funktion zu übertragen .
Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
 
sss20192:
Der Fehler lag im Indikator-Handle, das in der OnTick-Funktion erstellt wurde, und die Daten werden auf demselben Tick kopiert. Ich habe es in der Nacht verstanden, jetzt werde ich versuchen, die Indikatoren-Handles in die OnInit-Funktion zu übertragen .

Es hat nicht geklappt. Hier ist der Code jetzt


#property version   "1.00"

input int                  InpFastEMA=12;                // Fast EMA period
input int                  InpSlowEMA=26;                // Slow EMA period
input int                  InpSignalMA=9;                // Signal MA period
input ENUM_APPLIED_PRICE   InpAppliedPrice=PRICE_CLOSE;  // Applied price
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int Handle1, Handle2, Handle3;
double MacdArray[];

int OnInit()
  {
//---
  Handle1 = iMACD(_Symbol, PERIOD_M5, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
  Handle2 = iMACD(_Symbol, PERIOD_M15, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
  Handle3 = iMACD(_Symbol, PERIOD_H1, InpFastEMA, InpSlowEMA, InpSignalMA, InpAppliedPrice);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
        CopyBuffer(Handle1, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
        
        CopyBuffer(Handle2, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
        
        CopyBuffer(Handle3, 0, 1, 1, MacdArray);
        Print(MacdArray[0], " ", GetLastError());
  }
//+------------------------------------------------------------------+

Im Protokoll erscheinen die folgenden Meldungen

2013.04.13 15:21:31 2010.01.04 00:00:01 6.187448020344988e-005 0

2013.04.13 15:21:31 2010.01.04 00:00:01 6.187448020344988e-005 0

2013.04.13 15:21:31 2010.01.04 00:00:01 6.187448020344988e-005 0

Und das ist immer so. Es scheint kein Kopierfehler vorzuliegen.

 
sss20192: Es hat nicht geholfen. Hier ist der Code

Bisher gibt es aber weder eine Prüfung auf erfolgreiche Erstellung von Handles, noch eine Prüfung auf erfolgreiche Berechnung von Indikatoren und eine Prüfung auf Kopieren. Die Idee, die Initialisierung von Handles in OnInit() zu verschieben, ist richtig.

Fügen Sie außerdem die Print(MacdArray[0])-Zeile am Anfang von OnTick() ein, um zu sehen, welcher Wert im Array enthalten ist, bevor Sie mit dem Kopieren von Puffern beginnen.

Zum Hinzufügen. Natürlich kann die Verwendung von GetLastError() nach der eigentlichen Funktion eine Besonderheit des Programmierstils sein. Wenn ich mich nicht irre, bedeutet ein Nullwert von GetLastError() nicht immer, dass die Funktion erfolgreich war.

 
Yedelkin:
Bisher gibt es aber weder eine Prüfung auf erfolgreiche Erstellung von Handles, noch eine Prüfung auf erfolgreiche Berechnung von Indikatoren und eine Prüfung auf Kopieren. Die Idee, die Initialisierung von Handles in OnInit() zu verschieben, ist richtig.
Aber nur zum ersten Mal. Wenn sich an einer anderen Stelle des Programms herausstellt, dass ein Handle ungültig ist, müssen wir versuchen, es erneut zu erhalten. Daher können wir nicht sagen, dass der Code, der für das Abrufen von Handles in OnInit() geschrieben wurde, das Problem vollständig löst und zu 100 % korrekt ist. ))
 
Überprüft, wie viele Daten mit der CopyBuffer-Funktion kopiert wurden, schreibt immer 1. Und es gibt keinen Fehler, aber die Daten sind immer noch falsch.
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
Документация по MQL5: Доступ к таймсериям и индикаторам / CopyBuffer
  • www.mql5.com
Доступ к таймсериям и индикаторам / CopyBuffer - Документация по MQL5
 

tol64

Yedelkin : Die Idee, die Initialisierung von Handles in OnInit() zu verschieben, ist gut.

Aber nur zum ersten Mal. Wenn sich an anderer Stelle im Programm herausstellt, dass ein Handle ungültig ist, müssen Sie versuchen, es erneut zu erhalten. Daher können wir nicht sagen, dass der Code, der für das Abrufen von Handles in OnInit() geschrieben wurde, das Problem vollständig löst und zu 100 % korrekt ist. ))

Wollen Sie damit sagen, dass die Idee, die Initialisierung von Handles von OnTick() nach OnInit() zu verschieben , an sich falsch ist?
 
sss20192:
Ich habe überprüft, wie viele Daten mit der Funktion CopyBuffer kopiert wurden, es wird immer 1 geschrieben, und es gibt keinen Fehler, aber die Daten sind trotzdem falsch.

Ich habe dieses Ergebnis dieses Codes im Testgerät:

//---

Das Einzige, was ich vor dem Test getan habe, war, die Indikatorwerte vor der Ausgabe in das Protokoll umzuwandeln:

Print(DoubleToString(MacdArray[0],Digits())," ",GetLastError());
 
Yedelkin:
Wollen Sie damit sagen, dass die Idee, die Initialisierung des Handlers von OnTick() nach OnInit() zu verschieben , an sich falsch ist?
Wenn nur in OnInit() und nirgendwo sonst, dann ja - falsch. Das erste Mal, dass wir versuchen, ein Handle in OnInit() zu bekommen. Dann wird vor jedem Versuch, Indikatordaten zu erhalten, geprüft, ob der Handle gültig ist. Wenn er gültig ist, erhalten wir die Daten, wenn nicht, versuchen wir erneut, den Handle zu erhalten.
 
tol64:

Ich habe dieses Ergebnis dieses Codes im Testgerät erhalten:

//---

Das Einzige, was ich vor dem Test gemacht habe, war die einfache Konvertierung der Indikatorwerte vor der Ausgabe in das Protokoll:

Oh, das ist genial! Herzlichen Dank! Dritter Tag, an dem das Problem gelöst wird)
 
tol64:
Yedelkin: Wollen Sie damit sagen, dass die Idee, die Initialisierung von Handles von OnTick() nach OnInit() zu verschieben, an sich falsch ist?
Wenn nur in OnInit() und nirgendwo sonst, ja - falsch. Das erste Mal, dass wir versuchen, ein Handle in OnInit() zu bekommen. Dann wird vor jedem Versuch, Indikatordaten abzurufen, geprüft, ob der Handle gültig ist. Wenn er gültig ist, erhalten wir die Daten, wenn nicht, versuchen wir erneut, den Handle zu erhalten.

Und ohne "wenn"? Und in Bezug auf diese besondere Situation? Das Handle des Indikators wurde in der Funktion OnTick bei jedem Tick erstellt, und die Daten werden während desselben Ticks kopiert. Das bedeutet, dass jedes Mal derselbe Indikator-Handle angefordert wurde, ohne dass die Gültigkeit/Ungültigkeit geprüft wurde. Werden Sie vor diesem Hintergrund weiterhin argumentieren, dass die Idee, die Initialisierung von Handles von OnTick() zu OnInit() zu verlagern, per se falsch ist?

PS. Es scheint, dass Sie dem Mann geholfen haben, so dass die Frage als erschöpft betrachtet werden kann.