fonction sommeil alternative

 

Bonjour la communauté MQL4,

J'ai rencontré un problème lors de l'exécution d'une EA incluant la fonction Sleep() dans le testeur de stratégie. Apparemment, le testeur n'exécute pas correctement l'EA avec l'inclusion de la fonction Sleep() dans le code.

Est-ce que des codeurs ont découvert une méthode alternative à la fonction Sleep() pour coder un EA afin qu'il "attende" un certain temps pendant que l'EA est exécuté dans le testeur ?


Merci de votre compréhension.

 
WhooDoo22:

Bonjour la communauté MQL4,

J'ai rencontré un problème lors de l'exécution d'une EA incluant la fonction Sleep() dans le testeur de stratégie. Apparemment, le testeur n'exécute pas correctement l'EA avec l'inclusion de la fonction Sleep() dans le code.

Est-ce que des codeurs ont découvert une méthode alternative à la fonction Sleep() pour coder un EA afin qu'il "attende" un certain temps pendant que l'EA est exécuté dans le testeur ?

Il n'y a aucune raison logique pour que la fonction Sleep() fonctionne dans le testeur de stratégie... Qu'essayez-vous de faire ? Si vous essayez de chronométrer un événement, utilisez le temps et n'essayez pas simplement de faire une pause pendant le temps nécessaire, ce n'est pas à cela que sert la fonction Sleep().
 

Simon,

Si j'ai choisi d'utiliser la fonction 'Sleep()', c'est parce que Seconds() renvoie les valeurs à partir de la dernière heure connue du serveur (la récupération des données à partir de la dernière heure connue du serveur entraîne le saut et/ou la pause des secondes). Je souhaite une fiabilité, pas une généralité.

Que pensez-vous de cela ?


Je vous remercie

 
WhooDoo22:

Simon,

Si j'ai choisi d'utiliser la fonction 'Sleep()', c'est parce que Seconds() renvoie les valeurs à partir de la dernière heure connue du serveur (la récupération des données à partir de la dernière heure connue du serveur entraîne le saut et/ou la pause des secondes).

Vous ne pouvez "voir" le temps que pour les temps qui ont des ticks, s'il n'y a pas de ticks pendant 30 secondes, vous verrez un saut de 30 secondes... vous ne pouvez rien y faire, c'est comme ça. Les temps des ticks dans le testeur de stratégie doivent être raisonnablement uniformes car les ticks ne sont pas réels mais synthétisés.
 

Simon,

Vous écrivez donc : "Si je les appelle "sauts" et/ou "pauses" en secondes, c'est parce qu'aucun tic n'est créé entre [secondes x] et [secondes y]. En termes simples, un tic est créé, puis la seconde x est enregistrée. Aucun tic n'est créé pendant trois secondes, puis un tic est créé. Les " secondes y " sont alors enregistrées. ('secondes y' = (secondes x +trois secondes)) comme ('secondes x' = (secondes y-trois secondes)).

Qu'en pensez-vous ?


Je vais réfléchir à mes options pour l'instant.

Merci beaucoup pour vos réponses.

 
  1. Jusqu'à ce que vous reveniez du départ. Aucun ticks n'est JAMAIS créé dans le testeur. Enregistrez le TimeCurrent() dans une variable statique/commune (globale). Prochain tick int deltaSec = TimeCurrent() - previous.
  2. https://www.mql5.com/en/forum/127483 a signalé que DayOfWeek() renvoie toujours 5 dans le testeur (ce n'est certainement pas la même chose dans les indicateurs, tout comme Ask et Bid). Je n'utilise jamais AUCUNE des fonctions Seconds(), DayOfWeek() etc. parce que vous ne voulez pas l'heure actuelle du serveur, vous voulez l'heure du tick du testeur. now = TimeCurrent(), sec = TimeSeconds(now) ; int DOW=TimeDayOfWeek(now) ...
 
WhooDoo22:

Simon,

Vous écrivez donc : "Si je les appelle "sauts" et/ou "pauses" en secondes, c'est parce qu'aucun tic n'est créé entre [secondes x] et [secondes y]. En termes simples, un tic est créé, puis la seconde x est enregistrée. Aucun tic n'est créé pendant trois secondes, puis un tic est créé. Les " secondes y " sont alors enregistrées. ('secondes y' = (secondes x +trois secondes)) comme ('secondes x' = (secondes y-trois secondes)).

Qu'en dites-vous ?

Oui, il pourrait facilement y avoir 3 secondes entre les ticks, tout comme dans le monde réel, regardez n'importe quelle paire de devises à minuit GMT, vous verrez beaucoup de temps de plusieurs secondes entre les ticks ... vous pouvez même avoir aucun ticks pendant plus d'une minute et manquer les barres M1 ... ce n'est pas une chose rare.
 

William,

Merci beaucoup pour votre réponse.

1. Jusqu'à ce que vous reveniez du départ. Aucun ticks n'est JAMAIS créé dans le testeur. Enregistrez le TimeCurrent() dans une variable statique/commune (globale). Prochain tick int deltaSec = TimeCurrent() - previous.

Je ne comprends pas ce que vous voulez dire par "Jusqu'à ce que vous reveniez du début". Pouvez-vous m'expliquer ?


"Aucun ticks n'est jamais créé dans le testeur".

Ne voulez-vous pas dire, aucun ticks réels sont jamais créés dans le testeur. N'êtes-vous pas d'accord que des ticks artificiels sont créés dans le testeur ?


"Sauvegarder le TimeCurrent() dans une variable statique/commune(globale). Tic suivant int deltaSec = TimeCurrent() - précédent."

Sauvegarder le TimeCurrent() dans une variable. Au prochain tick, int deltaSec =TimeCurrent() - previous.

La variable "précédente" ne serait-elle pas la variable dans laquelle TimeCurrent() est sauvegardée...

deltaSec = TimeCurrent() -(TimeCurrent() sauvegardé dans une variable précédente)

Veuillez clarifier William.


https://www.mql5.com/en/forum/127483 a signalé que DayOfWeek() renvoie toujours 5 dans le testeur. Je n'utilise jamais AUCUNE des fonctions Seconds(), DayOfWeek() etc. parce que vous ne voulez pas l'heure actuelle du serveur, vous voulez l'heure du tick du testeur. now = TimeCurrent(), sec = TimeSeconds(now) ; int DOW=TimeDayOfWeek(now) ...


"vous voulez l'heure du tick du testeur".

Oui, je CROIS que c'est EXACTEMENT ce que je veux lorsque je teste un EA dans le testeur de stratégie en raison du post de Simon décrivant le raisonnement derrière la raison pour laquelle les secondes semblent sauter et/ou faire une pause.


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

En d'autres termes...

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

Qu'en dites-vous ?


Merci
 
WhooDoo22:

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

En d'autres termes...

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

Regardez ce que TimeSeconds() vous donne, puis pensez à ce que TimeCurrent() vous donne . ... lequel vous faut-il et pourquoi ?
 
WhooDoo22:

Je ne comprends pas ce que vous voulez dire par "jusqu'à ce que vous reveniez du départ". Pourriez-vous nous expliquer ?"

Aucun tic n'est jamais créé dans le testeur" Ne voulez-vous pas dire, aucun tic réel n'est jamais créé dans le testeur. N'êtes-vous pas d'accord que des tics artificiels sont créés dans le testeur ?

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

  2. Aucun ticks d'aucune sorte n'est créé jusqu'à ce que vous reveniez et qu'il crée le suivant et appelle votre start(). Si vous calculez pendant 5 minutes et que vous retournez, le volume (nombre de ticks) lors du prochain appel sera de +1. Sur un graphique en direct, si vous calculez pendant 5 minutes, il vous manquera 5 minutes de ticks et sur le M1 plusieurs nouvelles barres se seront formées.
 
RaptorUK:
Il n'y a aucune raison logique pour que sleep() fonctionne dans le Strategy Tester ...

il n'y a pas de raison logique pour que sleep() fonctionne dans le testeur de stratégie. il n'y a aucune raison logique pour que sleep() fonctionne dans le testeur de stratégie ...

quand avons-nous besoin de sleep dans Tester? si, par exemple, je teste un script qui interagit avec un EA en cours de test, je peux avoir besoin de synchroniser l'état. je parle des mutex. pour acquérir un mutex de manière propre, les deux parties doivent avoir la possibilité d'attendre, c'est à dire utiliser sleep.

il en va de même pour les indicateurs. peu importe que l'indicateur tourne dans le thread de l'interface utilisateur. si deux threads ont besoin de se synchroniser, ils doivent tous deux pouvoir "dormir". et sleep() est la seule solution propre si vous devez attendre un nombre donné de cycles CPU, les constructions "for" ne font que démontrer un manque de connaissances.

ok, donnons un exemple pratique : mes EA peuvent afficher l'état des ordres (flèches auto dessinées, etc.). ils le font en répondant à des commandes externes "envoyées" par des descriptions textuelles d'objets graphiques (1-ordres en attente, 2-positions ouvertes, 3-transactions fermées, 4-toutes ensemble), c'est pourquoi je les appelle des commandes graphiques. ou ils peuvent démarrer/arrêter/reprendre des séquences de transactions en répondant à d'autres commandes ("start", "stop", "resume"). pour lire les commandes, ils doivent synchroniser l'accès à ces objets graphiques (create chart object + set text property n'est pas une opération atomique). et bien sûr, je voudrais tester ce comportement dans Tester, donc j'ai besoin de sleep() pour attendre.

Il en va de même pour les indicateurs fonctionnant dans Tester ou en ligne. S'ils font quelque chose de similaire, je "dois" arrêter le thread de l'interface utilisateur pour obtenir un état propre, 10 millisecondes n'ont pas d'importance. En fait, une implémentation propre de mutex vérifie le temps d'attente, sort de la boucle et signale une erreur si elle ne peut pas obtenir un verrou de synchronisation après, disons, quelques secondes.

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

J'utilise ces commandes en écrivant un script et en lui assignant un raccourci clavier. Ensuite, si je veux contrôler un expert/indicateur, il me suffit d'appuyer sur une touche, par ex. ALT-O pour basculer le mode d'affichage de l'ordre entre toutes les valeurs possibles. Ou bien j'ai un script "start" et un script "stop" dans les favoris et je démarre/arrête/reprends une ea par un clic de souris.

dans Tester par exemple, une ea avec VisualMode=On en pleine vitesse se plantera presque immédiatement si elle n'est pas correctement synchronisée.