"Erreur de PositionSelect() flottante - page 2

 

Karputov Vladimir Et simplifier OnTradeTransaction()- envisager d'ajouter uniquement une transaction à l'historique - pas d'ordres.

Vous vous en sortirez, ne prenez même pas la peine de l'écrire (ne perdez pas votre temps).

 
prostotrader:

J'ai commencé à m'y intéresser parce que le vrai se plantait.

Il semble qu'ils aient mis à jour le serveur pendant le week-end. Les millisecondes sont apparues. Il peut y avoir d'autres surprises.

Apparemment, la fonctionOnTradeTransaction fonctionne indépendamment du journal des transactions.

Je pense que ce comportement de la fonction est raisonnable - il n'est pas nécessaire de ralentir le flux des opérations et d'attendre que le journal soit écrit et que tout soit calculé.

Dans votre cas, il est probablement préférable d'utiliserOnTrade,

ou attendre et vérifier périodiquement avec une pause minimale lorsque l'affaire apparaît dans l'historique.

 
Sergey Chalyshev:

On dirait qu'ils ont mis à jour le serveur ce week-end. Les millisecondes sont apparues. Il peut y avoir d'autres surprises.

Apparemment, la fonctionOnTradeTransaction fonctionne indépendamment du journal des opérations.

Je pense que ce comportement de la fonction est justifié - il n'est pas nécessaire de ralentir le flux des opérations et d'attendre que tout soit enregistré et comptabilisé dans le journal.

Dans votre cas, il est probablement préférable d'utiliserOnTrade,

ou attendre et vérifier périodiquement avec une pause minimale lorsque l'affaire apparaît dans l'historique.

Salut Sergei !

Oui, nous l'avons fait, mais pas le week-end, mais le jeudi après la session du soir (j'ai demandé à mon courtier).

Je ne peux pas utiliser l'événement Trade() et attendre que les données soient mises à jour dans le terminal.

Le conseiller expert a été écrit il y a longtemps et jusqu'à récemment, il fonctionnait "comme une horloge" (j'ai peut-être eu de la chance et l'événementTRADE_TRANSACTION_DEAL_ADD étaittoujours le premier à arriver).

Il est important pour le conseiller expert d'exécuter une transaction réciproque dès que possible, c'est pourquoi le mode asynchrone et OnTradeTransaction().

Maintenant, le conseiller expert envoie (parfois) des ordres en double pour ouvrir et fermer des positions.

Vous : "Je pense que ce comportement de la fonction est justifié, il n'est pas nécessaire de ralentir le flux des opérations et d'attendre que tout soit écrit et comptabilisé dans le journal".

De toute façon, tout est écrit et compté après l'arrivée deTRADE_TRANSACTION_DEAL_ADD :)

Le problème est queTRADE_TRANSACTION_DEAL_ADD peut être perdu etTRADE_TRANSACTION_HISTORY_ADD peut arriver et alors le terminal aura des données de position périmées.:(,

ce qui se passe réellement.

C'est étrange que les développeurs n'y aient pas pensé.

TRADE_TRANSACTION_HISTORY_ADD n'intervient que si l'ordre a été exécuté ou supprimé (annulé), donc

si l'état de la commande change (respectivement, la position peut changer), le terminal doit recevoir l'information sur le changement de position,

même siTRADE_TRANSACTION_DEAL_ADD est perdu.

Voyons ce que les développeurs ont à dire.

 
prostotrader:

Karputov Vladimir Et simplifier OnTradeTransaction() - envisager d'ajouter uniquement une transaction à l'historique - pas d'ordres.

Vous vous en sortirez, ne prenez même pas la peine de l'écrire (ne perdez pas votre temps).

Eh bien, si tu n'en as pas besoin, ne le fais pas.
 
prostotrader:

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.

Avant de vous montrer devant des personnes qui veulent vous aider, vous devez formuler correctement votre question. Quel est le rapport avec l'envoi asynchrone d'un ordre, si la clôture partielle est effectuée par la fonction OrderSend()? Qu'est-ce que vous demandez ?
 
Dmitry Fedoseev:
Avant de vous montrer aux personnes qui veulent vous aider, vous devez formuler votre question normalement. Quel est le rapport avec l'envoi asynchrone d'un ordre, si la clôture partielle est effectuée par la fonction OrderSend() ? Sur quoi porte votre question ?

Super !

Cela doit-il être considéré comme une aide ?

Бред. Какая связь между кэшем, где сохраняются данные о запрашиваемой позиции, и транзакциями?

prostotrader, у Вас там с логикой алгоритма наверное что-то не то. Хотел было покопаться в чужом коде, но влом... потом тип исполнения тут:

request.type_filling=ORDER_FILLING_IOC;    // разве так?
request.type_filling=ORDER_FILLING_RETURN; // а может так?
И вообще в каких университетах так учат кодировать?

Et Karputov n'a rien à voir avec ça, c'est juste que lorsque j'ai écrit mon message, il avait déjà posté le sien et je ne l'ai pas vu.

Initialement, la question était posée comme suit (au cas où vous seriez trop paresseux pour la lire d'abord)

Comment créer une journalisation pour montrer l'erreur aux développeurs ?

Pourquoi, je l'ai fait moi-même et les logs montrent clairement que

aprèsTRADE_TRANSACTION_HISTORY_ADD (avantTRADE_TRANSACTION_DEAL_ADD)

le terminal ne met pas à jour les informations de position.

 

prostotrader, Dimitri vous dit correctement que les fermetures partielles (et complètes) ne sont pas asynchrones dans votre code, mais synchrones... ce qui signifie que le programme attend une réponse du serveur...

Il est probable que la transaction OnTradeTransaction soit déclenchée plus rapidement que la position elle-même ne change.

Alors ici :

//+------------------------------------------------------------------+
//| 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;
     }
  }

vous pourriez essayer de boucler la vérification de la position. Peut-être que cela aidera....

C'est quelque chose comme ça :

//+------------------------------------------------------------------+
//| 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);
            bool is_position=false;
            //--- 5 попыток на проверку наличия позиции
            for(int attempt_idx=0;attempt_idx<5;attempt_idx++)
              {
               is_position=PositionSelect(Symbol());
               if(is_position)
                  break;
               Sleep(25);
              }
            //---
            if((order_select==SELECT_TRUE) || (order_select==SELECT_FALSE))
              {
               if(is_position)
                 {
                  pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
                  volume=(long)PositionGetDouble(POSITION_VOLUME);
                  is_select=true;
                 }
               else
                  Print(__FUNCTION__,": Position not exist.");
              }
            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;
        }
     }
  }

Sans connaître l'algorithme exact(ce dont vous avez besoin de la part du programme), il est difficile d'évaluer la justesse de son implémentation...

 

Passé complètement en mode asynchrone

 //+------------------------------------------------------------------+
//|                                               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_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 ;
     }
  }
//+------------------------------------------------------------------+
//| 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_id = 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 ( OrderSendAsync (request,result))
     {
       if (result.retcode== TRADE_RETCODE_PLACED )
        {
         request_id=result.request_id;
         exp_busy= true ;   
         Print ( __FUNCTION__ , ": Order sent for close position." );
        }
     }
   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_id= 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 ( OrderSendAsync (request,result))
     {
       if (result.retcode== TRADE_RETCODE_PLACED )
        {
         request_id=result.request_id;
         exp_busy= true ;
         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 volume = " ,request.volume);
        }
     }
     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);
     }
  }  
//+------------------------------------------------------------------+

Mais rien n'a changé

 2016.08 . 03 16 : 57 : 53.415 Test_Pos_selct (GAZR- 9.16 ,M1)   OnBookEvent : Position exists
2016.08 . 03 16 : 57 : 53.415 Test_Pos_selct (GAZR- 9.16 ,M1)   OnBookEvent : Position type: POSITION_TYPE_BUY
2016.08 . 03 16 : 57 : 53.415 Test_Pos_selct (GAZR- 9.16 ,M1)   OnBookEvent : Position volume: 2
2016.08 . 03 16 : 57 : 53.415 Test_Pos_selct (GAZR- 9.16 ,M1)   PartClosePos: Order sent for part close position.
2016.08 . 03 16 : 57 : 53.423 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Order resived # 50276179
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Order # 50276179 add to history.
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Order # 50276179 not found.
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position exists
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position type: POSITION_TYPE_BUY
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position volume: 2
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Deal, based on order # 50276179 done.
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position exists.
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position type: POSITION_TYPE_BUY
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position volume: 1

C'était évident, mais "pour la pureté" de l'expérience...

Bûches pleines au sous-sol

Dossiers :
 

1. >Sans connaître l'algorithme exact (ce que vous attendez du programme), il est difficile d'évaluer s'il est implémenté correctement...

Je pensais qu'il n'était pas difficile de comprendre ce que fait le programme, mais si ce n'est pas clair, alors...

Un Expert Advisor ouvre une position sur le marché FORTS avec un volume de 2 contrats ; si la position est ouverte, elle est partiellement fermée avec un volume de 1 contrat,

alors la position sera complètement fermée. Répétez cette procédure jusqu'à ce que le compteur tr_cnt<50

2. Vous pouvez " exécuter " PositionSelect() un million de fois, cela ne changera rien, car

l'événementTRADE_TRANSACTION_DEAL_ADD ne sera pas reçu avant que vous ne soyez dans la boucle, et donc, le terminal ne mettra pas à jour

informations sur le poste

 
prostotrader:

...


Je l'ai dit plus haut - ne vous laissez pas emporter par les ordres : regardez les transactions. Voici un code court qui montre QUAND le volume de la position change et de quel type de transaction il s'agit :

//+------------------------------------------------------------------+
//|                             OnTradeTransactionPartialСlosure.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"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---
   string   text     =EnumToString(trans.type);
   long     pos_type =-1;
   double   volume   =-1.0;
   Print(__FUNCTION__,", ",text);
//---
   if(PositionSelect(Symbol()))
     {
      ResetLastError();
      if(!PositionGetInteger(POSITION_TYPE,pos_type))
        {
         Print("Error PositionGetInteger #",GetLastError());
         return;
        }
      ResetLastError();
      if(!PositionGetDouble(POSITION_VOLUME,volume))
        {
         Print("Error PositionGetDouble #",GetLastError());
         return;
        }
      text+=", "+EnumToString((ENUM_POSITION_TYPE)pos_type)+" "+DoubleToString(volume,2);
      Print(text);
     }
   else
      Print("PositionSelect error");
  }
//+------------------------------------------------------------------+

Et voici les empreintes, à la fermeture partielle :

2016.08.03 17:19:50.506 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        OnTradeTransaction, TRADE_TRANSACTION_ORDER_ADD
2016.08.03 17:19:50.506 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        TRADE_TRANSACTION_ORDER_ADD, POSITION_TYPE_BUY 2.00
2016.08.03 17:19:50.506 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        OnTradeTransaction, TRADE_TRANSACTION_REQUEST
2016.08.03 17:19:50.506 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        TRADE_TRANSACTION_REQUEST, POSITION_TYPE_BUY 2.00
2016.08.03 17:19:50.507 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        OnTradeTransaction, TRADE_TRANSACTION_ORDER_UPDATE
2016.08.03 17:19:50.507 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        TRADE_TRANSACTION_ORDER_UPDATE, POSITION_TYPE_BUY 2.00
2016.08.03 17:19:50.538 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        OnTradeTransaction, TRADE_TRANSACTION_ORDER_UPDATE
2016.08.03 17:19:50.538 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        TRADE_TRANSACTION_ORDER_UPDATE, POSITION_TYPE_BUY 2.00
2016.08.03 17:19:50.539 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        OnTradeTransaction, TRADE_TRANSACTION_DEAL_ADD
2016.08.03 17:19:50.539 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        TRADE_TRANSACTION_DEAL_ADD, POSITION_TYPE_BUY 1.00
2016.08.03 17:19:50.539 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        OnTradeTransaction, TRADE_TRANSACTION_ORDER_DELETE
2016.08.03 17:19:50.539 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        TRADE_TRANSACTION_ORDER_DELETE, POSITION_TYPE_BUY 1.00
2016.08.03 17:19:50.539 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        OnTradeTransaction, TRADE_TRANSACTION_HISTORY_ADD
2016.08.03 17:19:50.539 OnTradeTransactionPartialСlosure (GAZR-9.16,M30)        TRADE_TRANSACTION_HISTORY_ADD, POSITION_TYPE_BUY 1.00

Vous pouvez clairement voir que dès qu'un événement avec le type de transactionTRADE_TRANSACTION_DEAL_ADD est passé, ça y est, les données de position dans le terminal sont mises à jour.

Raison: