Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
qlua.dll - это библиотека, неотъемлемая от терминала. Так что ее можно считать частью среды исполнения. Я же говорю о библиотеках реализующие часть функциональности, которую можно реализовать самому. Предпочтение будет всегда тем, которые имеют открытый код.
Владимир, как угодно. Можете доверять чужим рукам.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
С точки зрения ГК коммерческая деятельность - это деятельность предприятия (организации, юридического образования) направленную на рыночную деятельность, имеющую своей целью получение прибыли или рыночного дохода.
Так что это не о том.
А по существу уже все обсудили. Я слабо себе могу представить разработчика, использующего библиотеки без исходных кодов.
Владимир написал: Игорь М, Непохоже. Там у меня вообще стоит 10 секунд, а данные обновляются НАМНОГО чаще!
Эти секунды берутся, если установлен флаг "Запрашивать данные раз в". Если не установлен, то происходит постоянное получение данных, с учетом минимальной допустимой дискретности.
Время лучше всегда и сравнивать в секундах, переведя его в unix-time, используя os.time. Надо определить переменную, определяющую время 12:00 текущего дня и сравнивать ее с временем таблицы. Условно: os.time(trade.datetime) > time_12
Владимир, неужели Вы думаете, что если бы такое было, то за все время существования языка (с 1993 года) это никто не заметил бы? Такого рода проблема (самопроизвольное магическим образом изменение значения переменной) - это просто крест на языке.
Владимир написал: Старатель, Да приводил уже, Господи! Почти сразу после моего появления здесь! Когда элемент брался по двойной индексации a=b[i[j]] тип был один, а если заменить на k=i[j];a=b[k] - другой.
Не бывает такого поведения. Если Вы между индексациями таблицы изменение значение переменной к, то язык здесь не виноват. В случае же первого варианта у Вас нет переменной и нет проблемы. Часто такое наблюдается при использовании глобальных переменных, когда к, объявленная в одном месте, перезаписывется в другом.
Свечи могут не поступать. Есть такая ошибка (особенность) у серверной части брокера - последняя цена обновляется, а свечи нет. При этом торговая сессия идет. Смотришь на график, не двигается, а цена последней сделки меняется.
Данные стакана, тоже могут не поступать. При этом еще есть планка, когда нет заявок. Есть предторговый аукцион, когда стакан заполнен, а сессия не идет. Для срочного рынка есть клиринг, когда сессия не идет, а заявки какое-то время еще есть в стакане.
Владимир, я не очень понимаю в чем у Вас проблема с типами. Ее нет. Если Вы записываете в переменную значение другого типа, то это чья проблема? В других языках получите ошибку компиляции, здесь просто следите за руками.
Игорь М написал: Да, 2-ой. И у меня 2-ой. Можно с префиксом "0x" поставить для наглядности: bit.band(trade.flags, 0x4). И bit.band в отличие от bit.test число возвращает. Почему bit.test лучше, чем bit.band - готов узнать.
То что получение данных таблицы сделано разово - это хорошо, т.к. это затратная по памяти функция. А вот то, что функция аггрегирования вызывается несколько раз - это не очень.
Почему не произвести расчет разово, перебрав сделки в одном цикле.
Что касается направления сделки, то если это обычная таблица trades (а не обезличенные сделки), то направление это 2-ой бит флага. И проверять его лучше логически через функцию bit.test, а не сравнивать с десятичным числом.
Владимир, разработчики терминала Вам в этом вопросе не помогут.
Перед подачей транзакции Вы можете проверить какое количество доступно для заявки данного направления. Данная ошибка возникает по причине проверки параметров заявки на сервере Брокера. В периоды высокой нагрузки на сервере брокера Вы еще и не такие ошибки будете получать. Допустим, транзакция прошла, Вы видите сделки в таблице сделок, а баланс до сих пор показывает, что бумаги у Вас есть или их нет. Потом и баланс обновится, но задержка может быть существенной.
В данном контексте у нас последний бар = Size. Можно порассуждать о теоретических ситуациях, но зачем.
Я такие задачи предпочитаю решать через замыкание. Но можно, конечно, и переменные создать.
Код
--Общая сумма
local sum = 0
--Сумма текущего бара
local ind_sum = 0
--Последний рассчитанный индекс
local last_index = 0
function OnCalculate(index)
--Рассчет необходимо произвести один раз при появлении нового бара, рассчитав только что завершившийся.
--Если этот код вызывать на каждой сделке, то sum не будет равен сумме объемов баров
if index ~= last_index then
sum = sum + ind_sum
end
if not C(index) then return sum end
ind_sum = 0
if T(index).hour == 9 then
ind_sum = 0
end
if O(index) ~= C(index) then --исключаем пред и пост торговые бары, а также бары без движения.
if O(index) < C(index) then
ind_sum = V(index)
else
ind_sum = -V(index)
end
end
last_index = index
return sum + ind_sum
end
Так расчет будет только для исторических баров при старте. Текущий бар всегда равен Size, а значит и расчета нет. Когда появится новый бар, он опять равен Size.
Если Вы хотите при поступлении нового бара произвести расчет прошлого бара, то необходимо обеспечить хранение последнего рассчитанного бара он будет равен Size()-1, а при поступлении нового увеличить индекс рассчитанного бара и произвести расчет. Т.о. Вы будете производить расчет последнего закрытого бара.
Так расчет будет только для исторических баров при старте. Текущий бар всегда равен Size, а значит и расчета нет. Когда появится новый бар, он опять равен Size. Также Вы переменную sum инициализировали где-то? Иначе будет арифметика с nil.
В Квик нумерация баров идет от 1, в отличии от MT.
Поэтому последний бар равен результату выполнения функции Size(). Она возвращает текущее число баров. Если индекс равен ему, то он последний существующий бар.
За это время брокер уже восстановил данные в потоке данных. При этом в какие-то дни наблюдались частично корректные данные. В частности для класcа FQBR (иностранные акции) данные были всегда корректны. Для TQBR данные были заполнены по нескольким инструментам, остальные были пустые. С чем связана такая избирательности не очень понятно.
В голову приходит одно: взять w32 и поискать главное окно. Если найдено на английском, то english. Правда, если несколько терминалов, то уже может быть не вариант.
При постановке Лимитной заявки необходимо не выходить за допустимый диапазон цен. Тыкать палочкой (отправить заявку и прочитать ответ) - не вариант, т.к. никто штрафы за превышение числа транзакций не отменял. Поэтому эти параметры критически важны.
Кстати, забыл уточнить, на срочной секции все корректно, параметры заполнены.
Владимир, вот зачем в каждой ветке писать свое мнение... К сведению, от выбора языка интерфейса терминала можно и нужно выводить сообщения, комментарии на разных языках, что вполне естественно.
Если есть интерфейс у скрипта, ставить задержку меньше 50млс не рекомендуется. А если поставить 0, то по идее влиять не должно, раз у нас много ядер, но Квик все же "висит". Поэтому хоть что-то да лучше поставить.
Единый счет - это конструкция, когда данные собираются из разных мест. Вы бы сказали хоть какие изменения должны вызывать событие. Если деньги - это одно. Если позиции по бумагам - это другое. Портфель - слишком общее понятие.
Если говорить о доступных call back, то их список описан в документации. Не очень ясно, что требуется. Но можно предположить, что если речь про денежные средства, а не позиции, может подойти: OnMoneyLimit.
Но можете и сами организовать вызов некой функции при изменении данных портфеля, сделав регулярную проверку оного.
Верну вопрос, т.к. он потерялся за потоком бессмысленных сообщений:
Можно ли утверждать, что время в параметре 'TIME', полученное в колбеке OnParam через getParamEx(class_code, sec_code, 'TIME') не может быть больше чем время последней записи getInfoParam('LASTRECORDTIME')?
Чтобы получить данные по деньгам, позициям надо обратиться к определенной таблице и просканировать строки, либо использовать специализированные функции для получения денежных лимитов, позиций и т.д., допустим getMoneyEx или getPortfolioInfoEx.
Вам надо уточнить, что Вы подразумеваете под "по новой запускает main". Также не очень понятно работает ли Квик круглосуточно или перезапускается.
main - это точка входа работы скрипта, если эта функция завершит свою работу, то скрипт прекратит выполнение. Поэтому повторный запуск main - это либо новый запуск скрипта, либо у Вас все же организованы циклы ожидания нового дня, где происходят какие-то действия приводящие к очистке переменных. Собственно объявленные Вами переменные могут только Вами и быть переопределены, т.е. тем кодом, что написан.
Nikolay написал: include файлы и lua54.lib взято с оф. сайта lua.
Не точно, но возможно, вы взяли статическую библиотеку lua54.lib (~300 кб.). Надо использовать библиотеку импорта dll lua54.lib (~30 кб.) с тем, чтобы использовались функции QUIK из его lua54.dll. Либо надо самому создать библиотеку импорта lua54.lib, используя lua54.dll из QUIK.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
Приведенный список можно продолжить, но, кому это интересно, может прочесть в файле OS_Quesha.pdf.
Дело в том, что Вы привели пример простого диалога, который очень просто пишется на lua. При этом у меня уже давно написан dsl, где я даже проще чем у вас создаю формы и реакции.
Хотелось бы понять, зачем это для реальной работы. Ведь диалог - это вообще последняя вещь, хоть и важная если пишешь не для себя.
Проверил подключение библиотек dll на версиях 11, 12 в режиме lua 5.4. Случайно подключил библиотеку для lua 5.3. Квик молча упал. Воспроизводится стабильно.
Вроде как моя ошибка, но хотелось бы наверно, чтобы это не приводило к аварийному падению.
Так такая ситуация бывает редко. Иначе бы это было явно видно. Просто когда выходит цена из прошлого, то она зачастую гораздо выше(ниже) текущей. Некоторые алгоритмы анализируют диапазон изменения цены и такие выпады мешают.
Колбек OnOParam здесь используется просто как триггер, не более.
Цена берется последняя из параметра LAST в момент срабатывания колбека. Так что это тоже самое, что делаете Вы.
Но вот незадача, последняя цена кривая. Поэтому время и анализируется, чтобы понять почему она кривая. Иначе просто опрашивая цену, получаем ту, что была вчера. Ну так отправил брокер.
Вот сегодня брокер сбербанк выдал такую цену и время по SRH1: price = 26588, time = 184459
Это было примерно в такое время 2021-01-29 16:03:01
Возвращаясь к вопросу - это как понять? Почему время, полученное в колбеке OnParam через getParamEx(class_code, sec_code, 'TIME') - будущее. Хотя, судя по цене, это прошлое. Но т.к. здесь мы имеем только время, то равновероятно прошлое и будущее.
Можно ли утверждать, что время в параметре 'TIME' не может быть больше чем время последней записи getInfoParam('LASTRECORDTIME')? Хотелось бы верить, что хотя бы это выполняется.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
Средства разработки многопоточных скриптов в QUIK., OS_Quesha, свидетельство регистрации в Роспатенте № RU 2020612905. Бесплатная для некоммерческого использования.
Я уже видел изделие в прошлый раз, на другом ресурсе. Кажется, что кота в мешке лучше не здесь показывать. Тем более с ссылкой на архив непонятного содержания на mail.ru. Код библиотек не проверить, луа код - ... Вы бы хоть абсолютные пути и отладочные выражения убрали из поставки, если это продукт. Лицензия не ясна. Я такое только в виртуалках распаковываю. А уж про запуск на рабочем сервере - даже не обсуждается. Интерфейс на iup уже вызывает вопрос о необходимости даже пробовать.
Что касается простой/сложный робот, то как-то не увидел проблем в написании скрипта с сложным интерфейсом и псевдоасинхронной обработкой очередей событий.
Раз уж Вы разместили это здесь, то хотелось бы увидеть пример применения, где средств lua будет явно недостаточно и необходимо использовать данный продукт.
Маленький совет со временем: переходите на unix-time.
Если Вам надо сравнивать времена, то определите строковые представления в конфигурации и переведите их в числа при старте алгоритма, чтобы не делать это постоянно. Тогда уже сравнивать время будет проще, т.к. это будут просто числа. Ну и прибавлять, убавлять время намного проще, т.к. все в секундах.
Как заставить индикатор отреагировать в нужный момент на какие-то внешние изменения, вот же в чем вопрос.
Если инструмент ликвиден и сделки часты, то OnCalculate часто дергается. Если будет внешний флаг "прочитай данные", то задержка будет малая. А если мало сделок, то здесь уже только если самому сделку сделать, чтобы заставить индикатор отработать.
Сдвинуть обе метки в скрипте. Индикатор видит новые координаты меток (опрашивает метку) и рисует по ним линию.
С другой стороны, раз есть связка скрипт-индикатор, то проще с Вашей библиотекой передавать новые координаты в индикатор.
Я обычно метки использую для обратной передачи, когда надо из индикатора передать информацию от пользователя в скрипт. Пользователь метку двигает - т.е. он интерактивно с графика задает какой-то уровень в скрипт.
Нанести линию на график можно. Правда с использованием костыля: меток. Наносите пары метки на график. А также пишите индикатор, который читает положения парных меток на графике и строит по ним линию.
Я бы сказал, что это просто порочная практика жить в глобальном окружении. Не в смысле плохая - иногда можно, но лучше не надо. Иначе в одном месте написал f = 5 и все сломалось.