OnTradeTransaction-Verarbeitung

 

Guten Abend.

Leute, bitte helft mir. Das Problem ist wahrscheinlich nicht neu, aber ich habe keine einzige Lösung gefunden (weder in der Praxis noch in den Foren).

Ich lasse 2 verschiedene Roboter im Terminal auf 2 verschiedenen Instrumenten laufen. Die Magie ist überall anders. Der Roboter setzt Pending-Limits und die Prozedur OnTradeTransaction erlaubt es mir, eine Transaktion zu erkennen und Pending-Stop-Orders mit dieser Transaktion zu platzieren.

Im Folgenden finden Sie den Code für das Handelsgeschäft

case TRADE_TRANSACTION_DEAL_ADD:
        {
         drop_info2("TRADE_TRANSACTION_DEAL_ADD\r\n"+TransactionDescription(trans));
         if((trans.deal_type==DEAL_TYPE_BUY || trans.deal_type==DEAL_TYPE_SELL) && trans.order!=0)
           {
            if(getIsDealOfExpert(trans.deal)) //функция проверки принадлежности сделки к роботу
              {
               drop_info2("Сделка наша");
               analyzeFilledOrder(trans.order,trans.volume); //процедура по выставлению отложенных стоп ордеров
              }
           }
        }
      break;

Dies ist der Code der Funktion, die prüft, ob das Geschäft zu einem Roboter gehört

bool getIsDealOfExpert(ulong dealTicket)
     {
      if(HistoryDealSelect(dealTicket) && HistoryDealGetInteger(dealTicket,DEAL_MAGIC)==magic_number && HistoryDealGetString(dealTicket,DEAL_SYMBOL)==symbol)
         return true;
      else
         return false;
     }

Dies ist der Code des Verfahrens für schwebende Stop-Aufträge

void analyzeFilledOrder(ulong orderTicket,double volume)
  {
   bool isFindOrder=false;
   string fullComment;
   ENUM_ORDER_TYPE orderType;
   if(getIsOrderOfExpert(orderTicket,true)) //Если ордер из сделки уже в истории
     {
      fullComment=HistoryOrderGetString(orderTicket,ORDER_COMMENT);
      orderType=ENUM_ORDER_TYPE(HistoryOrderGetInteger(orderTicket,ORDER_TYPE));
      isFindOrder=true; //локальная переменная, если нашли в истории
     }
   if(!isFindOrder && getIsOrderOfExpert(orderTicket,false)) //Если не нашли ордер в истории и ордер есть не в истории
     {
      fullComment=OrderGetString(ORDER_COMMENT); 
      orderType=ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE));
      isFindOrder=true; //локальная переменная, если нашли не в истории
     }
   if(isFindOrder) //если хоть где-то нашли, то выставляем отложенные стоп ордера
     {
     //выставляем стоп ордера

Dies ist der Code der Funktion für die Suche nach einem Auftrag in der Historie und aus der Historie

bool getIsOrderOfExpert(ulong OrderTicket,bool isHistory)
     {
      bool is_expert=false;
      //если ордер находится в истории
      if(isHistory)
        {
         if(HistoryOrderSelect(OrderTicket) && HistoryOrderGetInteger(OrderTicket,ORDER_MAGIC)==magic_number && HistoryOrderGetString(OrderTicket,ORDER_SYMBOL)==symbol)
            is_expert=true;
        }
      else
        {
         if(OrderSelect(OrderTicket) && OrderGetInteger(ORDER_MAGIC)==magic_number && OrderGetString(ORDER_SYMBOL)==symbol)
            is_expert=true;
        }
      return is_expert;
     }

Ich würde die Informationen über die eingehenden Transaktionen in den Protokolldateien in der Reihenfolge ausgeben, in der sie im Terminal empfangen werden. Jetzt habe ich ein Problem, das ich beim Handel mit einem Demokonto hatte:

Manchmal kommen Transaktionen in der folgenden Reihenfolge: TRADE_TRANSACTION_ORDER_DELETE, dann TRADE_TRANSACTION_DEAL_ADD, dann TRADE_TRANSACTION_HISTORY_ADD. In diesem Fall werden Stop-Aufträge häufig nicht nach der Ausführung eines Geschäfts erteilt. Ich vermute, dass dies daran liegt, dass der Auftrag bereits gelöscht wurde, aber noch nicht in die Historie aufgenommen wurde. Das bedeutet, dass wir die Bestellung aus dem Geschäft weder in der Historie noch im Terminal finden können. Es ist zwar zweifelhaft, aber Tatsache ist, dass keine Stop-Order platziert wird, weil der Roboter sie nicht findet, nachdem er in allen Dimensionen nach der Order gesucht hat(isFindOrder=false). Die Reihenfolge der Transaktionen kann korrekt sein, aber der Auftrag ist trotzdem nicht zu finden. In allen Fällen erkennt der Roboter die Transaktion korrekt, kommt aber nicht dazu, Aufträge zu erteilen. Esgibt aber auch Fälle, in denen er korrekt arbeitet und Aufträge erteilt werden.

Ich habe verschiedene Ansätze ausprobiert, nichts funktioniert. Ich denke nun daran, zu Beginn der anstehenden Auftragserteilung ein 1-Sekunden-Intervall einzufügen. Ich weiß nicht, wo ich sonst noch graben soll.

Bitte teilen Sie uns Ihre Erfahrungen und Ideen mit.

 
Илья Ребенок:

Guten Abend.

Leute, bitte helft mir. Das Problem ist wahrscheinlich nicht neu, aber ich habe keine einzige Lösung gefunden (weder in der Praxis noch in den Foren).

Ich lasse 2 verschiedene Roboter im Terminal auf 2 verschiedenen Instrumenten laufen. Die Magie ist überall anders. Der Roboter setzt Pending-Limits und die Prozedur OnTradeTransaction erlaubt es mir, eine Transaktion zu erkennen und Pending-Stop-Orders mit dieser Transaktion zu platzieren.

Nachfolgend finden Sie den Code für das Handelsgeschäft

Dies ist der Code der Funktion, die prüft, ob das Geschäft zu einem Roboter gehört

Dies ist der Code des Verfahrens für schwebende Stop-Aufträge

Dies ist der Code der Funktion für die Suche nach dem Auftrag in der Historie und aus der Historie

Ich würde die Informationen über die eingehenden Transaktionen im Protokoll in der Reihenfolge ausgeben, in der sie im Terminal eingegangen sind. Jetzt habe ich ein Problem, das ich beim Handel mit einem Demokonto hatte:

Manchmal kommen Transaktionen in der folgenden Reihenfolge: TRADE_TRANSACTION_ORDER_DELETE, dann TRADE_TRANSACTION_DEAL_ADD, dann TRADE_TRANSACTION_HISTORY_ADD. In diesem Fall werden Stop-Aufträge häufig nicht nach der Ausführung eines Geschäfts erteilt. Ich vermute, dass dies daran liegt, dass der Auftrag bereits gelöscht wurde, aber noch nicht in die Historie aufgenommen wurde. Das bedeutet, dass wir die Bestellung aus dem Geschäft weder in der Historie noch im Terminal finden können. Es ist zwar zweifelhaft, aber Tatsache ist, dass keine Stop-Order platziert wird, weil der Roboter sie nicht findet, nachdem er in allen Dimensionen nach der Order gesucht hat(isFindOrder=false). Die Reihenfolge der Transaktionen mag zwar korrekt sein, aber der Auftrag ist immer noch nirgends zu finden.

Ich habe verschiedene Ansätze ausprobiert, aber nichts hilft. Ich überlege nun, ob ich zu Beginn einer Prozedur eine 1-sekündige Pause einfüge, um ausstehende Aufträge zu platzieren, vielleicht ist die Zeit nicht ausreichend. Ich weiß nicht einmal, wo ich sonst noch graben soll.

Bitte teilen Sie uns Ihre Erfahrungen und Ideen mit.

Ich habe noch nicht damit begonnen, den gesamten Code durchzusehen. Ich glaube, dass dieser Ansatz überhaupt nicht richtig ist.

Im Moment der Transaktionsart TRADE_TRANSACTION_DEAL_ADD müssen wir die trans.position auswählen und ihre Magie überprüfen.

if(PositionSelectByTicket(trans.position) && PositionGetInteger(POSITION_MAGIC) == mag)

Sie können auch prüfen, ob trans.symbol == _Symbol ist und eine Entscheidung auf der Grundlage der Ergebnisse dieser Prüfungen treffen.

 
Alexey Viktorov:

Ich habe mir nicht den ganzen Code angesehen. Meiner Meinung nach ist der Ansatz überhaupt nicht korrekt.

Im Moment der Transaktionsart TRADE_TRANSACTION_DEAL_ADD sollte man trans.position wählen und seine Magie überprüfen.

Sie können auch prüfen, ob trans.symbol == _Symbol ist und eine Entscheidung auf der Grundlage der Ergebnisse dieser Prüfungen treffen.

Ich habe vergessen, hinzuzufügen, dass der Modus Netting ist. Die Position ist bei allen Robotern die gleiche. Das heißt, ein Roboter kaufte eine Position, der zweite kaufte sie, die TRADE_TRANSACTION_DEAL_ADD-Ereignisse kamen in umgekehrter Reihenfolge und der erste Roboter sah sie nicht als Ergebnis.

Und ich muss logischerweise den Auftragskommentar aus dem Handel erhalten, die Position ist hier keine große Hilfe.
 
Илья Ребенок:

Bitte teilen Sie uns Ihre Erfahrungen und Ideen mit.

Eine Situation

Forum für Handel, automatisierte Handelssysteme und Strategietests

Wanzen, Wanzen, Fragen

fxsaber, 2018.06.20 23:18

Ich beschloss zu prüfen, wie lange diese Phantomaufträge dauern, wenn ein Auftrag im System, aber nicht im Terminal ist.

// Советник отслеживает длительность ситуаций, когда ордер отсутствует среди текущих и исторических

#define  TOSTRING(A)  #A + " = " + (string)(A) + "\n"
#define  TOSTRING2(A) #A + " = " + EnumToString(A) + " (" + (string)(A) + ")\n"

bool OrderIsExist( const ulong &OrderTicket )
{
  return(OrderTicket ? OrderSelect(OrderTicket) || HistoryOrderSelect(OrderTicket) : true);
}

void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest&, const MqlTradeResult& )
{
  static bool PrevIsExist = true;
  static ulong StartTime = 0;
  static ulong MaxInterval = 0;
  
  const ulong NowTime = GetMicrosecondCount();
  const bool IsExist = OrderIsExist(Trans.order);
    
  if (!IsExist)
  {
    Print(TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
  
    if (PrevIsExist) 
      StartTime = NowTime;
  }
  else if (!PrevIsExist)
  {
    const ulong Interval = NowTime - StartTime;
    
    Print(TOSTRING(Interval) + TOSTRING2(Trans.type) + TOSTRING(Trans.order) +
          TOSTRING(OrderSelect(Trans.order)) + TOSTRING(HistoryOrderSelect(Trans.order)));       
    
    if (Interval > MaxInterval)
    {
      MaxInterval = Interval;
      
      Comment(TOSTRING(MaxInterval) + TOSTRING(Trans.order)); // mcs.
    }
  }
          
  PrevIsExist = IsExist;
}


Ergebnis

2018.06.21 00:10:31.047 Trans.type = TRADE_TRANSACTION_ORDER_DELETE (2)
2018.06.21 00:10:31.047 Trans.order = 2210967406
2018.06.21 00:10:31.047 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 HistoryOrderSelect(Trans.order) = false
2018.06.21 00:10:31.047 
2018.06.21 00:10:31.080 Interval = 32643
2018.06.21 00:10:31.080 Trans.type = TRADE_TRANSACTION_HISTORY_ADD (3)
2018.06.21 00:10:31.080 Trans.order = 2210967406
2018.06.21 00:10:31.080 OrderSelect(Trans.order) = false
2018.06.21 00:10:31.080 HistoryOrderSelect(Trans.order) = true


32 Millisekunden lang ist ein Auftrag da, aber nicht im Terminal! Stellen Sie sich die Folgen vor, wenn die Handelslogik in diesem Intervall ausgeführt würde ...


Interessant ist, dass Phantomaufträge am häufigsten nur bei den TransaktionsartenTRADE_TRANSACTION_ORDER_DELETE und TRADE_TRANSACTION_DEAL_ADD (viel seltener) vorkommen.


Sehr schlechte Nuancierung der Plattform.


ZZY fragwürdige Geschwindigkeit der Handelsgeschäfte auf fünf, leider.


Zweite

zur Eröffnung einer Position platziert und OrdersTotal hat sich um eins erhöht.

  • Sie wurde ausgeführt und OrdersTotal verringerte sich um eins, aber PositionsTotal erhöhte sich nicht um eins. Mit anderen Worten: Es gibt eine Position, aber das Terminal weiß nichts davon.
  • Zum Beispiel gibt es keine Positionen oder Aufträge - PositionsTotal = 0, OrdersTotal = 0.

    Sie erteilen einen Börsenauftrag. In diesem Fall ist PositionsTotal = 0, OrdersTotal = 1.

    Der Marktauftrag wird ausgeführt - OrdersTotal = 0. Aber PositionsTotal = 0!

     
    Илья Ребенок:

    Ich habe vergessen, hinzuzufügen, dass der Modus Netting ist. Die Position ist bei allen Robotern die gleiche.

    Das spielt keine Rolle. Die Position hat immer ein Ticket, kann aber auch über ein Symbol ausgewählt werden. Möglicherweise müssen Sie eine Prüfung des Geschäftsvolumens oder etwas anderes hinzufügen. Wählen Sie z. B. Aufträge und Geschäfte einer Position aus und schütteln Sie sie, um die richtige Position zu finden. Aber ein Deal ist ein Deal... Und niemand garantiert die Konsistenz der Transaktionen. Vor nicht allzu langer Zeit gab es eine Warnung vor dem möglichen Verlust von Transaktionen.


    Angesichts des Zusatzes in Ihrem Beitrag ist das alles falsch. In diesem Fall müssen Sie sich die Sache genauer ansehen.

     
    Илья Ребенок:

    Ich habe verschiedene Ansätze ausprobiert, aber nichts funktioniert.

    Schreiben Sie eine einfache Aktion, die durchgeführt werden muss.

     
    fxsaber:

    Eine Situation


    Zweite

    Danke, ich werde es lesen, aber auf den ersten Blick bestätigt es meine Vermutung.

    Alexey Viktorov:

    Das spielt keine Rolle. Die Position hat immer ein Ticket, aber Sie können auch nach Symbolen auswählen. Möglicherweise müssen Sie eine Prüfung des Transaktionsvolumens oder etwas anderes hinzufügen. Wählen Sie z. B. Aufträge und Geschäfte einer Position aus und schütteln Sie sie, um die richtige Position zu finden. Aber ein Deal ist ein Deal... Und niemand garantiert die Konsistenz der Transaktionen. Vor nicht allzu langer Zeit gab es eine Warnung vor dem möglichen Verlust von Transaktionen.


    In Anbetracht des Zusatzes in Ihrem Beitrag passt das alles nicht. In diesem Fall müssen Sie sich die Sache genauer ansehen.

    Ich habe einen Beitrag über Transaktionsverluste gesehen, aber die Moderatoren dort sagten, es sei ein Relikt der Vergangenheit und sie hätten vergessen, es aus der Dokumentation zu entfernen.

    fxsaber:

    Schreiben Sie eine einfache Aktion, die durchgeführt werden soll.

    Ich verstehe nicht ganz, wie man eine einfache Aktion schreibt) Bitte erklären Sie das.

     
    Илья Ребенок:


    Ich habe einen Beitrag über den Verlust von Transaktionen gesehen, aber die Moderatoren dort meinten, das sei ein Relikt der Vergangenheit und hätten vergessen, es aus der Dokumentation zu entfernen.

    Ja, aber das ist noch gar nicht so lange her.

     
    Илья Ребенок:

    Ich verstehe nicht ganz, wie man eine einfache Aktion schreibt) Erklären Sie das bitte.

    Was ist das Handelsziel?

     
    fxsaber:

    Was ist Ihr Handelsziel?

    Wir platzieren Limit-Orders, und wenn sie ausgelöst werden, platzieren wir eine Stop-Order und eine Take-Profit-Order. Wenn eine Stop-Order ausgelöst wird, entfernen wir den Take Profit und umgekehrt. Das ursprüngliche Limit-Ticket, auf dessen Grundlage wir die Stop-Order und den Take-Profit setzen, wird in den Kommentar der Stop-Order und des Take-Profits geschrieben. Deshalb ist es wichtig, Orderkommentare zu erhalten, damit Sie, wenn eine Stop-Order ausgelöst wird, den Take-Profit mit demselben Kommentar finden und ihn löschen können.

    Da unser Roboter das Nachfüllen von Aufträgen erlaubt, sollten wir auch eine Stop-Order und eine Take-Profit-Order platzieren und einen Kommentar mit der Eingabe eines Nachfüll-Tickets hinterlassen.

    Kann 1 Sekunde Schlaf eine gute Idee sein? Um Zeit für alle TransaktionenTRADE_TRANSACTION_ORDER_DELETE undTRADE_TRANSACTION_HISTORY_ADD zu haben

    Общие принципы - Торговые операции - MetaTrader 5
    Общие принципы - Торговые операции - MetaTrader 5
    • www.metatrader5.com
    Перед тем как приступить к изучению торговых функций платформы, необходимо создать четкое представление об основных терминах: ордер, сделка и позиция. — это распоряжение брокерской компании купить или продать финансовый инструмент. Различают два основных типа ордеров: рыночный и отложенный. Помимо них существуют специальные ордера Тейк Профит...
     

    Илья Ребенок:

    Der Roboter erlaubt eine Skalierung, d.h. wenn wir mehr kaufen, platzieren wir auch eine Stop-Order und einen Take-Profit und zeichnen die Skalierung im Ticket auf.

    Können wir >=2 Take- und Stop-Aufträge gleichzeitig haben?