Hallo MQL4-Gemeinschaft,
Ich bin beim Ausführen eines EA mit der Funktion Sleep() im Strategietester auf ein Problem gestoßen. Offenbar führt der Tester den EA nicht ordnungsgemäß aus, wenn die Funktion Sleep() in den Code eingebettet ist.
Haben einige Programmierer eine alternative Methode zur Funktion Sleep() entdeckt, um einen EA so zu programmieren, dass er eine bestimmte Zeit "wartet", während der EA im Tester ausgeführt wird?
Simon,
Ein Grund, warum ich mich für die Funktion "Sleep()" entschieden habe, war, dass Seconds() Werte aus der letzten bekannten Serverzeit zurückgibt (das Abrufen von Daten aus der letzten bekannten Serverzeit führt dazu, dass Sekunden übersprungen werden und/oder eine Pause entsteht). Ich wünsche mir Zuverlässigkeit, nicht Allgemeinheit.
Was sagen Sie dazu?
Ich danke Ihnen
Simon,
Ein Grund, warum ich mich für die Funktion "Sleep()" entschieden habe, war, dass Seconds() Werte von der letzten bekannten Serverzeit zurückgibt (das Abrufen von Daten von der letzten bekannten Serverzeit führt dazu, dass Sekunden übersprungen werden und/oder pausieren).
Simon,
Du schreibst also, ein Grund, warum ich diese "Sprünge" &/oder "Pausen" in Sekunden nenne, ist, dass zwischen [Sekunden x] und [Sekunden y] keine Ticks erzeugt werden. Laienhaft ausgedrückt: Es wird ein Tick erzeugt, jetzt wird 'Sekunden x' gespeichert. Drei Sekunden lang wird kein Tick erzeugt, dann wird ein Tick erzeugt. Jetzt wird 'Sekunden y' gespeichert. ('Sekunden y' = (Sekunden x +drei Sekunden)) als ('Sekunden x' = (Sekunden y-drei Sekunden)).
Was sagen Sie dazu?
Ich werde meine Optionen erst einmal abwägen.
Vielen Dank für Ihre Antworten.
- Bis Sie vom Start zurückkehren. Im Tester werden NIEMALS Ticks erstellt. Speichern Sie die TimeCurrent() in einer statischen/gemeinsamen (globalen) Variablen. Nächster Tick int deltaSec = TimeCurrent() - previous.
- https://www.mql5.com/en/forum/127483 berichtet, dass DayOfWeek() im Tester immer 5 zurückgibt (definitiv nicht dasselbe in Indikatoren, wie Ask und Bid). Ich verwende nie die Seconds(), DayOfWeek() usw., weil Sie nicht die aktuelle Serverzeit wollen, sondern die Zeit des Ticks des Testers. now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ..
Simon,
Du schreibst also, ein Grund, warum ich diese "Sprünge" &/oder "Pausen" in Sekunden nenne, ist, dass zwischen [Sekunden x] und [Sekunden y] keine Ticks erzeugt werden. Laienhaft ausgedrückt: Es wird ein Tick erzeugt, jetzt wird 'Sekunden x' gespeichert. Drei Sekunden lang wird kein Tick erzeugt, dann wird ein Tick erzeugt. Jetzt wird 'Sekunden y' gespeichert. ('Sekunden y' = (Sekunden x +drei Sekunden)) als ('Sekunden x' = (Sekunden y-drei Sekunden)).
Was sagen Sie dazu?
William,
vielen Dank für Ihre Antwort.
1. Bis Sie vom Start zurückkehren. Im Tester werden NIEMALS Ticks erstellt. Speichern Sie die TimeCurrent() in einer statischen/gemeinsamen (globalen) Variablen. Nächster Tick int deltaSec = TimeCurrent() - previous.
Ich verstehe nicht, was Sie mit "Bis Sie vom Start zurückkehren" meinen. Könnten Sie das bitte erläutern?
"Im Tester werden NIEMALS Ticks erzeugt"
Meinen Sie nicht, dass im Tester NIEMALS echte Ticks erzeugt werden? Würden Sie nicht zustimmen, dass künstliche Ticks im Tester erstellt werden?
"Speichern Sie die TimeCurrent() in einer statischen/gemeinsamen (globalen) Variablen. Nächster Tick int deltaSec = TimeCurrent() - previous."
Speichern Sie TimeCurrent() in einer Variablen. Wenn der nächste Tick kommt, int deltaSec =TimeCurrent() - previous.
Wäre die "vorherige" Variable nicht die Variable, in der TimeCurrent() gespeichert ist...
deltaSec = TimeCurrent() -(TimeCurrent() wurde zuvor in einer Variablen gespeichert)
Bitte klären Sie das, William.
https://www.mql5.com/en/forum/127483 berichtet, dass DayOfWeek() im Tester immer 5 zurückgibt. Ich verwende nie die Seconds(), DayOfWeek() usw., weil Sie jetzt die aktuelle Serverzeit wollen, Sie wollen die Zeit des Ticks des Testers. now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ..
"Sie wollen die Zeit des Ticks des Testers."
Ja, ich GLAUBE, dass dies GENAU das ist, was ich will, wenn ich einen EA im Strategietester teste, da Simon in seinem Beitrag die Gründe dafür beschrieben hat, warum Sekunden zu überspringen und/oder zu pausieren scheinen.
now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ..
Mit anderen Worten...
sec = TimeSeconds(TimeCurrent()); und DOW = TimeDayOfWeek(TimeCurrent());
Was sagen Sie dazu?
now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ..
Mit anderen Worten...
sec = TimeSeconds(TimeCurrent()); und DOW = TimeDayOfWeek(TimeCurrent());
Ich verstehe nicht, was Sie mit "Bis Sie vom Start zurückkehren" meinen. Könnten Sie das bitte erläutern?"
Im Tester werden NIEMALS Zecken erzeugt" Meinen Sie nicht, dass im Tester NIEMALS echte Zecken erzeugt werden? Würden Sie nicht zustimmen, dass künstliche Zecken im Tester erzeugt werden?
int start(){ // do something return; // Return from start. }
int start(){ // do something // Fall off the end is a Return from start. }
- Es werden keinerlei Ticks erzeugt, bis Sie zurückkehren und der nächste Tick erzeugt wird und Ihr start() aufgerufen wird. Wenn Sie die Berechnung für 5 Minuten durchführen und zurückkehren, beträgt das Volumen (Tickanzahl) beim nächsten Aufruf +1. In einem Live-Chart, wenn Sie für 5 Minuten berechnen, dann werden Sie 5 Minuten Ticks verpassen und auf der M1 werden mehrere neue Bars gebildet haben.
Es gibt keinen logischen Grund, warum sleep() im Strategy Tester funktionieren sollte ...
Seien Sie vorsichtig mit einer solchen Aussage. Es gibt immer einen logischen Grund, sleep() auszuführen. im Tester und sogar in Indikatoren. Richtig, für den Anwendungsfall des OP sollten Sie nicht mit sleep spielen, aber Sie können das nicht für alle MQL verallgemeinern.
wann brauchen wir sleep in Tester? wenn ich zum Beispiel ein skript teste, das mit einem zu testenden EA interagiert, könnte ich die notwendigkeit haben, den status zu synchronisieren. ich spreche von mutexes. um einen mutex auf saubere Weise zu erhalten, müssen beide teile die fähigkeit haben zu warten, d.h. sleep zu verwenden.
das gleiche gilt für indikatoren. es spielt keine rolle, dass der indikator im UI thread läuft. wenn zwei threads synchronisieren müssen, brauchen beide die fähigkeit zu "schlafen". und sleep() ist die einzige saubere lösung, wenn man auf eine bestimmte anzahl von CPU-zyklen warten muss, "for"-konstrukte zeigen nur einen mangel an wissen.
Ok, ein praktisches Beispiel: Meine EAs können den Status von Aufträgen anzeigen (selbst gezeichnete Pfeile usw.). Sie tun dies, indem sie auf externe Befehle reagieren, die durch Textbeschreibungen von Chart-Objekten "gesendet" werden (1: ausstehende Aufträge, 2: offene Positionen, 3: geschlossene Geschäfte, 4: alle zusammen), deshalb nenne ich sie Chart-Befehle. oder sie können Sequenzen von Trades starten/stoppen/fortsetzen, indem sie auf andere Befehle reagieren ("start", "stop", "resume"). um die Befehle zu lesen, müssen sie den Zugriff auf diese Chart-Objekte synchronisieren (Chart-Objekt erstellen + Texteigenschaft setzen ist keine atomare Operation). und natürlich würde ich dieses Verhalten gerne im Tester testen, also brauche ich sleep() zum Warten.
dasselbe gilt für Indikatoren, die im Tester oder online laufen. wenn sie etwas ähnliches tun, "muss" ich den UI-Thread stoppen, um einen sauberen Zustand zu erhalten, 10 Millisekunden spielen keine Rolle. btw: eine saubere Mutex-Implementierung prüft die Zeit, die sie bereits wartet, bricht aus der Schleife aus und meldet einen Fehler, wenn sie nach, sagen wir, ein paar Sekunden keine Synchronisationssperre erhalten kann.
int seconds; // run until the lock is aquired while (true) { ... // warn every second and cancel after 10 seconds duration = GetTickCount() - startTime; if (duration >= seconds*1000) { if (seconds >= 10) return(_false(catch("AquireLock(5) failed to get lock for mutex \""+ mutexName +"\" after "+ DoubleToStr(duration/1000.0, 3) +" sec., giving up", ERR_RUNTIME_ERROR))); warn(StringConcatenate("AquireLock(6) couldn't get lock for mutex \"", mutexName, "\" after ", DoubleToStr(duration/1000.0, 3), " sec., retrying...")); seconds++; } //debug("AquireLock() couldn't get lock for mutex \""+ mutexName +"\", retrying..."); if (IsTesting() || IsIndicator()) SleepEx(100, true); // expert or indicator under test else Sleep(100); }
ich verwende diese befehle, indem ich ein skript schreibe und ihm eine taste zuweise. wenn ich dann einen experten/indikator steuern will, brauche ich nur eine taste zu drücken, z.b. ALT-O, um zwischen allen möglichen Werten umzuschalten. oder ich habe ein "start" und ein "stop" Skript in den Favoriten und starte/stoppe/nehme eine ea durch einen Mausklick.
Im Tester wird z.B. ein Ea mit VisualMode=On in voller Geschwindigkeit fast sofort abstürzen, wenn es nicht richtig synchronisiert ist.
- 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.
Hallo MQL4-Gemeinschaft,
Ich bin beim Ausführen eines EA mit der Funktion Sleep() im Strategietester auf ein Problem gestoßen. Offenbar führt der Tester den EA nicht ordnungsgemäß aus, wenn die Funktion Sleep() in den Code eingebettet ist.
Haben einige Programmierer eine alternative Methode zur Funktion Sleep() entdeckt, um einen EA so zu programmieren, dass er eine bestimmte Zeit "wartet", während der EA im Tester ausgeführt wird?
Vielen Dank für Ihre Hilfe.