FORTS: codici di ritorno di OnTradeTransaction() - pagina 9

 
Михаил:

Hai frainteso.

Era il server che non inviava lo stato dell'ordine PLASED per 20 secondi.

Intendevo gli sviluppatori del server.
 
Михаил:

C'è un errore evidente nel terminale, dove lo stato dell'ordineORDER_STATE_STARTED si "blocca".

È stato finalmente risolto?

Che cosa ha detto esattamente lo scambio su questo ordine? È stato collocato rapidamente? Se è così, è ovvio che c'è stato un errore sul server o sul terminale MT che non ha aggiornato lo stato. E con questo si può andare al service-desk.

 

Come risultato della discussione sul problema con Michael in Service Desk:

A quanto pare dobbiamo spiegare come funziona il sistema degli ordini e cosa significa il posizionamento.

Quindi:

1. Si invia una richiesta

buy limit 5.00 SNGR-3.16 at 35501

2. Il server MT5 controlla questa richiesta (parametri, pre-trade, ecc.). Se c'è un problema, si otterrà un codice di errore corrispondente in risposta alla richiesta.

Dopo di che si crea un nuovo ordine dandogli un biglietto (#24025010) - con questo lo stato "iniziato" è impostato per l'ordine. Il biglietto d'ordine è utilizzato per collegare l'identificatore dell'ordine in MT5 con l'ordine in borsa al momento del piazzamento dell'ordine in borsa.
Il terminale invia una transazione sull'aggiunta di un nuovo ordine nello stato "iniziato", che può essere tracciato in OnTradeTransaction.

3. Successivamente, il server di trading (tramite il gateway) invia il tuo ordine alla borsa, se la richiesta è stata inviata con successo, la tua richiesta riceverà una risposta - questo significa
"che la richiesta è stata inviata", i risultati saranno eseguiti in modo asincrono, poiché non si sa in anticipo quanto tempo la borsa risponderà.

Rispettivamente è a questo punto che si vede la registrazione nel diario

2015.11.26 10:48:23.726 Trades  'xxxxxx': buy limit 5.00 SNGR-3.16 at 35501 placed for execution in 7 ms

4. Dopo un po' di tempo, la borsa imposta l'ordine nel suo sistema, gli assegna un identificatore e poi lo notifica al gateway e al server MT5.
Se la borsa ha impostato l'ordine, l'identificatore dell'ordine viene scritto nell'ordine in MT5 e lo stato dell'ordine cambia con => inserito.
Se lo scambio si rifiuta di effettuare un ordine per qualche motivo, l'ordine sarà rimosso.

Tutto questo può essere tracciato semplicemente registrando le transazioni che arrivano in OnTradeTransaction.

================================================================================

Cosa succede:

1. Presenta una richiesta d'ordine - vedi i passi 1-3.

E nel momento in cui l'ordine è già in MT5, e non c'è nessun ordine in borsa, si invia un ordine per ritirare questo ordine.
Ma siccome questo ordine è nel suo stato iniziale (iniziato) e l'esistenza di un ordine per esso non è definita, si riceve un rifiuto di ritirare l'ordine
.

Devi fare dei controlli-correzioni appropriati nella logica del tuo EA.


Z.U. L'altra cosa è che in un secondo.

2015.11.26 10:48:24.583 Trades  'xxxxxx': failed cancel order #24025010 buy limit 5.00 SNGR-3.16 at 35501.00000 [Invalid request]
(e per di più per 20 secondi) l'ordine dovrebbe essere stato effettuato, questo è in corso di trattamento, uno dei potenziali problemi è stato trovato - lo stiamo correggendo.
 
MQ Alexander:
Grazie per le spiegazioni! Si prega di aggiungere questo alla documentazione!
 
MQ Alexander:

Come risultato della discussione sul problema con Michael al Service Desk:

A quanto pare dobbiamo spiegare come funziona il sistema degli ordini e cosa significa il posizionamento.

Quindi:

1. Si invia una richiesta


2. Il server MT5 controlla questa richiesta (parametri, pre-trade, ecc.). Se c'è un problema, si otterrà un codice di errore corrispondente in risposta alla richiesta.

Dopo di che si crea un nuovo ordine dandogli un biglietto (#24025010) - con questo lo stato "iniziato" è impostato per l'ordine. Il biglietto d'ordine è utilizzato per collegare l'identificatore dell'ordine in MT5 con l'ordine in borsa al momento del piazzamento dell'ordine in borsa.
Il terminale invia una transazione sull'aggiunta di un nuovo ordine nello stato "iniziato", che può essere tracciato in OnTradeTransaction.

3. Successivamente, il server di trading (tramite il gateway) invia il tuo ordine alla borsa, se la richiesta è stata inviata con successo, la tua richiesta riceverà una risposta - questo significa
"che la richiesta è stata inviata", i risultati saranno eseguiti in modo asincrono, poiché non si sa in anticipo quanto tempo la borsa risponderà.

Rispettivamente è a questo punto che si vede la registrazione nel diario

4. Dopo un po' di tempo, la borsa imposta l'ordine nel suo sistema, gli assegna un identificatore e poi lo notifica al gateway e al server MT5.
Se la borsa ha impostato l'ordine, l'identificatore dell'ordine viene scritto nell'ordine in MT5 e lo stato dell'ordine cambia con => inserito.
Se lo scambio si rifiuta di effettuare un ordine per qualche motivo, l'ordine sarà rimosso.

Tutto questo può essere tracciato semplicemente registrando le transazioni che arrivano in OnTradeTransaction.

================================================================================

Cosa succede:

1. Si invia una richiesta d'ordine - vedere i passi 1-3.

2. nel momento in cui l'ordine è già in MT5, e non è ancora presente in borsa, si invia un ordine per ritirare questo ordine.
Ma siccome questo ordine è nel suo stato iniziale (iniziato) e l'esistenza di un ordine per esso non è definita, si riceve un rifiuto di ritirare l'ordine
.

Devi fare dei controlli-correzioni appropriati nella logica del tuo EA.


P.S. L'altra cosa è che in un secondo

(e inoltre, per 20 secondi) l'ordine dovrebbe essere piazzato, ce ne stiamo occupando, abbiamo trovato uno dei potenziali problemi - sistemiamolo.
Non abbiamo ancora capito a che punto lo stato dell'ordine "iniziato" cambia nello stato "piazzato". Questo accade secondo il punto 3 della sua spiegazione, secondo il punto 4 della sua spiegazione o in entrambi i casi punto 3 e 4?
 
Yury Kirillov:
Non è chiaro a che punto lo stato dell'ordine "iniziato" cambia in "piazzato". Questo accade secondo il punto 3 della sua spiegazione, secondo il punto 4 della sua spiegazione o in entrambi i casi punto 3 e 4?
MQ Alexander:

4. Dopo un po' di tempo, la borsa imposta l'ordine nel suo sistema, assegna il suo identificatore, e poi lo notifica al gateway e al server MT5.
Se la borsa ha impostato l'ordine - l'identificatore dell'ordine viene scritto nell'ordine in MT5, e lo stato dell'ordine cambia da iniziato => piazzato.

 
MQ Alexander:

3. Poi il server di trading (attraverso il gateway) invia la tua richiesta alla borsa, se la richiesta è stata inviata con successo, allora la tua richiesta sarà risposta, il che significa

"che la richiesta è stata inviata", i risultati del suo lavoro saranno eseguiti in modo asincrono, perché non si sa in anticipo a che ora la risposta di scambio.

Di conseguenza, è a questo punto che si vede nella voce di registro

2015.11.26 10:48:23.726 Trades  'xxxxxx': buy limit 5.00 SNGR-3.16 at 35501 placed for execution in 7 ms

4. Dopo un po' di tempo, la borsa imposta l'ordine nel suo sistema, gli assegna un identificatore e poi lo notifica al gateway e al server MT5.
Se la borsa ha impostato l'ordine, l'identificatore dell'ordine in MT5 viene scritto nell'ordine in MT5 e lo stato dell'ordine cambia con => inserito.

Ecco un altro motivo di confusione: nel log si dice che l'ordine è già stato effettuato, ma in realtà il suo stato non è ancora cambiato.

Forse dovremmo scrivere qualcosa come "inviato" invece di "piazzato" perché l'ordine non è stato effettivamente accettato dallo scambio?

 

Risulta quanto segue.

Prima (o dopo) di eseguire qualsiasi azione su un ordine,

devi "controllare" il suo stato ogni volta (correggimi se non sono sicuro):

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  //Ордер выставлен на биржу, частично исполнился, возможны действия над ним
};
//
ENUM_ORD_REAL_STATE CheckOrderState( const ulong ticket )
{
  if ( ticket > 0 )
  {
    if ( HistoryOrderSelect( ticket ) ) //Только не существующий ордер может находится в истории
    {
      ENUM_ORDER_STATE ord_state = ENUM_ORDER_STATE( HistoryOrderGetInteger( ticket, ORDER_STATE ) );
      double init_volume = HistoryOrderGetDouble( ticket, ORDER_VOLUME_INITIAL );
      double cur_volume = HistoryOrderGetDouble( ticket, ORDER_VOLUME_CURRENT );
//---      
      switch( ord_state )
      {
                                                           
        case ORDER_STATE_CANCELED:       if ( init_volume == init_volume )
                                         {
                                           return( ORD_NONE_CANCELED );
                                         }
                                         else
                                         {
                                           return( ORD_NONE_PARTIAL_CANCELED );
                                         }  
                                         break;
                                         
        case ORDER_STATE_PARTIAL:        return( ORD_NONE_PARTIAL );
                                         break;
                                         
        case ORDER_STATE_EXPIRED:        return( ORD_NONE_EXPIRED );
                                         break;
                                                                              
        case ORDER_STATE_FILLED:         return( ORD_NONE_FILLED );
                                         break;
                                         
        case ORDER_STATE_REJECTED:       return( ORD_NONE_REJECTED );
                                         break;   
 
       
      }
    }
    else
    if ( OrderSelect( ticket ) ) 
    {
      ENUM_ORDER_STATE ord_state = ENUM_ORDER_STATE( OrderGetInteger( ORDER_STATE ) );
//---      
      switch( ord_state )
      {
        case ORDER_STATE_STARTED:
        case ORDER_STATE_REQUEST_ADD:
        case ORDER_STATE_REQUEST_MODIFY:
        case ORDER_STATE_REQUEST_CANCEL: return( ORD_BUSY );
                                         break; 
 
        case ORDER_STATE_PARTIAL:        return( ORD_EXIST_PARTIAL );
                                         break;
                                          
        case ORDER_STATE_PLACED:         return( ORD_EXIST );
                                         break;
      }
    }
  }
  return( ORD_NOT_SPECIFIED );
}
 
Михаил:

Risulta quanto segue.

Prima (o dopo) di eseguire qualsiasi azione su un ordine,

dovete "controllare" il suo stato ogni volta (correggetemi se mi sono perso qualcosa):

Sbagliato,

Se guardiamo aHistoryOrderSelect( ticket ), allora dobbiamo applicareHistoryOrderGetInteger(),HistoryOrderGetDouble()

 
Sergey Chalyshev:

Non è corretto,

Se guardiamo inHistoryOrderSelect( ticket ), dobbiamo applicareHistoryOrderGetInteger(),HistoryOrderGetDouble()

Giusto, è un errore di stampa :)

Grazie, l'ho corretto...