MT5 и скорость в боевом исполнении - страница 60

 
Anton:

Код теста:

Этот код показывает, что автор не понимает проблемы.

Доказывайте.
// Классический SYMBOL_BID vs Альтернативный SYMBOL_BID.
// Запускать только на демо-счетах.

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

#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

bool GetPosition( const int Type = OP_BUY )
{
  bool Res = false;
  
  for (int i = PositionsTotal() - 1; (i >= 0) && !Res; i--)
    Res = PositionGetTicket(i) && (PositionGetInteger(POSITION_TYPE) == Type) && 
                                  (PositionGetString(POSITION_SYMBOL) == _Symbol);
                                  
  return(Res);
}

// Альтернативный способ получения Bid-цены текущего символа.
// Запускать только на демо-счетах.
double GetBid()
{
  static const TICKET_TYPE Ticket = GetPosition() ? PositionGetInteger(POSITION_TICKET) : OrderSend(_Symbol, OP_BUY, 0.1, Ask, 0, 0, 0);
  
  return(PositionSelectByTicket(Ticket) ? PositionGetDouble(POSITION_PRICE_CURRENT) : 0);
}

#define TOSTRING(A) ", "#A + " = " + (string)(A)

#define MACROS(A, B)                                              \
  const ulong StartTime##A = GetMicrosecondCount();               \
  const double A = B;                                             \
  const ulong Interval##A = GetMicrosecondCount() - StartTime##A; \
                                                                  \
  if (Interval##A > 100)                                          \
    Time##A += (long)Interval##A;  

long TimeBid1 = 0; // Суммарное время на длительный SYMBOL_BID
long TimeBid2 = 0; // Суммарное время на длительный GetBid()

const bool Init = EventSetTimer(10) && GetBid(); // Будем выводить статистику каждый 10 секунд.

void OnTimer()
{
  // На сколько отстает один вариант от другого по времени выполнения.
  Alert(TOSTRING(TimeBid1 - TimeBid2) + " mcs." + TOSTRING(TimeBid1) + TOSTRING(TimeBid2));
}

void OnTick()
{  
  const uint StartTime = GetTickCount();
  
//  return;
  
  while (!IsStopped() && (GetTickCount() - StartTime < 10000))
  {
    MACROS(Bid1, SymbolInfoDouble(_Symbol, SYMBOL_BID))
    MACROS(Bid2, GetBid())
      
//    if (Bid1 != Bid2)
//      Alert("Error!" + TOSTRING(Bid1) + TOSTRING(Bid2));
    
//    Sleep(0); // Специально убрал.
  }
}

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


Загрузил 6/8 Агентов. И запустил этот советник на шести чартах (разные символы) на демо-сервере RannForex-Server. Результат.

2020.10.26 16:10:40.596 Test9 (EURNZD,H1)       Alert: , TimeBid1-TimeBid2 = 236507295 mcs., TimeBid1 = 246491044, TimeBid2 = 9983749
2020.10.26 16:10:42.596 Test9 (CAC40,H1)        Alert: , TimeBid1-TimeBid2 = 235249710 mcs., TimeBid1 = 241768964, TimeBid2 = 6519254
2020.10.26 16:10:44.267 Test9 (DAX30,H1)        Alert: , TimeBid1-TimeBid2 = 243552816 mcs., TimeBid1 = 253424672, TimeBid2 = 9871856
2020.10.26 16:10:44.382 Test9 (DJI30,H1)        Alert: , TimeBid1-TimeBid2 = 265778370 mcs., TimeBid1 = 272279313, TimeBid2 = 6500943
2020.10.26 16:10:44.623 Test9 (ASX200,H1)       Alert: , TimeBid1-TimeBid2 = 210921561 mcs., TimeBid1 = 219901110, TimeBid2 = 8979549
2020.10.26 16:10:44.732 Test9 (FTSE100,H1)      Alert: , TimeBid1-TimeBid2 = 226824499 mcs., TimeBid1 = 235809635, TimeBid2 = 8985136

Имеем полное доказательство того, что суммарное время (TimeBid1) выполнения SYMBOL_BID катастрофически проигрывает (TimeBid2) альтернативному получению Bid-цены.


Такое костыльное решение получения текущих цен уделывает по производительности самую главную функцию MQL5. Согласны с этим доказательством?


Жаль, раньше не пришел в голову этот красноречивый костыль.


ЗЫ Для работы советника нужно разрешить алготорговлю. Поэтому только на демо-счетах запускать.

 
fxsaber:

Этот советник получает Bid-цену текущего символа двумя способами.

POSITION_PRICE_CURRENT снепшотится?

Тогда что с чем сравниваем? Получение последней сохраненной (когда?) цены с получением последней известной терминалу цены?

Ну и про 6 из 8 ядер сказали прямо. Зачем такие тесты?

 
fxsaber:

Этот код показывает, что автор не понимает проблемы.

Ваше утверждение доказывает, что вы не хотите видеть очевидного.

Этот код показывает, что нет никаких "тормозов SymbolInfoTick".

На более-менее современном железе время выполнения SymbolInfoTick не превышает 1 МИКРОсекунды.

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

Загрузил 6/8 Агентов. И запустил этот советник на шести чартах (разные символы) на демо-сервере RannForex-Server. Результат.

Имеем полное доказательство того, что суммарное время (TimeBid1) выполнения SYMBOL_BID катастрофически проигрывает (TimeBid2) альтернативному получению Bid-цены.

Такое костыльное решение получения текущих цен уделывает по производительности самую главную функцию MQL5. Согласны с этим доказательством?

Жаль, раньше не пришел в голову этот красноречивый костыль.

ЗЫ Для работы советника нужно разрешить алготорговлю. Поэтому только на демо-счетах запускать.

Нет, это не доказательство. Абсолютно грязный тест, который невозможно воспринимать серьезно.

Подробно даже разбирать не буду, достаточно того, что вы опять делаете замер времени единичного колла через GetMicrosecondCount(), и опять на фоне "Загрузил 6/8 Агентов" на 4 ядерном цпу.

Я уже наглядно показывал выше, что так можно и в выполнении "x++" воображаемые тормоза найти.

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

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

В последних билдах она лишена и этого недостатка.

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

"Давайте спорить о вкусе устриц и кокосовых орехов с теми, кто их ел".

 
Andrey Khatimlianskii:

POSITION_PRICE_CURRENT снепшотится?

Нет. MT4Orders используется только для выставления позиции.

Тогда что с чем сравниваем? Получение последней сохраненной (когда?) цены с получением последней известной терминалу цены?

Сравниваем длительность получения цены из Обзора рынка и позиции. Цены, конечно, совпадают.

Ну и про 6 из 8 ядер сказали прямо. Зачем такие тесты?

Только для того, чтобы даже слепому было видно, что проблема есть. Ну это же бред, когда Bid-цена через позицию не тормозит, а SymbolInfoTick - лагает по-страшному.


Чувствую, что без поддержки форумчан эту MQ-стену не пробить. Код короткий, профи должны быстро въехать. Нет там изъянов. Четко показано, что цены через позиции получаются значительно быстрее, чем из Обзора рынка. Как MQ не видят очевидного - не понимаю.

 
Anton:

Ваше утверждение доказывает, что вы не хотите видеть очевидного.

Этот код показывает, что нет никаких "тормозов SymbolInfoTick".

На более-менее современном железе время выполнения SymbolInfoTick не превышает 1 МИКРОсекунды.

Нет, это не доказательство. Абсолютно грязный тест, который невозможно воспринимать серьезно.

Подробно даже разбирать не буду, достаточно того, что вы опять делаете замер времени единичного колла через GetMicrosecondCount(), и опять на фоне "Загрузил 6/8 Агентов" на 4 ядерном цпу.

Я уже наглядно показывал выше, что так можно и в выполнении "x++" воображаемые тормоза найти.

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

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

В последних билдах она лишена и этого недостатка.

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

"Давайте спорить о вкусе устриц и кокосовых орехов с теми, кто их ел".

Вы не смотрели код. Не верю в некомпетентность.

  if (Interval##A > 100)                                          \
    Time##A += (long)Interval##A;

Это условие, при котором только если выполнение длилось больше 100 мкс, оно учитывается. Если считаете это малым значением, сделайте на порядок больше. Эффект тот же самый.

Обе сравниваемые функции находятся в абсолютно равных условиях. Одна по итогу тормозит, другая - нет. Посмотрите еще раз внимательно, что замеряет код.


На данный момент замена в боевых советниках SymbolInfoTick на предложенный костыль убирает почти все тормоза, связанные с получением текущих цен. Это бредово, но, к сожалению, это так.


ЗЫ Обращаю внимание на while  в OnTick. Он специально сделан, чтобы поймать тики, которые пришли после того, что акцептировал OnTick. Код не на ровном месте писался. Это не абсолютно искусственный for-цикл с измерением средней температуры по больнице в идеальных условиях.

 
fxsaber:

Чувствую, что без поддержки форумчан эту MQ-стену не пробить. Код короткий, профи должны быстро въехать. Нет там изъянов. Четко показано, что цены через позиции получаются значительно быстрее, чем из Обзора рынка. Как MQ не видят очевидного - не понимаю.

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

прикольный хак получать цену из позиции, не допетрил бы и даже бы не догадался никогда что может быть такая разница
 
fxsaber:

Только для того, чтобы даже слепому было видно, что проблема есть. Ну это же бред, когда Bid-цена через позицию не тормозит, а SymbolInfoTick - лагает по-страшному.

попробуйте протестировать SymbolInfoTick когда в обзоре рынка один символ и когда несколько десятков символов, но запрашивайте один инструмент - как в Вашем примере

высока вероятность, что с сервера идет сжатый трафик и эти периодические тормоза SymbolInfoTick появляются когда происходит распаковка данных

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


ну и соответственно, если это подтвердится, то переделывать всю архитектуру.... сомнительное удовольствие

 
Igor Makanu:

попробуйте протестировать SymbolInfoTick когда в обзоре рынка один символ и когда несколько десятков символов, но запрашивайте один инструмент - как в Вашем примере

высока вероятность, что с сервера идет сжатый трафик и эти периодические тормоза SymbolInfoTick появляются когда происходит распаковка данных

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

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

 
fxsaber:

Обе сравниваемые функции находятся в абсолютно равных условиях.

Как минимум, GetBid вызывается после SymbolInfoDouble. Если поменять местами, результат не изменится?

Мне что-то подсказывает, что POSITION_PRICE_CURRENT берет сохраненную цену, а не пытается получить свежую.

Ну и повторюсь, не вижу смысла в тестировании на 80% загруженном процессоре. Тестируем производительность проца и распределение ресурсов виндой, а не нужные функции.

 
Andrey Khatimlianskii:

Как минимум, GetBid вызывается после SymbolInfoDouble. Если поменять местами, результат не изменится?

Экспериментировал с этим еще до публикации. Нет влияет на результат.

Мне что-то подсказывает, что POSITION_PRICE_CURRENT берет сохраненную цену, а не пытается получить свежую.

В том и дело, что MQL-прогам нужна последняя цена, пришедная в Терминал, а не что-то другое. Когда приходит тик в Терминал, он автоматически обновляет все таблицы с позициями/ордрерами.

Ну и повторюсь, не вижу смысла в тестировании на 80% загруженном процессоре. Тестируем производительность проца и распределение ресурсов виндой, а не нужные функции.

Главное условие - идентичность окружения для обеих функций. Загрузка ЦПУ - более яркий фактор для заметности расхождений.

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


Повторюсь, идентичность условий тестирования соблюдена для обеих функций. Факт.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

MT5 и скорость в боевом исполнении

fxsaber, 2020.10.26 17:53

На данный момент замена в боевых советниках SymbolInfoTick на предложенный костыль убирает почти все тормоза, связанные с получением текущих цен. Это бредово, но, к сожалению, это так.

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