Tiki in Echtzeit - Seite 22

 
Andrey Khatimlianskii:

Schauen Sie sich die Uhrzeit des Protokolls an. Dies alles geschah in einer MS, und daneben (in derselben MS) eine Reihe von OnBooks.

Sie können alle Ereignisse mit Zählern zählen, aber auch visuell können Sie sehen, dass es mehr OnBooks gibt.

Andrew, die Zahlen dort sind feste Mikrosekunden, wenn OnFunctions ausgelöst werden, und alles wird dann zusammen aus dem Array gedruckt. Vielleicht gibt es insgesamt mehr OnBooks - ich werde sie zählen, aber es ist unklar, warum sie in der Warteschlange vor den OnTicks übersprungen werden. Oder entspricht nicht jeder OnTick einem OnBook?
 
prostotrader:


Haben Sie nicht geschrieben, dass Sie Async-Aufträge verwenden?
Ich frage mich, welchen Algorithmus Sie verwenden, um die Ausführung von Geschäften zu kontrollieren?

 
Aleksey Mavrin:
Andrew, die Zahlen dort sind feste Mikrosekunden, wenn OnFunctions ausgelöst werden, und alles wird dann zusammen aus dem Array gedruckt. Die Gesamtzahl der OnBooks könnte höher sein - ich werde nachzählen, aber es ist unklar, warum sie in der Warteschlange vor den OnTicks stehen oder was. Oder entspricht nicht jeder OnTick einem OnBook?

willkommen in der Welt der Vernetzung ))))

Am einfachsten ist es, wenn SieNetstat - a -b unter dem Administrator ausführen.

Sie werden Ports und Software sehen, ich will mich nicht damit aufhalten, aber ich denke, dass der MT5-Server asynchron Pakete mit verschiedenen Informationen weiterleitet, die das Terminal in die benötigten "Regale" legt.

HH: Kennen Sie Print() und das Überspringen von Ausdrucken, wenn Sie viele davon auf einmal ausgeben? - Schreiben Sie einfach Ihre Informationen in die Datei - auf diese Weise speichern Sie alles und in der richtigen Reihenfolge, aber vergessen Sie nicht, die Datei vor dem Schließen zu schließen. In der Theorie und Print() in den Protokollen in der Datei sollte vollständig sein, aber nicht überprüft haben und im Allgemeinen ich nicht vertrauen, wenn eine Menge von Daten ausgegeben. Diskutiert hierhttps://www.mql5.com/ru/forum/329730, sehr oft werden "fehlende Drucke" diskutiert ))) - Suche

 
Aleksey Mavrin:
Andrew, die Zahlen sind feste Mikrosekunden, wenn OnFunctions ausgelöst werden, und werden dann alle zusammen aus dem Array gedruckt. Vielleicht gibt es insgesamt mehr OnBooks - ich werde sie zählen, aber es ist unklar, warum sie in der Warteschlange vor den OnTicks übersprungen werden. Oder entspricht nicht jeder OnTick einem OnBook?

Ich hab's.

Nun, es gibt sowieso eine Menge OnBooks. Es ist schwer, aus einem solchen Protokoll irgendwelche Schlüsse zu ziehen.

 
Roman:

Ich dachte, Sie hätten geschrieben, dass Sie Async-Aufträge verwenden?
Ich habe mich gefragt, welchen Algorithmus Sie zur Kontrolle der Handelsausführung verwenden.

In OnTradeTransaction()+ Funktion prüfen, wenn für längere Zeit keine Serverantwort erfolgt.

Im Allgemeinen durch Magie.

Ich reserviere 65535 magische Symbole für jedes Symbol, wenn ich einen EA einstelle,

und wenn ich einen Auftrag abschicke, weise ich ihm eine eindeutige magische Nummer zu, die sich in keiner Weise mit anderen Symbolen überschneidet.

das sich in keiner Weise mit anderen Instrumenten überschneidet.

So lege ich die anfängliche magische Zahl für ein Symbol fest

//+------------------------------------------------------------------+
//|                                                    AutoMagic.mqh |
//|                                 Copyright 2017-2018 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
//version   "1.01
ulong symb_magic;
//-------------------------------------------------------------------+
// Split string function                                             |
//+------------------------------------------------------------------+
string SplitString(const string a_str,ulong &a_month,ulong &a_year)
  {
   int str_size=StringLen(a_str);
   int str_tire=StringFind(a_str, "-");
   int str_tochka=StringFind(a_str, ".", str_tire);
   if((str_tire>0) && (str_tochka>0) &&(str_size > 0))
     {
      a_month= ulong(StringToInteger(StringSubstr(a_str,str_tire+1,str_tochka-str_tire-1)));
      a_year = ulong(StringToInteger(StringSubstr(a_str,str_tochka+1,str_size-str_tochka-1)));
      if((a_month > 0) && (a_year > 0)) return(StringSubstr(a_str, 0, str_tire));
     }
   return("");
  }
//-------------------------------------------------------------------+
// Get Magic function                                                |
//+------------------------------------------------------------------+
ulong GetMagic(const string a_symbol)
{
  symb_magic = 0;
  if(SymbolSelect(Symbol(), true) == false)
  {
    Print(__FUNCTION__, ": Нет такого символа!");
    return(0);
  }
  ulong month = 0;
  ulong year = 0;
  string new_str = SplitString(a_symbol,month,year);
  if(StringLen(new_str)>0)
  {
    uchar char_array[];
    int result=StringToCharArray(new_str,char_array,0,WHOLE_ARRAY,CP_ACP);
    if(result>0)
   {
     ulong value;
     for(int i = 0; i < result - 1; i++)
     {
       value=ulong(char_array[i]);
       value<<=(56 -(i*8));
       symb_magic += value;
     }
     month<<=24;
     symb_magic += month;
     year<<=16;
     symb_magic += year;
     return(symb_magic);
   }
 }
  return(0); 
}
//-------------------------------------------------------------------+
// Is my magic function                                              |
//+------------------------------------------------------------------+
bool IsMyMagic(const ulong m_magic)
{
  if(m_magic > 0)
  {
    ulong stored_magic=symb_magic;
    stored_magic>>=16;
    ulong in_magic = m_magic;
    in_magic>>=16;
    if(in_magic == stored_magic) return(true);
  }  
  return(false);
}
//-------------------------------------------------------------------+
// Get stored magic function                                         |
//+------------------------------------------------------------------+
ulong GetStoredMagic()
{
  if(symb_magic > 0) return(symb_magic);
  return(0);  
}
//+------------------------------------------------------------------+

Magic - ulong (8 Bytes) z.B.

GAZR-3.12

Byte[7] (hohes Byte) ist "G".

Byte[6] ist "A"

Byte[5] für "Z"

Byte[4] ist "R

Byte[3] ist "3

Byte[2] ist "12".

Byte[1] und Byte[0] sind magische Reserven (65535)

So gehe ich durch die Zaubereien, wenn ich eine Bestellung abschicke:

  mem_magic = magic_storage + 1;
  if(magic_storage >= (magic_number + 65530)) mem_magic = magic_number;

Dies funktioniert jedoch nur für FORTS, da die Symbolnamen standardisiert sind!

Hinzugefügt

Wenn der Auftrag erfolgreich gesendet wurde, dann

sich an die Zeit erinnern

  if(OrderSendAsync(request, result) == true)
  {
    if((result.retcode == TRADE_RETCODE_PLACED) || (result.retcode == TRADE_RETCODE_DONE)) 
    {
      req_id = result.request_id;
      magic_storage = mem_magic;
      state = ORD_DO_SET;
      mem_time = GetMicrosecondCount();
      mem_start_time = TimeCurrent();
      SetTransCount();
    }
    else
    {
      mem_magic = 0;
      mem_time = 0;
      mem_start_time = 0;
      CheckError(result.retcode, "Place: Ордер не установлен! Причина: ", order_status, ticket);
    }
  }
mem_time = GetMicrosecondCount(); - для проверки времени задержки OnTradeTransaction
mem_start_time = TimeCurrent();   - для сужения рамок поиска в истории

Und dann (wenn es keine Antwort in OnTradeTransaction gibt)

ticket = FindOrderBuyMagic(mem_magic, start_time);

Und dann die FunktionFindOrderBuyMagic selbst

#define  TIME_DELAY    180
//+------------------------------------------------------------------+
// Expert Find order Buy Magic function                              |
//+------------------------------------------------------------------+
ulong FindOrderBuyMagic(const ulong a_magic, const datetime set_time)
{
  if(a_magic > 0)
  {
    if(IsMyMagic(a_magic) == true)
    {
      ulong cur_ticket = 0;
      for(int i = OrdersTotal() - 1; i >= 0; i--)
      {
        cur_ticket = OrderGetTicket(i);
        if(OrderSelect(cur_ticket))
        {
          if( ulong(OrderGetInteger(ORDER_MAGIC)) == a_magic) return(cur_ticket);
        }  
     }
      cur_ticket = 0;
      datetime start_time = datetime(ulong(set_time) - TIME_DELAY);
      datetime end_time = datetime(ulong(TimeCurrent()) + TIME_DELAY);    
      if(HistorySelect(start_time, end_time))
      {
        for(int i = HistoryOrdersTotal() - 1; i >= 0; i--)
        {
          cur_ticket = HistoryOrderGetTicket(i);
          if(ulong(HistoryOrderGetInteger(cur_ticket, ORDER_MAGIC)) == a_magic) return(cur_ticket);
        }
      }
    }
  }
  return(0);
}

Hinzugefügt von

"Gute Idee", die EA-Kennung(0-255) an das 1. Byte in der Automagic anzuhängen,

aber ich brauche es noch nicht, also habe ich es nicht getan :)

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
В языке MQL5 предусмотрена обработка некоторых предопределенных событий. Функции для обработки этих событий должны быть определены в программе MQL5: имя функции, тип возвращаемого значения, состав параметров (если они есть) и их типы должны строго соответствовать описанию функции-обработчика события. Именно по типу возвращаемого значения и по...
 
prostotrader:

In OnTradeTransaction()+ Funktion prüfen, wenn für längere Zeit keine Serverantwort erfolgt.

Danke für den Hinweis.

 
prostotrader:

1. Das zweite und die folgenden Terminals beim Broker sind umlagefinanziert, und ich habe keine Strategien, bei denen ich nur mit Aktien(Aktienportfolios) handle.

2. Wenn Sie den akkumuliertenGetMicrosecondCount() ausgeben wollen, dann

tun Sie es ohne Timer in OnDeinit(), wenn EA beendet wird, wird alles gedruckt.

Bitte senden Sie mir den Link zum Broker, es ist im LC möglich.

Es ist ein interessanter Zweig... :-)

 
Igor Makanu:

willkommen in der Welt der Vernetzung ))))

Am einfachsten ist es, wenn SieNetstat - a -b unter dem Administrator ausführen.

Sie werden Ports und Software sehen, ich will mich nicht damit aufhalten, aber ich denke, dass der MT5-Server asynchron Pakete mit verschiedenen Informationen weitergibt, die das Terminal in die benötigten "Regale" legt.

SZZY: Wissen Sie etwas über Print() und das Überspringen von Ausdrucken, wenn Sie viele davon auf einmal drucken? - Schreiben Sie einfach Ihre Informationen in die Datei - auf diese Weise speichern Sie alles und in der richtigen Reihenfolge, aber vergessen Sie nicht, die Datei zu schließen, bevor Sie sie schließen. In der Theorie und Print() in den Protokollen in der Datei sollte vollständig sein, aber nicht überprüft haben und im Allgemeinen ich nicht vertrauen, wenn eine Menge von Daten ausgegeben. Diskutiert hierhttps://www.mql5.com/ru/forum/329730, sehr oft werden "fehlende Drucke" diskutiert ))) - Suche

Igor, der Verlust von Ausdrucken wird von denjenigen, die die Protokolldatei nicht geöffnet haben, hundertmal diskutiert, und Rinat Fatkullin selbst schrieb, dass in der Protokolldatei nichts verloren geht. Aber für Ihren Beitrag war nicht vergeblich :) Ich habe die Ausgabe in einer separaten Datei hinzugefügt, außerdem habe ich die zweite Datei, wo ich ein wenig anders (Sammeln aller Ereignisse in CArrayObj), um mögliche Fehler meines Designs zu umgehen, die zwei Arrays bestellt, d.h. ich habe alles in CArrayObj aus zwei Arrays, dann sortieren nach Mikrosekunden und Ausgabe mit Kennzeichnung, welches Ereignis Tick oder Buch.

Und ja, was hat das mit Häfen zu tun, was hat das damit zu tun? Ich teste gerade die EA-Ereigniswarteschlange. Wenn ein Tick kam, sollten zwei Ereignisse gebildet werden - OnTick, und entsprechende OnBook, und OnBook ist immer in der Warteschlange platziert, und OnTick kann verschwinden, wenn es bereits OnTick in der Warteschlange (wie in Handbuch), dh . die Situation, wenn einer nach dem anderen OnTick ohne OnTick kann nur sein, wenn 1. die OnTicks gehen "ohne Warteschlange" 2. gibt es eine Systemverzögerung von OnBook, das ist, was ich überprüfen möchte, kann dies die Verzögerung von Sekunden, die zuvor von Kollegen identifiziert erklären. Insgesamt OnBooks sind 2+ mal mehr in einem Tag, aber warum sind sie verzögert? Wenn diese Verzögerung ist aufgrund von asynchronen Paketen und Parsing, vielleicht, aber bisher habe ich nur die Tatsache, ihr Einkommen in der EA überprüfen. Ich habe noch nicht darüber nachgedacht, wie ich den Rest der Nuancen bei der Prüfung berücksichtigen kann.

Hier ist der neue Code, beim Öffnen werde ich die Korrektheit der Arbeit testen und für den Tag laufen lassen.

s.w. Der Grund kann auch sein: wenn Tick zu den gleichen Preisen weitergegeben, ohne die Tasse zu ändern - OnBook wird nicht gebildet? Ich bin kein Spezialist in Aktienhandel, wer kann mir sagen. Ich dachte, OnTick verursacht immer OnBook.

//+------------------------------------------------------------------+
//|                                                   TestOnBook.mq5 |
//|                                           Copyright 2019, Allex@ |
//|                                                 alex-all@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, Allex@"
#property link      "alex-all@mail.ru"
#property version   "1.00"
#include <Allex\Logger.mqh>
#include <Arrays\ArrayObj.mqh>
//---
bool is_book;
enum ENUM_BOOK_OR_TICK
{
        USE_BOOK,       // Use OnBookEvent
        USE_TICK        // Use OnTick
};
class CMcsOn: public CObject
{
public:
ulong mcs;
ENUM_BOOK_OR_TICK Ontype;
CMcsOn(ulong m, ENUM_BOOK_OR_TICK t):mcs(m),Ontype(t){};
int       Compare(const CObject*Object,const int mode=0) const
     {
      const CMcsOn* obj1=dynamic_cast<const CMcsOn*>(Object);
      CMcsOn* obj=(CMcsOn*)(obj1);
      if(!obj)return 0;
      return (mcs-obj.mcs);
      }
};
input ENUM_BOOK_OR_TICK Mode = USE_BOOK;
input int   SecForPrint =  3600;
//---
ulong TimeArrayBook[65536];
ulong TimeArrayTick[65536];
ushort curBook,curTick;
ulong  DelaySum=0,DelayCount=0,CountOnBook=0,CountOnTick=0;
int delay,delayMax=0;
CLogger* Logger,*Logger2;
CArrayObj ArrayObj;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   curBook=0;
   curTick=0; 
   DelaySum=0;DelayCount=0;CountOnBook=0;CountOnTick=0;delayMax=0;
   ArrayInitialize(TimeArrayBook,INT_MAX);
   ArrayInitialize(TimeArrayTick,INT_MAX);
   Logger=CLogger::GetLogger();
   Logger2= new CLogger();
   Logger.SetSetting(__FILE__+"\\",Symbol()+"_"+EnumToString(Period())+"_"+TimeToString(TimeCurrent(),TIME_DATE));  
   Logger2.SetSetting(__FILE__+"\\","Alt_"+Symbol()+"_"+EnumToString(Period())+"_"+TimeToString(TimeCurrent(),TIME_DATE));  
  if(Mode == USE_BOOK) is_book = MarketBookAdd(Symbol());
  ArrayObj.Shutdown();
  if (EventSetTimer(SecForPrint) &&  Logger.Init() && Logger2.Init()) 
  return(INIT_SUCCEEDED);
  else return (INIT_FAILED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(Mode == USE_BOOK)
  {
    if(is_book == true) MarketBookRelease(Symbol());
  }  
   delete Logger;
   delete Logger2;
}
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{  
  TimeArrayBook[curBook++]=GetMicrosecondCount();
  CountOnBook++;
  //Print(__FUNCTION__, " ",curBook);
}
void OnTick()
{
  TimeArrayTick[curTick++]=GetMicrosecondCount();
  CountOnTick++;
  //Print(__FUNCTION__, " ",curTick);

}
//+------------------------------------------------------------------+
void OnTimer()
  {
   string out=NULL;
   int total=MathMax(curBook,curTick);
   int i=0,k=0;
   while(i<total)
     {
      while(i<total && TimeArrayBook[i]<TimeArrayTick[k] )
        {
          MyPrint("Book "+TimeArrayBook[i++]);
        }    
      if(k<curTick-1)
        {
        if(i<total)
          {
           delay=TimeArrayBook[i]-TimeArrayTick[k];
           if (delay>delayMax) 
            delayMax=delay;
           if (delay>0)
              {
                 DelaySum+=delay;
                 DelayCount++;
              }
          }
         MyPrint("Tick "+TimeArrayTick[k++]+ " delay mcs "+delay);
        }       
        i++;
     }
     if (curTick>0)
     {
     MyPrint("Tick "+TimeArrayTick[curTick-1]+ " last");
     string out="Count Event Book after Tick "+DelayCount+". Delay Average "+DoubleToString(DelaySum/DelayCount,2)+". Max "+delayMax+" OnBooks "+CountOnBook+" OnTicks "+CountOnTick;
     MyPrint (out);
     Comment(out);
     }
     Logger.Logger();
     Alt();
     curBook=0;
     curTick=0;
  }
//---
void MyPrint(string out)  
{
   Print(out);
   Logger.Log(__FUNCTION__,out,2,false);
}
//---
void Alt()
{
int last=ArrayObj.Total();
for(int i=0;i<curBook;i++)
  {
   if (!ArrayObj.Add(new CMcsOn(TimeArrayBook[i],USE_BOOK)))
      Logger2.Log(__FUNCTION__,"Error Book Add",0);   
  }
for(int i=0;i<curTick;i++)
  {
   if (!ArrayObj.Add(new CMcsOn(TimeArrayTick[i],USE_TICK)))
      Logger2.Log(__FUNCTION__,"Error Tick Add",0);   
  }
  ArrayObj.Sort();
  int total=ArrayObj.Total();
  total-=last;
  CMcsOn*Obj;
  for(int i=0;i<total;i++)
    {    
     Obj=ArrayObj.At(i);
     if(CheckPointer(Obj)==POINTER_INVALID )
      { Logger2.Log(__FUNCTION__,"Error At Array",0); continue;}
      string out = Obj.USE_BOOK ? "Book ": "Tick ";
      out+= Obj.mcs  ;
      Logger2.Log(__FUNCTION__,out,2);
    }
   Logger2.Log("ArrayObj_","Last "+last+" total "+ArrayObj.Total(),1);  
   Logger2.Logger();
   //ArrayObj.Shutdown(); 
}
 
prostotrader:
Aber ich frage mich, ob der Verantwortliche mit den Antworten auf seine Frage zufrieden ist.

Ich habe bereits alle Antworten erhalten und meine eigenen Schlussfolgerungen gezogen.
Ich muss den Streifen von Geschäften für einen bestimmten Zeitraum analysieren - Preise von Geschäften, realisierte Volumina, etc.
Und ich muss auch die Funktionsweise des Algorithmus im Strategietester simulieren.
Das OnTick-Ereignis kommt damit perfekt zurecht, die Ergebnisse des realen Handels und die Ergebnisse der Modellierung im Tester stimmen mit einem kleinen Fehler zu meiner Zufriedenheit überein.
Wenn Sie eine schnellere Analyse des Streifens benötigen, können Sie OnTimer verwenden.

Und es ist nicht notwendig, dass jeder Tick, der am Terminal ankommt, im OnBook platziert wird - dies ist die Besonderheit der Ausführung von Marktaufträgen.

 
Vladimir Mikhailov:


Und jeder Tick, der am Terminal eingeht, muss nicht zwangsläufig ins OnBook gehen - das sind die Besonderheiten der Ausführung von Marktaufträgen.

Im Gegenteil, jeder Tick(Ereignis), der zum OnTick-Handler kommt, muss mit OnBook synchronisiert werden.
Es gibt drei Ereignisse im OnTick-Handler, die Preisänderung des besten Bid, die Preisänderung des besten Ask und den Trade (Last).
Wenn sich der Geld- oder Briefkurs ändert, ohne dass ein Handel stattfindet, ist dies ein Ereignis und OnTick empfängt diese Ereignisse.
Und OnBook muss diese Ereignisse ebenfalls abfangen, aber seine eigenen Ereignisse, seinen Handler, sonst kommt es zu einer Fehlanpassung der Geld- und Briefkurse zwischen den Handlern.

Und wenn OnTick ein letztes Ereignis empfängt, bedeutet dies, dass ein Handel stattgefunden hat.
Der Abschluss erzeugt das Ereignis in OnTick, da sich nach dem Abschluss der Preis oder das Volumen der Gebote und Nachfragen auf dem Markt ändern.
Es ist ein Teufelskreis.

Sowohl in OnTick als auch in OnBook gibt es ein Ereignis Best Bid und Best Ask.
Diese Ereignisse sollten immer in beiden Handlern synchron sein.
Und das Ereignis dauert von selbst, es erzeugt ein Ereignis in OnBook nach dem Handel.
Daher muss jedes Ereignis, das den OnTick-Handler erreicht, synchron in OnBook reflektiert werden.