Funktion Schlaf Alternative

 

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.

 
WhooDoo22:

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?

Es gibt keinen logischen Grund dafür, dass sleep() im Strategietester funktioniert ... was versuchen Sie zu tun? Wenn Sie versuchen, ein Ereignis zu timen, dann verwenden Sie die Zeit und versuchen Sie nicht einfach, für die erforderliche Zeit zu pausieren, dafür ist sleep() nicht gedacht.
 

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

 
WhooDoo22:

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).

Was ist Ihr Beweis dafür? Sie können die Zeit nur für Zeiten "sehen", die Ticks haben, wenn es 30 Sekunden lang keine Ticks gibt, dann sehen Sie einen Sprung von 30 Sekunden ... Sie können nichts dagegen tun, so ist es nun mal. Die Zeiten für Ticks im Strategietester sollten einigermaßen gleichmäßig sein, da die Ticks nicht real sind, sondern synthetisiert werden.
 

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.

 
  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.
  2. 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) ..
 
WhooDoo22:

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?

Ja, es könnten leicht 3 Sekunden zwischen den Ticks liegen, genau wie in der realen Welt. Schauen Sie sich ein beliebiges Währungspaar um Mitternacht GMT an, Sie werden viele große Zeiträume von mehreren Sekunden zwischen den Ticks sehen ... Sie können sogar über eine Minute lang keine Ticks bekommen und M1-Balken fehlen ... das ist keine seltene Sache.
 

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?


Ich danke Ihnen
 
WhooDoo22:

now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ..

Mit anderen Worten...

sec = TimeSeconds(TimeCurrent()); und DOW = TimeDayOfWeek(TimeCurrent());

Schauen Sie sich an, was TimeSeconds() Ihnen gibt, und überlegen Sie dann, was TimeCurrent() Ihnen gibt. . welche brauchen Sie und warum?
 
WhooDoo22:

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?

  1. int start(){
       // do something
       return; // Return from start.
    }
    int start(){
       // do something
       // Fall off the end is a Return from start.
    }

  2. 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.
 
RaptorUK:
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.