Тики в реальном времени - страница 3

 
Aleksey Mavrin:

Честно говоря не понял, что именно вы хотели по этой ссылке чтобы я прочитал про ECN, тем более такого чего не было известно ранее )

Я хотел? Это вы что то хотели. )))

Вы не понимаете разницу между форекс и биржей, вот и дал вам ссылку.

Пожалуйста, не засоряйте биржевой раздел форексом.

 
Sergey Chalyshev:

Я хотел? Это вы что то хотели. )))

Вы не понимаете разницу между форекс и биржей, вот и дал вам ссылку.

Пожалуйста, не засоряйте биржевой раздел форексом.

Да я бы очень хотел чтобы люди умели понятно изъясняться, но это недостижимо, довольствуемся тем что есть. 

Вы пожалуйста тоже не указывайте мне что делать, ок. И вы возможно тоже чего-то не понимаете, не думали? Взять хотя бы для чего вы запостили ссылку)

и ещё - Форекс здесь упоминаю в первую очередь не я, я вступаю в уже начатую дискуссию. Это во первых.

Во 2-х - кто-то разве запретил в биржевом разделе обсуждать сравнение разных рынков с биржевым?

и в 3-их - Давайте прекратим препинания аля лыжники vs сноубордитсы, или вы против?

 

Небольшие итоги с экспериментами по анализу тиков.

1. Обработчик OnTick пропускает значительное количество тиков.
Поэтому, если требуется анализировать ленту сделок через пришедший тик, то смысла нет.
При таком подходе результаты работы алгоритма в тестере и реальные результаты торговли будут отличаться.

Как вариант, можно анализировать ленту сделок за выбранный период или определенное количество последних сделок посредством получения исторических тиков через функции CopyTicks() или CopyTicksRange().
В этом случае результаты тестирования алгоритма в тестере и реальные результаты торговли совпадают.
Из минусов понижение производительности алгоритма.

2. Событий OnBookEvent значительно больше, чем исторических тиков, это и понятно, так как помимо тиков это событие обрабатывает и изменение стакана.
Поэтому может показаться, что посредством этого события можно анализировать все приходящие тики.
Однако это не так, не все сделки проходят через стакан.
Рыночные биржевые ордера могут не проходить через стакан, при этом в ленте сделок они будут отражаться.
Причина этому заключается в том, что стакан это по факту книга заявок, которые ожидают своего исполнения при выполнении требуемых условий.

Пример - Сделка не прошла через обработчик OnEventBook (а это целых 5 тиков).

MT5

Опять же решение, как и в первом варианте, это анализ исторических тиков.
Минус такого решения - невозможность тестирования в тестере. События изменения стакана в тестере не генерируются. 

3. Про недокументированный 8 бит в флаге тика ответа так и не было. Задавал этот же вопрос и в другой ветке форума. 

Для себя я уже определился со способом анализа ленты сделок - через историю, пусть и с понижением производительности.
Это позволяет получать достоверные результаты при тестировании алгоритма в тестере.

Всем спасибо за идеи и обсуждения.

 
Vladimir Mikhailov:

Небольшие итоги с экспериментами по анализу тиков.

1. Обработчик OnTick пропускает значительное количество тиков.
Поэтому, если требуется анализировать ленту сделок через пришедший тик, то смысла нет.
При таком подходе результаты работы алгоритма в тестере и реальные результаты торговли будут отличаться.

Как вариант, можно анализировать ленту сделок за выбранный период или определенное количество последних сделок посредством получения исторических тиков через функции CopyTicks() или CopyTicksRange().
В этом случае результаты тестирования алгоритма в тестере и реальные результаты торговли совпадают.
Из минусов понижение производительности алгоритма.

2. Событий OnBookEvent значите.....
Однако это не так, не все сделки проходят через стакан.

Пример - Сделка не прошла через обработчик OnEventBook (а это целых 5 тиков).

3. Про недокументированный 8 бит в флаге тика ответа так и не было. Задавал этот же вопрос и в другой ветке форума. 


2. Выложите код Вашего сборщика тиков (уверен что Вы делаете что-то не правильно)

3. В принте сделайте EnumToString(flags) 

 
prostotrader:

2. Выложите код Вашего сборщика тиков (уверен что Вы делаете что-то не правильно)

3. В принте сделайте EnumToString(flags) 

Код обычный, минимальный. Событие OnBookEvent получает последний известный тик и выводит на печать.

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

По третьему пункту - флаги тика не являются перечислением, поэтому функция EnumToString к ним не применима.

 
Vladimir Mikhailov:

Код обычный, минимальный. Событие OnBookEvent получает последний известный тик и выводит на печать.

По третьему пункту - флаги тика не являются перечислением, поэтому функция EnumToString к ним не применима.

Вы копируете 1 тик и хотите, чтобы пропусков не было :) 

OnBookEvent() срабатывает на любое изменение стакана, но в один момент времени

может быть несколько тиков. В терминал приходит не один тик, а ПАКЕТ тиков.

В индикаторе, который я вам порекомендовал (Лента всех сделок) есть описание

на русском языке. Не поленитесь, прочтите.

 
prostotrader:

Вы копируете 1 тик и хотите, чтобы пропусков не было :) 

OnBookEvent() срабатывает на любое изменение стакана, но в один момент времени

может быть несколько тиков. В терминал приходит не один тик, а ПАКЕТ тиков.

В индикаторе, который я вам порекомендовал (Лента всех сделок) есть описание

на русском языке. Не поленитесь, прочтите.

Смотреть более одного тика - это обращение в историю.

 
Vladimir Mikhailov:

Смотреть более одного тика - это обращение в историю.

Вы совершенно не понимаете как работает терминал.

Прочтите комментарии в индикаторе!!!

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

Добавлено

В примере, указанном выше, "ловятся" не все тики, т.к во вновь пришедшем пакете тиков

могут быть тики с предыдущим временем.

Внимательно изучите код "Лента всех сделок" (он с комментариями).

 

Если Вам трудно (или лень) разбираться в коде индикатора, то

посмотрите более простой код правильного сборщика всех тиков в реальном времени

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

посмотрите более простой код правильного сборщика всех тиков в реальном времени

Зачем их собирать "в реальном времени", если все равно используется CopyTicks?

В любой нужный момент можно скопировать тики на нужную глубину.

Причина обращения: