"Floating PositionSelect() error - page 2

 

Karputov Vladimir And simplify OnTradeTransaction()- consider only adding a trade to the history - no orders

You'll be fine, don't even bother writing it (don't waste your time).

 
prostotrader:

I started to look into it because the real one was crashing.

It looks like they upgraded the server over the weekend. Milliseconds came up. There may be more surprises.

Apparently,OnTradeTransaction function works independently from the transaction log.

I think this behavior of the function is reasonable - there is no need to slow down the flow of operations and wait until the log is written and everything is calculated.

In your case, it would probably be better to useOnTrade,

or wait and periodically check with a minimum pause when the deal appears in the history.

 
Sergey Chalyshev:

Looks like they upgraded the server at the weekend. Milliseconds appeared. There may be more surprises.

ApparentlyOnTradeTransaction function works independently from operation log.

I think this behavior of the function is justified - there is no need to slow down the operation flow and wait until everything is registered and counted in the journal.

In your case, it would probably be better to useOnTrade,

or wait and periodically check with a minimum pause when the deal appears in the history.

Hi Sergei!

Yes we did, but not at the weekend, but on Thursday after the evening session (asked my broker).

I can't use the Trade() event and wait for the data to update in the terminal.

The Expert Advisor was written long ago and until recently it worked "like clockwork" (maybe I was lucky andTRADE_TRANSACTION_DEAL_ADD event wasalways the first to arrive).

It is important for the Expert Advisor to execute a reciprocal trade as soon as possible, that's why the asynchronous mode and OnTradeTransaction().

Now, the Expert Advisor (sometimes) sends duplicate orders to open and close positions.

You: "I think this behavior of the function is justified. There is no need to slow down the flow of operations and wait for everything to be written and counted in the journal".

Anyway, everything is being written and counted afterTRADE_TRANSACTION_DEAL_ADD arrives:)

The thing is thatTRADE_TRANSACTION_DEAL_ADD may be lost andTRADE_TRANSACTION_HISTORY_ADD may come and then the terminal will have outdated position data.:(,

which actually happens.

It's strange that developers didn't think about it.

TRADE_TRANSACTION_HISTORY_ADD only comes if the order has been executed or deleted (cancelled), therefore

if the order state changes (respectively, the position can change), the terminal should receive the information about the position change,

even ifTRADE_TRANSACTION_DEAL_ADD is lost

Let us see what the developers have to say.

 
prostotrader:

Karputov Vladimir And simplify OnTradeTransaction() - consider only adding a trade to the history - no orders

You'll be fine, don't even bother writing it (don't waste your time).

Well, if you don't need it, don't do it.
 
prostotrader:

Please ask "teachers" and "know-it-alls" to speak on substance,

and not just to put their foot up at the post to make a point.

Before showing off in front of people who want to help you, you should formulate your question properly. What does asynchronous sending an order have to do with it, if partial closing is performed by the OrderSend() function? What are you asking about?
 
Dmitry Fedoseev:
Before showing off to people who want to help you, you should formulate your question normally. What does asynchronous sending of an order have to do with it, if partial closing is performed by the OrderSend() function? What are you asking questions about?

Great!

Should that be seen as help?

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

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

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

And Karputov has nothing to do with it, it's just that when I wrote my post he had already posted his and I didn't see it.

Initially, the question was posed as follows (in case you're too lazy to read it first)

How to build logging to show developers the error?

Why, I did it myself and the logs clearly show that

afterTRADE_TRANSACTION_HISTORY_ADD (beforeTRADE_TRANSACTION_DEAL_ADD)

the terminal does not update the position information.

 

prostotrader, Dimitri correctly tells you that partial (and full) closures are not asynchronous in your code, but synchronous... which means the program is waiting for a response from the server...

It's likely that OnTradeTransaction is triggered faster than the position itself changes.

Then here:

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

you could try looping the position check. Maybe it will help....

It's something like this:

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

Without knowing the exact algorithm(TH AT you need from the program), it's hard to assess the correctness of its implementation...

 

Changed completely to asynchronous mode

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

But nothing has changed

 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

It was obvious, but "for the sake of purity" of the experiment...

Full logs in the basement

Files:
 

1. >Without knowing the exact algorithm (THAT you need from the program), it's hard to assess whether it's implemented correctly...

Thought it wasn't hard to understand what the program does, well if it's not clear, then

An Expert Advisor opens a position in the FORTS market with a volume of 2 contracts; if the position is opened, it is partially closed with a volume of 1 contract,

then the position will be closed completely. Repeat this procedure until the counter tr_cnt<50

2. You can "run" PositionSelect() a million times - it won't change anything, because

theTRADE_TRANSACTION_DEAL_ADD eventwill not be received until you are in the loop, and therefore, the terminal will not update

position information

 
prostotrader:

...


I said above - don't get carried away with orders: look at the transactions. Here's a short code that shows WHEN the position volume changes and what type of transaction it is:

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

And here are the prints, at partial close:

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

You can clearly see that as soon as an event with the trade transaction typeTRADE_TRANSACTION_DEAL_ADD has passed, that's it, the position data in the terminal is updated.

Reason: