Organisation des Auftragszyklus - Seite 5

 
Vasiliy Sokolov:

Schleifen sind eine der gefährlichsten Programmiertechniken. Sie verursacht seltsame, seltene Fehler, die fast unmöglich zu analysieren sind.

Im Gegenteil, Sie sollten versuchen, einen Benutzer-Thread so schnell wie möglich zu beenden, anstatt eine Schleife zu drehen. Wenn Sie "am Puls der Zeit" sein wollen - analysieren Sie OnTradeTransaction im MT5. MT4 ist im Allgemeinen nicht für solche Spiele geeignet, denn Einfachheit ist schlimmer als Diebstahl, wie man sagt.

Ich meinte nicht eine konkrete Erkenntnis, sondern das Prinzip des TS-Schüttelns nach jeder Pause. Gut und wo es eine schreckliche Fixierung gibt - ist nicht klar. Es ist nicht klar, warum es so eilig ist, einen Benutzer-Thread zu beenden.

 
fxsaber:

Wo also die beängstigende Schleife ist - das ist nicht klar.

Der Aufruf von OnTick aus OnTick ist eine nicht-triviale Schleife durch Rekursion:

// Редкий, но правильный костяк модификации ордеров
for (int i = OrdersTotal() - 1; i >= 0; i--)
  if (OrderSelect(i, SELECT_BY_POS))
    if (OrderModify(OrderTicket(), Price, SL, TP, OrderExpiration()))     
    {
      i = OrdersTotal(); // Хотя бы так
      
      // А лучше так
      // OnTick(); break; // вместо строки выше лучше делать такой вызов (переполнения стека от рекурсивных вызовов быть не должно)
    }

Es ist auch nicht klar, warum es so eilig ist, den Benutzer-Thread zu beenden.

Wir arbeiten mit einem ereignisgesteuerten Modell. Deshalb müssen wir das aktuelle Ereignis so schnell wie möglich verarbeiten, um auf das nächste zu warten. Die Zeit, die in diesem Thema verbracht wird, ist ein schwarzes Loch. Je mehr Zeit wir im Fluss verbringen, desto veralteter ist das Handelsumfeld, mit dem wir arbeiten.

 
Vasiliy Sokolov:

Der Aufruf von OnTick aus OnTick ist eine nicht-triviale Schleife durch Rekursion:

Offenbar ist dies das Einzige, was abschreckt.

Wir arbeiten mit einem Ereignismodell. Deshalb müssen wir das aktuelle Ereignis so schnell wie möglich bearbeiten, um auf das nächste warten zu können. Zeit, die im Fluss verbracht wird, ist ein schwarzes Loch. Je mehr Zeit wir im Fluss verbringen, desto veralteter ist das Handelsumfeld, mit dem wir arbeiten.

Nun, das stimmt nicht!
 
:
void OnTick()
{
   for(int i = 0; i < symbols.Total(); i++)
   {
      request.symbol = symbols.At(i); 
      OrderSendAsynch(request, result); // Начиная с этой строки, анализировать торговое окружение в текущем потоке не имеет смысла
                                        // Единственная верная стратегия - как можно быстрее завершить цикл, и выйти из OnTick
                                        // Для дальнейшего анализа например в OnTransaction
   }
}

s. Wir verstehen uns überhaupt nicht. Ich glaube nicht, dass es einen Dialog zwischen uns geben kann.

 
Vasiliy Sokolov:
:

Wo haben Sie eine Pause in Ihrem Code gesehen, deren bloßes Vorhandensein der einzige Grund ist, den TS von Grund auf zu schütteln? Sie haben es nicht!

 
fxsaber:

Wo haben Sie eine Pause in Ihrem Code gesehen, deren bloßes Vorhandensein der einzige Grund ist, den TS von Grund auf zu schütteln? Sie haben es nicht!

Dieser Code veranschaulicht also, warum der aktuelle Thread so schnell wie möglich beendet werden muss. Sie sollten nicht einmal versuchen, die Handelsumgebung in OnTick anzufordern:

void OnTick()
{
   for(int i = 0; i < symbols.Total(); i++)
   {
      request.symbol = symbols.At(i); 
      OrderSendAsynch(request, result); // Начиная с этой строки, анализировать торговое окружение в текущем потоке не имеет смысла
                                        // Единственная верная стратегия - как можно быстрее завершить цикл, и выйти из OnTick
                                        // Для дальнейшего анализа например в OnTransaction      
   }
   // Далее торговое окружение начинает меняться. Мы не можем анализировать его в OnTick
   // Бессмысленно зацикливать OnTick дальше.
   // Результат работы этого кода будет неопределен
   Sleep(50);
   int total_1 = OrdersTotal();
   Sleep(50);
   int total_2 = OrdersTotal();
   //Результат операции не определен
   if(total_1 == total_2)
}

Sobald wir an dem Punkt angelangt sind, an dem die beiden Variablen verglichen werden, können wir sie nicht mehr miteinander vergleichen, da sich die Umgebung ständig ändert. Die Werte in total_1 und total_2 sind entweder nicht mehr gleich, oder sie sind beide veraltet, oder sie enthalten nicht die vorhandene Anzahl der Aufträge, oder sie enthalten die richtigen Werte. Es ist sinnlos, in OnTick gegen ein sich änderndes Handelsumfeld anzukämpfen. Stattdessen sollte OnTick unmittelbar nach der for-Schleife beendet und auf neue Ereignisse gewartet werden, die anzeigen, dass sich das Handelsumfeld geändert hat.

 
Vasiliy Sokolov:

Dieser Code veranschaulicht also, warum der aktuelle Thread so schnell wie möglich beendet werden sollte. Sie können nicht einmal versuchen, die Handelsumgebung in OnTick abzufragen:

Sobald wir an dem Punkt angelangt sind, an dem die beiden Variablen verglichen werden, können wir sie nicht mehr miteinander vergleichen, da sich die Umgebung ständig ändert. Die Werte in total_1 und total_2 sind entweder nicht mehr gleich, oder sie sind beide veraltet, oder sie enthalten nicht die vorhandene Anzahl der Aufträge, oder sie enthalten die richtigen Werte. Es ist sinnlos, sich mit der Änderung der Handelsumgebung in OnTick herumzuschlagen. Stattdessen müssen wir nur OnTick direkt nach der for-Schleife beenden und auf neue Ereignisse warten, die anzeigen, dass sich die Handelsumgebung geändert hat.

Warum haben Sie dann Pausen gemacht?!


Auch hier muss nach jeder Pause (Slips oder synchrone Handelsaufträge) TC wieder aufgerüttelt werden - die Handelslogik muss bei Null beginnen. Dementsprechend treten bei asynchronen Handelsaufträgen die erwähnten Pausen nicht auf, und es gibt einen Ausgang der Ereignisfunktion, der auf ein neues Ereignis wartet. Wenn es keine asynchronen Operationen gibt, kann die gesamte Handelslogik sogar in einem Skript mit Schleife untergebracht werden.

 
fxsaber:

Warum haben Sie dann Pausen gemacht?!

Auch hier gilt, dass nach jeder Pause (Slips oder synchrone Handelsaufträge) der TS neu gestartet werden muss - die Handelslogik muss bei Null beginnen. Dementsprechend treten bei asynchronen Handelsaufträgen die erwähnten Pausen nicht auf, und es gibt einen Ausgang der Ereignisfunktion, der auf ein neues Ereignis wartet. Wenn es keine asynchronen Operationen gibt, kann die gesamte Handelslogik sogar in einem Skript mit Schleife untergebracht werden.

Ich werde über Thomas sprechen, und Sie werden über Yury sprechen. Kurzum, lassen Sie uns unseren Dialog beenden. Erstellen Sie weiterhin Ihre eigenen Skripte mit Schleifen. Ja, es funktioniert wirklich, aber es kann nicht als Arbeitsmethode empfohlen werden.

 

Ich bin daran interessiert, ihre Meinung zu dieser Situation in MT4 zu wissen, wie sie es handhaben?


Die Aufgabe des Expert Advisors besteht darin, schwebende Aufträge und offene Positionen in einem bestimmten festen Abstand zum aktuellen Kurs bei jedem Tick zu halten.


Lassen Sie die Änderungen des Brokers etwas länger dauern als das durchschnittliche Zeitintervall zwischen den Kurssticks.


Wir laufen also in einem umgekehrten Zyklus (in abnehmender Richtung von SELECT_BY_POS) und führen entsprechende OrderModify durch.


Während dieser Schleife, die in OnTick verpackt ist, kann also Folgendes passieren

  1. OrdersTotal kann sich erhöhen (z. B. durch geöffnete oder teilweise Füllungen).
  2. Es kann zu einer Neuindizierung von schwebenden Aufträgen und Positionen kommen (z. B. wurden einige schwebende Aufträge während des Zyklus ausgeführt oder einige schwebende Aufträge wurden manuell gelöscht, und einige schwebende Aufträge wurden auf einem Rechner mit einem kurzen Ping platziert).
  3. 1. oder 2. Punkt, aber es tritt kein OrderSelect- und OrderModify-Fehler auf. Nur während des Zyklus werden aufgrund von S.1/2 einige Aufträge/Positionen fehlen.

Was ist zu tun?

Die Frage steht in indirektem Zusammenhang mit der obigen Diskussion, die hier jedoch nicht fortgesetzt werden soll (Thema abgeschlossen). Ich brauche, um einige nicht offensichtliche Nuancen in MT4Orders für MT5 zu lösen. Es wäre also nützlich, die Meinung derjenigen zu den beschriebenen Situationen zu hören, die sich mit MT4 besonders gut auskennen. Und ich bin nicht der Einzige, der sie nützlich finden könnte.


Lösen Sie das Problem durch OnTimer - dies ist wahrscheinlich der erste Vorschlag. Aber wir brauchen es nicht - nur OnTick.

 
fxsaber:

Ich bin daran interessiert, ihre Meinung zu dieser Situation in MT4 zu wissen, wie sie es handhaben?


Die Aufgabe des Expert Advisors besteht darin, schwebende Aufträge und offene Positionen in einem bestimmten festen Abstand zum aktuellen Kurs bei jedem Tick zu halten.


Lassen Sie die Änderungen des Brokers etwas länger dauern als das durchschnittliche Zeitintervall zwischen den Kurssticks.


Wir laufen also in einem umgekehrten Zyklus (in abnehmender Richtung von SELECT_BY_POS) und nehmen entsprechende OrderModify vor.


Während dieser Schleife, die in OnTick verpackt ist, kann also Folgendes passieren

  1. OrdersTotal kann sich erhöhen (z. B. durch geöffnete oder teilweise Füllungen).
  2. Es kann zu einer Neuindizierung von schwebenden Aufträgen und Positionen kommen (z. B. wurden einige schwebende Aufträge während des Zyklus ausgeführt oder einige schwebende Aufträge wurden manuell gelöscht, und einige schwebende Aufträge wurden auf einem Rechner mit einem kurzen Ping platziert).
  3. 1. oder 2. Punkt, aber es tritt kein OrderSelect- und OrderModify-Fehler auf. Nur während des Zyklus werden aufgrund von S.1/2 einige Aufträge/Positionen fehlen.

Was ist zu tun?

Die Frage steht in indirektem Zusammenhang mit der obigen Diskussion, die hier jedoch nicht fortgesetzt werden soll (Thema abgeschlossen). Ich brauche, um einige nicht offensichtliche Nuancen in MT4Orders für MT5 zu lösen. Es wäre also nützlich, die Meinung derjenigen zu den beschriebenen Situationen zu hören, die sich mit MT4 besonders gut auskennen. Und ich bin nicht der Einzige, der sie nützlich finden könnte.


Lösen Sie das Problem durch OnTimer - dies ist wahrscheinlich der erste Vorschlag. Aber lassen wir das mal weg - nur OnTick.

Erstens ist die Situation nicht standardisiert und nur sehr wenige Menschen, wenn überhaupt, haben sie jemals gelöst.

Rein theoretisch:

Wir müssen keine Kehrschleife für OrderModify einrichten, also lassen Sie es direkt sein.

int i, total = OrdersTotal();
for(i = 0; i < total; i++)

Dann prüfen wir, ob sich die Liste der Aufträge geändert hat

if(total != OrdersTotal())
 {
  i = 0;
  total = OrdersTotal();
  continue;
 }

Wenn sich die Anzahl der Aufträge geändert hat, beginnen wir diese Schleife erneut mit einer neuen Anzahl von Aufträgen.

Eine weitere Frage:

fxsaber:

  1. OrdersTotal kann sich erhöhen (z. B. durch geöffnete oder teilweise Füllungen).
  2. Es kann zu einer Neuindizierung von schwebenden Aufträgen und Positionen kommen (z. B. wurden einige schwebende Aufträge während eines Zyklus ausgeführt oder einige schwebende Aufträge wurden manuell gelöscht, und einige schwebende Aufträge wurden auf einen kurzen Ping gesetzt).
  3. 1. oder 2. Punkt, aber es tritt kein OrderSelect- und OrderModify-Fehler auf. Es ist nur so, dass während des Zyklus aufgrund von S.1/2 einige Aufträge/Stellungen fehlen werden.

Es ist verständlich, dass sie oder andere vermisst werden, wenn sie hinzugefügt wurden. Aber was wäre, wenn sie einfach gelöscht würden? Wir können nicht über die Bestellliste hinausgehen?