"Плавающая" ошибка PositionSelect() - страница 2

 

Karputov Vladimir И упростить OnTradeTransaction() - рассматривать только добавление сделки в историю - никаких ордеров

Ну и будет у Вас всё нормально, даже и не начинайте писать (не тратьте время).

 
prostotrader:

А начал разбираться с этим вопросом, потому что на реале сбои пошли. 

Похоже на выходных обновили сервер. Миллисекунды появились. Возможно будут еще сюрпризы.

Видимо функция OnTradeTransaction работает независимо от журнала операций.

Думаю такое поведение функции оправдано, незачем тормозить поток операций и ждать пока в журнале все запишется и посчитается.

В вашем случае наверное лучше использовать OnTrade,

или ждать и периодически с минимальной паузой проверять когда сделка появится в истории.  

 
Sergey Chalyshev:

Похоже на выходных обновили сервер. Миллисекунды появились. Возможно будут еще сюрпризы.

Видимо функция OnTradeTransaction работает независимо от журнала операций.

Думаю такое поведение функции оправдано, незачем тормозить поток операций и ждать пока в журнале все запишется и посчитается.

В вашем случае наверное лучше использовать OnTrade,

или ждать и периодически с минимальной паузой проверять когда сделка появится в истории.  

Привет, Сергей!

Да обновили, но не в выходные, а в четверг после вечерней сессии (спрашивал у брокера). 

Я не могу использовать событие Trade() и ждать, когда обновятся данные в терминале.

Эксперт был написан давно, и до недавнего времени работал "как часы" (возможно мне везло, и событие TRADE_TRANSACTION_DEAL_ADD всегда приходило первым).

Эксперту важно как можно быстрее совершить ответную сделку, поэтому ассинхронный режим и OnTradeTransaction(). 

Сейчас, эксперт отсылает (иногда) дублирующие ордера на открытие и закрытие позиции.

Вы: "Думаю такое поведение функции оправдано, незачем тормозить поток операций и ждать пока в журнале все запишется и посчитается".

Всё равно пишется и считается после прихода TRADE_TRANSACTION_DEAL_ADD :)

Дело в том, что TRADE_TRANSACTION_DEAL_ADD может потерятся, а TRADE_TRANSACTION_HISTORY_ADD прийти,  и тогда в терминале будут устаревшие данные о позиции. :(,

что собственно и происходит. 

Странно, что разработчики не подумали об этом.

TRADE_TRANSACTION_HISTORY_ADD приходит лишь в том случае, если ордер исполнился или удалён (отменён), следовательно,

при изменении состояния ордера (соответственно позиция может изменится), в терминал должна поступить информация об изменении позиции,

даже, если  TRADE_TRANSACTION_DEAL_ADD - потерялось 

Посмотрим, что ответят разработчики. 

 
prostotrader:

Karputov Vladimir И упростить OnTradeTransaction() - рассматривать только добавление сделки в историю - никаких ордеров

Ну и будет у Вас всё нормально, даже и не начинайте писать (не тратьте время).

Ну если не надо, так не надо.
 
prostotrader:

Просьба к "учителям" и "всезнайкам" выступать по существу,

а не просто ногу задирать у столба, чтобы отметится. 

Прежде чем выпендриваться пред людьми желающими вам помочь, сформулировали бы нормально свой вопрос. Причем здесь асиннхронная отправка ордера, если частичное закрытие выполняется функцией OrderSend(). Вы вообще о чем вопрос то задаете?  
 
Dmitry Fedoseev:
Прежде чем выпендриваться пред людьми желающими вам помочь, сформулировали бы нормально свой вопрос. Причем здесь асиннхронная отправка ордера, если частичное закрытие выполняется функцией OrderSend(). Вы вообще о чем вопрос то задаете?  

Супер!

Это нужно рассматривать как помощь?

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

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

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

 А Карпутов вообще не причём, просто когда я писал своё сообщение он уже запостил своё, а я не видел.

Изначально вопрос ставился так (если лень ситать сначала) 

Как построить логирование, чтобы показать разработчикам наличие ошибки?  

Зачем, я сам всё сделал и с логах отчётливо видно, что

после прихода TRADE_TRANSACTION_HISTORY_ADD (перед TRADE_TRANSACTION_DEAL_ADD) 

терминал не обновляет информацию о позиции. 

 

prostotrader, Вам Дмитрий правильно подсказывает, что частичное (и полное) закрытие идёт не в асинхронном порядке в вашем коде, а в синхронном... значит программа ждёт отклика с сервера...

Вероятно, что OnTradeTransaction срабатывает быстрее, чем изменяется сама позиция.

Потом тут:

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

можно попробовать зациклить проверку позиции. Может поможет....

Вот как-то так:

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

Не зная точный алгоритм (ТО, ЧТО нужно от программы), сложно оценивать правильность его реализации...

 

Изменил полностью на ассинхронный режим

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

 Но ничего не изменилось

 

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

Это было очевидно, но "ради чистоты" эксперимента... 

Полные логи в подвале

Файлы:
 

1. >Не зная точный алгоритм (ТО, ЧТО нужно от программы), сложно оценивать правильность его реализации...

Думал, что не сложно понять, что делает программа, ну если не понятно, то

Экперт открывает позизию на рынке ФОРТС объёмом 2 контракта, если позизия открыта, то она частично закрывается объёмом в 1 контракт,

затем, позиция закрывается полностью. И так несколько раз, пока счётчик tr_cnt<50  

2. Вы можете "крутить" PositionSelect() хоть миллион раз - это ничего не изменит, потому что

пока вы в цикле, событие TRADE_TRANSACTION_DEAL_ADD не поступит, а значит терминал не обновит

информацию о позициию 

 
prostotrader:

...


Я выше говорил - не увлекайтесь ордерами: смотрите на сделки. Вот короткий код, который показывает КОГДА изменяется объём позиции и какой тип транзакции при этом:

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

И вот принты, при частичном закрытии:

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

 

Хорошо видно, что как только прошло события с типом торговой транзакции TRADE_TRANSACTION_DEAL_ADD - всё, данные позиции в терминале обновлены. 

Причина обращения: