События в QLua
Добрый день, друзья!
Изучаю QLua, посмотрел несколько примеров, в том числе у Albus'a.
Обычно в цикле пишут sleep(n), при обновлении котировок или любых других значений.
Вопрос к опытным кулуйстам:
1. Есть ли возможность как-то подписаться на событие получения, к примеру, новой котировки, а не перезапускать цикл через n-млсекунд постоянно?
2. Есть ли интерфейс подключения к квику, чтобы программировать не через lua, а, например на c#?
1К |
Читайте на SMART-LAB:
Облигации на пальцах: как устроен главный инструмент инвестора
Если у вас все еще нет облигаций в портфеле — вы либо неверно инвестируете, либо не совсем понимаете, зачем они нужны и по какому принципу...
Каждый инвестор желает знать, где сидит доходность? Взгляд Goldman Sachs на инвестиции до конца года
Если вы инвестируете свой капитал на фондовом рынке, то каждый год легко может принести вам как большие потери, так и несметные богатства....
💡 ГК «Мать и дитя»: тренд на долгосрочный рост
🔹 Группа компаний «Мать и дитя» — качественная идея в несырьевом секторе российского рынка. По мнению начальника управления торговых операций ВТБ...
Башнефть: есть шанс на переоценку, но нужно запастись терпением. Прогноз сошелся с фактом в высокой точностью, ищем инвест идею
Башнефть отчиталась по МСФО за 2025 год — внимание, квартальных отчетов в прошлом году не было вообще!
Традицицинно сравниваем прогноз...
quikluacsharp.ru/
вот, тут всё расскажут, подскажут
на сколько я понимаю на оба вопроса ответ - да
DataSource = CreateDataSource(ClassCode, SecCode, INTERVAL_M1) — подписываемся на источник данных
DataSource:SetUpdateCallback(CallBackDataSource) --назначаем функцию обратного вызова
2. Стандартного интерфейса в квике нет. Нужно писать «прокладку» на С++ для передачи необходимых данных в прогу на С#.
Просторы инета, например https://quikluacsharp.ru/bez-rubriki/s-chego-nachat/
Я не клуист, но судя по этой логике, если бы была возможность подписки на событие, так бы и делали, просто вешали бы коллбек на событие. Скорей всего, там котировки получаются по запросу на сервер. То бишь, pull-технология, она самая распространенная на текущий момент, даже в вебе.
ru.wikipedia.org/wiki/%D0%A2%D0%B5%D1%85%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D1%8F_pull
Смотрите какой в цикле запрос.
Для того, чтобы было то что Вы хотите в чистом виде, нужно чтобы сервер квика сам рассылал обновления котировок.
ru.wikipedia.org/wiki/%D0%A2%D0%B5%D1%85%D0%BD%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D1%8F_push
Не факт что эта фича там есть. Поинтересуйтесь у техподдержки на эту тему
Один нюанс, в quik должна быть открыта таблица обезличенных сделок с необходимым инструментом.
это к примеру, а так есть несколько функций обратного вызова, они описаны в документации
Например OnDisconnected(), можно просто отдельно прописать и он вызовется при разрыве соединения или его необходимо указать и в main?
function OnDisconnected()
message('Disconnected')
end
function OnStop(s)
bStopped = true
end
function main()
bStopped = false
while not bStopped do
sleep(100)
end
end
Интересно, поймут ли меня сейчас?
Если очень кратко, то примерно так — примите во внимание наличие в QUIK независимых потоков Windows, претендующих на использование процессора(ов) ПК.
Все индикаторы (OnCalculate) и все асинхронные выходы (OnStop, OnTrade, OnConnect, OnTransReply, …, много их там) вызываются-выполняются после возникновения каких-либо событий (связь ли разорвалась, в стакане что-то поменялось, ...) последовательно в одном (основном) потоке QUIK. По этой причине крайне нежелательно загружать этот поток длительной обработкой – можно серьезно затормозить работу QUIK, а при зацикливании, например, индикатора – вовсе блокировать.
Все скрипты (main) выполняются каждый в своем отдельном потоке, с претензией на параллельность, насколько это позволяют аппаратные возможности ПК (многоядерность) и возможности Windows по разделению времени процессора(ов) между потоками-претендентами.
Синхронизация потоков и совместная обработка общих данных требует определенной аккуратности от программиста.
Одно дело – когда основной поток в рамках отработки асинхронного выхода OnStop просто взведет где-то флажок, а скрипт его заметит.
Другое – когда в основном потоке и в скрипте (main) вы обновляете одни и те же таблицы или пишете в один и тот же файл – приключения вам гарантированы. Рано или поздно возникнет ситуация, когда вы частично (не до конца) обновили совместно используемый ресурс, но вдруг ваш поток на полуслове прервали, а поток, который получил управление, прошелся своим обновлением по этому же ресурсу. Что получится, когда первый поток снова получит управление и завершит обновление ресурса – непредсказуемо.
Поэтому обычно используют схему периодического засыпания-просыпания скрипта (sleep) со сканированием таблиц QUIK, а возможности асинхронных выходов используются по минимуму. Для передачи данных между основным потоком и скриптом разработчики дали несколько потокобезопасных функций: sinsert, sremove,sconcat.
Схема плоха тем, что периодически, закрывая глаза на происходящие события, вы на какое-то время опаздываете с их обработкой, а, проснувшись, пытаетесь оценить, были ли важные для вас изменения, возможно, напрасно, их может и не быть.
Можно устранить этот дефект с помощью нескольких фукций API Windows.
Например, скрипт (main) ждет наступления какого-либо события с помощью функции WaitForMultipleObjects (в ней есть и отсчет временного интервала), а асинхронные выходы оповещают main о наступлении событий с помощью функции SetEvent. Дополнительно потребуются функции CreateEvent, ResetEvent, CloseHandle.
С уровня LUA эти функции доступны через использование w32.dll. Подробно см. “Вызов WinAPI функций в Lua” (https://quik2dde.ru/viewtopic.php?id=78) .
Если не было опыта работы в многозадачных средах, то придется что-то почитать, типа “Многопоточность и синхронизация. Процессы и потоки” (http://www.kurzenkov.com/Articles/multithreading1.html)
Вполне приличный простой потокобезопасный движок для робота получается, события не пропускаются и нет холостых ходов. LUA + несколько DLL (еще одна на С++ может потребоваться для ускорения мощной арифметики).
Предварительную быструю фильтрацию событий можно делать и в программах асихронных выходов. Например, заказывая источник данных (CreateDataSource) и функцию асинхронного выхода (обратного вызова, SetUpdateCallback), я передаю из нее в скрипт (main) через sinsert/sremove (данные) и SetEvent (событие) только около 10% изменений текущей свечки.
P.S. Еще где-то встречал полезную testc.dll, одна из функций — GetCurrentThreadId (узнать идентификатор потока), для ориентации в многопоточности. О, она и в w32 есть!
В QUIK исследователькой работы очень много, но для программиста это преодолимо.
Кстати, WaitForMultipleObjects ожидаемо используется в самом QUIK (taskinfo показывал).Придётся повозиться с документацией и форумом, т.к. есть не очевидные вещи, с которыми наскоком не разобраться) но если разобраться, даёт неограниченные возможности.
если что пиши в личку, помогу чем смогу