Erreurs, bugs, questions - page 540

 

Mon conseiller expert, qui participe actuellement au championnat, effectue des actions incorrectes en raison du fonctionnement incorrect de la bibliothèque standard de CTrade.

J'utilise la fonction PositionClose pour fermer les positions. Mais en plus de fermer des positions, cette fonction ouvre elle-même des transactions !

La fonction est utilisée comme suit :

//--- Объект класса СTrade
CTrade mytrade;
//--- Объект класса СPositionInfo
CPositionInfo myposition;

//+------------------------------------------------------------------+
//| Проверяет и если нужно, закрывает открытую позицию               |
//+------------------------------------------------------------------+
bool ClosePosition(string ptype,double clp)
  {
   bool R=false, marker=false; int i;
     
      if(myposition.Select(_Symbol)==true)
        {
         if(myposition.Symbol()==_Symbol)
           {
            //--- Делаем попытки закрыть позицию, если позиция не закрылась с первого раза
              for (i=5; i>=1; i--) 
                {R=mytrade.PositionClose(_Symbol,50,5); if (R == true && myposition.Select(_Symbol)==false) break;}
               if(i >= 1) 
                 {//--- запрос успешно выполнен
                  Alert("Открытая позиция была успешно закрыта!!");
                  marker=true;
                 }
               else
                 {
                  Alert("Запрос на закрытие позиции не выполнен - ошибка: ",mytrade.ResultRetcodeDescription());
                 }
            //  }
           }
        }
      return(marker);
     }

PositionClose finit par ouvrir des ordres parfois inutiles.

Ici, la transaction d'achat a été fermée en premier, puis une transaction de vente supplémentaire de la même taille a été ouverte. De plus, AccountInfoDouble(ACCOUNT_FREEMARGIN) n'a pas remarqué cette transaction supplémentaire. Parce qu'il a été suivi d'un échange avec un lot plus important, bien qu'il n'y ait pas eu assez d'argent pour cela selon le MM utilisé.

Je me rends compte que je n'utilise peut-être pas les fonctions MQL de manière optimale. Mais le fait qu'une fonction de la bibliothèque propriétaire MQL destinée à fermer des transactions ouvre des transactions par elle-même ne correspond pas à mon idée du comportement acceptable des fonctions.

 
masharov:

Je comprends que je n'utilise peut-être pas les fonctions MQL de manière optimale. Mais le fait qu'une fonction de la bibliothèque propriétaire MQL destinée à fermer des transactions ouvre des transactions par elle-même ne correspond pas à mon idée du comportement acceptable des fonctions.

Lisez l'article Trading Events in MetaTrader 5:

Les événements commerciaux et les changements dans l'historique des transactions sont signalés par des canaux indépendants. Lorsque vous envoyez une demande d'achat à l'aide de la fonction OrderSend(), vous pouvez immédiatement reconnaître le ticket de l'ordre, qui a été créé si la demande a été vérifiée avec succès. Mais en même temps, l'ordre lui-même peut ne pas encore apparaître dans le terminal du client, et une tentative de le sélectionner à l'aide de la fonction OrderSelect() échouera.

Voir également l'article Ordres, positions et transactions dans MetaTrader 5.
 

Je n'ai pas utilisé la fonction OrderSend. La fonction PositionClose de la bibliothèque MQL standard est utilisée, qui est conçue pour fonctionner avec des ordres.

L'aide pour cette fonction ne décrit pas qu'elle peut ouvrir des transactions.

Citation de la référence :

PositionClose

Ferme une position au symbole spécifié.

bool PositionClose(
const string symbol, // symbole
ulong deviation=ULONG_MAX // déviation
)

Paramètres

symbole

[Nom de l'instrument commercial sur lequel la position doit être fermée.

déviation=ULONG_MAX

[Écart maximal par rapport au prix actuel (en points).

Valeur retournée

true - si la vérification de base des structures est réussie, sinon false.

Note

La fin réussie de la méthode PositionClose(...) ne signifie pas toujours l'exécution réussie d'une opération commerciale. Il est nécessaire de vérifier le résultat d'une requête commerciale (le code de retour du serveur commercial) en appelant la méthode ResultRetcode().

 
masharov:

Je n'ai pas utilisé la fonction OrderSend. On utilise la fonction PositionClose de la bibliothèque MQL standard, qui est conçue pour simplifier le travail avec les ordres.

L'aide pour cette fonction ne décrit pas qu'elle peut ouvrir des transactions.

Citation de la référence :

PositionClose

Ferme une position au symbole spécifié.

bool PositionClose(
const string symbol, // symbole
ulong deviation=ULONG_MAX // déviation
)

Paramètres

symbole

[Nom de l'instrument commercial sur lequel la position doit être fermée.

déviation=ULONG_MAX

[Écart maximal par rapport au prix actuel (en points).

Valeur retournée

true - si la vérification de base des structures est réussie, sinon false.

Note

La fin réussie de la méthode PositionClose(...) ne signifie pas toujours l'exécution réussie d'une opération commerciale. Le résultat de l'exécution de la demande de transaction (le code de retour du serveur de transaction) doit être vérifié en appelant la méthode ResultRetcode().

Il n'y a pas d'erreur dans la fonction de bibliothèque PositionClose(...). Mais il y en a un dans votre code. Voici la citation de la référence.

Успешное окончание работы метода PositionClose(...) не всегда означает успешное совершение торговой операции. 
Необходимо проверять результат выполнения торгового запроса (код возврата торгового сервера) вызовом метода ResultRetcode(). 

Par exemple, je ne vois pas cette vérification dans votre code.

 
masharov:

Je n'ai pas utilisé la fonction OrderSend. La fonction PositionClose de la bibliothèque MQL standard, qui est conçue pour fonctionner avec des ordres, est utilisée.

L'aide pour cette fonction ne décrit pas qu'elle peut ouvrir des transactions.


Et vous pouvez regarder l'implémentation de la fonction PositionClose :

bool CTrade::PositionClose(const string symbol,ulong deviation)
  {
   bool   partial_close=false;
   int    retry_count  =10;
   uint   retcode      =TRADE_RETCODE_REJECT;
//--- check stopped
   if(IsStopped(__FUNCTION__)) return(false);
//--- variables
   string action,result;
//--- clean
   ClearStructures();
   do
     {
      //--- checking
      if(PositionSelect(symbol))
        {
         if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
           {
            //--- prepare request for close BUY position
            m_request.type =ORDER_TYPE_SELL;
            m_request.price=SymbolInfoDouble(symbol,SYMBOL_BID);
           }
         else
           {
            //--- prepare request for close SELL position
            m_request.type =ORDER_TYPE_BUY;
            m_request.price=SymbolInfoDouble(symbol,SYMBOL_ASK);
           }
        }
      else
        {
         //--- position not found
         m_result.retcode=retcode;
         return(false);
        }
      //--- setting request
      m_request.action      =TRADE_ACTION_DEAL;
      m_request.symbol      =symbol;
      m_request.deviation   =(deviation==ULONG_MAX) ? m_deviation : deviation;
      m_request.type_filling=m_type_filling;
      m_request.volume      =PositionGetDouble(POSITION_VOLUME);
      //--- check volume
      double max_volume=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
      if(m_request.volume>max_volume)
        {
         m_request.volume=max_volume;
         partial_close=true;
        }
      else
         partial_close=false;
      //--- order check
      if(!OrderCheck(m_request,m_check_result))
        {
         //--- copy return code
         m_result.retcode=m_check_result.retcode;
         if(m_log_level>LOG_LEVEL_NO)
            printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
         return(false);
        }
      //--- order send
      if(!OrderSend(m_request,m_result))
        {
         if(--retry_count!=0) continue;
         if(retcode==TRADE_RETCODE_DONE_PARTIAL)
            m_result.retcode=retcode;
         if(m_log_level>LOG_LEVEL_NO)
            printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
         return(false);
        }
      retcode=TRADE_RETCODE_DONE_PARTIAL;
      if(partial_close) Sleep(1000);
     }
   while(partial_close);
   if(m_log_level>LOG_LEVEL_ERRORS)
      printf(__FUNCTION__+": %s [%s]",FormatRequest(action,m_request),FormatRequestResult(result,m_request,m_result));
//--- ok
   return(true);
  }
 

Je me suis dit que je n'avais pas besoin d'étudier le code source des bibliothèques standard.

L'aide ne décrit pas la possibilité d'ouvrir des transactions avec la fonction PositionClose. Les contrôles et protections contre l'ouverture de transactions avec la fonction PositionClose, que votre équipe a développée, devraient se contenir. Je pense que les bibliothèques standard constituent un code idéal qui devrait servir de modèle aux autres. Par conséquent, il ne devrait pas être nécessaire d'analyser le code des bibliothèques avant de les utiliser.

Citation :

La bibliothèque standard MQL5 est écrite en langage MQL5 et est conçue pour faciliter l'écriture de programmes (indicateurs, scripts, experts) aux utilisateurs finaux. Labibliothèque permet d'accéder facilement à la plupart des fonctions internes de MQL5.

 
masharov:

Je me suis dit que je n'avais pas besoin d'étudier le code source des bibliothèques standard.

L'aide ne décrit pas la possibilité d'ouvrir des transactions avec la fonction PositionClose. Les contrôles et protections contre l'ouverture de transactions avec la fonction PositionClose, que votre équipe a développée, devraient se contenir. Je pense que les bibliothèques standard constituent un code idéal qui devrait servir de modèle aux autres. Par conséquent, l'analyse du code des bibliothèques avant de les utiliser ne devrait pas être nécessaire.

L'ignorance de la loi ne vous exonère pas de votre responsabilité. Où dans votre code se trouve la vérification de la fermeture de la position ?

            //--- Делаем попытки закрыть позицию, если позиция не закрылась с первого раза
              for (i=5; i>=1; i--) 
                {
                 R=mytrade.PositionClose(_Symbol,50,5); 
                 if (R == true && myposition.Select(_Symbol)==false) break;
                }

Expression

R == true

indique seulement que la fonction PositionClose() a été exécutée avec succès, mais pas que la position a été fermée :

Note

L'exécution réussie de la méthode PositionClose(...) ne signifie pas toujours l'exécution réussie d'une opération commerciale. Il est nécessaire de vérifier le résultat de l'exécution d'une requête commerciale (code de retour du serveur commercial) en appelant la méthode ResultRetcode().

La deuxième expression

myposition.Select(_Symbol)==false)

est équivalent à

PositionSelect(_Symbol)==false)

et ne donne pas non plus de garantie pour les opérations commerciales asynchrones. Une position a déjà été fermée sur le serveur commercial et le terminal n'a pas encore reçu de message à ce sujet. Il s'avère donc que vous avez créé un bug dans votre code.

Dans la vie réelle, tout n'est pas aussi fluide que dans le testeur ; il peut y avoir de petits délais entre l'envoi d'une demande de transaction et le résultat de son exécution. Chacun résout ce problème lui-même, pour commencer il ne serait pas mal de vérifier le code de retour en utilisant la fonction ResultRetcode(), comme il est écrit dans l'aide.

 

Encore une fois.

Je me rends compte que je n'utilise peut-être pas les fonctions MQL de manière optimale. Mais le fait qu'une fonction de la bibliothèque propriétaire MQL destinée àfermer des transactionsouvre elle-mêmedes transactions ne correspond pas à mon idée du comportement acceptable des fonctions.

Tout ce que vous dites s'applique à la clôture des transactions. Oui, l'EA ne vérifie pas de manière optimale les positions de clôture. Mais cela ne permet pas à une fonction conçue pour fermer d'ouvrir des transactions par elle-même.

L'aide dit :

PositionClose

Ferme la position selon le symbole spécifié.

Aucune condition n'est décrite pour que la fonction puisse ouvrir une transaction. La recommandation de vérifier le code de retour ne sert également qu'à vérifier en plus si la transaction est fermée ou non.

 
masharov:

Encore une fois.

Je comprends que je n'utilise peut-être pas les fonctions MQL de manière optimale. Mais le fait que la fonction de la bibliothèque propriétaire MQL destinée àfermer des transactionsouvre des transactions par elle-même ne correspond pas à mon idée du comportement acceptable des fonctions.
Il n'y a pas de fonction de fermeture de position, il n'y a que la fonction d'envoi d'une demande d'achat ou de vente (et le résultat - ouverture ou fermeture d'une position - est inconnu). Dans votre cas, à cause d'une erreur algorithmique, des demandes répétées sont envoyées sans vérifier si la demande précédente a été exécutée.
 
Rosh:
Il n'y a pas de fonction de fermeture de position, il n'y a que la fonction d'envoi d'une demande d'achat ou de vente (et le résultat - l'ouverture ou la fermeture d'une position - est inconnu). Dans votre cas, à cause d'une erreur algorithmique, des demandes répétées sont envoyées sans vérifier si la demande précédente a été exécutée.

L'aide a cette fonction

Référence MQL5 / Bibliothèque standard / Classes de trading / CTrade / PositionClose

Ferme la position par le symbole spécifié.

L'utilisateur ne doit pas se soucier de la manière dont la fonction est mise en œuvre au niveau inférieur. Puisque cette fonction existe, MetaQuotes a garanti qu'elle n'aura pas de comportement non standard non décrit dans l'aide.

La bibliothèque standard MQL5 est écrite en MQL5 et vise à faciliter l'écriture de programmes (indicateurs, scripts et Expert Advisors) par les utilisateurs finaux. Labibliothèque permet d'accéder facilement à la plupart des fonctions internes de MQL5.