"플로팅" PositionSelect() 오류 - 페이지 2

 

Karputov Vladimir OnTradeTransaction() 단순화 - 내역에 거래 추가만 고려 - 주문 없음

글쎄, 모든 것이 잘 될 것입니다. 쓰기 시작하지 마십시오 (시간 낭비하지 마십시오).

 
prostotrader :

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

주말에 서버를 업데이트 한 것 같습니다. 밀리초가 나타났습니다. 아마도 더 많은 놀라움이있을 것입니다.

분명히 OnTradeTransaction 기능은 트랜잭션 로그와 독립적으로 작동합니다.

이 함수의 동작은 정당하다고 생각합니다. 작업의 흐름을 늦추고 모든 것이 로그에 기록되고 계산될 때까지 기다릴 필요가 없습니다.

귀하의 경우 OnTrade 를 사용하는 것이 더 나을 것입니다.

또는 최소한의 일시 중지로 주기적으로 트랜잭션이 기록에 나타나는지 확인하십시오.

 
Sergey Chalyshev :

주말에 서버를 업데이트 한 것 같습니다. 밀리초가 나타났습니다. 아마도 더 많은 놀라움이있을 것입니다.

분명히 OnTradeTransaction 기능은 트랜잭션 로그와 독립적으로 작동합니다.

이 함수의 동작은 정당하다고 생각합니다. 작업의 흐름을 늦추고 모든 것이 로그에 기록되고 계산될 때까지 기다릴 필요가 없습니다.

귀하의 경우 OnTrade 를 사용하는 것이 더 나을 것입니다.

또는 최소한의 일시 중지로 주기적으로 트랜잭션이 기록에 나타나는지 확인하십시오.

안녕, 세르게이!

예, 업데이트했지만 주말에는 업데이트하지 않았지만 저녁 세션 후 목요일에 업데이트했습니다(중개인에게 요청했습니다).

Trade() 이벤트를 사용할 수 없고 터미널의 데이터가 업데이트될 때까지 기다릴 수 없습니다.

Expert Advisor 오래 전에 작성되었으며 최근까지 "시계처럼" 작동했습니다.

Expert Advisor가 가능한 한 빨리 반환 거래를 하는 것이 중요합니다. 이것이 비동기 모드와 OnTradeTransaction()인 이유입니다.

이제 EA는 포지션을 열고 닫기 위해 (때로는) 중복 주문을 보냅니다.

당신: "나는 이 함수의 행동이 정당하다고 생각합니다. 작업의 흐름을 늦추고 모든 것이 로그에 기록되고 계산될 때까지 기다릴 필요가 없습니다."

어쨌든 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 ; // а может так?
И вообще в каких университетах так учат кодировать?

그리고 Karputov는 그것과 아무 관련이 없습니다. 제가 제 메시지를 썼을 때 그는 이미 자신의 메시지를 게시했지만 저는 그것을 보지 못했습니다.

처음에는 이렇게 질문을 했습니다.

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

왜, 나는 모든 것을 스스로했고 로그에서 분명히 볼 수 있습니다.

TRADE_TRANSACTION_HISTORY_ADD 도착 후 ( TRADE_TRANSACTION_DEAL_ADD)

단말기는 위치 정보를 업데이트하지 않습니다.

 

prostotrader , Dmitry는 부분적(그리고 완전한) 클로저가 코드에서 비동기식 순서로 발생하지 않고 동기식으로 발생한다고 올바르게 알려줍니다. 따라서 프로그램은 서버의 응답을 기다리고 있습니다 ...

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. > 정확한 알고리즘( 프로그램 에서 필요한 것)을 모르면 구현의 정확성을 평가하기 어렵습니다...

프로그램이 하는 일을 이해하는 것은 어렵지 않다고 생각했는데, 글쎄요, 명확하지 않으면

전문가는 FORTS 시장에서 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인 이벤트가 통과하자마자 터미널의 위치 데이터가 업데이트됨을 분명히 알 수 있습니다.