Библиотеки: OnTickMulti - страница 4

 
fxsaber #:

Не будет больше тиков с последним известным временем.

Миллисекундный OnTimer гарантирует, что прошли все тики ДО этого таймерного события. Т.е. по всем символам тики актуальны.

Если речь о том, что индикатор-шпион может по каким-то техническим причинам задержать "старый" тик и прислать его после более нового по другому инструменту, то вероятно это может случиться. Иначе не вижу проблем непосредственно в коде.

Не думаю, что таймер что-то гарантирует в большей степени, чтобы прошли все тики ДО нового "события" (отсчета единицы времени). Таймер работает в локальном времени, а таймстемпы в тиках содержат серверное время. Поэтому лучше на таймер не опираться для синхронизации инструментов.

 
Stanislav Korotky #:

Хорошо, для тиков такое приемлемо, ввиду сложности синхронизации, хотя мы можем ввести миллисекундный таймфрейм и подогнать тики по времени.

Но ведь по ценам открытия тоже самое, хотя время открытия по всем символам одинаковое.

И из-за такого поведения ряд систем невозможно нормально тестировать.

 

Демонстрация проблемы.

#include <fxsaber\OnTickMulti\OnTickMulti.mqh> // https://www.mql5.com/ru/code/47647

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

input bool inTimer = false; // false - OnTick, true - OnTimer

ulong TimeMsc = TimeTradeServer() * 1000 + (inTimer && EventSetMillisecondTimer(1));

void PositionOpen()
{
  for (uint i = ArraySize(OnTickMultiObject.Symbols); (bool)i--;)
  {
    const string SymbName = OnTickMultiObject.Symbols[i];
    
    OrderSend(SymbName, OP_BUY, 1, SymbolInfoDouble(SymbName, SYMBOL_ASK), 0, 0, 0);
  }
}

void OnTimer()
{
  if (TimeMsc++ == 1759280400081) // 2025.10.01 01:00:00.081
    PositionOpen();
}

// Мультисимвольный OnTick.
void OnTickMulti( const string &Symb, const uint &Index )
{  
  MqlTick Tick;
  
  if (!inTimer && SymbolInfoTick(Symb, Tick) && (Tick.time_msc == 1759280400081) && // 2025.10.01 01:00:00.081
      !OrdersTotal())
    PositionOpen();
}

На скрине все данные для воспроизведения на MetaQuotes-Demo. Хорошо видно, что через OnTick тики не синхронизированы, а через OnTimer (жутко тормозной) - синхронизированы.

 
fxsaber #:

через OnTick тики не синхронизированы, а через OnTimer (жутко тормозной) - синхронизированы.

Похоже, единственный способ ускорить расчеты в синхронизированном режиме - мат. режим по подобию EAToMath.


Или же заранее записать в файл эти данные одиночного прохода.

#include <fxsaber\OnTickMulti\OnTickMulti.mqh> // https://www.mql5.com/ru/code/47647

// Мультисимвольный OnTick.
void OnTickMulti( const string &Symb, const uint &Index )
{  
  static MqlTick Ticks[];
  static const int Size = ArrayResize(Ticks, ArraySize(OnTickMultiObject.Symbols));  
  
  bool Res = SymbolInfoTick(Symb, Ticks[Index]);

  for (int i = 1; Res && (i < Size); i++)
    Res = (Ticks[i].time_msc == Ticks[i - 1].time_msc);
    
  if (Res)
    ArrayPrint(Ticks);  
}
2025.10.01 01:00:00                    [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2025.10.01 01:00:00   [0] 2025.10.01 01:00:00 1.17345 1.17363 0.0000        0 1759280400081     134       0.00000
2025.10.01 01:00:00   [1] 2025.10.01 01:00:00 1.34417 1.34501 0.0000        0 1759280400081     134       0.00000
2025.10.01 01:00:00   [2] 2025.10.01 01:00:00 0.66103 0.66122 0.0000        0 1759280400081     134       0.00000
2025.10.01 06:07:02                    [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2025.10.01 06:07:02   [0] 2025.10.01 06:07:02 1.17388 1.17390 0.0000        0 1759298822726     134       0.00000
2025.10.01 06:07:02   [1] 2025.10.01 06:07:02 1.34417 1.34422 0.0000        0 1759298822726     130       0.00000
2025.10.01 06:07:02   [2] 2025.10.01 06:07:02 0.65959 0.65967 0.0000        0 1759298822726     134       0.00000
2025.10.01 07:30:23                    [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2025.10.01 07:30:23   [0] 2025.10.01 07:30:23 1.17467 1.17469 0.0000        0 1759303823965       4       0.00000
2025.10.01 07:30:23   [1] 2025.10.01 07:30:23 1.34486 1.34490 0.0000        0 1759303823965     134       0.00000
2025.10.01 07:30:23   [2] 2025.10.01 07:30:23 0.65970 0.65978 0.0000        0 1759303823965       4       0.00000

И в своем советнике использовать данные этого файла для синхронизации в OnTick. Будет работать быстро и правильно.

Подробнее о способах ускорения оптимизации советников в MT5.
Подробнее о способах ускорения оптимизации советников в MT5.
  • 2025.09.02
  • www.mql5.com
Классификация советников. Все советники, запускаемые в Оптимизаторе, делятся на два типа. Торговые. Статистические: "обучение", обработка котировочных данных. Каждый из них тоже делится на два типа
 
fxsaber #:

Демонстрация проблемы.

На скрине все данные для воспроизведения на MetaQuotes-Demo. Хорошо видно, что через OnTick тики не синхронизированы, а через OnTimer (жутко тормозной) - синхронизированы.

Ну так Вы взяли свой код с условием вхождения в сделку по ==. Я выше написал, что условие должно быть на строго >, без равно. Чтобы совершить синхронные сделки по последним ценам известным до 2025.10.01 01:00:00.081 по всем инструментам, Вы должны начать мониторинг тиков до этого времени, т.е. взять в качестве демонстрационной константы, например, >1759280400080. Под каждый алгоритм нужно модифицировать логику - просто подменить один тип обработчика на другой не выйдет.

PS. Я под синхронизацией имею в виду торговлю по последним известным ценам. Для синхронизации по равенству миллисекунд нужны конечно доп.проверки, но вероятность таких ситуаций (совпадение мс тиков разных инструментов) - мала, что означает пропуск потенциальных сигналов. Не уверен, что такая синхронизация имеет практический интерес.

 
Stanislav Korotky #:

Чтобы совершить синхронные сделки по последним ценам известным до 2025.10.01 01:00:00.081 по всем инструментам, Вы должны начать мониторинг тиков до этого времени, т.е. взять в качестве демонстрационной константы, например, >1759280400080.

Готов посмотреть Ваш вариант в коде.
 

Самый простой способ синхронизации - создать множество из времени тиков используемых символов. 

На ходу, в 1 проход сделать синхронизацию сложно.

Сложность в неопределенности отставания. Какой символ будет ведущим неизвестно. 

 
fxsaber #:
Готов посмотреть Ваш вариант в коде.

Для полноценного тесткейса мне бы понять практическую задачу - торгуем только по тикам, у которых совпало время с точностью до миллисекунды?

Для искусственного примера с одной единственной сделкой для заранее известного момента с синхронными тиками по всем инструментам - можно придумывать искусственный оптимальный алгоритм, но зачем?

 
Rorschach #:

Но ведь по ценам открытия тоже самое, хотя время открытия по всем символам одинаковое.

Надо бы уточнить задачу. По ценам открытия, если алгоритм требует наличия баров всех символов, дожидаемся когда iTime(,,0) у всех символов совпадет. Для баров в таком подходе обычно нет логической проблемы, потому что бары (даже M1) редко отсутствуют, а вот для секунд и более мелких отсчетов провалы в синхронизации могут быть частыми. Что в такие моменты делать?

Я полагаю, что на практике в качестве синхронизации следует рассматривать наличие любой цены не старше некоторого заданного таймаута, а не строгое равенство таймстемпов тиков.

 
Stanislav Korotky #:

Надо бы уточнить задачу. По ценам открытия, если алгоритм требует наличия баров всех символов, дожидаемся когда iTime(,,0) у всех символов совпадет. Для баров в таком подходе обычно нет логической проблемы, потому что бары (даже M1) редко отсутствуют

Имееся в виду режим тестера по ценам открытия.

Stanislav Korotky #:
для секунд и более мелких отсчетов провалы в синхронизации могут быть частыми. Что в такие моменты делать?

Подавать последнее известное значение.