Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 607

 
Vitaly Gorbunov:

Le fait que vous ayez identifié quelque part le nombre de commandes dont vous avez besoin est une bonne chose, mais dans ce bloc, il faut repasser toutes les commandes et les vérifier !

Décomposez le code correctement et vous verrez tout de suite !

Vous pouvez bien sûr le recalculer à nouveau. Mais ça ne fait pas la différence. L'opérateur if() ne fait pas "autrement". Ce n'est qu'un cas, et il y en a eu d'autres.
 
for(int h = OrdersTotal()-1; h >= 0; h--)
    {
     if(OrderSelect(h, SELECT_BY_POS))
      {
       if((cnt_OO >= 2))
        {
       if((OrderMagicNumber() == Magic)&&(OrderLots() <= Lots/Prikup - Dplus))
        {
         Nextstep  = NextStep;
         BaseNext  = OrderOpenPrice();
         LotsNext  = NormalizeDouble(OrderLots()*K,lotDigit);
         if(NewPB > 0)
          PBcloseON = true;
         Alert ("Pospedny Order NEXT  ",OrderTicket());
         Alert ("Otkritih orderov  ",cnt_OO);
//         break;
        }
       break;
       }
         LotsNext    = NormalizeDouble(Lots*Prikup,lotDigit); 
         Alert ("Otkritih orderov NEXT net ");
        Alert ("Otkritih orderov  ",cnt_OO);
         break;
     
        }}

Essayez comme ça !

Je ne vois rien d'autre dans votre code !

Jetez les autres cas, voyons ce qui ne va pas :)

Après une étude attentive de la logique, j'ai fait de la rétro-ingénierie de votre code.

Cela a donné quelque chose comme ceci

if(cnt_OO>0) //Если нет ордеров то и не надо ни чего делать
{
  for(int h = OrdersTotal()-1; h >= 0; h--)
   {
    if(OrderSelect(h, SELECT_BY_POS))
     {
      if(cnt_OO==1)
         {
          //Если ордер один проверяем тот ли ордер (майджик и прочее) и что то там делаем
         }
      else
         {
          //Если ордеров больше чем 1 проверяем те ли ордера (майджик и прочее) и что то там делаем
         }
     }
   }
   
}
 

Nous pouvons le faire de cette façon. Mais le tutoriel indique que si la condition n'est pas remplie, les commandes après le crochet fermant le bloc pour traiter la condition de l'opérateur if() sont traitées. Cela ne se produit pas.

Il y avait un autre problème :

     if((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld==zLots))
      {
       

Si j'ai ajouté une condition supplémentaire au premier opérateur if - la suivante - cela n'a pas fonctionné.

J'ai deux suggestions

1. Stupide testeur de stratégie. Comme ces situations se produisent au stade du débogage du programme, il faut être complètement idiot pour le vérifier sur un compte réel. Et sur un compte de démonstration aussi, car il est difficile de reproduire la situation de redémarrage. Le fait que le testeur soit un idiot nous indique que l'ordre de clôture de plusieurs ordres dans la fenêtre MT4 ne correspond souvent pas à l'ordre réel si la clôture a lieu en même temps. Ceci est clairement visible si vous recalculez les derniers ordres dans le programme. Cette erreur m'a fait passer une semaine à essayer de trouver qui était cinglé.

La logique même du fonctionnement du testeur, même sur l'historique des tics, est loin de la vie réelle. C'est très important pour mon algorithme.

2. comme une supposition. Une question aux gourous particulièrement avancés non seulement dans MQL/MT4, mais aussi aux spécialistes des systèmes.

- J'ai deux EAs identiques sur la même paire dans des fenêtres différentes. Lorsque je lance les EAs, par exemple le lundi après que l'ordinateur soit éteint pour le week-end, ils commencent tous les deux à fonctionner en même temps lorsque le premier tick apparaît. J'espérais que l'un travaillerait d'abord à la restauration de l'État, puis l'autre. Celui qui avait de la chance, travaillait en premier.

En fait, les messages sur la récupération des données sont mitigés. En d'autres termes, l'exécution du programme est interrompue par une condition quelconque, par exemple le timer du système, puis se poursuit. Des situations intéressantes se produisent lorsque, par exemple, on passe à un autre compte pour voir comment les choses se passent là-bas. Les conditions de vérification du compte sont au début du programme et au moment du retour au compte initial, le programme est au milieu et se moque du compte qui s'y trouve maintenant.

J'ai trouvé une solution : au début de chaque bloc, je vérifie le numéro de compte. Je ne suis pas sûr de l'endroit où il est censé être.

 

Amon1953, avez-vous regardé la première version que j'ai corrigée ? Est-ce que ça marche ? Exactement comme cela est écrit dans le manuel if() et cela fonctionne depuis de nombreuses années d'utilisation. Le problème est que dans votre code, vous avez placé une rupture dans un mauvais bloc.

si((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld==zLots)) vous devez vérifier ce qui est attribué aux variables.

Pour ce qui est du deuxième point, les deux hiboux fonctionneront en parallèle et leurs messages seront donc mélangés. Pour faire ce que vous décrivez, vous devez implémenter le sémaphore entre les copies de l'hibou. Et c'est très intéressant que quelque chose de bizarre se passe quand je change de compte. J'aimerais beaucoup voir OnInit et OnDeinit. Il est fort probable que le problème se situe à cet endroit.

 
Vitaly Gorbunov:

Amon1953, avez-vous regardé la première version que j'ai corrigée ? Est-ce que ça marche ? Exactement comme cela est écrit dans le manuel if() et cela fonctionne depuis de nombreuses années d'utilisation. Le problème est que dans votre code, vous avez placé une rupture dans un mauvais bloc.

si((OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))&&(OrderMagicNumber() == Magic)&&(OrderLotsOld==zLots)) vous devez vérifier ce qui est attribué aux variables.

Pour ce qui est du deuxième point, les deux hiboux fonctionneront en parallèle et leurs messages seront donc mélangés. Pour faire ce que vous décrivez, vous devez implémenter le sémaphore entre les copies de l'hibou. Et c'est très intéressant que quelque chose de bizarre se passe quand je change de compte. J'aimerais beaucoup voir OnInit et OnDeinit. Il est fort probable que le problème se situe à cet endroit.

Je ne l'ai pas vérifié car nous devons sortir de la boucle par le dernier ordre (c'est le premier de la liste).

Je ne suis pas un programmeur expérimenté et je ne comprends pas bien le fonctionnement de OnInit et OnDeinit. C'est pourquoi ils ne sont pas utilisés dans mon code, mais ils semblent permettre au programme de fonctionner sans interruption au milieu.

Je ne comprends pas non plus le sémaphore, les conseillers sont installés dans des fenêtres différentes et ont des majors différentes.

 
Si vous n'avez commencé à programmer que récemment, je vous conseille de revoir les principes de base de la programmation. Sans vouloir vous offenser, il est très difficile de communiquer avec vous.
 
Vitaly Gorbunov:
Si vous n'avez commencé à programmer que récemment, je vous conseille d'étudier à nouveau les bases de la programmation. Sans vouloir vous offenser, il est très difficile de communiquer avec vous.
Merci. Cette section est destinée aux débutants. Même ce type de communication m'a été bénéfique. Il est difficile de faire à la fois l'algorithme de l'EA et d'écrire le code du programme (de plus, le langage de programmation est assez nouveau pour moi).
 
Amon1953:
Merci. Il s'agit d'une section pour les débutants. Même ce type de communication m'a été bénéfique. Il est difficile de faire à la fois l'algorithme de l'EA et le code du programme (d'autant plus que le langage de programmation est assez nouveau pour moi).
Il semble que vous ayez besoin d'améliorer les bases ! Comme je ne comprends pas bien, à partir de votre code, le type de logique que vous voulez mettre en œuvre, essayez d'expliquer en mots ce que vous voulez faire. Et je vais essayer d'expliquer où vous avez une erreur.
 
Vitaly Gorbunov:
On dirait que tu dois resserrer la base ! Comme je ne comprends pas bien, à partir de votre code, la logique que vous voulez mettre en œuvre, essayez d'expliquer en mots ce que vous voulez faire. Et je vais essayer d'expliquer où vous avez fait une erreur.

J'ai déjà expliqué ce dont j'ai besoin auparavant. Je vais essayer de clarifier les détails.

Lorsque vous redémarrez l'EA, vous devez rétablir l'état précédent, car l'algorithme est une chaîne d'ordres. La première commande est la commande de base, et nous pouvons calculer les paramètres des commandes suivantes dans la chaîne à partir de celle-ci. Par exemple, le volume de la deuxième commande est de 50% de la base, la troisième de 75%, et ainsi de suite. Lors du redémarrage d'un EA, nous devons connaître le volume de l'ordre de base et du dernier ordre, puisque le volume du prochain ordre sera calculé à partir du dernier. Par exemple, il y a 3 ordres ouverts. Pour calculer le prochain (quatrième) ordre, nous devons trouver le volume du dernier ordre ouvert.

S'il n'y a qu'une seule commande, cela signifie qu'il s'agit de la commande de base et dans ce cas, elle ne nous intéresse pas, elle est traitée par une autre unité.

L'algorithme est très simple. Mais cela ne fonctionne qu'avec deux opérateurs if().

 
Amon1953:

J'ai déjà expliqué ce dont j'ai besoin auparavant. Je vais essayer de clarifier les détails.

Lorsque vous redémarrez l'EA, vous devez rétablir l'état précédent, car l'algorithme est une chaîne d'ordres. La première commande est la commande de base, et nous pouvons calculer les paramètres des commandes suivantes dans la chaîne à partir de celle-ci. Par exemple, le volume de la deuxième commande est de 50% de la base, la troisième de 75%, et ainsi de suite. Lors du redémarrage d'un EA, nous devons connaître le volume de l'ordre de base et du dernier ordre, puisque le volume de l'ordre suivant sera calculé à partir du dernier ordre. Par exemple, il y a 3 ordres ouverts. Pour calculer le prochain (quatrième) ordre, nous devons trouver le volume du dernier ordre ouvert.

S'il n'y a qu'une seule commande, cela signifie qu'il s'agit de la commande de base et dans ce cas, elle ne nous intéresse pas, elle est traitée par une autre unité.

L'algorithme est très simple. Mais cela ne fonctionne qu'avec deux opérateurs if().

Amon1953:

Je ne l'ai pas vérifié car nous devons sortir de la boucle par le dernier ordre (c'est le premier de la liste).

Je ne suis pas un programmeur expérimenté et je ne comprends pas bien le fonctionnement de OnInit et OnDeinit. C'est pourquoi ils ne sont pas utilisés dans mon code, mais ils semblent permettre au programme de fonctionner sans interruption au milieu.

Les Expert Advisors sont installés dans des fenêtres différentes et ont des majors différentes.

Veuillez lire la documentation :

OnInit

La fonction OnInit() est le gestionnaire de l'événement Init . Ilpeut être de type void ou int, n'a pas de paramètres:

voidOnInit() ;

Les événements Init sont générés immédiatement après le chargement d'un Expert Advisor ou d'un indicateur. La fonction OnInit() est utilisée pour l'initialisation. Si OnInit() a une valeur de retour int, le code de retour non nul signifie que l'initialisation a échoué, et génère l'événement Deinit avec le code de raison de désinitialisationREASON_INITFAILED.

Réglez également la question de la visibilité des variables.

События клиентского терминала - Программы MQL4 - Справочник MQL4
События клиентского терминала - Программы MQL4 - Справочник MQL4
  • docs.mql4.com
Сразу же после того, как клиентский терминал загрузит программу (эксперт или пользовательский индикатор) и запустит процесс инициализации глобальных переменных, будет послано событие Init, которое обрабатывается функцией OnInit(), если она есть. Это событие также генерируется после смены финансового инструмента и/или периода графика, после...