Ошибки, баги, вопросы - страница 2962
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Indicator1 и Indicator2 должны тогда каким-то образом синхронизироваться, чтобы оба числа суметь записать в одну общую строку.
Очень сложное решение выйдет.
Два индикатора и советник на одном графике?
Indicator1 и Indicator2 должны тогда каким-то образом синхронизироваться, чтобы оба числа суметь записать в одну общую строку.
Очень сложное решение выйдет.
Для синхронизации уже давно придумана функция GlobalVariableSetOnCondition
В курсе, умею пользоваться. Пытаемся уйти от глобальных, потому что они страшнейше тормозят.
Indicator1 и Indicator2 должны тогда каким-то образом синхронизироваться, чтобы оба числа суметь записать в одну общую строку.
Очень сложное решение выйдет.
зачем им синхронизироваться? это за них сделает user32.dll.
Им главное правильно пронумероваться, чтобы каждый имел уникальный номер и этот номер был индексом массива данных.
Это можно в крайнем случае сделать в ручную. А можно и автоматом. Кстати я недавно что-то подобное публиковал в КБ (Indicator Сopies), правда для одного окна, но не сложно переделать под весь терминал.
А чем не нравятся ресурсы? По-моему оптимально в границах одного терминала. В том варианте, который я предлагаю через user32.dll (реализовал этот вариант лет 10 назад, когда по-молодости баловался арбитражем), время доступа и парсинга данных окого 50 микросекунд (думаю, что можно убыстрить в 1.5-2 раза). Неужели с ресурсами медленее?
зачем им синхронизироваться? это за них сделает user32.dll.
Попробуйте написать. Возможно, Вы не до конца поняли задачу.
А чем не нравятся ресурсы? По-моему оптимально в границах одного терминала. В том варианте, который я предлагаю через user32.dll (реализовал этот вариант лет 10 назад, когда по-молодости баловался арбитражем), время доступа и парсинга данных окого 50 микросекунд (думаю, что можно убыстрить в 1.5-2 раза). Неужели с ресурсами медленее?
100 микросекунд на чтение уходит на домашней машине в идеальных условиях. Советник на одном тике может вызвать чтение сотню раз. Медленно выходит.
В идеальных условиях GlobalVariableGet выполняется за 10 мкс. Но это не показатель, т.к. в новых для меня боевых условиях это ужасный тормоз.
Это HistoryTicks - ловля всех тиков для советников. Поэтому EventChartCustom не подходит, там своя очередь. С буфером аналогично.
У меня работает на EventChartCustom. 99.8% тиков поступают в течении 0.15 мс
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
EventChartCustom => indicator is too slow
Andrey Khatimlianskii, 2019.12.12 09:27
Вот статистика за 9 часов работы на 5 инструментах:
Советник стоял на GBPUSD, поэтому для него работал родной OnTick.
Ошибок "indicator is too slow" не было.
А вот на ВПС от MQ и процент пропущенных тиков и средняя задержка сильно выше (чуть позже выложу статистику).
И ошибок "indicator is too slow" достаточно много.
Не понятна природа переполнения очереди, ведь советник обрабатывает накопившиеся события моментально (просто return-ится).
Кто-то еще ее обрабатывает?
У меня работает на 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
Они неблокирующиеся, атомарные и выполняются по сути за несколько асм-инструкций.
В пределах 1 терминала самое быстрое в винапи будет выделение памяти (глобальное в пределах процесса) и работа через интерлокед функции типа https://docs.microsoft.com/ru-ru/windows/win32/api/winnt/nf-winnt-interlockedexchange
Они неблокирующиеся, атомарные и выполняются по сути за несколько асм-инструкций.
Без примера не обойдусь.
Для этого он читает номер (задача и состоит в чтении этого номера) самого последнего отправленного индикатором тика. Если пойманный тик имеет тот же номер - очередь пуста, и можно пачку тиков пускать в работу.
Ну и по ходу работы OnTick после всяких тормозных OrderSend нужно удостовериться, а не отправил ли индикатор еще тиков. Для этого снова нужно прочесть число от индикатора. И вот таких проверок за выполнение одного OnTick может быть за сотню. Поэтому и нужно быстро читать.
Инициализация.
1. В 1 потоке (скорее всего записывающем) выделить память любым способом под переменную нужного размера.
2. В нужные потоки (читающие) переслать адрес этой памяти.
Основная работа.
3. Пишущий поток дёргает InterlockedExchange или InterlockedExchange64 в зависимости от размерности переменной для записи в неё.
4. Читающий поток дёргает например InterlockedCompareExchange для чтения.
Завершение.
5. Освободить выделенную память, желательно в том же потоке, кто и выделял её.
При необходимости можно повторить для заведения нескольких счётчиков. Из минусов-потребуется подключение WinAPI. Из особенностей-адрес выделенной памяти должен быть выровнен, но по дефолту это обычно так.
Работать будет в пределах 1 процесса, память общая для потоков 1 процесса. Если надо, есть и другие интерлокед функции типа InterlockedDecrement, InterlockedAdd и тд.
Функции неблокирующиеся, ничего не ждут, автомарные, выполняются за несколько асм-инструкций.
P.S. Вообще насколько помню, обычные операции чтения и записи через mov в ассемблере и так атомарны. И если компилятор не городит огород (а по идее и не должен), то можно попробовать тупо читать и писать в переменную в выделенной памяти и это будет атомарно.
Если под условия задачи подходит, быстрее в пределах 1 процесса сделать вряд ли получится. Для межпроцессного самое быстрое будет аналогично, но с разделяемой памятью, в этом случае без WinAPI не обойтись.