Vladimir spb написал: Я так понимаю, что стаканы, через подписки на них, мне не светят. Буду курить прямой запрос котировок по таймеру.
Без подписки не будет и данных в getQuoteLevel2().
Цитата
Когда стаканы приходят, повторить https://www.quantower.com DOM Surface (история стаканов) на Питоне не сложно. Правда я нигде не нашел, что они называют Imbalance ?
Такие графики строятся по таблице обезличенных сделок.
Subscribe_Level_II_Quotes работает нормально, ищите проблему у себя. onQuote передает только изменения стакана, возможно вы торгуете неликвид, где стаканы обновляются раз в час.
Все что расположено вне блоков выполняется первым и только один раз после запуска. getParamEx("QJSIM", "SPBE", "LAST").param_value может вернуть nil, если нет заказа данных с сервера этого параметра.
Для заказа данные должна быть открыта таблица ТТТ с данным инструментом и параметром или осуществлен заказ данных самим скриптом через:
Запрос не мгновенный, и серверу необходимо время что бы начать отправлять запрошенное значение, поэтому вызов getParamEx сразу после ParamRequest вернет все тот же nil. Хорошей практикой будет производить подписку в колбэке OnInit().
Горячих клавиш для вывода отдельных таблиц нет, поэтому надежное и простое решение не получится найти. Конечно есть разные программы для автоматизации и написания макросов (например, autoit) но все эти решения я не считаю надежными.
1. getParamEx никогда не возвращает nil, но вот 0 там может быть запросто 2. Скорее всего у вас цена запрашивается тоже через getParamEx и тоже может быть 0, кроме того до первой сделки по инструменту, после открытия торговой сессии она гарантировано 0. 3. Money/(Price * LOTSIZE) Вызовет ошибку при 0 значениях в делителе.
Пожалуйста добавьте возможность получения доходности облигаций в функцию getQuoteLevel2, в стаканах в самой программе она есть, но по видимому ее забыли добавить в getQuoteLevel2.
Все еще интереснее, если снять эту заявку, то в таблице не обновляется значение, а по другой бумаге значение устанавливается в "-1" Вот скриншот, активных заявок нет. Была снята стоп-заявка POLY, в результате имеем AGRO "-1"
После выставления стоп-заявки (тейк-профит) признак ее наличия (колонка стоп-заявки) в таблице "состояние счета" отображается для совсем другой бумаги, для бумаги для которой в реальности выставлен стоп - не отображается. После перезаказа данных локальных справочников и перезапуска терминала отображение корректное.
Функции обратного вызова вызываются по нескольку раз и это обычное поведение. Вызываются они не только после изменения свойств входящего параметра доступных внутри луа, но и свойств которые остаются "за кадром".
Не нужно вставлять задержки в main, организуйте очередь задач и обрабатывайте их последовательно, возвращаясь к незавершенным (требующим ожидания) задачам уже после.
Все так как и должно быть. Просто вы не учитываете, что процедура Subscribe_Level_II_Quotes выполняется асинхронно и требует значительного времени на выполнение.
Станислав написал: Настройте динамическое название библиотеки, например, mylib-723cf36f.dll, где 723cf36f - динамический хеш. Да, будут оставаться файлы старых версий и в памяти и на диске, но их можно подчищать после закрытия терминала.
Как это сделать? Можно поподробней.
Напишите макрос для post-build события сборки, который будет переименовывать файл. Готового решения у меня нет.
Настройте динамическое название библиотеки, например, mylib-723cf36f.dll, где 723cf36f - динамический хеш. Да, будут оставаться файлы старых версий и в памяти и на диске, но их можно подчищать после закрытия терминала.
Если использовать источником данных DataSource, то использовать SetUpdateCallback для получения информации о том, что появилась новая свеча можно.
При появлении новой свечи в OnDataSourceUpdate изменится index и время свечи, пример:
-- Функция вызывается при изменении свечки в таблице data_source -- OnDataSourceUpdate(TABLE data_source, STRING class_code, STRING sec_code, NUMBER interval, STRING param, NUMBER index) function OnDataSourceUpdate(ds, class_code, sec_code, interval, param, index) ... local datetime = ds:T(index)
end
...
local ds, error = CreateDataSource(class_code, sec_code, interval, param) if ds ~= nil then ds:SetUpdateCallback(function (...) OnDataSourceUpdate(ds, class_code, sec_code, interval, param, ...) end) end
OnTransReply не всегда содержит поле с номером заявки order_num (параметр указан со звездочкой в руководстве). Номер заявки обычно поступает в одном из последних вызовов OnTransReply. Лучше всего номер заявки получать из таблицы заявок по trans_id транзакции.
Станислав написал: А интерпретатор JavaScript в Node.js? По идее должна быть хорошая производительность.
Не видел торговых систем на их основе Подключать к КВИКУ не планирую. Вполне устраивает Lua, MQL5 и C.
PineScript, TradingView, терминал Тинькофф.
Да я и не прошу его подключать к квик. Сейчас молодежь со школы учат программировать на python, наверное, это был бы самый востребованный вариант в будущем. (сам не программирую на нем)
Производительность не бывает лишней. Как вариант можно тестировать стратегию на истории прямо внутри квик ( т.к. появляется возможность запустить задачу в отдельном потоке)
Subscribe_Level_II_Quotes заказывает с сервера поток котировок (далеко не быстрая процедура) Естественно getQuoteLevel2 вернет значения только для уже заказанных ранее стаканов (или открытых в quik)
Причина данной проблемы установлена и будет устранена в одной из ближайших версий библиотеки qlua. В качестве временного решения рекомендуем перед вызовом ds:Close() для закрытия таблицы устанавливать пустую функцию обратного вызова с помощью ds:SetEmptyCallback().
Столкнулся с данной проблемой в терминале версии 10.0.1.18, ds:SetEmptyCallback() перед ds:Close() не решает проблему. Есть еще идеи как это обойти на данный момент?