FORTS: OnTradeTransaction() Rückgabecodes - Seite 9

 
Михаил:

Das haben Sie falsch verstanden.

Es war der Server, der 20 Sekunden lang den Bestellstatus PLASED nicht gesendet hat.

Ich meinte die Server-Entwickler.
 
Михаил:

Es gibt einen offensichtlichen Fehler im Terminal, wo der AuftragsstatusORDER_STATE_STARTED"hängen bleibt".

Ist das Problem nun endlich gelöst?

Was genau hat die Börse zu diesem Auftrag gesagt? Wurde sie schnell platziert? Wenn dies der Fall ist, liegt es auf der Hand, dass ein Fehler auf dem Server oder dem MT-Terminal vorliegt, der den Status nicht aktualisiert hat. Und damit können Sie zum Service-Desk gehen.

 

Als Ergebnis der Diskussion über das Problem mit Michael im Service Desk:

Offenbar müssen wir erklären, wie das Bestellsystem funktioniert und was die Platzierung bedeutet.

Also:

1. Sie senden eine Anfrage

buy limit 5.00 SNGR-3.16 at 35501

2. Der MT5-Server prüft diese Anfrage (Parameter, Pre-Trade, usw.). Wenn es ein Problem gibt, erhalten Sie als Antwort auf die Anfrage einen entsprechenden Fehlercode.

Danach legen Sie einen neuen Auftrag an und geben diesem ein Ticket (#24025010) - damit wird der Status "gestartet" für den Auftrag gesetzt. Das Auftragsticket wird verwendet, um die Auftragskennung im MT5 mit dem Auftrag an der Börse zum Zeitpunkt der Auftragserteilung an der Börse zu verknüpfen.
Das Terminal sendet eine Transaktion über das Hinzufügen eines neuen Auftrags im Zustand "gestartet", die in OnTradeTransaction verfolgt werden kann.

3. Als Nächstes sendet der Handelsserver (über das Gateway) Ihren Auftrag an die Börse. Wenn die Anfrage erfolgreich gesendet wurde, erhält Ihre Anfrage eine Antwort - dies bedeutet
"dass die Anfrage gesendet wurde", die Ergebnisse werden asynchron ausgeführt, da Sie nicht im Voraus wissen, wie lange die Börse antworten wird.

Genau an dieser Stelle sehen Sie den Eintrag im Journal

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. Nach einiger Zeit setzt die Börse die Order in ihrem System, weist ihr eine Kennung zu und benachrichtigt dann das Gateway und den MT5-Server.
Wenn die Börse die Order gesetzt hat, wird die Orderkennung in die Order im MT5 geschrieben und der Orderstatus ändert sich mit => platziert.
Weigert sich die Börse aus irgendeinem Grund, einen Auftrag zu erteilen, wird der Auftrag gelöscht.

All dies kann durch einfaches Protokollieren der in OnTradeTransaction eingehenden Transaktionen nachverfolgt werden.

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

Was passiert:

1. Sie stellen eine Bestellanfrage - siehe Schritte 1-3.

Und in dem Moment, in dem der Auftrag bereits im MT5 ist und es keinen Auftrag an der Börse gibt, senden Sie einen Auftrag, um diesen Auftrag zurückzuziehen.
Da sich dieser Auftrag jedoch im Anfangszustand befindet (gestartet) und die Existenz eines Auftrags für ihn nicht definiert ist, erhalten Sie eine Ablehnung, den Auftrag zurückzuziehen
.

Sie müssen in der Logik Ihres EA entsprechende Kontrollen und Korrekturen vornehmen.


Z.U. Die andere Sache ist, dass innerhalb einer Sekunde.

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]
(und darüber hinaus 20 Sekunden lang) die Bestellung hätte aufgegeben werden müssen, dies wird gerade bearbeitet, eines der möglichen Probleme wurde gefunden - wir beheben es.
 
MQ Alexander:
Vielen Dank für die Erläuterungen! Bitte fügen Sie dies der Dokumentation hinzu!
 
MQ Alexander:

Als Ergebnis der Diskussion über das Problem mit Michael vom Service Desk:

Offenbar müssen wir erklären, wie das Bestellsystem funktioniert und was die Platzierung bedeutet.

Also:

1. Sie senden eine Anfrage


2. Der MT5-Server prüft diese Anfrage (Parameter, Pre-Trade, usw.). Wenn es ein Problem gibt, erhalten Sie als Antwort auf die Anfrage einen entsprechenden Fehlercode.

Danach legen Sie einen neuen Auftrag an und geben ihm ein Ticket (#24025010) - damit wird der Status "gestartet" für den Auftrag gesetzt. Das Orderticket wird verwendet, um die Orderkennung im MT5 mit der Order an der Börse zum Zeitpunkt der Auftragserteilung an der Börse zu verknüpfen.
Das Terminal sendet eine Transaktion über das Hinzufügen eines neuen Auftrags im Zustand "gestartet", die in OnTradeTransaction verfolgt werden kann.

3. Als Nächstes sendet der Handelsserver (über das Gateway) Ihren Auftrag an die Börse. Wenn die Anfrage erfolgreich gesendet wurde, erhält Ihre Anfrage eine Antwort - dies bedeutet
"dass die Anfrage gesendet wurde", die Ergebnisse werden asynchron ausgeführt, da Sie nicht im Voraus wissen, wie lange die Börse antworten wird.

Genau an dieser Stelle sehen Sie den Eintrag im Journal

4. Nach einiger Zeit setzt die Börse die Order in ihrem System, weist ihr eine Kennung zu und benachrichtigt dann das Gateway und den MT5-Server.
Wenn die Börse die Order gesetzt hat, wird die Orderkennung in die Order im MT5 geschrieben und der Orderstatus ändert sich mit => platziert.
Weigert sich die Börse aus irgendeinem Grund, einen Auftrag zu erteilen, wird der Auftrag gelöscht.

All dies kann durch einfaches Protokollieren der in OnTradeTransaction eingehenden Transaktionen nachverfolgt werden.

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

Was passiert:

1. Sie stellen eine Bestellanfrage - siehe Schritte 1-3.

2. in dem Moment, in dem der Auftrag bereits im MT5 ist, aber noch nicht an der Börse vorliegt, senden Sie einen Auftrag, um diesen Auftrag zurückzuziehen.
Da sich dieser Auftrag jedoch im Anfangszustand befindet (gestartet) und die Existenz eines Auftrags für ihn nicht definiert ist, erhalten Sie eine Ablehnung, den Auftrag zurückzuziehen
.

Sie müssen in der Logik Ihres EA entsprechende Kontrollen und Korrekturen vornehmen.


Z.U. Die andere Sache ist, dass innerhalb einer Sekunde

(und darüber hinaus 20 Sekunden lang) sollte die Bestellung aufgegeben werden, wir befassen uns damit, wir haben eines der möglichen Probleme gefunden - beheben wir es.
Wir verstehen immer noch nicht, an welchem Punkt der Status des Auftrags "gestartet" in den Status "erteilt" übergeht. Geschieht dies gemäß Punkt 3 Ihrer Erklärung, gemäß Punkt 4 Ihrer Erklärung oder in beiden Fällen gemäß Punkt 3 und 4?
 
Yury Kirillov:
Es ist nicht klar, zu welchem Zeitpunkt der Status des Auftrags von "begonnen" zu "erteilt" wechselt. Geschieht dies gemäß Punkt 3 Ihrer Erklärung, gemäß Punkt 4 Ihrer Erklärung oder in beiden Fällen gemäß Punkt 3 und 4?
MQ Alexander:

4. Nach einiger Zeit stellt die Börse die Order in ihrem System ein, vergibt ihre Kennung und benachrichtigt dann das Gateway und den MT5-Server darüber.
Wenn die Börse die Order eingestellt hat - wird die Orderkennung in die Order im MT5 geschrieben, und der Orderstatus ändert sich von gestartet => platziert.

 
MQ Alexander:

3. Dann sendet der Handelsserver (über das Gateway) Ihre Anfrage an die Börse. Wenn die Anfrage erfolgreich gesendet wurde, wird Ihre Anfrage beantwortet, was bedeutet

"dass die Anfrage gesendet wurde", werden die Ergebnisse seiner Arbeit asynchron ausgeführt, da Sie nicht im Voraus wissen, wann die Antwort des Austauschs erfolgt.

Dementsprechend sehen Sie an dieser Stelle im Protokolleintrag

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. Nach einiger Zeit setzt die Börse die Order in ihrem System, weist ihr eine Kennung zu und benachrichtigt dann das Gateway und den MT5-Server.
Wenn die Börse die Order gesetzt hat, wird die Kennung der Order in MT5 in die Order in MT5 geschrieben und der Orderstatus ändert sich mit => gesetzt.

Hier gibt es einen weiteren Grund für Verwirrung: Im Protokoll steht, dass die Bestellung bereits aufgegeben wurde, aber in Wirklichkeit hat sich ihr Status noch nicht geändert.

Vielleicht sollten wir etwas wie "gesendet" anstelle von "platziert" schreiben, weil der Auftrag noch nicht wirklich von der Börse angenommen wurde?

 

Es stellt sich folgendes heraus.

Vor (oder nach) der Durchführung einer Aktion an einem Auftrag,

Sie müssen den Status jedes Mal "überprüfen" (korrigieren Sie mich, wenn ich nicht sicher bin):

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 );
}
 
Михаил:

Es stellt sich folgendes heraus.

Vor (oder nach) der Durchführung einer Aktion an einem Auftrag,

Sie müssen den Status jedes Mal "überprüfen" (korrigieren Sie mich, wenn ich etwas übersehen habe):

Falsch,

Wenn wir uns dieHistoryOrderSelect( ticket ) ansehen, dann müssen wirHistoryOrderGetInteger(),HistoryOrderGetDouble()

 
Sergey Chalyshev:

Falsch,

Wenn wirHistoryOrderSelect( ticket ) betrachten, müssen wirHistoryOrderGetInteger(),HistoryOrderGetDouble() anwenden

Richtig, das ist ein Druckfehler :)

Danke, habe es korrigiert...