"Erreur de PositionSelect() flottante

 

Salut !

La situation est la suivante MT5, build 1375

Dans son travail, lorsqu'il négocie des contrats à terme, le robot utilise la fonction OrderSendAsync().

Supposons qu'il y ait une position ouverte avec un volume de 2 contrats.

Un ordre de fermeture partielle de la position (volume 1) est envoyé et nous obtenons une réponse du serveur

dans la fonction OnTradeTransaction(), la position PositionSelect(Symbol()) est vérifiée et la position

sur la position. Très souvent, lorsqu'un ordre de fermeture partielle d'une position est exécuté, ses données sont reçues.

position, lorsque les données de position sont reçues, les données contiennent les informations qui

la position n'a pas été modifiée (le volume reste égal à 2).

Comment puis-je créer un journal pour montrer aux développeurs qu'il y a une erreur ?

 

Je suis gêné de demander, comment pouvez-vous être si sûr qu'il y a une erreur ? Ou pensez-vous que les développeurs sont aussi denses que la taïga ? ;-)

Lisez le manuel de fonctionnement asynchrone.

 
Dennis Kirichenko:

Je suis embarrassé de demander, comment pouvez-vous être si sûr qu'il y a une erreur ? Ou pensez-vous que les développeurs sont aussi denses que la taïga ? ;-)

Lire les opérations asynchrones.

Cher Monsieur, je vous suggère de lire le début du message.

J'ai demandé comment construire une base de preuves pour les développeurs, et non pas comment utiliser la

fonction asynchrone !

Les builds précédents (avant la couverture) n'avaient pas cette erreur.

 

A écrit un expert en test

 //+------------------------------------------------------------------+
//|                                               Test_Pos_selct.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"
input uint TrCount= 50 ; //Кол-во транзакций
uint tr_cnt;
ulong order_ticket;
ulong request_id;
ulong Magic= 1234567890 ;
#define ERR_ZERO_TICKET - 11 ;
bool exp_busy;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum ENUM_ORD_SELECT
  {
   SELECT_ERROR = 0 ,
   SELECT_FALSE = 1 ,
   SELECT_TRUE  = 2 ,
   SELECT_BUSY  = 3
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum ENUM_ORD_REAL_STATE
  {
   ORD_NOT_SPECIFIED         = 0 , //Состояние ордера не определено
   ORD_NONE_CANCELED         = 1 , //Ордера нет, отменён пользователем
   ORD_NONE_PARTIAL_CANCELED = 2 , //Ордера нет, исполнился частично (не был залит вторым объёмом)
   ORD_NONE_PARTIAL          = 3 , //Ордера нет, исполнился частично
   ORD_NONE_EXPIRED          = 4 , //Ордера нет, удалён по сроку
   ORD_NONE_FILLED           = 5 , //Ордера нет, исполнился полностью
   ORD_NONE_REJECTED         = 6 , //Ордера нет, отклонён брокером(биржей)
   ORD_BUSY                  = 7 , //Ордер находится в переходном состоянии
   ORD_EXIST                 = 8 , //Ордер выставлен на биржу, возможны действия над ним
   ORD_EXIST_PARTIAL         = 9    //Ордер выставлен на биржу, частично исполнился, возможны действия над ним
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
struct ORDER_DATA
  {
   int                error_code;
   datetime           time_setup;
   ENUM_ORDER_TYPE    type;
   ENUM_ORDER_STATE   state;
   ENUM_ORD_REAL_STATE real_state;
   datetime           expiration;
   datetime           time_done;
   long               t_set_msc;
   long               t_done_msc;
   ENUM_ORDER_TYPE_FILLING type_filling;
   ENUM_ORDER_TYPE_TIME type_time;
   long               magic;
   long               pos_id;
   double             vol_init;
   double             vol_cur;
   double             price_open;
   double             sl;
   double             tp;
   double             price_cur;
   double             price_stlim;
   string             symbol;
   string             comment;
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit ()
  {
//---
   Print ( __FUNCTION__ , ": Start testing: " , TimeTradeServer ());
   tr_cnt= 0 ;
   order_ticket= 0 ;
   request_id= 0 ;
   exp_busy= false ;
   if (! MarketBookAdd ( Symbol ())){ return ( INIT_FAILED );}
//---
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason)
  {
//---
   MarketBookRelease ( Symbol ());
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction ( const MqlTradeTransaction &trans,
                         const MqlTradeRequest &request,
                         const MqlTradeResult &result)
  {
   bool is_select= false ;
   ENUM_POSITION_TYPE pos_type= NULL ;
   long volume= 0 ;
   switch (trans.type)
     {
       case TRADE_TRANSACTION_REQUEST : if ((request_id!= 0 ) && (result.request_id==request_id))
        {
         order_ticket=result.order;
         request_id= 0 ;
         Print ( __FUNCTION__ , ": Order resived #" , result.order);
        }
       break ;
       case TRADE_TRANSACTION_HISTORY_ADD : if ((order_ticket!= 0 ) && (trans.order==order_ticket))
        {
         Print ( __FUNCTION__ , ": Order #" , order_ticket, " add to history." ); 
         ORDER_DATA order_data;
         ENUM_ORD_SELECT order_select=OrderRealSelect(order_ticket,order_data, false );
         switch (order_select)
         {
           case SELECT_TRUE: if ( PositionSelect ( Symbol ()))
          {
            pos_type=( ENUM_POSITION_TYPE ) PositionGetInteger ( POSITION_TYPE );
            volume=( long ) PositionGetDouble ( POSITION_VOLUME );
            is_select= true ;
          }
           else
           Print ( __FUNCTION__ , ": Position not exist." );                    
           break ;
           case SELECT_FALSE: if ( PositionSelect ( Symbol ()))
          {
           pos_type=( ENUM_POSITION_TYPE ) PositionGetInteger ( POSITION_TYPE );
           volume=( long ) PositionGetDouble ( POSITION_VOLUME );
           is_select= true ;
          }
           else
           Print ( __FUNCTION__ , ": Position not exist." );
           break ;
         }
         if (is_select)
          {
           Print ( __FUNCTION__ , ": Position exists" );
           Print ( __FUNCTION__ , ": Position type: " , EnumToString (pos_type));
           Print ( __FUNCTION__ , ": Position volume: " , volume);
          }
          tr_cnt++;
          exp_busy= false ; 
        }
       break ;
     }
  }
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent ( const string &symbol)
  {
//---
   if (symbol== Symbol ()&&(!exp_busy))
     {
       if (tr_cnt>=TrCount)
        {
         if ( PositionSelect ( Symbol ()))
           {
            order_ticket= 0 ;
             ENUM_POSITION_TYPE pos_type=( ENUM_POSITION_TYPE ) PositionGetInteger ( POSITION_TYPE );
             long vol=( long ) PositionGetDouble ( POSITION_VOLUME );
            ClosePosition(pos_type,vol);
             Print ( __FUNCTION__ , ": End testing: " , TimeTradeServer ());
             if (order_ticket> 0 ) ExpertRemove ();
           }
         else
           {
             Print ( __FUNCTION__ , ": End testing: " , TimeTradeServer ());
             ExpertRemove ();
           }
        }
       else
        {
         if ( PositionSelect ( Symbol ()))
           {
             ENUM_POSITION_TYPE pos_type=( ENUM_POSITION_TYPE ) PositionGetInteger ( POSITION_TYPE );
             long vol=( long ) PositionGetDouble ( POSITION_VOLUME );
             Print ( __FUNCTION__ , ": Position exists" );
             Print ( __FUNCTION__ , ": Position type: " , EnumToString (pos_type));
             Print ( __FUNCTION__ , ": Position volume: " , vol);
             switch ( int (vol))
            {
               case 1 : ClosePosition(pos_type,vol);
               break ;
               default : PartClosePos(pos_type);
               break ;
            } 
           }
           else
           {
             Print ( __FUNCTION__ , ": Try open position..." );
             OpenPosition();
           }
        }
     }   
  }
//
void ClosePosition( ENUM_POSITION_TYPE p_type, const long volume)
  {
   MqlTradeRequest request={ 0 };
   MqlTradeResult   result={ 0 };
   switch (p_type)
     {
       case POSITION_TYPE_BUY : request.type= ORDER_TYPE_SELL ;
       break ;
       case POSITION_TYPE_SELL : request.type= ORDER_TYPE_BUY ;
       break ;
     }
   order_ticket= 0 ;
   request.magic=Magic;
   request.symbol= Symbol ();
   request.volume=( double )volume;
   request.type_filling= ORDER_FILLING_IOC ;
   request.type_time= ORDER_TIME_DAY ;
   request.action= TRADE_ACTION_DEAL ;
   request.comment= "" ;
   request.price= 0 ;
   if ( OrderSend (request,result))
     {
       if (result.retcode== TRADE_RETCODE_PLACED )
        {
         //order_ticket=result.order;
         exp_busy= false ;
         tr_cnt++;
         Print ( __FUNCTION__ , ": Position slosed." );
        }
     }
   else
     { Print ( __FUNCTION__ , ": Order not sent for close position!" );}
  }
//+------------------------------------------------------------------+  
void PartClosePos( ENUM_POSITION_TYPE p_type)
  {
     MqlTradeRequest request={ 0 };
     MqlTradeResult   result={ 0 };
     switch (p_type)
     {
       case POSITION_TYPE_BUY : request.type= ORDER_TYPE_SELL ;
       break ;
       case POSITION_TYPE_SELL : request.type= ORDER_TYPE_BUY ;
       break ;
     }
   order_ticket= 0 ;
   request.magic=Magic;
   request.symbol= Symbol ();
   request.volume= 1 ;
   request.type_filling= ORDER_FILLING_IOC ;
   request.type_time= ORDER_TIME_DAY ;
   request.action= TRADE_ACTION_DEAL ;
   request.comment= "" ;
   request.price= 0 ;
   if ( OrderSend (request,result))
     {
       if (result.retcode== TRADE_RETCODE_PLACED )
        {
         order_ticket=result.order;
         exp_busy= true ;
         tr_cnt++;
         Print ( __FUNCTION__ , ": Order sent for part close position." );
        }
     }
   else
     { Print ( __FUNCTION__ , ": Order not sent for part close position!" );}
  }
   //+------------------------------------------------------------------+  
void OpenPosition()
  {
     MqlTradeRequest request={ 0 };
     MqlTradeResult   result={ 0 };
    request_id= 0 ;
    order_ticket= 0 ;
    request.magic=Magic;
    request.symbol= Symbol ();
    request.volume= 2 ;
    request.type_filling= ORDER_FILLING_IOC ;
    request.type_time= ORDER_TIME_DAY ;
    request.action= TRADE_ACTION_DEAL ;
    request.comment= "" ;
    request.price= 0 ;
    request.type= ORDER_TYPE_BUY ;
     if ( OrderSendAsync (request,result))
     {
       if (result.retcode== TRADE_RETCODE_PLACED )
        {
          request_id=result.request_id;
          exp_busy= true ;
           Print ( __FUNCTION__ , ": Order sent successfully for open position" );
        }
     }
     else
     Print ( __FUNCTION__ , ": Order not sent for open position!" );
  }
ENUM_ORD_SELECT OrderRealSelect( const ulong ticket,ORDER_DATA &ord_data, const bool get_data)
  {
   double init_vol= 0 ;
   double cur_vol = 0 ;
   ZeroMemory (ord_data);
   ord_data.real_state = ORD_NOT_SPECIFIED;
   ord_data.error_code = ERR_SUCCESS ;
   ResetLastError ();
//---  
   if (ticket> 0 )
     {
       if ( HistoryOrderSelect (ticket))
        {
         if (get_data)
           {
            ord_data.comment= HistoryOrderGetString (ticket, ORDER_COMMENT );
            ord_data.expiration= datetime ( HistoryOrderGetInteger (ticket, ORDER_TIME_EXPIRATION ));
            ord_data.magic= HistoryOrderGetInteger (ticket, ORDER_MAGIC );
            ord_data.pos_id= HistoryOrderGetInteger (ticket, ORDER_POSITION_ID );
            ord_data.price_cur= HistoryOrderGetDouble (ticket, ORDER_PRICE_CURRENT );
            ord_data.price_open= HistoryOrderGetDouble (ticket, ORDER_PRICE_OPEN );
            ord_data.price_stlim= HistoryOrderGetDouble (ticket, ORDER_PRICE_STOPLIMIT );
            ord_data.sl= HistoryOrderGetDouble (ticket, ORDER_SL );
            ord_data.state= ENUM_ORDER_STATE ( HistoryOrderGetInteger (ticket, ORDER_STATE ));
            ord_data.symbol= HistoryOrderGetString (ticket, ORDER_SYMBOL );
            ord_data.t_done_msc= datetime ( HistoryOrderGetInteger (ticket, ORDER_TIME_DONE_MSC ));
            ord_data.t_set_msc = datetime ( HistoryOrderGetInteger (ticket, ORDER_TIME_SETUP_MSC ));
            ord_data.time_done = datetime ( HistoryOrderGetInteger ( ticket, ORDER_TIME_DONE ));
            ord_data.time_setup= datetime ( HistoryOrderGetInteger (ticket, ORDER_TIME_SETUP ));
            ord_data.tp= HistoryOrderGetDouble (ticket, ORDER_TP );
            ord_data.type= ENUM_ORDER_TYPE ( HistoryOrderGetInteger (ticket, ORDER_TYPE ));
            ord_data.type_filling= ENUM_ORDER_TYPE_FILLING ( HistoryOrderGetInteger (ticket, ORDER_TYPE_FILLING ));
            ord_data.type_time= ENUM_ORDER_TYPE_TIME ( HistoryOrderGetInteger (ticket, ORDER_TYPE_TIME ));
            ord_data.vol_cur= HistoryOrderGetDouble (ticket, ORDER_VOLUME_CURRENT );
            ord_data.vol_init= HistoryOrderGetDouble (ticket, ORDER_VOLUME_INITIAL );
           }
         else
           {
            ord_data.state= ENUM_ORDER_STATE ( HistoryOrderGetInteger (ticket, ORDER_STATE ));
            cur_vol= HistoryOrderGetDouble (ticket, ORDER_VOLUME_CURRENT );
            init_vol= HistoryOrderGetDouble (ticket, ORDER_VOLUME_INITIAL );
           }
         //---
         switch (ord_data.state)
           {
             case ORDER_STATE_CANCELED : if (get_data)
              {
               if (ord_data.vol_init==ord_data.vol_cur)
                 {
                  ord_data.real_state=ORD_NONE_CANCELED;
                 }
               else
                 {
                  ord_data.real_state=ORD_NONE_PARTIAL_CANCELED;
                 }
              }
             else
              {
               if (init_vol==cur_vol)
                 {
                  ord_data.real_state=ORD_NONE_CANCELED;
                 }
               else
                 {
                  ord_data.real_state=ORD_NONE_PARTIAL_CANCELED;
                 }
              }
             break ;

             case ORDER_STATE_PARTIAL :  ord_data.real_state=ORD_NONE_PARTIAL;
             break ;

             case ORDER_STATE_EXPIRED :  ord_data.real_state=ORD_NONE_EXPIRED;
             break ;

             case ORDER_STATE_FILLED :   ord_data.real_state=ORD_NONE_FILLED;
             break ;

             case ORDER_STATE_REJECTED : ord_data.real_state=ORD_NONE_REJECTED;
             break ;
           }
        }
       else
       if ( OrderSelect (ticket))
        {
         if (get_data)
           {
            ord_data.comment= OrderGetString ( ORDER_COMMENT );
            ord_data.expiration= datetime ( OrderGetInteger ( ORDER_TIME_EXPIRATION ));
            ord_data.magic= OrderGetInteger ( ORDER_MAGIC );
            ord_data.pos_id= OrderGetInteger ( ORDER_POSITION_ID );
            ord_data.price_cur= OrderGetDouble ( ORDER_PRICE_CURRENT );
            ord_data.price_open= OrderGetDouble ( ORDER_PRICE_OPEN );
            ord_data.price_stlim= OrderGetDouble ( ORDER_PRICE_STOPLIMIT );
            ord_data.sl= OrderGetDouble ( ORDER_SL );
            ord_data.state= ENUM_ORDER_STATE ( OrderGetInteger ( ORDER_STATE ));
            ord_data.symbol= OrderGetString ( ORDER_SYMBOL );
            ord_data.t_done_msc= datetime ( OrderGetInteger ( ORDER_TIME_DONE_MSC ));
            ord_data.t_set_msc = datetime ( OrderGetInteger ( ORDER_TIME_SETUP_MSC ));
            ord_data.time_done = datetime ( OrderGetInteger ( ORDER_TIME_DONE ));
            ord_data.time_setup= datetime ( OrderGetInteger ( ORDER_TIME_SETUP ));
            ord_data.tp= OrderGetDouble ( ORDER_TP );
            ord_data.type= ENUM_ORDER_TYPE ( OrderGetInteger ( ORDER_TYPE ));
            ord_data.type_filling= ENUM_ORDER_TYPE_FILLING ( OrderGetInteger ( ORDER_TYPE_FILLING ));
            ord_data.type_time= ENUM_ORDER_TYPE_TIME ( OrderGetInteger ( ORDER_TYPE_TIME ));
            ord_data.vol_cur= OrderGetDouble ( ORDER_VOLUME_CURRENT );
            ord_data.vol_init= OrderGetDouble ( ORDER_VOLUME_INITIAL );
           }
         else
           {
            ord_data.state= ENUM_ORDER_STATE ( OrderGetInteger ( ORDER_STATE ));
           }
         //--- 
         switch (ord_data.state)
           {
             case ORDER_STATE_STARTED :
             case ORDER_STATE_REQUEST_ADD :
             case ORDER_STATE_REQUEST_MODIFY :
             case ORDER_STATE_REQUEST_CANCEL : ord_data.real_state=ORD_BUSY;
             break ;

             case ORDER_STATE_PARTIAL :        ord_data.real_state=ORD_EXIST_PARTIAL;
             break ;

             case ORDER_STATE_PLACED :         ord_data.real_state=ORD_EXIST;
             break ;
           }
        }
       else
        {
         ord_data.error_code= GetLastError ();
        }
       //---   
       if (( ord_data.error_code!= ERR_SUCCESS ) || 
         (ord_data.real_state==ORD_NOT_SPECIFIED))
        {
         return (SELECT_ERROR);
        }
       else
        {
         switch (ord_data.real_state)
           {
             case ORD_BUSY:           return (SELECT_BUSY);
             break ;

             case ORD_EXIST:
             case ORD_EXIST_PARTIAL: return (SELECT_TRUE);
             break ;

             default :                 return (SELECT_FALSE);
             break ;
           }
        }
     }
   else
     {
      ord_data.error_code=ERR_ZERO_TICKET;
       return (SELECT_ERROR);
     }
  }  
//+------------------------------------------------------------------+

Lancé sur Demo en Opening, je crois que c'est une erreur, que la commande est déjà dans l'historique, et que le terminal "ne sait pas" que

poste ouvert 2016.08 . 02 17 : 52 : 34.427 Test_Pos_selct (GAZR- 9.16 ,M1) OnTradeTransaction : la position n'existe pas.

 2016.08 . 02 17 : 52 : 34.403 Test_Pos_selct (GAZR- 9.16 ,M1)   OnBookEvent : Try open position...
2016.08 . 02 17 : 52 : 34.403 Test_Pos_selct (GAZR- 9.16 ,M1)   OpenPosition: Order sent successfully for open position
2016.08 . 02 17 : 52 : 34.409 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Order resived # 50224643
2016.08 . 02 17 : 52 : 34.427 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Order # 50224643 add to history.
2016.08 . 02 17 : 52 : 34.427 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position not exist.
2016.08 . 02 17 : 52 : 34.437 Test_Pos_selct (GAZR- 9.16 ,M1)   OnBookEvent : Position exists

Journaux complets joints

Demande d'assistance envoyée

Plateforme MetaTrader 5 : erreur

brut ,   Commencé : 2016.08.02 17:20 ,   #1529580

Dossiers :
 

Personne n'a jamais prêté attention à ce bug auparavant ?

Élargissement de la journalisation de la fonction OnTradeTransaction

void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   bool is_select=false;
   ENUM_POSITION_TYPE pos_type=NULL;
   long volume=0;
   switch(trans.type)
     {
      case TRADE_TRANSACTION_REQUEST: if((request_id!=0) && (result.request_id==request_id))
        {
         order_ticket=result.order;
         request_id=0;
         Print(__FUNCTION__, ": Order resived #", result.order);
        }
      break;
      case TRADE_TRANSACTION_DEAL_ADD: if((order_ticket!=0) && (trans.order==order_ticket))
      {
       Print(__FUNCTION__, ": Deal, based on order #", order_ticket, " done.");
       if(PositionSelect(Symbol()))
       {
        Print(__FUNCTION__, ": Position exists.");
        pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
        volume=(long)PositionGetDouble(POSITION_VOLUME);
        Print(__FUNCTION__, ": Position type: ", EnumToString(pos_type));
        Print(__FUNCTION__, ": Position volume: ", volume);
       } 
       else
        Print(__FUNCTION__, ": Position not exist.");
      }
      break;
      case TRADE_TRANSACTION_HISTORY_ADD: if((order_ticket!=0) && (trans.order==order_ticket))
        {
         Print(__FUNCTION__, ": Order #", order_ticket, " add to history."); 
         ORDER_DATA order_data;
         ENUM_ORD_SELECT order_select=OrderRealSelect(order_ticket,order_data,false);
         switch(order_select)
         {
          case SELECT_TRUE: if(PositionSelect(Symbol()))
          {
            pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
            volume=(long)PositionGetDouble(POSITION_VOLUME);
            is_select=true;
          }
          else
           Print(__FUNCTION__, ": Position not exist.");
           Print(__FUNCTION__, ": Order #",trans.order," exists.");                    
          break;
          case SELECT_FALSE: if(PositionSelect(Symbol()))
          {
           pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
           volume=(long)PositionGetDouble(POSITION_VOLUME);
           is_select=true;
          }
          else
           Print(__FUNCTION__, ": Position not exist.");
           Print(__FUNCTION__, ": Order #",trans.order," not found.");
          break;
         }
         if(is_select)
          {
           Print(__FUNCTION__, ": Position exists");
           Print(__FUNCTION__, ": Position type: ", EnumToString(pos_type));
           Print(__FUNCTION__, ": Position volume: ", volume);
          }
          tr_cnt++;
          exp_busy=false; 
        }
      break;
     }
  }

Bien que les événements TRADE_TRANSACTION_DEAL_ADD et TRADE_TRANSACTION_HISTORY_ADD

n'ont pas d'ordre, mais le terminal doit connaître l'état de la position à n'importe laquelle de ces

ou ça va faire des dégâts. Voici un exemple lorsque l'événement TRADE_TRANSACTION_HISTORY_ADD

l'événement arrive en premier (ordre dans l'historique, la transaction est exécutée et le terminal a toujours une position avec le volume de 2 au lieu de 1)

2016.08.02 19:28:02.259 Test_Pos_selct (GAZR-9.16,M1)   OnBookEvent: Position exists
2016.08.02 19:28:02.259 Test_Pos_selct (GAZR-9.16,M1)   OnBookEvent: Position type: POSITION_TYPE_BUY
2016.08.02 19:28:02.259 Test_Pos_selct (GAZR-9.16,M1)   OnBookEvent: Position volume: 2
2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1)   PartClosePos: Order sent for part close position.
2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1)   OnTradeTransaction: Order #50232966  add to history.
2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1)   OnTradeTransaction: Order #50232966  not found.
2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1)   OnTradeTransaction: Position exists
2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1)   OnTradeTransaction: Position type: POSITION_TYPE_BUY
2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1)   OnTradeTransaction: Position volume: 2
2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1)   OnTradeTransaction: Deal, based on order #50232966  done.
2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1)   OnTradeTransaction: Position exists.
2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1)   OnTradeTransaction: Position type: POSITION_TYPE_BUY
2016.08.02 19:28:02.288 Test_Pos_selct (GAZR-9.16,M1)   OnTradeTransaction: Position volume: 1
 

Extrait de l'aide de MQL5

Один торговый запрос, отправленный из терминала вручную или через торговые функции OrderSend()/OrderSendAsync(),
может порождать на торговом сервере несколько последовательных торговых транзакций.
При этом очередность поступления этих транзакций в терминал не гарантирована,
поэтому нельзя свой торговый алгоритм строить на ожидании поступления одних торговых транзакций после прихода других.
Кроме того, транзакции могут потеряться при доставке от сервера к терминалу.

Ça n'aurait pas d'importance s'il n'y avait pas la dernière phrase.

Si l'événementTRADE_TRANSACTION_HISTORY_ADD est arrivé en premier et queTRADE_TRANSACTION_DEAL_ADD

est perdu :(, les données de la position précédente restent "suspendues" dans le terminal !

 
prostotrader:

Extrait de l'aide de MQL5

Ça n'aurait pas d'importance s'il n'y avait pas la dernière phrase.

Si l'événement TRADE_TRANSACTION_HISTORY_ADD est arrivé en premier et que TRADE_TRANSACTION_DEAL_ADD

est perdu :(, les données de position précédentes seront toujours "suspendues" dans le terminal !

C'est absurde. Quel est le lien entre le cache, où sont stockées les données de position demandées, et les transactions ?

prostotrader, il doit y avoir un problème dans la logique de l'algorithme. Je voulais regarder le code de quelqu'un d'autre, mais je ne me donne pas la peine. J'aurais aimé fouiller dans le code de quelqu'un d'autre, mais je n'en ai pas le courage :

request.type_filling=ORDER_FILLING_IOC;    // разве так?
request.type_filling=ORDER_FILLING_RETURN; // а может так?

Quelles universités vous apprennent à coder comme ça ?

 switch(trans.type)
     {
      case TRADE_TRANSACTION_REQUEST: if((request_id!=0) && (result.request_id==request_id))
        {
         order_ticket=result.order;
         request_id=0;
         Print(__FUNCTION__, ": Order resived #", result.order);
        }
      break;
      case TRADE_TRANSACTION_HISTORY_ADD: if((order_ticket!=0) && (trans.order==order_ticket))
        {
         Print(__FUNCTION__, ": Order #", order_ticket, " add to history."); 
         ORDER_DATA order_data;
         ENUM_ORD_SELECT order_select=OrderRealSelect(order_ticket,order_data,false);
         switch(order_select)
         {
          case SELECT_TRUE: if(PositionSelect(Symbol()))
          {
            pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
            volume=(long)PositionGetDouble(POSITION_VOLUME);
            is_select=true;
          }
          else
           Print(__FUNCTION__, ": Position not exist.");                    
          break;
          case SELECT_FALSE: if(PositionSelect(Symbol()))
          {
           pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
           volume=(long)PositionGetDouble(POSITION_VOLUME);
           is_select=true;
          }
          else
           Print(__FUNCTION__, ": Position not exist.");
          break;
         }
         if(is_select)
          {
           Print(__FUNCTION__, ": Position exists");
           Print(__FUNCTION__, ": Position type: ", EnumToString(pos_type));
           Print(__FUNCTION__, ": Position volume: ", volume);
          }
          tr_cnt++;
          exp_busy=false; 
        }
      break;
     }
 
Dennis Kirichenko:

Conneries. Quel est le lien entre le cache, où sont stockées les données de position demandées, et les transactions ?

prostotrader, il doit y avoir un problème avec la logique de votre algorithme. Je voulais regarder le code de quelqu'un d'autre, mais je ne me donne pas la peine. J'aurais aimé fouiller dans le code de quelqu'un d'autre, mais je n'en ai pas le courage :

Quelles universités vous apprennent à coder de cette manière ?

Avez-vous lu ce que vous avez écrit ?

Il y a toujours un "professeur" qui ne peut rien faire lui-même, mais...

écrit régulièrement...

Il voit un mot familier(ORDER_FILLING_IOC) et commence à jouer avec.

Pour toi, Monsieur Je-sais-tout

 ORDER_FILLING_IOC
Означает согласие совершить сделку по максимально доступному на рынке объему в пределах указанного в ордере.
В случае невозможности полного исполнения ордер будет исполнен на доступный объем, а неисполненный объем ордера будет отменен.
 
 
prostotrader:

Avez-vous lu ce que vous avez écrit ?

Il y a toujours un "professeur" qui ne peut rien faire lui-même, mais...

écrit régulièrement...

Il voit un mot familier(ORDER_FILLING_IOC) et commence à jouer avec.

Je dois (demain seulement) créer deux exemples - envoi synchrone et asynchrone. Et simplifier OnTradeTransaction() - considérer seulement l'ajout d'une transaction à l'historique - pas d'ordres à fermer. Mais je vais le faire uniquement par le biais de la classe CTrade standard.

Au fait, sur quel serveur commercial faites-vous vos expériences ?

 

Veuillez demander aux "enseignants" et aux "je sais tout" de parler sur le fond,

et pas seulement pour mettre le pied sur le poteau pour marquer un point.

 
Karputov Vladimir:

Nous avons besoin (seulement demain) de faire deux exemples - envoi synchrone et asynchrone. Et simplifiez OnTradeTransaction() - envisagez de n'ajouter que la transaction à l'historique - pas d'ordres, de sorte qu'on soit loin du compte. Mais je vais le faire uniquement par le biais de la classe CTrade standard.

Au fait, sur quel serveur commercial faites-vous vos expériences ?

Les messages disaient définitivement Démo.

J'ai commencé à m'occuper de cette question parce que mon compte réel tombe en panne.