Сразу предупрежу, использовать GUI в QUIK через сторонние библиотеки -- это не для нубов Откуда качать, как устанавливать и примеры кода -- в следующих двух сообщениях.
VCLua - это название графической библиотеки для Lua.
У неё есть несколько версий и они все между собой не совместимы (то есть код на Lua, годящийся для создания GUI с использованием одной из версий VCLua типа 0.5, 0.6.2, 0.9.2 и 1.0, не будет работать с другой версией VCLua). Причины этого среди прочего в том, что разные версии VCLua используют внутри разные версии LCL - графической библиотеки для Free Pascal.
Я значительно расширил VCLua 0.9.2, почти полностью переписав, и зарелизил версию 1.0.0, использующую LCL 3.2. Общие принципы программирования остались те же.
Последние полгода она стабильно работает на QUIK 11 и 12 под Lua 5.4.
Я использую для рисования стаканов
и управления скриптом
Доступна очень подробная документация, но она на английском и про добавление GUI в отдельностоящий скрипт на Lua, про QUIK там ни слова.
Есть графическая утилита для рисования формы vt-form, которую потом можно сохранить в json и использовать (в т.ч. менять) в своих скриптах.
Здесь я попытаюсь дополнительно задокументировать на русском то, что важно для программирования GUI через VCLua 1.0 для QUIK.
Библиотека основана на визуальных контролах LCL 3.2, поэтому всю документацию этих контролов следует искать в документации к LCL (для более новой версии, чем 3.2), а не в документации к VCLua. Однако то, какие из этих контролов доступны, и какие их поля и методы доступны, как их вызывать из Lua, следует искать в class reference (нажмите Download raw file) к VCLua. Как контролы выглядят и что делают их поля, можно вживую увидеть или в vt-form, или установив Lazarus, или почитав вики по free pascal
LCL уже давно использует кодировку символов UTF8, в отличие от ранних версий VCLua и в отличие от QUIK, который до сих пор на 1251. Поэтому, чтобы видеть русские символы в VCLua, нужно конвертировать из квиковской 1251 в UTF8 с помощью функции VCL.UTF8. Обратно через VCL.WinCP, что нужно, например, для сохранения файлов, путь к которым получен из диалога VCLua.
Если у вас несколько скриптов будут использовать VCLua, то лучше использовать разные файлы core.dll. В противном случае после закрытия одного из скриптов вы не сможете его запустить второй раз, пока не закроете все остальные скрипты (и тем самым не выгрузите библиотеку core.dll из памяти). Также при использовании одного файла core.dll есть ограничение на то, что главные формы разных скриптов должны иметь разные названия (у всех компонентов LCL есть внутренние названия).
LCL является однопоточной библиотекой, а скрипты в квике как минимум двухпоточные. Поэтому, чтобы избежать падений VCLua, а вместе с ней и квика, следует обновлять GUI только из того же потока, где была запущена основная форма. Начиная с версии VCLua 1.0 стало возможным запускать GUI из потока квика main вместо главного потока. Я делаю только так, вариант со стартом в главном потоке квика не тестирую. В частности, я не пытался стартовать GUI из кода индикатора, но это возможно.
Необдуманная установка обработчиков событий может привести к утечкам памяти и падениям скрипта, особенно если устанавливать их из разных потоков.
В документации большой раздел посвящён тому, как обрабатывать ошибки при использовании библиотеки и почему для этого нельзя использовать GUI самой библиотеки. Для квика я во всех скриптах использую один и тот же код как в примере стакана ниже.
Размер dll 6.7 мегабайт, все LCL dll большие. Даже если вы выкинете из библиотеки те контролы, которые вы не используете, и перекомпилируете, сильно меньше она не станет.
В окне редактирования настроек добавляем на него разные инструменты до тех пор, пока не вылезет окно с ошибкой: "Слишком много графиков. Возможно снижение производительности." В моём случае 5 областей, в каждой по инструменту и 5-6 индикаторов
Закрываем окно настроек, нажимаем правой кнопкой мыши на цене любого инструмента и выбираем пункт "Заменить инструмент"
Выбираем новый инструмент, нажимаем Ок и ничего не происходит (price не меняется на новый инструмент, как должна)
ТП БКС говорит, что QUIK не предоставляет такую возможность, как показ сделок IPO в таблице сделок. Так ли это? Есть ли в планах добавлять такую функциональность?
Зарелизился сабж 0.9.2 Качать Писать багрепорты здесь, примеры тут
Из нового, помимо новых контролов, их свойств, и обновления версии Lazarus:
По моей просьбе появилась поддержка виндовой кодировки (надо написать VCL.setCPWin(true) после стандартной инициализации, которая показана в примерах по ссылке выше). Реализована она конвертацией в UTF8 и обратно для всех строк, идущих внутрь GUI.
Форма нормально работает в main(), то есть не в главном потоке. Надо просто создавать форму в main() и потом в цикле делать VCL.Application():ProcessMessages(). Вроде раньше с этим были проблемы.
Я так понял, что изменилось создание меню. Пример. Действия заворачиваются внутрь Action вместе с иконкой и горячей клавишей.
Также обновляется GUI утилита для создания форм прямо на Lua (т.е. без установки Free Pascal) и сохранения формы в JSON. Сохраняется в UTF8, но если файл пересохранить в CP1251, загрузить в скрипте в квике и использовать пункт 1 списка, то русский язык должен быть на месте. Из минусов, утилита поддерживает не все доступные в VCLua контролы, и не все их свойства позволяет редактировать. В частности, пока нельзя задать иконки, картинки. Я утилиту запускаю через интерпретатор, перейдя в папку vt-form\vt-form\dist54\ и выполняю там команду путь-до-луа\qlua\bin\lua54.exe vt-form.lua
Автор сейчас активен на github и жаждет багрепортов.
Собственно, вопрос в названии темы. Во всех случаях индикатор для каждой линии считает одну и ту же функцию, например, EMA50.
Адресуется разработчикам (что они рекомендуют исходя из архитектуры, были ли у них внутренние тесты, что быстрее работает) и к тем пользователям, кто этот вопрос проверял.
Собственно, сабж. Сменил язык (хотел в кармане транзакций и в .tri файле видеть английские названия и значения полей, а не русские), QUIK рестартовал, а теперь не могу (даже после ещё одного рестарта):
Сменить язык назад (при нажатии на System-Settings-Language settings... ничего не происходит)
Соединиться с сервером (System-Connect... или Ctrl+Q или кнопка на панели -- ничего не происходит)
Вызвать настройки (F9 или System-Settings-General Settings... -- ничего не происходит)
Для теста хотелось бы соединиться с сервером. Есть способ это сделать? Если нет, где найти ВСЕ английские названия параметров транзакций? Например, для "Тип стоп-заявки=Тейк-профит и стоп-лимит" есть параметр "Флаги=258", но в описании в "6.9 Импорт транзакций" я его не вижу даже в последней версии квика.
В документации к getParamEx, getParamEx2, ParamRequest, CancelParamRequest и CreateDataSource фигурирует имя параметра Таблицы текущих торгов, но нигде в документации по qlua нет ни списка этих параметров, ни информации о том, где их брать. Благодаря этому сообщению выяснилось, что есть некий список в документации к qpile, но там он не полный. В частности, из сообщения видно, что существует параметр COMPLEXPRODUCT (и вроде бы он, равно как и его имя, устанавливается биржей), а в списке параметров для qpile в разделе 8 info.chm такого параметра нет, равно как и QUALIFIED.
Просьба исправить документацию, и пояснить, где взять полный список этих параметров.
Версия 10.1.2.2 Дано: график с двумя областями, в одной инструмент имеет свечек больше, чем во второй, из-за чего во второй области, когда всё загружено, видны гэпы. Пример - EUR (данные с форекса у меня транслируются откуда-то) и SiU3 (или фьючерс и базовый актив, или RTSI + IMOEX2). Таймфрейм 1 или 5 минут, торги активны. На том инструменте, где есть гэпы, ставим два индикатора с одинаковыми параметрами (кроме может быть визуальных) - встроенный SMA и SMA из официальных примеров индикаторов, с изменением для определения скачка номеров свечей:
Код
function OnCalculate(Index)
if prev_index and Index > prev_index + 1 then
message(string.format("gap at %d %s, jump from %d", Index, os.date("%c", os.time(T(Index))), prev_index), 1)
end
prev_index = Index
return tonumber(Settings.Horizontal_line),ConvertValue(Settings,func(Index, Settings))
end
Этот индикатор должен быть одним из верхних (значит - приоритетных) в области. Нажимаем Ok после добавления индикаторов. Если в сообщениях не появилось про гэпы ничего, но они есть, меняем таймфрейм туда-сюда между 1 и 5 минутами, рано или поздно у меня появляется сообщение в духе: gap at 6061 Fri Jun 16 14:40:00 2023, jump from 4139 Почему? Потому что, видимо, квик случайным образом выбирает, какую область графика рисовать первой: ту, где гэпы возникнут после отрисовки всех областей, или ту, где свечей "больше". Если сначала рисовать более "полную" область, то во второй области индекс не прыгает, просто для отсутствующих свечей будет C(Index) = nil. Если сначала рисовать менее полную область, то индексы сначала не прыгают, все C(Index) ~= nil, потом грузится вторая область, потом при новых данных OnCalculate(Index) начинает получать внезапно большой Index (дебаг принты через PrintDbgStr номеров свечей и их времени):
... и при обращении к старым индексам уже можно получить C(i) == nil, т.к. попадёшь на гэп.
Так вот, я считаю такое поведение багом, ибо это препятствует кэшированию результатов по индексам. Например, начиная с этой свечи данные индикаторов из моего примера начинают различаться, встроенный SMA продолжает быть равным, скажем, аналогичному от TradingView, а индикатор из официальных примеров начинает немного врать. Врёт он потому, что внутри себя создаёт таблицу, индекс которой зависит от номера свечки.
Как такой баг победить? Предлагаю сначала для всех областей всех графиков "вычислять" только price (и может быть volume). После этого должно быть понятно, где будут пропуски свечей на каких областях, т.е. после этого индексы ВСЕХ старых свечей должны быть фиксированы до следующего добавления какой-нибудь области в какой-нибудь график. После этого можно вычислять и отрисовывать остальные индикаторы. Альтернативно - дать юзеру опцию вычислять свои индикаторы в конце цикла вычисления по данному графику (вне зависимости от того, высоко он должен быть отрисован или нет), чтобы он вычислялся в ситуации, когда старые свечки не могут поменять свой индекс, и можно было бы кэшировать.
Со времён этого поста ничего не поменялось, судя по всему.
Если в файле индикатора задать тип линии по умолчанию так
Код
Type = TYPE_BAR
, то при добавлении индикатора тип линии окажется просто "Линии", то есть TYPE_LINE. В документации "Интерпретатор языка Lua. Руководство пользователя. Версия 10.1" на странице 113 такая константа указана, и сказано, что она рисует бары, а не линии. Я знаю, что полноценные бары нельзя пока передать на рисование, но зато если выбрать "Бары" или "Свечи" через меню, то индикатор рисуется наиболее подходящим мне "пунктиром". Если выбирать "Пунктир" или "Пунктир-точка", то при увеличении масштаба индикатор сливается в линию быстрее, чем если рисовать его "барами" или "свечами". Предлагаю убрать эту константу из документации или добавить равной TYPE_CANDLE, так как визуально сейчас не отличаются индикаторы, нарисованные "барами" и "свечами"