OnTradeTransaction - Seite 8

 
Igor Zakharov:

Bei "normalen" Robotern, wie ich sie beschrieben habe, ist mir das überhaupt nicht aufgefallen; aber in einem Fall wurde ich gebeten, ein Sicherheitssystem zu entwickeln: Die Bedingung war, dass die Positionen immer gesperrt sind (entweder mit echten Positionen oder mit einem schwebenden Auftrag), d. h. die Anzahl der Kauflose ist gleich der Anzahl der Verkaufslose. Dies ist der Fall, der mich mit den Nuancen der Auftrags-/Positions-/Handelszählung in einem Fünfer vertraut machte.

Der Unterschied besteht darin, dass der four, wenn er eine Antwort vom Broker erhält, zunächst seine "Tabellen" mit den offenen Aufträgen und der Historie synchronisiert und dann den Benutzer über die Antwort des Brokers informiert. Der five sendet diese Antwort sofort an uns und korrigiert gleichzeitig seine "Tabellen" (und alle mql-Programme lesen Daten aus diesen "Tabellen"). Das ist der Moment, den wir mit dem Millisekunden-Timer erfassen. Aber warum fangen wir es dann nicht im Prüfgerät auf?

Im Allgemeinen habe ich meinen Seelenfrieden gemacht...

Nein, es ist noch schlimmer.

In dem Moment, in dem der Auftrag von einem schwebenden Auftrag (oder Marktauftrag) in einen historischen Auftrag (ausgeführt oder gelöscht) umgewandelt wird, verschwindet er für einige Zeit ganz aus dem Terminal. Sie erscheint weder unter den anhängigen (oder "gestarteten" Märkten) noch unter den historischen Märkten.

Es geht also nicht um die Ausführung, sondern um die Synchronisierung dieser beiden Tabellen. Wenn die Antwort vom Server kommt ("Auftrag ausgeführt, Transaktion so und so erzeugt"), wird sie aus der einen Tabelle entfernt, aber nicht in die andere eingetragen.

 
Andrey Khatimlianskii:

Nein, es ist noch schlimmer.

Wenn ein Auftrag von einem schwebenden Auftrag (oder Marktauftrag) zu einem historischen Auftrag (ausgeführt oder storniert) wechselt, verschwindet er für eine gewisse Zeit ganz aus dem Terminal. Sie erscheint weder unter den anhängigen (oder "gestarteten" Märkten) noch unter den historischen Märkten.

Es geht also nicht um die Ausführung, sondern um die Synchronisierung dieser beiden Tabellen. Die Antwort kam vom Server ("Auftrag ausgeführt, hat Transaktion soundso ausgelöst") und wird aus der einen Tabelle gelöscht, aber nicht in die andere eingetragen.

Es ist interessant, das zu überprüfen.Igor Makanu hat mich mit der Aufgabehttps://www.mql5.com/ru/forum/6343/page1097#comment_12518742 fasziniert.

Ich habe die erste Annäherung auf meinem Knie gemacht. Dann werde ich einigeStatistiken über OnOrder und OnOrderTransaction Betrieb und Handelsumgebung Zustand und wenn ich nicht zu faul bin, kann ich es für Demo-Test setzen, um zu sehen, was in verschiedenen Konten/Broker los ist.

dann wird es möglich sein, zu analysieren. Bisherige Annahmen: 1. Es wird keine Teilausführung geprüft und die Besonderheiten des Kontos werden nicht geprüft; ich habe eine Marktorder gesendet, die eröffnete Position wird gespeichert, ich warte auf das Erscheinen der Schließung dieser Position im Journal und eröffne erneut in der Gegenrichtung. 2. Idealerweise sollte eine bestimmte Transaktion in OnOrderTransaction abgefangen werden, aber bisher habe ich es so gemacht - in beiden Ereignissen prüfe ich alles auf dieselbe Weise.

Natürlich ist der Code nicht optimal. Ich kann schon sehen, wo die Auftragspositionen verloren gehen, wenn alles so schlecht ist, wie im obigen Beitrag beschrieben.

//+------------------------------------------------------------------+
//|                                                 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:

Es ist interessant, dies zu überprüfen.Igor Makanu fasziniert mich mit einer Herausforderung https://www.mql5.com/ru/forum/6343/page1097#comment_12518742

es gab eine Lösung in der Diskussionhttps://www.mql5.com/ru/forum/6343/page1098#comment_12519819, ein Teil der Diskussion wurde jedoch gelöscht (((
 
Es gibt eine Lösung im MT4Orders-Thread. Aber man muss jede Harke selbst spüren ;)
 
Aleksey Mavrin:

Ich habe eine erste Annäherung an das Knie vorgenommen.

Diese Demo ist besser zu sehen.ForexTimeFXTM-Demo01

 
Igor Zakharov:

Der von mir beschriebene Fall ist mir bei "normalen" Handelsrobotern überhaupt nicht aufgefallen.

Jede Handelsbibliothek kann und sollte mit Hilfe von Stresstests auf verschiedenen Demokonten auf ihre Lausigkeit überprüft werden. Es sollte alles ohne Probleme passieren.

Nun, dazu muss der Autor die MT5-Witze persönlich kennenlernen. In meiner Praxis hat sich gezeigt, dass selbst dies nicht ausreicht.

Es gibt einige sehr spezifische Dinge, die durch das schreckliche Spamming von Aufträgen an die Handelsserver nicht entdeckt wurden. Dank des Feedbacks war es möglich, ein recht merkwürdiges Verhalten zu entdecken, das selbst den Entwicklern nicht klar zu sein scheint.

 
Igor Makanu:
es gab eine Lösung in der Diskussionhttps://www.mql5.com/ru/forum/6343/page1098#comment_12519819, ein Teil der Diskussion wurde gelöscht (((
Andrey Khatimlianskii:
Es gibt eine Lösung in der Branche MT4Orders. Aber man muss jede Harke selbst spüren ;)

Das stimmt, der Rake ist immer interessant, und dann sehen Sie, wie die Profis es gemacht haben. Die Lösung vonfxsaber ist in ihrer Prägnanz brillant, aber ich sehe einen Haken in dieser Lösung in einer Sache - die Handbücher sagen, dass das Positionsticket EXAKT das Ticket des eröffneten Auftrags ist, aber NICHT ALLES.

Bei meiner Lösung bin ich davon ausgegangen.

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

Jede Handelsbibliothek kann und sollte durch Stresstests auf verschiedenen Demokonten auf ihre Lausigkeit überprüft werden. Es sollte alles ohne Probleme passieren.

Ich habe für die Tests 200 ms verwendet, und als ich es zurückgab, stellte der Mann es auf 5 ms ein. Bei fünf funktionierte es fast jedes Mal auf jedem Konto.

Ich weiß nicht, ob es wichtig ist, aber sie haben winapi timeBeginPeriod(1) verwendet, d.h. unter den standardmäßigen 20ms ist alles passiert

 
Aleksey Mavrin:

Der Positionsschein ist IMMER der Eröffnungsauftragsschein, aber NICHT IMMER.

Ich erinnere mich nicht mehr genau daran, aber es scheint immer so zu sein.

 
fxsaber:

Ich kann mich nicht mehr genau daran erinnern, aber ich glaube, es war schon immer da.

Ja, Sie haben Recht, denn in diesem Fall handelt es sich um eine Positionskennung, die während der gesamten Lebensdauer konstant ist. Ich habe es mit dem Positionsticker verwechselt, der sich bei Rollover und Netting ändert.

Aber ich verstehe nicht - wenn eine Position teilweise geschlossen wird, ändert sich das Ticket nicht in das Ticket des letzten Auftrags, der die Position betrifft?

Ich werde meine Codes überprüfen, danke. Ich habe das Forum nicht umsonst besucht)

Bezüglich der "verlorenen Bestellung", die nicht in der Liste der aktuellen oder historischen Bestellungen enthalten ist: Es scheint mir, dass dies kein Fehler ist, ich muss mir nur die Funktionen von

Ich denke, dies ist nicht ein Fehler, müssen nur sorgfältig auf Besonderheiten der Terminal-Server MT-Markt (im Falle der sofortigen Ausführung der Markt nicht funktioniert). Ich denke schon, sehen Sie - das Terminal sendet einen Börsenauftrag, im Falle einer synchronen Funktion - es wartet und bekommt eine Antwort vom Server,

Wenn kein Fehler auftritt, kann die Antwort nur TRADE_RETCODE_DONE lauten (im Falle einer sofortigen Ausführung sind es immer noch Requotes, aber bisher ist es der Markttyp), was im Wesentlichen bedeutet, dass der Server den Auftrag an den Markt geschickt hat und er

Es bedeutet, dass der Server die Bestellung abgeschickt hat und auf die Antwort wartet. Der Status des Auftrags ist in diesem MomentORDER_STATE_STARTED, wenn ich mich nicht irre, und sein Ticket ist bekannt. Wenn der Auftrag ausgeführt wird, sendet der Server OnTradeTransaction an das Terminal, und der Auftragsstatus ändert sich in ORDER_STATE_FILLED, und das Geschäft ist bekannt

und die Position wird bekannt. Erst zu diesem Zeitpunkt speichert das Terminal den Auftrag in der Historie. Er tut dies nicht vorher, da wir nicht wissen, was mit ihm passiert ist und er bereits die erste Antwort des Servers gegeben hat.

Dies ist die Zeit, bis der Auftrag im ECN-Netz oder anderswo ausgeführt wird, sie sind in keiner der beiden Listen enthalten. D.h. im Falle eines Marktauftrags erscheint er nur in der Historie (ich bin mir nicht sicher, was den Fall von Requotes bei sofortiger Ausführung betrifft),

wird er nie in der Liste der offenen Einträge erscheinen. Und wenn ein schwebender Auftrag ausgelöst wird, wird er aus der Liste der offenen Aufträge entfernt, weil er bereits ein Marktauftrag geworden ist, und wir warten auf die Antwort des Marktservers, und dann wird er an die Historie gesendet.

Habe ich Recht?

Grund der Beschwerde: