Tiki in real time - page 3

 
Aleksey Mavrin:

I honestly did not understand what you wanted me to read in this link about ECN, especially something that was not known before)

I did? It was you who wanted something. )))

You do not understand the difference between the Forex market and the exchange, so I gave you the link.

Please do not litter the exchange section with forex.

 
Sergey Chalyshev:

Did I want to? You were the one who wanted something. )))

You don't understand the difference between forex and exchange, so I gave you the link.

Please do not litter the exchange section with forex.

Yes, I would really like people to be able to communicate clearly, but it is unattainable, so we have to content ourselves with what we have.

And you may not understand something either, have you thought? Take for example why you posted the link)

And one more thing - I am not the one who mentioned Forex in the first place, I am stepping into a discussion that has already begun. First of all.

B 2 - Did someone forbid a discussion in the exchange section to compare different markets with the stock market?

And 3 - Let's stop punctuating ala skiers vs snowboarders, or are you against it?

 

A small summary with experiments on tic analysis.

1. the OnTick handler skips a significant number of ticks.
So, if you want to analyze a strip of trades through a incoming tick, it makes no sense.
With this approach, the results of the algorithm in the tester and the real trading results will be different.

As an alternative, you can analyze the strip of deals for a selected period or a certain amount of last deals by obtaining the history ticks using the CopyTicks() or CopyTicksRange() functions.
In this case, the results of testing the algorithm in the tester and the real trade results are the same.
The disadvantages are lower performance of the algorithm.

2. The number of events on the OnBookEvent is much larger than the number of historical ticks, which is understandable, because in addition to ticks this event processes the change of ticks.
So it may seem that all incoming ticks can be analysed using this event.
However, this is not the case, not all trades go through the ticks.
Market orders may not pass through the slider, but they will be reflected in the trades feed.
The reason for this is that the market slider is in fact a book of orders, which are waiting for execution if the required conditions are met.

Example - A trade did not go through the OnEventBook handler (which is as much as 5 ticks).

MT5

Again the solution, as in the first variant, is the analysis of historical ticks.
Minus of this solution is impossibility of testing in the tester. Events of change of the tick in the tester are not generated.

3. The undocumented 8 bits in the tick flag was never answered. I asked the same question in another forum thread.

I have already decided on the way of analysing the trades' feed - through history, though with reduced productivity.
This allows me to get reliable results when testing the algorithm in the tester.

Thank you all for ideas and discussions.

 
Vladimir Mikhailov:

A small summary with experiments on tic analysis.

1. The OnTick handler skips a significant number of ticks.
So, if you want to analyze a strip of trades through a incoming tick, it makes no sense.
With this approach, the results of the algorithm in the tester and the real trading results will be different.

As an alternative, you can analyze the strip of deals for a selected period or a certain amount of last deals by obtaining the history ticks using the CopyTicks() or CopyTicksRange() functions.
In this case, the results of testing the algorithm in the tester and the real trade results are the same.
The disadvantages are lower performance of the algorithm.

2. The events of OnBookEvent are significant.....
But this is not true, not all deals go through the book.

Example - A trade didn't go through the OnEventBook handler (and it's as much as 5 ticks).

3. The undocumented 8 bits in the tick flag was never answered. I asked the same question in another forum thread.


2. Please post your code of tick builder (I'm sure you are doing something wrong).

3. In the printer, do the EnumToString(flags)

 
prostotrader:

2. Post your tick builder code (I'm sure you're doing something wrong)

3. In printer do EnumToString(flags)

The code is the usual, minimal one. The OnBookEvent gets the last known tick and prints it.

//+------------------------------------------------------------------+
//|                                               TicksCollector.mq5 |
//|                               Copyright 2020, Vladimir Mikhailov |
//|                                                mikh.vl@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, Vladimir Mikhailov"
#property link      "mikh.vl@gmail.com"
#property version   "1.00"
MqlTick tick[1];
int counter=0;
string type;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   MarketBookAdd(_Symbol);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   MarketBookRelease(_Symbol);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnBookEvent(const string&  symbol)
  {
   CopyTicks(_Symbol,tick,COPY_TICKS_ALL,0,1);
   counter++;
   if((tick[0].flags&TICK_FLAG_BID)==TICK_FLAG_BID || (tick[0].flags&TICK_FLAG_ASK)==TICK_FLAG_ASK)
      {
       printf("Symbol: %s; tick #: %d; flags: %d; Time: %s.%03d; Ask: %s; Bid: %s", _Symbol, counter, tick[0].flags, TimeToString(tick[0].time,TIME_MINUTES|TIME_SECONDS),tick[0].time_msc%1000, DoubleToString(tick[0].ask,_Digits), DoubleToString(tick[0].bid,_Digits));
      }
   else if((tick[0].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY || (tick[0].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL)
      {
       type=(tick[0].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY? "Buy": (tick[0].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL? "Sell": "";
       printf("Symbol: %s; tick #: %d; flags: %d; Time: %s.%03d; Volume: %.0f; Type: %s; Last: %s", _Symbol, counter, tick[0].flags, TimeToString(tick[0].time,TIME_MINUTES|TIME_SECONDS),tick[0].time_msc%1000, tick[0].volume_real, type, DoubleToString(tick[0].last,_Digits));
      }  
  }
//+------------------------------------------------------------------+

On the third point - tick flags are not an enumeration, so the EnumToString function is not applicable to them.

 
Vladimir Mikhailov:

The code is plain, minimal. The OnBookEvent event gets the last known tick and prints it out.

On the third point - tick flags are not an enumeration, so the EnumToString function is not applicable to them.

You copy 1 tick and want to have no skips:)

OnBookEvent() is triggered by any change in the tick, but at one point in time

there may be several ticks. The terminal receives not one tick, but a PACKAGE of ticks.

The indicator I recommended (Tape of all deals) has a description

in Russian. Don't be lazy, read it.

 
prostotrader:

You copy 1 tick and want no skips:)

OnBookEvent() is triggered by any change to the glass, but at one point in time

there can be several ticks. The terminal receives not one tick, but a PACKAGE of ticks.

The indicator I recommended (Tape of all deals) has a description

in Russian. Do not be lazy to read it.

Watching more than one tick is a reversal of history.

 
Vladimir Mikhailov:

Watching more than one tick is an appeal to history.

You don't understand at all how the terminal works.

Read the comments in the indicator!!!

//+------------------------------------------------------------------+
//|                                                   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;
MqlTick ticks[];
ulong last_time;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
    is_book = MarketBookAdd(Symbol());
    int result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, 0, 1);
    if(result > 0)
    {
      last_time = ticks[0].time_msc;
    }  
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
    if(is_book == true) MarketBookRelease(Symbol());
   
  }
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
    if(Symbol() == symbol)
    {
       int result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0);
       if(result > 0)
       {
         for(int i= 0; i<result; i++)
         {
           if((ticks[i].flags&TICK_FLAG_ASK)==TICK_FLAG_ASK) Print("Tick is ", "TICK_FLAG_ASK"); else
           if((ticks[i].flags&TICK_FLAG_BID)==TICK_FLAG_BID) Print("Tick is ", "TICK_FLAG_BID"); else
           if((ticks[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) Print("Tick is ", "TICK_FLAG_BUY"); else
           if((ticks[i].flags&TICK_FLAG_LAST)==TICK_FLAG_LAST) Print("Tick is ", "TICK_FLAG_LAST"); else
           if((ticks[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL) Print("Tick is ", "TICK_FLAG_SELL"); else
           if((ticks[i].flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME) Print("Tick is ", "TICK_FLAG_VOLUME"); else
           Print("Unknown flag is ", ticks[i].flags);
         }
         last_time = ticks[0].time_msc + 1;
       }
     
    }
   
  }
//+------------------------------------------------------------------+
2020.01.29 10:51:42.077 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_ASK
2020.01.29 10:51:42.077 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_ASK
2020.01.29 10:51:42.077 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_BID
2020.01.29 10:51:42.121 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_BID
2020.01.29 10:51:42.194 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_BID
2020.01.29 10:51:50.903 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_BID
2020.01.29 10:51:52.235 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_BID
2020.01.29 10:51:52.399 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_BID
2020.01.29 10:52:05.174 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_BID
2020.01.29 10:52:24.630 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_BID
2020.01.29 10:52:24.630 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_LAST
2020.01.29 10:52:28.027 Ticks_test (GOLD-3.20,M1)       Tick is TICK_FLAG_LAST

Added

In the example above, not all ticks are "caught" as the newly arrived tick packet

may contain ticks with a previous time.

Carefully study the code "Ribbon of all trades" (it is with comments).

 

If you find it difficult (or lazy) to understand the indicator code, then

see the simpler code of a proper real-time collector of all ticks

//+------------------------------------------------------------------+
//|                                                   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;
MqlTick ticks[];
ulong last_time, mem_time;
bool is_first;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
    is_first = false;
    is_book = MarketBookAdd(Symbol());
    int result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, 0, 1);
    if(result > 0)
    {
      last_time = ticks[0].time_msc;
      is_first = true;
    }
    else
    {
      Alert("No start time!");
      return(INIT_FAILED);
    }   
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
    if(is_book == true) MarketBookRelease(Symbol());
   
  }
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
    if(Symbol() == symbol)
    {
      int result;
      if(is_first == true)
      {
        Print("First packet of ticks:");
        result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0);
        if(result > 0)
       {
         for(int i= 0; i<result; i++)
         {
           if((ticks[i].flags&TICK_FLAG_ASK)==TICK_FLAG_ASK) Print("Tick is ", "TICK_FLAG_ASK"); else
           if((ticks[i].flags&TICK_FLAG_BID)==TICK_FLAG_BID) Print("Tick is ", "TICK_FLAG_BID"); else
           if((ticks[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) Print("Tick is ", "TICK_FLAG_BUY"); else
           if((ticks[i].flags&TICK_FLAG_LAST)==TICK_FLAG_LAST) Print("Tick is ", "TICK_FLAG_LAST"); else
           if((ticks[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL) Print("Tick is ", "TICK_FLAG_SELL"); else
           if((ticks[i].flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME) Print("Tick is ", "TICK_FLAG_VOLUME"); else
           Print("Unknown flag is ", ticks[i].flags);
         }
         is_first = false;
         mem_time = last_time;
         last_time = ticks[0].time_msc + 1;
       } 
      }
      else
      {
        result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, mem_time, 0);
        if(result > 0)
        {
          for(int i= 0; i<result; i++)
          {
            if(ticks[i].time_msc == mem_time)
            {
              Print("Tick with old time:");
              if((ticks[i].flags&TICK_FLAG_ASK)==TICK_FLAG_ASK) Print("Tick is ", "TICK_FLAG_ASK"); else
              if((ticks[i].flags&TICK_FLAG_BID)==TICK_FLAG_BID) Print("Tick is ", "TICK_FLAG_BID"); else
              if((ticks[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) Print("Tick is ", "TICK_FLAG_BUY"); else
              if((ticks[i].flags&TICK_FLAG_LAST)==TICK_FLAG_LAST) Print("Tick is ", "TICK_FLAG_LAST"); else
              if((ticks[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL) Print("Tick is ", "TICK_FLAG_SELL"); else
              if((ticks[i].flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME) Print("Tick is ", "TICK_FLAG_VOLUME"); else
              Print("Unknown flag is ", ticks[i].flags);
            }
          }
        }
        result = CopyTicks(Symbol(), ticks, COPY_TICKS_ALL, last_time, 0);
        if(result > 0)
        {
          Print("Ticks with new time:");
          for(int i= 0; i<result; i++)
          {
            if((ticks[i].flags&TICK_FLAG_ASK)==TICK_FLAG_ASK) Print("Tick is ", "TICK_FLAG_ASK"); else
            if((ticks[i].flags&TICK_FLAG_BID)==TICK_FLAG_BID) Print("Tick is ", "TICK_FLAG_BID"); else
            if((ticks[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) Print("Tick is ", "TICK_FLAG_BUY"); else
            if((ticks[i].flags&TICK_FLAG_LAST)==TICK_FLAG_LAST) Print("Tick is ", "TICK_FLAG_LAST"); else
            if((ticks[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL) Print("Tick is ", "TICK_FLAG_SELL"); else
            if((ticks[i].flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME) Print("Tick is ", "TICK_FLAG_VOLUME"); else
            Print("Unknown flag is ", ticks[i].flags);
          }
          mem_time = last_time;
          last_time = ticks[0].time_msc + 1;
        }
      }
    }
 }
//+------------------------------------------------------------------+
 
prostotrader:

see simpler code for a proper real-time collector of all ticks

Why collect them "in real time" if CopyTicks is used anyway?

You can copy the ticks to the right depth at any time you want.