OnTradeTransaction - pagina 8

 
Andrey Khatimlianskii:

No, le cose vanno peggio.

Quando un ordine passa da pendente (o a mercato) a storico (eseguito o cancellato), scompare dal terminale per un certo tempo. Non appare né tra i mercati pendenti (o "iniziati"), né tra quelli storici.

Quindi non è una questione di esecuzione, ma di sincronizzazione di queste due tabelle. La risposta è arrivata dal server ("Order executed, triggered transaction so-and-so") e viene cancellata da una tabella ma non inserita nell'altra.

È interessante controllarlo.Igor Makanu mi ha incuriosito con il compitohttps://www.mql5.com/ru/forum/6343/page1097#comment_12518742

Ho fatto la prima approssimazione sul mio ginocchio. Poi farò alcunestatistiche sull'operazione OnOrder e OnOrderTransaction e sullo stato dell'ambiente di trading e se non sono troppo pigro potrei metterlo in prova per vedere cosa succede in diversi conti/broker.

allora sarà possibile analizzare. Ipotesi fatte finora: 1. non si controlla l'esecuzione parziale e non si controllano le peculiarità del conto; ho inviato un ordine a mercato, la posizione aperta viene ricordata, aspetto la comparsa della chiusura di questa posizione nel giornale e apro di nuovo in direzione opposta. 2. Idealmente, una certa transazione dovrebbe essere catturata in OnOrderTransaction, ma finora ho fatto così - in entrambi gli eventi controllo tutto allo stesso modo.

Naturalmente, il codice non è ottimale. Posso già vedere dove le posizioni d'ordine si perderanno se tutto è così male come descritto nel post sopra.

//+------------------------------------------------------------------+
//|                                                 Test_Makalu2.mq5 |
//|                                           Copyright 2019, Allex@ |
//|                                                 alex-all@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Allex@"
#property link      "alex-all@mail.ru"
#property version   "1.00"
#include <Expert\Expert.mqh>
//--- input parameters
input int      TP=200;
input int      SL=200;
input double   Lot=0.01;
input string   File;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CExpertTest : public CExpert
  {
public:
   int               type;
   ulong             order;
   ulong             deal;
   ulong             position;
   bool              send;
   bool              placed;
   bool              opened;
   bool              history;
   datetime          last_history;

                     CExpertTest() {order=0;};
                    ~CExpertTest() {};
   bool              Buy(double volume,double price,double sl,double tp,const string comment="") {return m_trade.Buy(volume, price, sl, tp,  comment);};
   bool              Sell(double volume,double price,double sl,double tp,const string comment="") {return m_trade.Sell(volume, price, sl, tp,  comment);};
   bool              CheckOrder(ulong order)
     {
      ulong state;
      if(OrderSelect(order))
        {
         if(OrderGetInteger(ORDER_STATE)==ORDER_STATE_FILLED)
            position=OrderGetInteger(ORDER_POSITION_ID);
        }
      else
         if(HistoryOrderSelect(order))
           {
            if(HistoryOrderGetInteger(order,ORDER_STATE,state)&& state==ORDER_STATE_FILLED)
               position=HistoryOrderGetInteger(order,ORDER_POSITION_ID);
           }
         else
           {
            return false;
           }
      return true;

     }
   virtual bool      Processing(void)
     {
      double price;
      if(order==0)
        {
         last_history=TimeCurrent();
         price=m_symbol.Ask();
         if(Buy(Lot,price,m_symbol.NormalizePrice(price-SL*m_symbol.Point()),m_symbol.NormalizePrice(price+TP*m_symbol.Point())))
            if(m_trade.ResultRetcode()==TRADE_RETCODE_DONE)
              {
               //ulong deal2;
               deal=m_trade.ResultDeal();
               order=m_trade.ResultOrder();
               if(order!=0 && CheckOrder(order))
                  return true;
              }
        }
      return false;
     }
   void              OnTrade()
     {
      if(order==0 || !CheckOrder(order))
         return;
      HistorySelect(last_history,TimeCurrent());
      for(int i=HistoryDealsTotal()-1; i>=0; i--)
        {
         ulong ticket=HistoryDealGetTicket(i);
         ulong ordticket=HistoryDealGetInteger(ticket,DEAL_ORDER);
         ulong pos=HistoryDealGetInteger(ticket,DEAL_POSITION_ID);
         if(pos==position || ordticket==order || ticket==deal)
           {
            int entry=HistoryDealGetInteger(ticket,DEAL_ENTRY);
            ulong type=HistoryDealGetInteger(ticket,DEAL_TYPE);
            if(pos==position && entry==DEAL_ENTRY_OUT)
              {
               Refresh();
               double price;
               double sl;
               double tp;
               bool result=false;
               datetime dt=TimeCurrent();
               if(type==DEAL_TYPE_SELL)
                 {
                  price=m_symbol.Bid();
                  sl=m_symbol.NormalizePrice(price+SL*m_symbol.Point());
                  tp=m_symbol.NormalizePrice(price-TP*m_symbol.Point());
                  result=Sell(Lot,price,sl,tp);
                 }
               if(type==DEAL_TYPE_BUY)
                 {
                  price=m_symbol.Ask();
                  sl=m_symbol.NormalizePrice(price-SL*m_symbol.Point());
                  tp=m_symbol.NormalizePrice(price+TP*m_symbol.Point());
                  result=Buy(Lot,price,sl,tp);
                 }
               if(result && m_trade.ResultRetcode()==TRADE_RETCODE_DONE)
                 {
                  deal=m_trade.ResultDeal();
                  order=m_trade.ResultOrder();
                  if(order!=0 && CheckOrder(order))
                     last_history=dt;
                 }
              }
           }
        }
     }
  };
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
CExpertTest Expert;
//---
int OnInit()
  {
   if(!Expert.Init(Symbol(),Period(),Point()))
      return INIT_FAILED;
   Expert.OnTradeProcess(true);
   return(INIT_SUCCEEDED);
  }
//---
void OnTick()
  {
   Expert.OnTick();
  }
//+------------------------------------------------------------------+
void OnTrade()
  {
   Expert.OnTrade();
  }
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
   Expert.OnTrade();
  }
Вопросы от начинающих MQL5 MT5 MetaTrader 5
Вопросы от начинающих MQL5 MT5 MetaTrader 5
  • 2019.07.21
  • www.mql5.com
Подскажите пожалуйста, такой показатель тестера в жизни реален? И хороший это или плохой результат за год с депо 3000...
 
Aleksey Mavrin:

Questo è interessante da controllare.Igor Makanu mi intriga con una sfida https://www.mql5.com/ru/forum/6343/page1097#comment_12518742

c'era una soluzione nella discussionehttps://www.mql5.com/ru/forum/6343/page1098#comment_12519819, parte della discussione però è stata cancellata (((
 
C'è una soluzione nel thread MT4Orders. Ma devi sentire tu stesso ogni rastrello ;)
 
Aleksey Mavrin:

Ha fatto una prima approssimazione sul ginocchio.

Questa demo è meglio da guardare.ForexTimeFXTM-Demo01

 
Igor Zakharov:

Non ho notato affatto il caso che ho descritto sui robot "normali".

Qualsiasi libreria di trading può e deve essere controllata per la sua pochezza usando stress test su vari conti demo. Dovrebbe passare tutto senza problemi.

Beh, per farlo, l'autore deve conoscere personalmente MT5-jokes. Nella mia pratica ho scoperto che anche questo non è sufficiente.

Ci sono cose molto specifiche che non sono state rilevate dal terribile spamming di ordini ai server commerciali. Grazie al feedback è stato possibile trovare un comportamento abbastanza strano di cui nemmeno gli stessi sviluppatori sembrano rendersi conto.

 
Igor Makanu:
c'era una soluzione nella discussionehttps://www.mql5.com/ru/forum/6343/page1098#comment_12519819, parte della discussione è stata cancellata (((
Andrey Khatimlianskii:
C'è una soluzione nel ramo di MT4Orders. Ma devi sentire tu stesso ogni rastrello ;)

È vero, il rake è sempre interessante, e poi vedere come hanno fatto i professionisti. La soluzione difxsaber è brillante nella sua concisione, ma vedo una fregatura in quella soluzione in una cosa - i manuali dicono che il ticket di posizione è ESATTAMENTE il ticket dell'ordine aperto, ma NON TUTTO.

Nella mia soluzione procedevo da questo.

fxsaber
fxsaber
  • www.mql5.com
Опубликовал пост "Out-Of-Sample" - где расположить, справа или слева? Когда-то в паблике столкнулся с мнением, что OOS должен располагаться только справа. Т.е. расположение его слева от интервала Оптимизации - ошибка. Я с этим был категорически не согласен, т.к. не видел разницы. Теперь вижу. Ошибался, был не прав... Опубликовал пост...
 
fxsaber:

Qualsiasi libreria di trading può e deve essere controllata per la sua pericolosità attraverso stress test su vari conti demo. Dovrebbe passare tutto senza problemi.

Ho usato 200ms per i test e quando l'ho restituito, l'uomo l'ha impostato a 5ms. A cinque ha funzionato quasi sempre su qualsiasi account.

Non so se è importante, ma hanno usato winapi timeBeginPeriod(1), cioè sotto i 20ms standard è successo di tutto

 
Aleksey Mavrin:

biglietto di posizione SOPRATTUTTO il biglietto d'ordine di apertura, ma NON SEMPRE.

Non me lo ricordo molto bene, ma sembra che sia sempre così.

 
fxsaber:

Non me lo ricordo molto bene, ma credo che sia sempre stato lì.

Sì, hai ragione, perché in questo caso si tratta di un identificatore di posizione, costante per tutta la sua vita. L'ho confuso con il ticker della posizione, che cambia durante i rollover e il netting.

Ma non capisco - quando una posizione è parzialmente chiusa, il ticket non passa al ticket dell'ultimo ordine che interessa la posizione?

Rivedrò i miei codici, grazie. Ho visitato il forum non per niente)

Per quanto riguarda l'"ordine perso" che non è nella lista degli ordini attuali o storici: mi sembra che non sia un bug, devo solo guardare attentamente le caratteristiche di

Penso che questo non sia un bug, solo bisogno di guardare attentamente le peculiarità del terminale-server MT-market (nel caso di esecuzione istantanea il mercato non funziona). Penso di sì, guarda - il terminale invia un ordine di mercato, nel caso della funzione sincrona - aspetta e riceve una risposta dal server,

Se non c'è errore, la risposta può essere solo TRADE_RETCODE_DONE (nel caso di esecuzione istantanea è requotes, ma finora è il tipo di mercato), il che significa essenzialmente che il server ha inviato l'ordine al mercato e

In realtà significa che il server ha inviato l'ordine e aspetta la sua risposta. Lo stato dell'ordine in questo momento èORDER_STATE_STARTED se non mi sbaglio e il suo biglietto è noto. Se l'ordine viene eseguito, il server invia OnTradeTransaction al terminale e lo stato dell'ordine cambia in ORDER_STATE_FILLED e la transazione è nota

e la posizione diventa nota. È solo a questo punto che il terminale registra l'ordine nella storia. Non lo fa prima, perché non siamo sicuri di quello che gli è successo e ha già dato la risposta iniziale dal server.

Questo è il tempo fino a quando l'ordine viene eseguito nella rete ECN o da qualche altra parte, non sono in nessuna delle due liste. Cioè, nel caso di un ordine a mercato, appare solo nella storia (non sono sicuro del caso di requotes durante l'esecuzione istantanea),

non apparirà mai nella lista di quelli aperti. E quando un ordine pendente scatta, viene rimosso dalla lista di quelli aperti perché è già diventato un ordine a mercato e aspettiamo che il market-server risponda, e poi viene inviato alla storia.

Ho ragione?

 
Aleksey Mavrin:

Sì, hai ragione, perché in questo caso si tratta di un identificatore di posizione, costante per tutta la sua vita. L'ho confuso con il ticket della posizione, che cambia durante i rollover e il netting.

Ma non capisco - quando una posizione è parzialmente chiusa, il ticket non passa al ticket dell'ultimo ordine che interessa la posizione?

Rivedrò i miei codici, grazie. Ho visitato il forum non per niente)

Per quanto riguarda l'"ordine perso" che non è nella lista degli ordini attuali o storici: mi sembra che non sia un bug, devo solo guardare attentamente le caratteristiche di

Penso che questo non sia un bug, solo bisogno di guardare attentamente le peculiarità del terminale-server MT-market (nel caso di esecuzione istantanea il mercato non funziona). Penso di sì, guarda - il terminale invia un ordine di mercato, nel caso della funzione sincrona - aspetta e riceve una risposta dal server,

Se non c'è errore, la risposta può essere solo TRADE_RETCODE_DONE (nel caso di esecuzione istantanea è requotes, ma finora è il tipo di mercato), il che significa essenzialmente che il server ha inviato l'ordine al mercato e

In realtà significa che il server ha inviato l'ordine e aspetta la sua risposta. Lo stato dell'ordine in questo momento èORDER_STATE_STARTED se non mi sbaglio e il suo biglietto è noto. Se l'ordine viene eseguito, il server invia OnTradeTransaction al terminale e lo stato dell'ordine cambia in ORDER_STATE_FILLED e la transazione è nota

e la posizione diventa nota. È solo a questo punto che il terminale registra l'ordine nella storia. Non lo fa prima perché non siamo sicuri di quello che gli è successo e ha già dato la risposta iniziale dal server.

Questo è il tempo fino a quando l'ordine viene eseguito nella rete ECN o da qualche altra parte, non sono in nessuna delle due liste. Cioè, nel caso di un ordine a mercato, appare solo nella storia (non sono sicuro del caso di requotes durante l'esecuzione istantanea),

non apparirà mai nella lista di quelli aperti. E quando un ordine pendente scatta, viene rimosso dalla lista di quelli aperti perché è già diventato un ordine a mercato e aspettiamo che il market-server risponda, e poi viene inviato alla storia.

Ho ragione?

Non proprio.
Motivazione: