Tiki in Echtzeit - Seite 19

 
Yuriy Zaytsev:

Wenn Sie nicht befürchten wollen, dass Symbol() zu viel Zeit in Anspruch nimmt, können Sie auch beide Handler gleichermaßen "füttern".

Wir können die Funktion Symbol() durch eine vordefinierte Variable _Symbol ersetzen

 

Symbol() hat damit nichts zu tun. Die Zeit im Protokoll ist korrekt.

Die Verzögerung liegt in der Ereigniswarteschlange oder den SymbolInfo-Funktionen.

Das ist es, wovon ich spreche.


Wenn Sie also das Glas brauchen, arbeiten Sie mit OnBook. Wenn nicht benötigt, arbeiten Sie in OnTick (ohne Warteschlangen und unnötige Aufrufe).

Bleibt nur noch herauszufinden, wie man am schnellsten die tatsächliche Tick-Historie für beide Methoden ermitteln kann.

Ich denke, wenn nur der letzte Tick benötigt wird, ist SymbolInfo besser. Wenn wir eine lückenlose Historie brauchen, dann nur CopyTicks.

 
Andrey Khatimlianskii:

Symbol() hat damit nichts zu tun. Die Zeit im Protokoll ist korrekt.

Die Verzögerung liegt in der Ereigniswarteschlange oder den SymbolInfo-Funktionen.

Das ist es, wovon ich spreche.

Ich stimme zu, dass Symbol kann nicht viel kauen, aber kann einen Beitrag leisten, und sicherlich für die Reinheit der Prüfung nehmen Sie Zeitvor jedem Anruf.

Was die Warteschlange betrifft, so bin ich neugierig, wie weit OnBook unter idealen Bedingungen hinter demselben OnTick zurückbleiben kann. D.h. wenn nur dieses Symbol abonniert ist, das Terminal mit nichts anderem beschäftigt ist, usw., und was die Ursache dafür ist.

Bisher kann ich nicht zustimmen, dass es nur um die Warteschlange geht, denn wenn die Handler nichts tun, dann sollte die Warteschlange von 5-6 OnBooks nicht mehr verbrauchen als der Vorgang der Überprüfung des Symbols.

Wir sollten alle Prüfungen entfernen und sehen, waszwischen OnTick und OnBook für denselben Tick fällt.

void OnBookEvent(const string &symbol)
{
ul=GetMicrosecondCount();  
  Print(__FUNCTION__, "; Time: ", ul, " mcs");
}
void OnTick()
{
ul=GetMicrosecondCount();  
  Print(__FUNCTION__, "; Time: ", ul, " mcs");
}
//+--

ap: Es wurde deutlich, dass das gefräßige Print nicht erlaubt, sauber zu prüfen, weil die Warteschlange durch das Print lang wird)

Ich muss die Zeit ohne den Druck in das Array ulong setzen, und dann schon einmal alle 5 Minuten alles in Prints ausgeben, ich werde es später codieren.

 

Ich wollte den Code zuerst testen

//---
bool is_book;
enum ENUM_BOOK_OR_TICK
{
        USE_BOOK,       // Use OnBookEvent
        USE_TICK        // Use OnTick
};
input ENUM_BOOK_OR_TICK Mode = USE_BOOK;
input int   SecForPrint =  120;
ulong TimeArrayBook[65536];
ulong TimeArrayTick[65536];
ushort curBook,curTick;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   curBook=0;
   curTick=0; 
   ArrayInitialize(TimeArrayBook,INT_MAX);
   ArrayInitialize(TimeArrayTick,INT_MAX);
  if(Mode == USE_BOOK) is_book = MarketBookAdd(Symbol());
  if (EventSetTimer(SecForPrint)) 
  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());
  }  
}
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
  TimeArrayBook[curBook++]=GetMicrosecondCount();
}
void OnTick()
{
  TimeArrayTick[curTick++]=GetMicrosecondCount();
}
//+------------------------------------------------------------------+
void OnTimer()
  {  
   int total=MathMax(curBook,curTick);
   int i=0,k=0;
   while(i<total)
     {
      while(i<total && TimeArrayBook[i]<TimeArrayTick[k])
        {
          Print("Book ",TimeArrayBook[i++]);
        }    
      if(k<curTick-1)
        {
         Print("Tick ",TimeArrayTick[k++]);
        }       
        i++;
     }
     if (curTick>0)Print("Tick ",TimeArrayTick[curTick-1], " last");
     curBook=0;
     curTick=0;
  }
//---

Aber ich kann das Demo-Eröffner-Konto aus irgendeinem Grund nicht eröffnen. Die Zeit funktioniert wahrscheinlich nicht, oder es gibt andere Probleme?



Dann Code zu dopilieren, um genau von einem Ereignis Tick zu vergleichen.

 
Aleksey Mavrin:

Ich wollte den Code zuerst testen

Aber ich kann das Demo-Eröffner-Konto aus irgendeinem Grund nicht eröffnen. Die Zeit ist wahrscheinlich nicht in Ordnung, oder stimmt etwas anderes nicht mit ihr?



Dann Code zu dopilieren, um genau von einem Ereignis Tick zu vergleichen.

Sie müssen es auf ihrer Website öffnen. Sie senden dann einen Code an die Post.

 
Andrey Khatimlianskii:


Ich denke, wenn nur der letzte Tick benötigt wird, ist SymbolInfo besser. Wenn Sie eine lückenlose Historie benötigen, dann nur mit CopyTicks.

Das Problem ist, dass der Eilmarkt (FORTS) selbst bei "hochliquiden" Instrumenten sehr schwach ist,

Das bedeutet, dass man zum richtigen Preis nur eine sehrbegrenzte Anzahl von Verträgen kaufen kann, es kommt also nicht nur auf den Preis an,

aber das Volumen der Verträge zu diesem Preis ist sehr wichtig.


Und SymbolInfo gibt das Volumen dieses Preises nicht an.

Aus diesem Grund müssen wirMarketBookGet() verwenden, das sowohl Preis als auch Volumen des gesamten Buches liefert.

Sie könnenMarketBookGet() nur in Verbindung mit MarketBookAdd verwenden, um die Änderungen des Marktbechers zu erhalten.

in OnBookEvent. Sie können den Markt hinzufügen (MarketBookAdd) undMarketBookGet() aus OnTck() verwenden,

aber in diesem Fall verpassen wir einige andere Veränderungen des Marktes(ausstehende Aufträge nicht zum besten Preis).

Es ist wahr, der Markt kann damit spielen und den Markt rutschen von eingehenden Ticks bauen, aber ist es wirklich notwendig?

Hinzugefügt von

Und ich stimme nicht zu, dass wir Ticks aus der Historie erhalten können, wenn OnTck() ausgelöst wird.

Indem wir uns die letzte Tick-Zeit merken, können wir beim Auslösen von OnTck() Ticks erhalten

In Echtzeit kam ein neuer Tick herein - ausgelöst durch OnTck() lesen wir ihn sofort, d.h. er ist nicht historisch.

 
Andrey Khatimlianskii:

Es bleibt noch herauszufinden, wie man am schnellsten den aktuellen Tickverlauf für beide Methoden erhält.


Meine OnTick() ist die gleiche oder etwas schneller als OnBook (aber OnBook hat große Verzögerungen).

Ich habe die Geschwindigkeit der Funktionen getestet(Mikrosekunden)

2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoTick: time = 2 mcs 2020.02.04 13:09:10.720 Bid=1573.1 
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoDouble: time = 28 mcs ask = 1573.3
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoDouble: time = 33 mcs bid = 1573.1
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       SymbolInfoDouble: time = 36 mcs last = 1573.4
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       OnTick: time = 41 mcs 2020.02.04 13:09:10.720 Bid=1573.1 
2020.02.04 13:09:13.101 Ticks_test (GOLD-3.20,M1)       OnTick: time = 41 mcs 2020.02.04 13:09:00.328 Ask=1573.3 
OnTick - имеется ввиду CopyTicks из OnTick

Am schnellsten geht es mitSymbolInfoTick, aber diese Funktion setzt das Volumen nicht in den Tick!

Siehe für Hilfe.

tick

[out]  Ссылка на структуру типа MqlTick, в которую будут помещены текущие цены и время последнего обновления цен.

D.h. nur Zeit und Preis, aber kein Volumen :(

 

Bei börsengehandelten Instrumenten (insbesondere FORTS) kommt es nicht nur auf den Preis an,

sondern auch das Volumen der Verträge zu diesem Preis!

 

Versucht, das Glas durch OnTick() zu nehmen - große Verzögerungen deutlich sichtbar "mit dem Auge"!

//+------------------------------------------------------------------+
//|                                                   Ticks_test.mq5 |
//|                                      Copyright 2019 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
bool is_book;
MqlBookInfo BookInfo[];
int book_cnt;
struct MARKET_DATA
{
  double ask;
  long   ask_vol;
  double bid;
  long   bid_vol;
  double prev_ask;
  long   prev_ask_vol;
  double next_bid;
  long   next_bid_vol; 
};
MARKET_DATA m_data;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  is_book = MarketBookAdd(Symbol());
  if(is_book == false)
  {
    Alert("No add book!");
    return(INIT_FAILED);
  }
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  if(is_book == true) MarketBookRelease(Symbol());
}
//+------------------------------------------------------------------+
//| Expert OnTick function                                           |
//+------------------------------------------------------------------+
bool GetBook(const string a_symb, int &cnt)
{
  cnt = 0;
  if(MarketBookGet(a_symb, BookInfo) == true)//getBook )
  {
    m_data.ask = 0;
    m_data.ask_vol = 0;
    m_data.prev_ask = 0;
    m_data.prev_ask_vol = 0;
    m_data.bid = 0;
    m_data.bid_vol = 0;
    m_data.next_bid = 0;
    m_data.next_bid_vol = 0;
    cnt = ArraySize(BookInfo);
    if(cnt > 0)
    {
      for(int i = 0; i < cnt; i++)
      {
        if(BookInfo[i].type == BOOK_TYPE_BUY) //Стакан агрегирован, т.е от наибольшего Sell к наименьшему Buy
        {
          if((i + 1) <= (cnt- 1))
          {
            m_data.ask = BookInfo[i-1].price;
            m_data.ask_vol = BookInfo[i-1].volume;
            m_data.prev_ask = BookInfo[i-2].price;
            m_data.prev_ask_vol = BookInfo[i-2].volume;
            m_data.bid = BookInfo[i].price;
            m_data.bid_vol = BookInfo[i].volume;
            m_data.next_bid = BookInfo[i+1].price;
            m_data.next_bid_vol = BookInfo[i+1].volume;
            break;
          } else break;
        }
      }
      return(true);
    }
  }
  return(false);
}  
//+------------------------------------------------------------------+
//| Expert OnTick function                                           |
//+------------------------------------------------------------------+
void OnTick()
{
  if(GetBook(Symbol(), book_cnt) == true)
  {
    if(book_cnt >= 4)
    {
      Print("Prev Sell: ask = ", m_data.prev_ask, " volume = ",m_data.prev_ask_vol); 
      Print("Sell: ask = ", m_data.ask, " volume = ",m_data.ask_vol);
      Print("Buy: bid = ", m_data.bid, " volume = ",m_data.bid_vol);
      Print("Next Buy: bid = ", m_data.next_bid, " volume = ",m_data.next_bid_vol);
    }  
  }
}
//+------------------------------------------------------------------+
 

Du hast alles durcheinander gebracht.

Ich habe bereits geschrieben, dass es sich bei Trades und Level2 um unterschiedliche Datenabonnements handelt, also um unterschiedliche Event-Handler.
Aus diesem Grund sollten Trades von OnTick und Volume Gangs von OnBook aufgerufen werden.
Sie versuchen, Trades von OnBook-Ereignissen und Gangs von OnTick-Ereignissen aufzurufen. Ich denke, dass OnBook für den Handel schneller sein wird.
Es wird nicht schneller sein, ich denke, es ist eine Täuschung, zwei Event-Handler zu vergleichen, die jeweils für ihren eigenen Datenstrom zuständig sind.
Ich verstehe, dass das alles Experimente sind, aber ohne die Logik zu verstehen, dass es zwei Datenströme gibt (Trades und Level2), werden Sie diese OnTick- und OnBook-Handler endlos verwirren.

Grund der Beschwerde: