" Error de PositionSelect() flotante - página 2

 

Karputov Vladimir Y simplificar OnTradeTransaction()- considerar sólo la adición de un comercio a la historia - sin órdenes

Estarás bien, ni te molestes en escribirlo (no pierdas el tiempo).

 
prostotrader:

Empecé a investigarlo porque el real se estrellaba.

Parece que han actualizado el servidor durante el fin de semana. Los milisegundos aparecieron. Puede haber más sorpresas.

Aparentemente, la funciónOnTradeTransaction funciona independientemente del registro de transacciones.

Creo que este comportamiento de la función es razonable - no hay necesidad de ralentizar el flujo de operaciones y esperar hasta que se escriba el registro y se calcule todo.

En su caso, probablemente sea mejor utilizarOnTrade,

o esperar y comprobar periódicamente con una pausa mínima cuando el acuerdo aparece en el historial.

 
Sergey Chalyshev:

Parece que han actualizado el servidor el fin de semana. Aparecieron milisegundos. Puede haber más sorpresas.

Al parecer, la funciónOnTradeTransaction funciona independientemente del registro de operaciones.

Creo que este comportamiento de la función está justificado - no hay necesidad de ralentizar el flujo de operaciones y esperar hasta que todo esté registrado y contabilizado en el diario.

En su caso, probablemente sea mejor utilizarOnTrade,

o esperar y comprobar periódicamente con una pausa mínima cuando el acuerdo aparece en el historial.

¡Hola Sergei!

Sí lo hicimos, pero no el fin de semana, sino el jueves después de la sesión vespertina (se lo pregunté a mi agente).

No puedo utilizar el evento Trade() y esperar a que los datos se actualicen en el terminal.

El Asesor Experto fue escrito hace mucho tiempo y hasta hace poco funcionaba "como un reloj" (tal vez tuve suerte y el eventoTRADE_TRANSACTION_DEAL_ADD fuesiempre el primero en llegar).

Es importante que el Asesor Experto ejecute una operación recíproca lo antes posible, por eso el modo asíncrono y OnTradeTransaction().

Ahora, el Asesor Experto (a veces) envía órdenes duplicadas para abrir y cerrar posiciones.

Usted: "Creo que este comportamiento de la función está justificado. No es necesario ralentizar el flujo de operaciones y esperar a que todo se escriba y se cuente en el diario".

De todos modos, todo se está escribiendo y contando después de que llegueTRADE_TRANSACTION_DEAL_ADD :)

La cuestión es queTRADE_TRANSACTION_DEAL_ADD puede perderse yTRADE_TRANSACTION_HISTORY_ADD puede llegar y entonces el terminal tendrá datos de posición desactualizados.:(,

lo que realmente sucede.

Es extraño que los desarrolladores no hayan pensado en ello.

TRADE_TRANSACTION_HISTORY_ADD sólo se produce si la orden ha sido ejecutada o eliminada (cancelada), por lo que

si el estado de la orden cambia (respectivamente, la posición puede cambiar), el terminal debe recibir la información sobre el cambio de posición,

incluso siTRADE_TRANSACTION_DEAL_ADD se pierde

Veamos qué dicen los desarrolladores.

 
prostotrader:

Karputov Vladimir Y simplificar OnTradeTransaction() - considerar sólo la adición de un comercio a la historia - sin órdenes

Estarás bien, ni te molestes en escribirlo (no pierdas el tiempo).

Si no lo necesitas, no lo hagas.
 
prostotrader:

Por favor, pida a los "profesores" y a los "sabelotodo" que hablen sobre el fondo,

y no sólo para poner el pie en el poste para hacer un punto.

Antes de lucirse ante las personas que quieren ayudarle, debe formular bien su pregunta. ¿Qué tiene que ver el envío asíncrono de una orden, si el cierre parcial lo realiza la función OrderSend()? ¿Por qué preguntas?
 
Dmitry Fedoseev:
Antes de mostrarse a la gente que quiere ayudarle, debe formular su pregunta con normalidad. ¿Qué tiene que ver el envío asíncrono de una orden, si el cierre parcial lo realiza la función OrderSend()? ¿Sobre qué preguntas?

¡Genial!

¿Debería considerarse eso como una ayuda?

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

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

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

Y Karputov no tiene nada que ver, es que cuando escribí mi post él ya había puesto el suyo y no lo vi.

Inicialmente, la pregunta estaba planteada de la siguiente manera (por si te da pereza leerla primero)

¿Cómo construir el registro para mostrar a los desarrolladores el error?

Porque, lo hice yo mismo y los registros muestran claramente que

después deTRADE_TRANSACTION_HISTORY_ADD (antes deTRADE_TRANSACTION_DEAL_ADD)

el terminal no actualiza la información de posición.

 

prostotrader, Dimitri te dice correctamente que los cierres parciales (y completos) no son asíncronos en tu código, sino síncronos... lo que significa que el programa está esperando una respuesta del servidor...

Es probable que OnTradeTransaction se active más rápido que los cambios de la propia posición.

Pues aquí:

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

podrías intentar hacer un bucle de comprobación de la posición. Tal vez ayude....

Es algo así:

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

Sin conocer el algoritmo exacto(que necesita del programa), es difícil evaluar la corrección de su implementación...

 

Cambiado completamente al modo asíncrono

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

pero nada ha cambiado

 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

Era obvio, pero "en aras de la pureza" del experimento...

Registros completos en el sótano.

Archivos adjuntos:
 

1. >Sin conocer el algoritmo exacto (que necesita del programa), es difícil evaluar si está implementado correctamente...

Pensaba que no era difícil entender lo que hace el programa, pues si no está claro, entonces

Un Asesor Experto abre una posición en el mercado FORTS con un volumen de 2 contratos; si la posición se abre, se cierra parcialmente con un volumen de 1 contrato,

entonces la posición se cerrará completamente. Repite este procedimiento hasta que el contador tr_cnt<50

2. Puedes "ejecutar" PositionSelect() un millón de veces - no cambiará nada, porque

el eventoTRADE_TRANSACTION_DEAL_ADD no se recibirá hasta que esté en el bucle, y por lo tanto, el terminal no se actualizará

información sobre el puesto

 
prostotrader:

...


Ya lo he dicho antes: no te dejes llevar por las órdenes: fíjate en las transacciones. Aquí hay un código corto que muestra CUANDO cambia el volumen de la posición y qué tipo de transacción es:

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

Y aquí están las huellas, en un cierre parcial:

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

Se puede ver claramente que en cuanto ha pasado un evento con el tipo de transacción comercialTRADE_TRANSACTION_DEAL_ADD, eso es, se actualizan los datos de posición en el terminal.

Razón de la queja: