Ошибки, баги, вопросы - страница 2963
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
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 не обойтись.
Эта схема видится нерабочей. Покажите элементарный пример, пожалуйста.
Почему не рабочей? Как раз мне кажется под задачу. Принцип геттера сеттора.
Получение значения скрытой переменной через функцию.
Если передаёшь структуру MqlTick, то определи свою структуру с набором полей как у MqlTick, и добавь в структуру своё поле счётчика.
И возвращай из export функции эту структуру.
Элементарный пример для индикатора. То что пример приведён в скрипте, не обращайте внимания.
В эксперте вызываешь GetTickStruct, и получаешь всю структуру, с своим счётчиком.
В эксперте вызываешь GetTickStruct, получаешь всю структуру, с своим счётчиком.
Элементарную передачу числа из индикатора в советника напишите, пожалуйста.
Элементарную передачу числа из индикатора в советника напишите, пожалуйста.
Замени структуру на одну переменную ))