"플로팅" PositionSelect() 오류

 

여기요!

상황은 다음 MT5, 빌드 1375입니다.

로봇은 작업에서 선물을 거래할 때 OrderSendAsync() 함수를 사용합니다.

2개의 계약 볼륨이 있는 열린 포지션이 있다고 가정해 보겠습니다.

부분적으로 포지션을 청산하라는 주문(볼륨 1)이 전송되어 서버로부터 응답을 받습니다.

OnTradeTransaction() 함수에서 PositionSelect(Symbol()) 위치를 확인하고 데이터를 가져옵니다.

위치에 대해. 그래서 종종 부분 마감 주문을 실행할

위치, 위치 데이터를 수신할 때 데이터에는 다음과 같은 정보가 포함됩니다.

위치는 변경되지 않습니다(볼륨은 2로 유지됨).

개발자에게 오류가 있음을 보여주기 위해 로깅을 작성하는 방법은 무엇입니까?

 

부끄럽지만 오류가 있다는 그런 자신감은 어디서 나오는 걸까요? 아니면 개발자들이 타이가 숲처럼 빽빽하다고 생각하십니까? ;-)

비동기 작업에 대한 자료를 읽으십시오.

 
Dennis Kirichenko :

부끄럽지만 오류가 있다는 그런 자신감은 어디서 나오는 걸까요? 아니면 개발자들이 타이가 숲처럼 빽빽하다고 생각하십니까? ;-)

비동기 작업에 대한 자료를 읽으십시오.

친애하는, 나는 당신이 메시지의 시작 부분을 읽을 것을 권장합니다.

사용 방법이 아닌 개발자를 위한 증명 기반을 구축하는 방법을 물었습니다.

비동기 기능!

이전 빌드(헤지 전)에는 이 오류가 없었습니다.

 

테스트 전문가 작성

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

             case ORDER_STATE_PARTIAL :  ord_data.real_state=ORD_NONE_PARTIAL;
             break ;

             case ORDER_STATE_EXPIRED :  ord_data.real_state=ORD_NONE_EXPIRED;
             break ;

             case ORDER_STATE_FILLED :   ord_data.real_state=ORD_NONE_FILLED;
             break ;

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

             case ORDER_STATE_PARTIAL :        ord_data.real_state=ORD_EXIST_PARTIAL;
             break ;

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

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

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

Demo in Opening에서 출시된 것은 이것이 실수라고 생각하며 주문이 이미 기록에 있으며 터미널에서 "모른다"

포지션 오픈 2016.08 . 02 17 : 52 : 34.427 Test_Pos_select (GAZR- 9.16 ,M1) OnTradeTransaction : 위치가 존재하지 않습니다.

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

첨부된 전체 로그

서비스 데스크 요청 전송됨

MetaTrader 5 플랫폼: 오류

원시 ,   시작일: 2016.08.02 17:20 ,   #1529580

파일:
 

아무도 전에 이 버그를 눈치채지 못했습니까?

OnTradeTransaction 기능의 확장된 로깅

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

이벤트 TRADE_TRANSACTION_DEAL_ADD 및 TRADE_TRANSACTION_HISTORY_ADD

시퀀스가 없지만 터미널은 위치 상태를 알아야 합니다.

들어오는 이벤트, 그렇지 않으면 그냥 쓰레기로 판명됩니다. 다음은 TRADE_TRANSACTION_HISTORY_ADD 이벤트가 발생한 경우의 예입니다.

먼저 온다 (역사상의 주문, 거래가 이루어지고 터미널에서 1이 아닌 2와 같은 볼륨을 가진 위치 "dangles")

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

MQL5 도움말에서

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

마지막 문구가 아니라면 모든 것이 괜찮을 것입니다.

TRADE_TRANSACTION_HISTORY_ADD 이벤트가 먼저 도착 하고 TRADE_TRANSACTION_DEAL_ADD 이벤트가 발생한 경우

lost :( 그러면 이전 위치 데이터가 터미널에서 "중단"됩니다!

 
prostotrader :

MQL5 도움말에서

마지막 문구가 아니라면 모든 것이 괜찮을 것입니다.

TRADE_TRANSACTION_HISTORY_ADD 이벤트가 먼저 도착하고 TRADE_TRANSACTION_DEAL_ADD 이벤트가 발생한 경우

lost :( 그러면 위치에 대한 이전 데이터가 터미널에서 "중단"됩니다!

날뛰다. 요청된 위치에 대한 데이터가 저장되는 캐시와 트랜잭션 간의 관계는 무엇입니까?

prostotrader , 당신은 아마도 알고리즘의 논리에 문제가 있을 것입니다. 다른 사람의 코드를 파헤치고 싶었지만 파산 했습니다. 실행 유형 은 다음과 같습니다.

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

일반적으로 어느 대학에서 그런 코딩을 가르칩니까?

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

날뛰다. 요청된 위치에 대한 데이터가 저장되는 캐시와 트랜잭션 간의 관계는 무엇입니까?

prostotrader , 당신은 아마도 알고리즘의 논리에 문제가 있을 것입니다. 다른 사람의 코드를 파헤치고 싶었지만 파산 했습니다. 실행 유형 은 다음과 같습니다.

일반적으로 어느 대학에서 그런 코딩을 가르칩니까?

당신이 쓴 것을 스스로 읽었습니까?

자신은 아무것도 모르는 '선생님'이 항상 존재하지만,

정기적으로 글을...

그는 익숙한 단어( ORDER_FILLING_IOC )를 보고 흐릿해지기 시작합니다.

당신을 위해, 모든 것을 알고

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

당신이 쓴 것을 스스로 읽었습니까?

자신은 아무것도 모르는 '선생님'이 항상 존재하지만,

정기적으로 글을...

익숙한 단어( ORDER_FILLING_IOC )를 회피하고 어지럽게 하기 시작합니다.

동기 전송 및 비동기의 두 가지 예를 만드는 것이 필요합니다(내일만). 그리고 OnTradeTransaction()을 단순화하려면 내역에 거래만 추가하는 것을 고려하십시오. 주문은 물론 마감도 아닙니다. 그러나 나는 표준 CTrade 클래스 를 통해서만 그것을 할 것입니다.

그건 그렇고, 어떤 거래 서버에서 실험하고 있습니까?

 

"선생님"과 "아는 사람"에게 장점에 대해 이야기해 달라는 요청,

표시를 하기 위해 기둥에서 다리를 들어올리는 것이 아닙니다.

 
Karputov Vladimir :

동기 전송 및 비동기의 두 가지 예를 만드는 것이 필요합니다(내일만). 그리고 OnTradeTransaction()을 단순화하려면 내역에 거래만 추가하는 것을 고려하십시오. 주문은 물론 마감도 아닙니다. 그러나 나는 표준 CTrade 클래스 를 통해서만 그것을 할 것입니다.

그건 그렇고, 어떤 거래 서버에서 실험하고 있습니까?

메시지는 확실히 데모라고 말했습니다.

실생활에서 실패가 시작되었기 때문에 그는 이 문제를 다루기 시작했습니다.

사유: