Organiser le cycle de commande - page 5

 
Vasiliy Sokolov:

Le bouclage est l'une des techniques de programmation les plus dangereuses. Il provoque des erreurs étranges et peu fréquentes qui sont presque impossibles à analyser.

Au contraire, vous devriez essayer de mettre fin à un fil d'utilisateur aussi rapidement que possible au lieu de le faire tourner en boucle. Si vous voulez avoir une "main sur le pouls" - analysez OnTradeTransaction dans MT5. MT4 n'est généralement pas adapté à ce type de jeux, car la simplicité est pire que le vol, comme on dit.

Je ne voulais pas parler d'une réalisation concrète, mais du principe du tremblement du TS après toute pause. Bien et où il y a une terrible fixation - n'est pas clair. Il n'est pas clair pourquoi il y a une telle hâte à terminer un fil d'utilisateur.

 
fxsaber:

Où est la boucle effrayante ici - ce n'est pas clair.

Appeler OnTick depuis OnTick est une boucle non triviale par récursion :

// Редкий, но правильный костяк модификации ордеров
for (int i = OrdersTotal() - 1; i >= 0; i--)
  if (OrderSelect(i, SELECT_BY_POS))
    if (OrderModify(OrderTicket(), Price, SL, TP, OrderExpiration()))     
    {
      i = OrdersTotal(); // Хотя бы так
      
      // А лучше так
      // OnTick(); break; // вместо строки выше лучше делать такой вызов (переполнения стека от рекурсивных вызовов быть не должно)
    }

On ne comprend pas non plus pourquoi il y a une précipitation à mettre fin au fil de discussion des utilisateurs.

Nous travaillons avec un modèle piloté par les événements. Par conséquent, nous devons traiter l'événement actuel aussi rapidement que possible pour attendre le suivant. Le temps passé dans le fil est un trou noir. Plus nous passons de temps dans le flux, plus l'environnement commercial avec lequel nous travaillons est dépassé.

 
Vasiliy Sokolov:

Appeler OnTick depuis OnTick est une boucle non triviale par récursion :

Apparemment, c'est la seule chose qui dissuade.

Nous travaillons avec un modèle d'événement. Par conséquent, nous devons traiter l'événement actuel aussi rapidement que possible afin d'attendre le suivant. Le temps passé dans le flux est un trou noir. Plus nous passons de temps dans le flux, plus l'environnement commercial avec lequel nous travaillons est dépassé.

Eh bien, ce n'est pas vrai !
 
:
void OnTick()
{
   for(int i = 0; i < symbols.Total(); i++)
   {
      request.symbol = symbols.At(i); 
      OrderSendAsynch(request, result); // Начиная с этой строки, анализировать торговое окружение в текущем потоке не имеет смысла
                                        // Единственная верная стратегия - как можно быстрее завершить цикл, и выйти из OnTick
                                        // Для дальнейшего анализа например в OnTransaction
   }
}

s. Nous ne nous comprenons pas du tout. Je ne pense pas qu'il puisse y avoir de dialogue entre nous.

 
Vasiliy Sokolov:
:

Où avez-vous vu une pause dans votre code, dont la simple présence est la seule raison pour secouer le TS à partir de zéro ? Vous ne l'avez pas !

 
fxsaber:

Où avez-vous vu une pause dans votre code, dont la simple présence est la seule raison pour secouer le TS à partir de zéro ? Vous ne l'avez pas !

Ce code est donc une illustration de la raison pour laquelle le thread actuel doit être terminé dès que possible. Vous ne devez même pas essayer de demander l'environnement de transaction dans OnTick :

void OnTick()
{
   for(int i = 0; i < symbols.Total(); i++)
   {
      request.symbol = symbols.At(i); 
      OrderSendAsynch(request, result); // Начиная с этой строки, анализировать торговое окружение в текущем потоке не имеет смысла
                                        // Единственная верная стратегия - как можно быстрее завершить цикл, и выйти из OnTick
                                        // Для дальнейшего анализа например в OnTransaction      
   }
   // Далее торговое окружение начинает меняться. Мы не можем анализировать его в OnTick
   // Бессмысленно зацикливать OnTick дальше.
   // Результат работы этого кода будет неопределен
   Sleep(50);
   int total_1 = OrdersTotal();
   Sleep(50);
   int total_2 = OrdersTotal();
   //Результат операции не определен
   if(total_1 == total_2)
}

Une fois que nous sommes arrivés au point où les deux variables sont comparées, nous ne pouvons plus les comparer car l'environnement change constamment. Les valeurs dans total_1 et total_2 ne sont plus égales l'une à l'autre, ou elles sont toutes deux obsolètes, ou elles ne contiennent pas le nombre existant de commandes, ou elles contiennent les valeurs correctes. Il est inutile de lutter contre un environnement commercial changeant dans OnTick, il suffit de quitter OnTick, immédiatement après la boucle for, et d'attendre de nouveaux événements indiquant que l'environnement commercial a changé.

 
Vasiliy Sokolov:

Ce code est donc une illustration de la raison pour laquelle le thread actuel doit être terminé le plus rapidement possible. Vous ne pouvez même pas essayer d'interroger l'environnement de négociation dans OnTick :

Une fois que nous sommes arrivés au point où les deux variables sont comparées, nous ne pouvons plus les comparer car l'environnement change constamment. Les valeurs dans total_1 et total_2 ne sont plus égales l'une à l'autre, ou elles sont toutes deux obsolètes, ou elles ne contiennent pas le nombre existant de commandes, ou elles contiennent les valeurs correctes. Il est inutile de se battre avec le changement d'environnement commercial dans OnTick, au lieu de cela, nous devons simplement sortir de OnTick, juste après la boucle for, et attendre de nouveaux événements indiquant que l'environnement commercial a changé.

Alors pourquoi tu as mis des pauses ? !


Une fois de plus, après toute pause (glissements ou ordres commerciaux synchrones), le TC doit être secoué - la logique de négociation doit être relancée à zéro. Par conséquent, si des ordres commerciaux asynchrones sont utilisés, les pauses mentionnées ne se produisent pas et il y a une sortie de la fonction événement en attente d'un nouvel événement. S'il n'y a pas d'opérations asynchrones, toute la logique de négociation peut même être placée dans un script en boucle.

 
fxsaber:

Alors pourquoi tu as mis des pauses ? !

Une fois de plus, après toute pause (glissements ou ordres commerciaux synchrones), le TS doit être redémarré - la logique commerciale doit être relancée à zéro. Par conséquent, si des ordres commerciaux asynchrones sont utilisés, les pauses mentionnées ne se produisent pas et il y a une sortie de la fonction événement en attente d'un nouvel événement. S'il n'y a pas d'opérations asynchrones, toute la logique de négociation peut même être placée dans un script en boucle.

Je vais parler de Thomas, et vous allez parler de Yury. En bref, terminons notre dialogue. Continuez à créer vos propres scripts en boucle. Oui, cela fonctionne vraiment, mais on ne peut pas le recommander comme méthode de travail.

 

Je suis intéressé de connaître leur opinion sur cette situation dans MT4, comment la gèrent-ils ?


Le ToR de l'Expert Advisor est de maintenir les ordres en attente et les positions ouvertes à une certaine distance fixe du prix actuel à chaque tick.


Laissez les modifications du courtier prendre un peu plus de temps que l'intervalle de temps moyen entre les ticks de prix.


Nous procédons donc à un cycle inverse (dans le sens décroissant de SELECT_BY_POS) et effectuons le OrderModify correspondant.


Donc, pendant cette boucle, emballé dans OnTick, le suivant peut se produire

  1. Les commandesTotal peuvent augmenter (à la main, par exemple, des remplissages ouverts ou partiels).
  2. Une réindexation des ordres et des positions en attente peut se produire (par exemple, certains ordres en attente ont été exécutés pendant le cycle, ou certains ordres en attente ont été supprimés manuellement, et certains ordres en attente ont été placés sur une machine avec un ping court).
  3. 1er ou 2ème point, mais aucune erreur OrderSelect et OrderModify ne se produit. Juste pendant le cycle à cause de p.1/2 certains ordres/positions vont finir par manquer.

Que faire ?

La question est indirectement liée à la discussion ci-dessus, mais il ne s'agit pas de la poursuivre (sujet clos). J'ai besoin de résoudre certaines nuances peu évidentes dans MT4Orders pour MT5. Il serait donc utile d'entendre l'avis de ceux qui maîtrisent bien MT4 sur les situations décrites. Et je ne suis pas le seul à pouvoir le trouver utile.


Résoudre le problème par le biais de OnTimer - c'est probablement la première suggestion. Mais nous n'en avons pas besoin - seulement OnTick.

 
fxsaber:

Je suis intéressé de connaître leur opinion sur cette situation dans MT4, comment la gèrent-ils ?


Le ToR de l'Expert Advisor est de maintenir les ordres en attente et les positions ouvertes à une certaine distance fixe du prix actuel à chaque tick.


Laissez les modifications du courtier prendre un peu plus de temps que l'intervalle de temps moyen entre les ticks de prix.


Nous procédons donc à un cycle inverse (dans le sens décroissant de SELECT_BY_POS) et effectuons le OrderModify correspondant.


Donc, pendant cette boucle, emballé dans OnTick, le suivant peut se produire

  1. Les commandesTotal peuvent augmenter (à la main, par exemple, des remplissages ouverts ou partiels).
  2. Une réindexation des ordres et des positions en attente peut se produire (par exemple, certains ordres en attente ont été exécutés pendant le cycle, ou certains ordres en attente ont été supprimés manuellement, et certains ordres en attente ont été placés sur une machine avec un ping court).
  3. 1er ou 2ème point, mais aucune erreur OrderSelect et OrderModify ne se produit. Juste pendant le cycle, en raison de la p.1/2, certains ordres/positions finiront par manquer.

Que faire ?

La question est indirectement liée à la discussion ci-dessus, mais il ne s'agit pas de la poursuivre (sujet clos). J'ai besoin de résoudre certaines nuances peu évidentes dans MT4Orders pour MT5. Il serait donc utile d'entendre l'avis de ceux qui maîtrisent bien MT4 sur les situations décrites. Et je ne suis pas le seul à pouvoir le trouver utile.


Résoudre le problème par le biais de OnTimer - c'est probablement la première suggestion. Mais passons outre - seulement OnTick.

Tout d'abord, la situation est atypique et très peu de personnes, voire aucune, ne l'ont jamais résolue.

De façon purement théorique :

Nous n'avons pas besoin d'organiser une boucle inverse pour OrderModify, alors laissez-la être directe.

int i, total = OrdersTotal();
for(i = 0; i < total; i++)

Ensuite, vérifions les changements dans la liste des commandes.

if(total != OrdersTotal())
 {
  i = 0;
  total = OrdersTotal();
  continue;
 }

Si le nombre de commandes a changé, nous recommençons cette boucle avec un nouveau nombre de commandes.

Une dernière question :

fxsaber:

  1. Les commandesTotal peuvent augmenter (à la main, par exemple, des remplissages ouverts ou partiels).
  2. La réindexation des ordres et des positions en attente peut se produire (par exemple, certains ordres en attente ont été exécutés pendant un cycle, ou certains ordres en attente ont été supprimés manuellement, et certains ordres en attente ont été placés sur un ping court).
  3. 1er ou 2ème point, mais aucune erreur OrderSelect et OrderModify ne se produit. C'est juste que pendant le cycle, à cause de p.1/2, certains ordres/positions vont finir par manquer.

Il est compréhensible que si ces personnes ont été ajoutées, elles ou d'autres seront regrettées. Mais que se passerait-il s'ils étaient simplement supprimés ? Nous ne pourrions pas aller au-delà de la liste des commandes ?