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

 
Roman Sharanov:
Pouvez-vous nous dire si la fonction de fermeture de tous les ordres ouverts par l'EA par le symbole est correctement implémentée ?

L'architecture elle-même est correcte. Les erreurs résident dans l'absence de contrôles et l'utilisation de certaines fonctions :

bool OrderCloseAll()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
         if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)
            continue;

         if(OrderSymbol() !=Symbol() || OrderMagicNumber() != Magic)
            continue;
         
         if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slippage, clrWhite))
            return false;
   }

   return true;
}

  1. La première itération dans votre cas échouera - la commande avec l'index OrdersTotal() n'existe pas.
  2. Il n'y a pas de contrôle du résultat de la fonction OrderSelect.
  3. Il n'y a pas de contrôle du résultat de la fonction OrderClose. Si la clôture de l'ordre échoue, nous ne pouvons pas rester dans la même fonction, car nous devons trouver pourquoi la clôture a échoué. Pour ce faire, nous devons quitter la fonction avec le résultat false, puis décider de ce qu'il faut faire ensuite.
  4. Nous ne pouvons pas utiliser un seul et même prix de clôture pour tous les ordres. Premièrement, les ordres peuvent être de types différents et, deuxièmement, le prix est susceptible d'avoir changé pendant l'exécution des ordres précédents (à la clôture). Nous pouvons utiliser une fonctionnalité de MT4 pour éviter de deviner le prix à utiliser : la valeur OrderClosePrice() d'un ordre au marché avant sa clôture est le prix Bid ou Ask selon le type d'ordre.
 
Ihor Herasko:

L'architecture elle-même est correcte. Les erreurs résident dans l'absence de contrôles et l'utilisation de certaines fonctions :

  1. La première itération dans votre cas échouera - la commande avec l'index OrdersTotal() n'existe pas.
  2. Il n'y a pas de contrôle du résultat de la fonction OrderSelect.
  3. Il n'y a pas de contrôle du résultat de la fonction OrderClose. Si la clôture de l'ordre échoue, nous ne pouvons pas rester dans la même fonction, car nous devons trouver pourquoi la clôture a échoué. Pour ce faire, nous devons quitter la fonction avec le résultat false, puis décider de ce qu'il faut faire ensuite.
  4. Nous ne pouvons pas utiliser un seul et même prix de clôture pour tous les ordres. Premièrement, les ordres peuvent être de types différents et, deuxièmement, le prix est susceptible d'avoir changé pendant l'exécution des ordres précédents (à la clôture). Pour éviter de deviner le prix à utiliser, nous pouvons utiliser une fonctionnalité de MT4 : la valeur OrderClosePrice() d'un ordre au marché avant sa clôture est le prix Bid ou Ask selon le type d'ordre.

Merci, le principal problème était probablement d'utiliser le même prix.

 

Extrait de l'aide d'OrderSelect " Lorsque les ordres sont sélectionnés de manière séquentielle à l'aide du paramètre SELECT_BY_POS, les informations sont données dans l'ordre dans lequel elles proviennent du serveur commercial. Aucun tri de la liste d'ordre obtenue n'est garanti".

Si nous pensons que cette phrase a été insérée dans l'aide pour rien, nous sommes d'accord. Si nous pensons qu'elle était là pour une raison, nous ne devrions pas modifier cette liste pendant le parcours de la boucle dans la liste des commandes. On ne sait pas comment les commandes seront ordonnées après la suppression de l'une d'entre elles sur le serveur et l'arrivée d'une nouvelle liste courante avec un plus petit OrdersTotal. Il est plus fiable, sans supprimer, de parcourir la même copie inchangée de la liste et de collecter (dans un tableau) tous les numéros de tickets des transactions à supprimer. Ensuite, oubliez cette liste et supprimez les transactions, en les sélectionnant par ticket.

On aimerait croire, bien sûr, que l'ordre dans la liste modifiable est préservé, ne serait-ce que pour ce cas de suppression de plusieurs ordres à la fin d'une liste non ordonnée, mais les développeurs s'y opposent... Maintenant, cela fonctionne, et si une nouvelle construction sort - "nous avons prévenu".

 
Vladimir:

Extrait de l'aide d'OrderSelect " Lorsque les ordres sont sélectionnés de manière séquentielle à l'aide du paramètre SELECT_BY_POS, les informations sont données dans l'ordre dans lequel elles proviennent du serveur commercial. Aucun tri de la liste d'ordre obtenue n'est garanti".

Si nous pensons que cette phrase a été insérée dans l'aide pour rien, nous sommes d'accord. Si nous pensons qu'elle était là pour une raison, nous ne devrions pas modifier cette liste pendant le parcours de la boucle dans la liste des commandes. On ne sait pas comment les commandes seront ordonnées après la suppression de l'une d'entre elles sur le serveur et l'arrivée d'une nouvelle liste courante avec un plus petit OrdersTotal. Il est plus fiable, sans supprimer, de parcourir la même copie inchangée de la liste et de collecter (dans un tableau) tous les numéros de tickets des transactions à supprimer. Ensuite, oubliez cette liste et supprimez les transactions, en les sélectionnant par ticket.

On aimerait croire, bien sûr, que l'ordre dans la liste modifiable est préservé, ne serait-ce que pour ce cas de suppression de plusieurs ordres à la fin d'une liste non ordonnée, mais les développeurs s'y opposent... Maintenant, cela fonctionne, et si une nouvelle construction sort - "nous avons prévenu".

Une telle "Amérique" est ouverte depuis environ trois cents ans :)

 
Artyom Trishkin:

Ce genre d'"Amérique" est ouvert depuis environ trois cents ans :)

Je ne pense pas que les personnes qui posent des questions ici au nom des nouveaux arrivants l'aient déjà découvert elles-mêmes. C'est pour ça que je l'écris. Pas pour les modérateurs, mais pour ceux qui posent des questions. Regardez le nom du fil de discussion.

P.S. J'ai cherché d'où venait cet intérêt. Il s'avère qu'il provient de la branche https://www.mql5.com/ru/forum/215783/page8"Organiser le cycle des commandes". Il se trouve qu'en octobre 2017, ces trois cents ans ne sont pas encore terminés, il y a encore de la nouveauté.

Организация цикла перебора ордеров
Организация цикла перебора ордеров
  • 2017.09.16
  • www.mql5.com
MQL4 и MetaTrader 4: Организация цикла перебора ордеров
 
Vladimir:

Je ne pense pas que les personnes qui posent des questions ici au nom des nouveaux arrivants l'aient déjà découvert elles-mêmes. C'est pour ça que j'écris. Pas pour les modérateurs, mais pour ceux qui posent des questions. Regardez le nom du fil de discussion.

P.S. J'ai regardé d'où venait cet intérêt. Il s'avère qu'il provient de la branche https://www.mql5.com/ru/forum/215783/page8"Organiser le cycle des commandes". Il se trouve qu'en octobre 2017, ces trois cents ans ne sont pas encore terminés, il y a encore de la nouveauté.

Encore faux :) Trois cents ans ont commencé sur mql4.com - il fut un temps où l'on y discutait activement. Et il y a même eu ces moments, que vous avez décrits dans "Maintenant, ça marche, et une nouvelle construction va sortir - "nous vous avions prévenus". Seulement sans avertissement, et donc plusieurs fois - ça dépend, ça ne dépend pas du tri...

Et, oui, il y a un fil spécial pour de telles réponses :

Особенности языка mql4, тонкости и приёмы работы
Особенности языка mql4, тонкости и приёмы работы
  • 2017.02.24
  • www.mql5.com
В данной теме будут обсуждаться недокументированные приёмы работы с языком mql4, примеры решения тех, или иных задач...
 
Vladimir:

Extrait de l'aide d'OrderSelect " Lorsque les ordres sont sélectionnés de manière séquentielle à l'aide du paramètre SELECT_BY_POS, les informations sont données dans l'ordre dans lequel elles proviennent du serveur commercial. Aucun tri de la liste d'ordre obtenue n'est garanti".

Si nous pensons que cette phrase a été insérée dans l'aide pour rien, nous sommes d'accord. Si nous pensons qu'elle était là pour une raison, nous ne devrions pas modifier cette liste pendant le parcours de la boucle dans la liste des commandes. On ne sait pas comment les commandes seront ordonnées après la suppression de l'une d'entre elles sur le serveur et l'arrivée d'une nouvelle liste courante avec un plus petit OrdersTotal. Il est plus fiable, sans supprimer, de parcourir la même copie inchangée de la liste et de collecter (dans un tableau) tous les numéros de tickets des transactions à supprimer. Ensuite, oubliez cette liste et supprimez les transactions, en les sélectionnant par ticket.

J'aimerais, bien sûr, croire que l'ordre dans la liste modifiée est préservé au moins pour ce cas de suppression de plusieurs ordres à la fin d'une liste non ordonnée, mais les développeurs sont contre... Maintenant ça marche, et si une nouvelle version sort, "on vous a prévenu".

Comme une bonne idée (considérant qu'il peut y avoir plusieurs Expert Advisors + trader travaillant sur le compte en parallèle), vous ne pouvez pas du tout effectuer des transactions en boucle. L'ordre nécessaire est reçu, l'opération est exécutée, l'ensemble de OnTick() est exécuté à nouveau (pas nécessairement avec l'arrivée d'un nouveau tick). Et ainsi de suite, jusqu'à ce que toutes les opérations nécessaires soient exécutées.

Ainsi, former un tableau pour supprimer des commandes est équivalent à supprimer des commandes dans la boucle.

 

Il y a un bouton "Stop", comment puis-je changer son texte en "Start" une fois appuyé ?

bool stop;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//Closed at Profit
   ObjectCreate(0,"Stop",OBJ_BUTTON,0,0,0);
   ObjectSetInteger(0,"Stop",OBJPROP_XDISTANCE,10);
   ObjectSetInteger(0,"Stop",OBJPROP_YDISTANCE,105);
   ObjectSetInteger(0,"Stop",OBJPROP_XSIZE,100);
   ObjectSetInteger(0,"Stop",OBJPROP_YSIZE,25);

   ObjectSetString(0,"Stop",OBJPROP_TEXT,"Stop");

   ObjectSetInteger(0,"Stop",OBJPROP_COLOR,White);
   ObjectSetInteger(0,"Stop",OBJPROP_BGCOLOR,Green);
   ObjectSetInteger(0,"Stop",OBJPROP_BORDER_COLOR,Green);
   ObjectSetInteger(0,"Stop",OBJPROP_BORDER_TYPE,BORDER_FLAT);
   ObjectSetInteger(0,"Stop",OBJPROP_HIDDEN,true);
   ObjectSetInteger(0,"Stop",OBJPROP_STATE,false);
   ObjectSetInteger(0,"Stop",OBJPROP_FONTSIZE,12);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
if(sparam=="Stop")
     {
      ObjectSetInteger(0,"Stop",OBJPROP_STATE,false);
      CloseAtProfit();
      stop=true;
     }
     }
 
lil_lil: Il y a un bouton "Stop", comment puis-je changer son texte en "Start" une fois appuyé ?

Voir mon exemple d'expert

Dossiers :
ToFile.mq4  11 kb
 
STARIJ:

Regardez l'exemple de mon conseiller expert

Merci, juste ce dont j'avais besoin.

Il pourrait être utile de savoir qu'il y a une erreur dans les positions manquantes--- ToFile EURUSD,H1 : zero divide in 'ToFile.mq4' (62,39)

/*62*/  Строка=DoubleToStr(AccountEquity()/AccountMargin()*100,2)+"%"; // Уровень=Средства/Залог
Le texte ne change pas dans le testeur, il n'y a pas cette option ?