Bei einem Standard-Indikator würden Sie die Puffer-Arrays mit Daten aus den Parametern aufbauen, die über die Ereignisfunktion OnCalulate( ... ) gesendet werden. Für Multi-Währungen und/oder Multi-Time-Frames müssen Sie jedoch eine von zwei Lösungen verwenden:
- Verwendung der alten Methode der "iFunction"-Variationen, wie iTime(), iVolume, iOpen, iClose usw., aber mit einem anderen Symbol wie "EURUSD", "JPYUSD" usw. anstelle des Standardwerts _Symbol oder Symbol().
- Die Verwendung der neueren Methode der ersten Variante der Funktion ArrayCopyRates() zusammen mit Array-Zeigern von MqlRates. Die "kopierten" Arrays nehmen eigentlich keinen Platz ein und sind nur Zeiger auf die vorhandenen Daten der verschiedenen Symbole und Zeitrahmen.
Damit dies funktioniert, muss jedoch eine von zwei Bedingungen erfüllt sein, damit die Multi-Symbol- und/oder Multi-Time-Frame-Funktion funktioniert:
- Entweder sind die jeweiligen Charts für die Symbole und Timeframes bereits geöffnet, so dass kein Fehler generiert wird,
- oder Sie erhalten einen Fehler 4066 (ERR_HISTORY_WILL_UPDATED), wenn Sie die Daten zum ersten Mal anfordern, und Sie müssen eine sleep & retry-Schleife programmieren, um zu warten, bis die Daten heruntergeladen sind und dann die Daten erneut anfordern.
Mein persönlicher Lösungsvorschlag, den ich für den effizientesten und einfachsten Weg halte, den 4066-Fehler zu behandeln, ist die ArrayCopyRates() und MqlRates Methode.
Es gibt mehr Informationen darüber in der MQL4 Dokumentation und den Hilfedateien.
PS! ACHTUNG! Denken Sie beim Zugriff auf integrierte Indikatorfunktionen wie iMA(), iATR() usw. für die verschiedenen Symbole und Zeitrahmen daran, auch die Schleifen sleep und retry zu implementieren, um den Fehler 4066 nicht zu erhalten. Hier ist ein Zitat aus dem MQL4-Dokument:
Denken Sie daran, dass der OP nach einem Indikator fragt. Sleep() wird in Indikatoren ignoriert.
Tut mir leid, das wusste ich nicht! Ich verwende diese Methode recht häufig in EAs, aber nicht in Indikatoren, so wusste nicht, über den Schlaf Handicap.
In diesem Fall muss er bei jedem Tick-Aufruf der OnCalculate() -Funktion eine Wiederholungsschleife um aufeinanderfolgende Aufrufe herum aufbauen (wobei die Verwendung von ArrayCopyRates() die bessere Lösung ist).
Wenn es in der OnInit() -Funktion funktioniert, könnte es alternativ die bevorzugte Methode zur Vorbereitung der Daten für den Indikator sein, mit einer sehr langen Wiederholungszahl (ohne Sleep) für diesen Fall.
...
- oder Sie erhalten einen Fehler 4066 (ERR_HISTORY_WILL_UPDATED), wenn Sie die Daten zum ersten Mal anfordern, und Sie müssen eine Schleife für Sleep & Retry programmieren, um zu warten, bis die Daten heruntergeladen sind, und dann die Daten erneut anfordern.
PS! ACHTUNG! Denken Sie beim Zugriff auf integrierte Indikatorfunktionen wie iMA(), iATR() usw. für die verschiedenen Symbole und Zeitrahmen daran, auch die Schleifen sleep und retry zu implementieren, um den Fehler 4066 nicht zu erhalten. Hier ist ein Zitat aus dem MQL4-Dokument:
Wenn sie nicht kürzlich etwas geändert haben, erhalten Sie den Fehler 4066 jedes Mal beim ersten Funktionsaufruf (und nur bei diesem ersten Aufruf), unabhängig von den Bedingungen oder dem Fortschritt der Aktualisierung der Historie. Es hat keinen praktischen Nutzen.
FMIC: In diesem Fall muss er bei jedem Tick-Aufruf der Funktion OnCalculate() eine Wiederholungsschleife um die aufeinander folgenden Aufrufe herum aufbauen (wobei die Verwendung von ArrayCopyRates() die bessere Lösung ist). Wenn es in der Funktion OnInit() funktioniert, könnte dies die bevorzugte Methode sein, um die Daten für den Indikator vorzubereiten, mit einer sehr langen Wiederholungszahl (ohne sleep) für diesen Fall. |
|
if(pair1[0].time == 0) return;
Dies wird nie der Fall sein.
Wenn für das Symbol und den Zeitrahmen eine Historie geladen ist, ruft die Funktion den aktuellsten Wert ab.
Wenn keine Historie geladen ist, erhalten Sie einen Fehler Array out of range.
Dasselbe gilt für iTime usw.
Dies wird nie der Fall sein.
Wenn für das Symbol und den Zeitrahmen eine Historie geladen ist, ruft die Funktion den aktuellsten Wert ab.
Wenn keine Historie geladen ist, erhalten Sie einen Fehler Array out of range.
Dasselbe gilt für iTime usw.
Ich bin geneigt zuzustimmen!
Ich persönlich überprüfe nur den Rückgabewert von "ArrayCopyRates()" und behalte danach nur die Array-Größe im Auge, bevor ich auf die Array-Daten zugreife.
In Bezug auf "iTime()" und andere derartige Funktionen prüfe ich immer zuerst "iBars()".
Dies wird nie der Fall sein.
if(pair1[0].time == 0) return;
Wenn für das Symbol und den Zeitrahmen eine Historie geladen ist, ruft die Funktion den aktuellsten Wert ab.
Wenn keine Historie geladen ist, erhalten Sie einen Array out of range Fehler.
Dasselbe gilt für iTime usw.
Es gibt viele historische (vor der Erstellung von 600) Beispiele für die Betrachtung eines ACR. Es gibt keine andere Möglichkeit, dies zu tun. Nachfolgende Aufrufe von ACR oder iTime geben NICHT 4066 zurück, wie können Sie also wissen, ob die Daten heruntergeladen worden sind.
iTime hat bei einem Fehler immer Null zurückgegeben.
Es gibt viele historische (vor dem Build 600) Beispiele für die Betrachtung eines ACR. Es gibt keine andere Möglichkeit, dies zu tun. Nachfolgende Aufrufe von ACR oder iTime geben NICHT die Zahl 4066 zurück, wie können Sie also wissen, ob die Daten heruntergeladen wurden.
iTime hat bei einem Fehler immer Null zurückgegeben.
Was meinen Sie mit "es gibt keinen anderen Weg, es zu tun"?
Die Überprüfung der Rückgabezahl von "ArrayCopyRates" und die Überprüfung der Array-Größe scheint eine robustere Methode der Überprüfung zu sein als "pair1[0].time == 0", die leicht einen"Array index is out of range"-Fehler liefern kann.
EDIT: Ich habe einige meiner Aussagen entfernt, nachdem ich Ihren Beitrag noch einmal genauer gelesen habe.
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Ich möchte zwischen 1 und 10 verschiedenen Währungen und 5 Balken für jede Währung wählen.
Aber ich weiß nicht, wie man das macht.