Ошибки, баги, вопросы - страница 2962

 
fxsaber:

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

Очень сложное решение выйдет.

Два индикатора и советник на одном графике?

 
fxsaber:

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

Очень сложное решение выйдет.

Для синхронизации уже давно придумана функция GlobalVariableSetOnCondition
Документация по MQL5: Глобальные переменные терминала / GlobalVariableSetOnCondition
Документация по MQL5: Глобальные переменные терминала / GlobalVariableSetOnCondition
  • www.mql5.com
GlobalVariableSetOnCondition - Глобальные переменные терминала - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Slava:
Для синхронизации уже давно придумана функция GlobalVariableSetOnCondition

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

 
fxsaber:

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

Очень сложное решение выйдет.

зачем им синхронизироваться? это за них сделает user32.dll.
Им главное правильно пронумероваться, чтобы каждый имел уникальный номер и этот номер был индексом массива данных. 
Это можно в крайнем случае сделать в ручную. А можно и автоматом. Кстати я недавно что-то подобное публиковал в КБ (Indicator Сopies), правда для одного окна, но не сложно переделать под весь терминал.
А чем не нравятся ресурсы? По-моему оптимально в границах одного терминала. В том варианте, который я предлагаю через user32.dll (реализовал этот вариант лет 10 назад, когда по-молодости баловался арбитражем), время доступа и парсинга данных окого 50 микросекунд (думаю, что можно убыстрить в 1.5-2 раза). Неужели с ресурсами медленее?

 
Nikolai Semko:

зачем им синхронизироваться? это за них сделает user32.dll.

Попробуйте написать. Возможно, Вы не до конца поняли задачу.

А чем не нравятся ресурсы? По-моему оптимально в границах одного терминала. В том варианте, который я предлагаю через user32.dll (реализовал этот вариант лет 10 назад, когда по-молодости баловался арбитражем), время доступа и парсинга данных окого 50 микросекунд (думаю, что можно убыстрить в 1.5-2 раза). Неужели с ресурсами медленее?

100 микросекунд на чтение уходит на домашней машине в идеальных условиях. Советник на одном тике может вызвать чтение сотню раз. Медленно выходит.

В идеальных условиях GlobalVariableGet выполняется за 10 мкс. Но это не показатель, т.к. в новых для меня боевых условиях это ужасный тормоз.

 
fxsaber:

Это HistoryTicks - ловля всех тиков для советников. Поэтому EventChartCustom не подходит, там своя очередь. С буфером аналогично.

У меня работает на EventChartCustom. 99.8% тиков поступают в течении 0.15 мс

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

EventChartCustom => indicator is too slow

Andrey Khatimlianskii, 2019.12.12 09:27

Вот статистика за 9 часов работы на 5 инструментах:

Windows 8.1 (build 9600) x64, IE 11, UAC, Intel Core i5-3570  @ 3.40GHz, Memory: 6979 / 16346 Mb, Disk: 341 / 499 Gb, GMT+2
[USDCHF]: 22784 of 22833 (99.8 %) ticks were processed (0.14 ms delay in average), 49 (0.2 %) ticks were skipped (103.4 ms delay in average)
[EURUSD]: 22944 of 22974 (99.9 %) ticks were processed (0.16 ms delay in average), 30 (0.1 %) ticks were skipped (115.6 ms delay in average)
[USDCAD]: 15331 of 15347 (99.9 %) ticks were processed (0.13 ms delay in average), 16 (0.1 %) ticks were skipped (104.6 ms delay in average)
[EURCHF]: 22516 of 22571 (99.8 %) ticks were processed (0.13 ms delay in average), 55 (0.2 %) ticks were skipped (127.8 ms delay in average)
[EURAUD]: 66842 of 66924 (99.9 %) ticks were processed (0.13 ms delay in average), 82 (0.1 %) ticks were skipped (117.8 ms delay in average)
[GBPUSD]: 41393 of 41393 (100.0 %) ticks were processed (0.00 ms delay in average)
Total trade requests time: 4.280 sec

