"Errore di PositionSelect() fluttuante - pagina 2

 

Karputov Vladimir E semplificare OnTradeTransaction()- considerare solo l'aggiunta di una transazione alla storia - nessun ordine

Starai bene, non preoccuparti nemmeno di scriverlo (non perdere tempo).

 
prostotrader:

Ho iniziato a guardarci dentro perché quello vero si stava bloccando.

Sembra che abbiano aggiornato il server durante il fine settimana. Sono arrivati i millisecondi. Potrebbero esserci altre sorprese.

Apparentemente, la funzioneOnTradeTransaction funziona indipendentemente dal registro delle transazioni.

Penso che questo comportamento della funzione sia ragionevole - non c'è bisogno di rallentare il flusso delle operazioni e aspettare che il registro sia scritto e tutto sia calcolato.

Nel tuo caso, è probabilmente meglio usareOnTrade,

o aspettare e controllare periodicamente con una pausa minima quando l'affare appare nella storia.

 
Sergey Chalyshev:

Sembra che abbiano aggiornato il server nel fine settimana. Sono apparsi dei millisecondi. Potrebbero esserci altre sorprese.

Apparentemente la funzioneOnTradeTransaction funziona indipendentemente dal registro delle operazioni.

Penso che questo comportamento della funzione sia giustificato - non c'è bisogno di rallentare il flusso delle operazioni e aspettare che tutto sia registrato e contato nel giornale.

Nel tuo caso, è probabilmente meglio usareOnTrade,

o aspettare e controllare periodicamente con una pausa minima quando l'affare appare nella storia.

Ciao Sergei!

Sì, ma non nel fine settimana, ma il giovedì dopo la sessione serale (chiesto al mio broker).

Non posso usare l'evento Trade() e aspettare che i dati si aggiornino nel terminale.

L'Expert Advisor è stato scritto molto tempo fa e fino a poco tempo fa funzionava "come un orologio" (forse sono stato fortunato e l'eventoTRADE_TRANSACTION_DEAL_ADD erasempre il primo ad arrivare).

È importante che l'Expert Advisor esegua un trade reciproco il più presto possibile, ecco perché la modalità asincrona e OnTradeTransaction().

Ora, l'Expert Advisor (a volte) invia ordini duplicati per aprire e chiudere posizioni.

Tu: "Penso che questo comportamento della funzione sia giustificato. Non c'è bisogno di rallentare il flusso delle operazioni e aspettare che tutto sia scritto e contato nel giornale".

Comunque, tutto viene scritto e contato dopo l'arrivo diTRADE_TRANSACTION_DEAL_ADD :)

Il fatto è cheTRADE_TRANSACTION_DEAL_ADD può essere perso eTRADE_TRANSACTION_HISTORY_ADD può arrivare e quindi il terminale avrà dati di posizione non aggiornati.:(,

cosa che accade realmente.

È strano che gli sviluppatori non ci abbiano pensato.

TRADE_TRANSACTION_HISTORY_ADD arriva solo se l'ordine è stato eseguito o cancellato (cancellato), quindi

se lo stato dell'ordine cambia (rispettivamente, la posizione può cambiare), il terminale dovrebbe ricevere le informazioni sul cambiamento di posizione,

anche seTRADE_TRANSACTION_DEAL_ADD è perso

Vediamo cosa hanno da dire gli sviluppatori.

 
prostotrader:

Karputov Vladimir E semplificare OnTradeTransaction() - considerare solo l'aggiunta di una transazione alla storia - nessun ordine

Starai bene, non preoccuparti nemmeno di scriverlo (non perdere tempo).

Beh, se non ne hai bisogno, non farlo.
 
prostotrader:

Per favore, chiedete agli "insegnanti" e ai "sapientoni" di parlare sulla sostanza,

e non solo per mettere il piede sul palo per fare un punto.

Prima di mostrarsi di fronte a persone che vogliono aiutarvi, dovreste formulare la vostra domanda in modo corretto. Cosa c'entra l'invio asincrono di un ordine, se la chiusura parziale viene eseguita dalla funzione OrderSend()? Cosa stai chiedendo?
 
Dmitry Fedoseev:
Prima di mostrarsi alle persone che vogliono aiutarvi, dovreste formulare normalmente la vostra domanda. Cosa c'entra l'invio asincrono di un ordine, se la chiusura parziale viene eseguita dalla funzione OrderSend()? Su cosa fai domande?

Grande!

Questo dovrebbe essere visto come un aiuto?

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

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

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

E Karputov non c'entra niente, è solo che quando ho scritto il mio post lui aveva già pubblicato il suo e non l'ho visto.

Inizialmente, la domanda è stata posta come segue (nel caso siate troppo pigri per leggerla prima)

Come costruire il log per mostrare agli sviluppatori l'errore?

Perché, l'ho fatto io stesso e i registri mostrano chiaramente che

dopoTRADE_TRANSACTION_HISTORY_ADD (prima diTRADE_TRANSACTION_DEAL_ADD)

il terminale non aggiorna le informazioni sulla posizione.

 

prostotrader, Dimitri ti dice correttamente che le chiusure parziali (e complete) non sono asincrone nel tuo codice, ma sincrone... il che significa che il programma sta aspettando una risposta dal server...

È probabile che OnTradeTransaction si attivi più velocemente di quanto la posizione stessa cambi.

Allora qui:

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

potreste provare a mettere in loop il controllo della posizione. Forse sarà d'aiuto....

È qualcosa del genere:

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

Senza conoscere l'algoritmo esatto(quello che ti serve dal programma), è difficile valutare la correttezza della sua implementazione...

 

Cambiato completamente in modalità asincrona

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

Ma nulla è cambiato

 2016.08 . 03 16 : 57 : 53.415 Test_Pos_selct (GAZR- 9.16 ,M1)   OnBookEvent : Position exists
2016.08 . 03 16 : 57 : 53.415 Test_Pos_selct (GAZR- 9.16 ,M1)   OnBookEvent : Position type: POSITION_TYPE_BUY
2016.08 . 03 16 : 57 : 53.415 Test_Pos_selct (GAZR- 9.16 ,M1)   OnBookEvent : Position volume: 2
2016.08 . 03 16 : 57 : 53.415 Test_Pos_selct (GAZR- 9.16 ,M1)   PartClosePos: Order sent for part close position.
2016.08 . 03 16 : 57 : 53.423 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Order resived # 50276179
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Order # 50276179 add to history.
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Order # 50276179 not found.
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position exists
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position type: POSITION_TYPE_BUY
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position volume: 2
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Deal, based on order # 50276179 done.
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position exists.
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position type: POSITION_TYPE_BUY
2016.08 . 03 16 : 57 : 53.454 Test_Pos_selct (GAZR- 9.16 ,M1)   OnTradeTransaction : Position volume: 1

Era ovvio, ma "per amore della purezza" dell'esperimento...

Tronchi pieni nel seminterrato

File:
 

1. >Senza conoscere l'algoritmo esatto (quello che ti serve dal programma), è difficile valutare se è implementato correttamente...

Pensavo che non fosse difficile capire cosa fa il programma, beh, se non è chiaro, allora

Un Expert Advisor apre una posizione nel mercato FORTS con un volume di 2 contratti; se la posizione viene aperta, viene chiusa parzialmente con un volume di 1 contratto,

allora la posizione sarà chiusa completamente. Ripetere questa procedura finché il contatore tr_cnt<50

2. Potete "eseguire" PositionSelect() un milione di volte - non cambierà nulla, perché

l'eventoTRADE_TRANSACTION_DEAL_ADD non sarà ricevuto finché non sarete nel ciclo, e quindi il terminale non aggiornerà

informazioni sulla posizione

 
prostotrader:

...


Ho detto sopra - non lasciatevi trasportare dagli ordini: guardate le transazioni. Ecco un breve codice che mostra QUANDO il volume della posizione cambia e che tipo di transazione è:

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

Ed ecco le stampe, a chiusura parziale:

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

Potete vedere chiaramente che non appena un evento con il tipo di transazione commercialeTRADE_TRANSACTION_DEAL_ADD è passato, ecco che i dati di posizione nel terminale vengono aggiornati.

Motivazione: