Tiki in tempo reale - pagina 19

 
Yuriy Zaytsev:

In alternativa, per evitare la preoccupazione che Symbol() mangi tempo, lasciate che entrambi i gestori si "nutrano" allo stesso modo.

Possiamo sostituire la funzione Symbol() con una variabile predefinita _Symbol

 

Symbol() non ha niente a che fare con questo. L'ora nel registro è corretta.

Il ritardo è nella coda degli eventi o nelle funzioni SymbolInfo.

Ecco di cosa sto parlando.


Quindi, se hai bisogno del vetro, lavora con OnBook. Se non è necessario, lavora in OnTick (senza code e chiamate inutili).

Quello che resta da capire è il modo più veloce per ottenere la storia effettiva dei tick per entrambi i metodi.

Penso che, se è necessario solo l'ultimo tick, SymbolInfo è meglio. Se abbiamo bisogno di una storia senza lacune, allora solo CopyTicks.

 
Andrey Khatimlianskii:

Symbol() non ha niente a che fare con questo. L'ora nel registro è corretta.

Ilritardo è nella coda degli eventi o nelle funzioni SymbolInfo.

Ecco di cosa sto parlando.

Sono d'accordo che Symbol non può masticare molto, ma può dare qualche contributo, e certamente per la purezza del test prendere tempoprima di qualsiasi chiamata.

Per quanto riguarda la coda - sono curioso su questo punto - quanto OnBook può rimanere indietro rispetto allo stesso OnTick in condizioni ideali. Cioè quando solo questo Symbol è sottoscritto, il terminale non è occupato con altro, ecc.

Finora non sono d'accordo che si tratti solo della coda, perché se i gestori non stanno facendo nulla, allora la coda di 5-6 OnBooks non dovrebbe consumare più dell'operazione di controllo del Symbol.

Dovremmo rimuovere tutti i controlli e vedere cosa cadetra OnTick e OnBook per lo stesso tick.

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

ap: è diventato chiaro che il vorace Print non permette di controllare in modo pulito, perché la coda sarà lunga a causa del Print)

Devo mettere il tempo senza la stampa nell'array ulong, e poi già una volta ogni 5 minuti per emettere tutto su Prints, lo codificherò più tardi.

 

Ho voluto mettere il codice in prova prima

//---
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;
  }
//---

Ma non posso aprire il conto demo opener per qualcosa. Il tempo è probabilmente fuori uso, o c'è qualcos'altro che non va?



Poi il codice per dopilizzare per confrontare esattamente da un tick di evento.

 
Aleksey Mavrin:

Ho voluto mettere il codice in prova prima

Ma non posso aprire il conto demo opener per qualcosa. Il tempo è probabilmente fuori uso, o c'è qualcos'altro che non va?



Poi il codice per dopilizzare per confrontare esattamente da un tick di evento.

Devi aprirlo sul loro sito web. Poi inviano un codice all'ufficio postale.

 
Andrey Khatimlianskii:


Penso che se è necessario solo l'ultimo tick, SymbolInfo è meglio. Se avete bisogno della storia senza salti, allora solo CopyTicks.

La questione è che il mercato urgente (FORTS) anche su strumenti "altamente liquidi" è molto debole,

Significa che al giusto prezzo è possibile acquistareun numero moltolimitato di contratti, quindi non abbiamo bisogno solo del prezzo,

Il volume dei contratti a questo prezzo è molto importante.


E SymbolInfo non dà il volume di questo prezzo.

A causa di questo, abbiamo bisogno di usareMarketBookGet() che fornisce sia il prezzo che il volume dell'intero libro.

Puoi usareMarketBookGet() solo in coppia con MarketBookAdd, ottenendo i cambiamenti della tazza del mercato.

in OnBookEvent. Puoi aggiungere il mercato (MarketBookAdd) e usareMarketBookGet() da OnTck(),

ma in questo caso, altri slippage di mercato(ordini pendenti non al miglior prezzo) verranno persi.

È vero, il mercato può giocare con questo e costruire lo slittamento del mercato dai tick in arrivo, ma è davvero necessario?

Aggiunto da

E non sono d'accordo sul fatto che possiamo ottenere i tick dalla storia quando OnTck() è attivato.

Ricordando il tempo dell'ultimo tick, quando OnTck() è attivato possiamo ottenere i tick

in tempo reale è arrivato un nuovo tick - attivato OnTck() lo leggiamo immediatamente, cioè non è storia.

 
Andrey Khatimlianskii:

Resta da scoprire il modo più veloce per ottenere la cronologia effettiva dei tick per entrambi i metodi.


Il mio OnTick() è lo stesso o leggermente più veloce di OnBook (ma OnBook ha enormi ritardi).

Stavo testando la velocità delle funzioni(microsecondi)

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

Il più veloce èSymbolInfoTick, ma questa funzione non mette il volume nel tick!

Vedere per aiuto.

tick

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

Cioè solo tempo e prezzo, ma nessun volume :(

 

Per gli strumenti scambiati in borsa (specialmente i FORTS) non è solo il prezzo che conta,

ma anche il volume dei contratti a quel prezzo!

 

Provato a prendere il bicchiere da OnTick() - enormi ritardi chiaramente visibili "a occhio"!

//+------------------------------------------------------------------+
//|                                                   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);
    }  
  }
}
//+------------------------------------------------------------------+
 

Hai fatto un gran casino.

Ho scritto prima che trade e level2 sono sottoscrizioni di dati diverse, quindi sono gestori di eventi diversi.
Ecco perché i trade dovrebbero essere chiamati da OnTick, e le bande di volume da OnBook.
Stai cercando di chiamare gli scambi da eventi OnBook e le bande da OnTick. Pensando che OnBook sarà più veloce per gli scambi.
Non sarà più veloce, penso che sia un'illusione confrontare due gestori di eventi, ognuno dedicato al proprio flusso di dati.
Capisco che sono tutti esperimenti, ma senza capire la logica che ci sono due flussi di dati (trades e Level2), confonderai all'infinito questi gestori OnTick e OnBook.