Советник стоял на GBPUSD, поэтому для него работал родной OnTick.

Ошибок "indicator is too slow" не было.


А вот на ВПС от MQ и процент пропущенных тиков и средняя задержка сильно выше (чуть позже выложу статистику).
И ошибок "indicator is too slow" достаточно много.

Не понятна природа переполнения очереди, ведь советник обрабатывает накопившиеся события моментально (просто return-ится).
Кто-то еще ее обрабатывает?


 
Andrey Khatimlianskii:

У меня работает на EventChartCustom. 99.8% тиков поступают в течении 0.15 мс

Тики из индикатора отправляю через это: sparam содержит MqlTick, lparam - номер тика.

Советник в OnChartEvent ловит эти тики. И ему надо понять, сейчас пойманный тик - это самый актуальный или нет? Т.е. есть ли очередь из тиков или она пустая?

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


Ну и по ходу работы OnTick после всяких тормозных OrderSend нужно удостовериться, а не отправил ли индикатор еще тиков. Для этого снова нужно прочесть число от индикатора. И вот таких проверок за выполнение одного OnTick может быть за сотню. Поэтому и нужно быстро читать.

 

В пределах 1 терминала самое быстрое в винапи будет выделение памяти (глобальное в пределах процесса) и работа через интерлокед функции типа https://docs.microsoft.com/ru-ru/windows/win32/api/winnt/nf-winnt-interlockedexchange

Они неблокирующиеся, атомарные и выполняются по сути за несколько асм-инструкций.

InterlockedExchange function (winnt.h) - Win32 apps
InterlockedExchange function (winnt.h) - Win32 apps
  • 2018.12.05
  • lastnameholiu
  • docs.microsoft.com
Sets a 32-bit variable to the specified value as an atomic operation.
 
traveller00:

В пределах 1 терминала самое быстрое в винапи будет выделение памяти (глобальное в пределах процесса) и работа через интерлокед функции типа https://docs.microsoft.com/ru-ru/windows/win32/api/winnt/nf-winnt-interlockedexchange

Они неблокирующиеся, атомарные и выполняются по сути за несколько асм-инструкций.

Без примера не обойдусь.

 
fxsaber:

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

Ну и по ходу работы OnTick после всяких тормозных OrderSend нужно удостовериться, а не отправил ли индикатор еще тиков. Для этого снова нужно прочесть число от индикатора. И вот таких проверок за выполнение одного OnTick может быть за сотню. Поэтому и нужно быстро читать.

Инициализация.

1. В 1 потоке (скорее всего записывающем) выделить память любым способом под переменную нужного размера.

2. В нужные потоки (читающие) переслать адрес этой памяти.

Основная работа.

3. Пишущий поток дёргает InterlockedExchange или InterlockedExchange64 в зависимости от размерности переменной для записи в неё.

4. Читающий поток дёргает например InterlockedCompareExchange для чтения.

Завершение.

5. Освободить выделенную память, желательно в том же потоке, кто и выделял её.


При необходимости можно повторить для заведения нескольких счётчиков. Из минусов-потребуется подключение WinAPI. Из особенностей-адрес выделенной памяти должен быть выровнен, но по дефолту это обычно так.


Работать будет в пределах 1 процесса, память общая для потоков 1 процесса. Если надо, есть и другие интерлокед функции типа InterlockedDecrement, InterlockedAdd и тд.

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


P.S. Вообще насколько помню, обычные операции чтения и записи через mov в ассемблере и так атомарны. И если компилятор не городит огород (а по идее и не должен), то можно попробовать тупо читать и писать в переменную в выделенной памяти и это будет атомарно.

Если под условия задачи подходит, быстрее в пределах 1 процесса сделать вряд ли получится. Для межпроцессного самое быстрое будет аналогично, но с разделяемой памятью, в этом случае без WinAPI не обойтись.