funzione sonno alternativo

 

Salve comunità MQL4,

Ho riscontrato un problema durante l'esecuzione di un EA che include la funzione Sleep() nel tester della strategia. Apparentemente il tester non esegue correttamente l'EA con l'inclusione della funzione Sleep() incorporata nel codice.

Qualche codificatore presente ha scoperto un metodo alternativo alla funzione Sleep() per codificare un EA per "aspettare" una certa quantità di tempo mentre l'EA viene eseguito nel tester?


Grazie

 
WhooDoo22:

Salve comunità MQL4,

Ho riscontrato un problema durante l'esecuzione di un EA che include la funzione Sleep() nel tester della strategia. Apparentemente il tester non esegue correttamente l'EA con l'inclusione della funzione Sleep() incorporata nel codice.

Qualche codificatore presente ha scoperto un metodo alternativo alla funzione Sleep() per codificare un EA per "aspettare" una certa quantità di tempo mentre l'EA viene eseguito nel tester?

Non c'è alcuna ragione logica per cui sleep() debba funzionare nello Strategy Tester... cosa stai cercando di fare? Se stai cercando di cronometrare un evento allora usa il tempo e non cercare di mettere in pausa per il tempo richiesto, non è a questo che serve sleep().
 

Simon,

Una ragione per cui ho scelto di usare la funzione 'Sleep()' è che Seconds() restituisce i valori dall'ultimo tempo noto del server (recuperare i dati dall'ultimo tempo noto del server fa saltare e/o mettere in pausa i secondi). Desidero l'affidabilità, non la generalità.

Cosa ne dite di questo?


Grazie a voi

 
WhooDoo22:

Simon,

Una ragione per cui ho scelto di usare la funzione 'Sleep()' è che Seconds() restituisce valori dall'ultimo tempo noto del server (il recupero dei dati dall'ultimo tempo noto del server fa saltare e/o mettere in pausa i secondi).

Qual è la tua prova per questo? puoi solo "vedere" il tempo per i tempi che hanno i tick, se non ci sono tick per 30 secondi allora vedrai un salto di 30 secondi . . . non c'è niente che tu possa fare su questo, è così che è. I tempi per i tick nello Strategy Tester dovrebbero essere ragionevolmente uniformi poiché i tick non sono reali ma sintetizzati.
 

Simon,

Così scrivi, una ragione per cui potrei chiamare questi "salti" e/o "pause" nei secondi è perché non vengono creati tick tra [secondi x] e [secondi y]. In termini profani, viene creato un tick, ora 'secondi x' viene salvato. Nessun tick viene creato per tre secondi, poi viene creato un tick. Ora viene salvato 'seconds y'. ('secondi y' = (secondi x +tre secondi)) come ('secondi x' = (secondi y-tre secondi)).

Cosa ne dite di questo?


Considererò le mie opzioni per il momento.

Molte grazie per le vostre risposte.

 
  1. Finché non si ritorna dall'inizio. Nessun tick viene creato nel tester. Salvate il TimeCurrent() in una variabile statica/comune (globale). Prossimo tick int deltaSec = TimeCurrent() - precedente.
  2. https://www.mql5.com/en/forum/127483 ha segnalato che DayOfWeek() restituisce sempre 5 nel tester (sicuramente non è lo stesso negli indicatori, così come Ask e Bid). Non uso mai NESSUNO dei Seconds(), DayOfWeek() ecc. perché non vuoi il tempo corrente del server, vuoi il tempo del tick del tester. now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ..
 
WhooDoo22:

Simon,

Così scrivi, una ragione per cui potrei chiamare questi "salti" e/o "pause" nei secondi è perché non vengono creati tick tra [secondi x] e [secondi y]. In termini profani, viene creato un tick, ora 'secondi x' viene salvato. Nessun tick viene creato per tre secondi, poi viene creato un tick. Ora viene salvato 'seconds y'. ('secondi y' = (secondi x +tre secondi)) come ('secondi x' = (secondi y-tre secondi)).

Cosa ne dite di questo?

Sì, ci potrebbero facilmente essere 3 secondi tra i tick, proprio come nel mondo reale, date un'occhiata a qualsiasi coppia di valute a mezzanotte GMT, vedrete un sacco di grandi tempi di più secondi tra i tick . . . potete anche avere nessun tick per oltre un minuto e barre M1 mancanti . . . non è una cosa rara.
 

William,

Molte grazie per la tua risposta.

1. Finché non si ritorna dall'inizio. Nessun tick viene creato nel tester. Salva il TimeCurrent() in una variabile statica/comune (globale). Prossimo tick int deltaSec = TimeCurrent() - precedente.

Non capisco cosa intendi per "finché non si ritorna dall'inizio". Potresti spiegarti meglio?


"Nessun tick viene MAI creato nel tester"

Non vuoi dire che nessun tick reale viene MAI creato nel tester. Non sei d'accordo che nel tester vengono creati tick artificiali?


"Salvare il TimeCurrent() in una variabile statica/comune (globale). Prossimo tick int deltaSec = TimeCurrent() - precedente".

Salvare TimeCurrent() in una variabile. Quando arriva il prossimo tick, int deltaSec =TimeCurrent() - precedente.

La variabile "precedente" non dovrebbe essere la variabile in cui viene salvato TimeCurrent()...

deltaSec = TimeCurrent() -(TimeCurrent() salvato in una variabile precedente)

si prega di chiarire William.


https://www.mql5.com/en/forum/127483 ha riportato che DayOfWeek() restituisce sempre 5 in tester. Non uso mai NESSUNO dei Seconds(), DayOfWeek() ecc. perché ora vuoi il tempo corrente del server, vuoi il tempo del tick del tester. now = TimeCurrent(), sec = TimeSeconds(now); int DOW=TimeDayOfWeek(now) ..


"vuoi il tempo del tick del tester".

Sì, CREDO che questo sia ESATTAMENTE ciò che voglio quando si testa un EA nel tester di strategia a causa del post di Simon che descrive il motivo per cui i secondi sembrano saltare e/o mettere in pausa.


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

In altre parole...

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

Cosa ne dite di questo?


Grazie a voi
 
WhooDoo22:

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

In altre parole...

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

Dai un'occhiata a ciò che ti dà TimeSeconds(), poi pensa a ciò che ti dà TimeCurrent() . . quale vi serve e perché?
 
WhooDoo22:

Non capisco cosa intendi con "Finché non torni dalla partenza". Potresti spiegarti meglio?"

Nessuna zecca viene creata nel tester" Non vuoi dire che nessuna zecca reale viene creata nel tester. Non siete d'accordo che nel tester si creano zecche artificiali?

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

  2. Non vengono creati tick di nessun tipo fino a quando non si ritorna e si crea il prossimo e si chiama la start(). Se calcoli per 5 minuti e restituisci il volume (conteggio dei tick) alla prossima chiamata sarà +1. In un grafico live, se calcoli per 5 minuti, allora perderai 5 minuti di tick e sull'M1 si saranno formate diverse nuove barre.
 
RaptorUK:
Non c'è alcuna ragione logica per cui sleep() funzioni nello Strategy Tester ...

Fai attenzione con questa affermazione. c'è sempre una ragione logica per eseguire sleep(). in Tester e anche negli indicatori. giusto, per il caso d'uso dell'OP non si dovrebbe giocare con sleep ma non si può generalizzare questo per tutti i MQL.

Quando abbiamo bisogno di dormire in Tester? se, per esempio, provo uno script che interagisce con un EA in prova potrei avere la necessità di sincronizzare lo stato. sto parlando di mutex. per acquisire un mutex in modo pulito entrambe le parti hanno bisogno della capacità di aspettare, cioè di usare sleep.

Lo stesso vale per gli indicatori. non importa che l'indicatore venga eseguito nel thread dell'UI. se due thread hanno bisogno di sincronizzarsi entrambi hanno bisogno della capacità di "dormire". e sleep() è l'unica soluzione pulita se si deve aspettare una certa quantità di cicli di CPU, i costrutti "for" dimostrano solo una mancanza di conoscenza.

ok, facciamo un esempio pratico: i miei EA possono visualizzare lo stato degli ordini (frecce auto disegnate ecc.). lo fanno rispondendo a comandi esterni "inviati" attraverso descrizioni testuali di oggetti grafici (1-ordini in sospeso, 2- posizioni aperte, 3-trade chiuse, 4-tutti insieme), ecco perché li chiamo comandi grafici. oppure possono avviare/fermare/riprendere sequenze di operazioni rispondendo ad altri comandi ("start", "stop", "resume"). per leggere i comandi hanno bisogno di sincronizzare l'accesso a questi oggetti grafico (creare oggetto grafico + impostare proprietà testo non è un'operazione atomica). e naturalmente vorrei testare questo comportamento in Tester, quindi ho bisogno di sleep() per aspettare.

Lo stesso per gli indicatori in esecuzione in Tester o online. se fanno qualcosa di simile "devo" fermare il thread UI per ottenere uno stato pulito, 10 miilisecondi non hanno importanza. btw: un'implementazione mutex pulita controlla il tempo che sta già aspettando, esce dal ciclo e segnala un errore se non può ottenere un lock di sincronizzazione dopo diciamo qualche secondo.

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);
}

Io uso questi comandi scrivendo uno script e assegnandogli un tasto di scelta rapida. poi, se voglio controllare un esperto/indicatore ho solo bisogno di premere un tasto, per es. ALT-O per alternare la modalità di visualizzazione dell'ordine tra tutti i valori possibili. oppure ho uno script "start" e uno "stop" nei preferiti e faccio partire/fermare/riprendere un ea con un clic del mouse.

in tester per es. un ea con VisualMode=On in piena velocità andrà quasi immediatamente in crash se non adeguatamente sincronizzato.