Anton написал: Виталий, чет не понял, в реальном коде updatecallback тоже определен после того, как использован в SetUpdateCallback? Тогда вы поставили nil в качестве колбека )
Могли бы Вы прислать конкретный код скрипта, используя который сталкиваетесь с описанной проблемой ?
Код
if sub == nil then
local r = cds.gds[datasourceid].ds:SetUpdateCallback(function(...)
updcallback(cds.gds[datasourceid].ds, clientid, datassourceid,...)
end)
utils.dprint("119 cds.lua subds "..tostring(r) )
end
...
function updcallback(lds, client, datasourceid, sub, index)
message("UPDCALLBACK "..class .." ".. security)
utils.dprint(security .. " updcallback")
end
Весь код не присылаю, там довольно много сторонней логики. но суть в том, что local r получает true, что по идее должно говорить о том, все вызвано правильно.
Создаю источник данных с интервалом INTERVAL_M1. Назначаю ему коллбэк и SetUpdateCallback возвращает true. В открытой таблице сделок вижу, что нужные сделки идут, но коллбэк не вызывается. Он также не вызывается при формировании новой минутной свечи, т.е. он вообще не вызывается. Правильно ли понял, что нужно явно CreateDataSource c тиковым интервалом вызвать, чтобы обновления получать или еще какая тонкость имеется?
Есть два терминала от разных брокеров. Они запускают один и тот же скрипт. Когда терминалы онлаин, скрипт определяет брокера по функции getInfoParam и полю userid. В офлаине она не работает. Можно ли как-то определять брокера, когда терминал в офлаине?
Nikolay написал: Т.к. Вы не озвучили настройки получения потока данных вашего рабочего места, то для начала прочтите раздел "Особенности получения значений Таблицы текущих торгов" в справке к терминалу (файл qlua.chm). А то может потока данных нет вовсе
Цитата
Nikolay написал: Т.к. Вы не озвучили настройки получения потока данных вашего рабочего места, то для начала прочтите раздел "Особенности получения значений Таблицы текущих торгов" в справке к терминалу (файл qlua.chm). А то может потока данных нет вовсе.
Поставлена галочка "умное получение данных". Также необходимые инструменты выбраны. И главное поток обезличенных сделок идет в таблице. Но минутные свечи можно получить только с открытым графиком. Это получается только так и можно? Без графика никак?
Создал gui-таблицу обезличенных сделок. Добавил в нее нужный инструмент. Вижу данные пошли в gui-таблице. Но функция CreateDataSource возвращает qlua таблицу нулевого размера. Если же помимо таблицы обезличенных сделок открыть еще и график инструмента, то возвращается qlua таблица с правильным размером. Вопрос. Как все-таки правильно запускать функцию CreateDataSource? Неужели нужно для каждого инструмента график рисовать?
Да, теперь пример тот, что я и имел в виду. Я, кстати, сразу сделал потокобезопасную очередь. Смущало лишь, что стеки стейтов могут друг на друга наложиться. Оказалось, что нормально все - на форуме нашел ссылку на документацию. Благодарю за разъяснения!
nikolz написал: В итоге каждый колбек пишет принимаемые им данные в свой массив А функция main лишь читает эти данные. Синхронизировать колбек и main нет надобности, так как если колбек изменил данные, то main на следующем цикле их увидет.
У меня меин в блокировке ждет данных периодических...в этот момент колбеки вызывают функциии другие. Но стек то получается один и надо его синхронизировать.
Виталий написал: Но ведь стейты разные же...и обращение к ним в любой момент времени не должно повлиять друг на друга
Смотрите, пусть у вас в длл есть сишный колбек OnAllTrade(lua_State * s). Квик его вызывает в потоке колбеков, передает стейт колбеков, на вершине стека лежит ссылка на таблицу с данными. При этом перед вызовом вашей сишной функции луа отпустил лок . Пока вы не вернетесь из колбека, никто этот стек трогать не будет, ссылка так и лежит на вершине. В этом смысле да, стейты разные, стеки разные, в пределах потока со стеком можно делать что угодно и считать, что он, пока вы не вернулись из вызова, только ваш. В том числе можно смело lua_pushinteger и прочая. А вот таблица , на которую ссылка указывает, она не ваша, ссылка на нее может быть и у другого потока, и тот тоже может с ней что-то делать в данный момент. Вот здесь вам надо синхронизировать доступ.
Виталий написал: Допустим на одном тике я в колбэк отправлю push_integer, а на следующем уже в колбэк также отправлю push_string. Не вызовет ли это неопределенного поведения?
Поправка Допустим на одном тике я в меин отправлю push_integer, а на следующем уже в колбэк также отправлю push_string. Не вызовет ли это неопределенного поведения?
Anton написал: Нет, в каждый момент времени выполняется только один колбек, между собой они никак не пересекутся, только с мейном.
Но ведь стейты разные же...и обращение к ним в любой момент времени не должно повлиять друг на друга...или все же разные стейты связаны друг с другом? К чему спрашиваю? Нужно ли как-то мне мэин и колбэк стеки вызовов синхронизировать или qlua.dll все уже сделала за меня? Допустим на одном тике я в колбэк отправлю push_integer, а на следующем уже в колбэк также отправлю push_string. Не вызовет ли это неопределенного поведения?
Известно, что функция main и колбэки (напр. OnTransReply) выполняются в разных потоках. Далее к проекту подключена с++ либа и функции из нее вызываются как и из функции main так и из колбэков. Далее, я понимаю механику следующим образом: - Функция main и колбэки отправляют в с++ либу разные lua_state, и поэтому в данном случае обращение к ним из либы в принципе не может пересечься поэтому потокобезопасно. - А вот разные колбэки сами по себе отправляют в либу одно и тоже lua_state и поэтому работа с ними в либе уже требует синхронизации.
Виталий написал: Все заработало как следует - терминал перестал падать.
Вы в какой версии Quik работаете? При выкладывании ошибок надо указывать версию QUIK, в которой эта ошибка возникает.
Думаю, уже неактуально. Причину выяснил. Это ascii кодировка некоторых данных в таблице getSecurityInfo и модуль json. Я добавил перекодировку в utf8 и все заработало стабильно и как следует.
s_mike@rambler.ru написал: Access violation - это проблема внешней библиотеки или неправильная работа с потоками qlua. Других вариантов не вилится
Я переделал код, сократив количество запросов через getClassSecurities, и терминал начал падать именно на некоторых запросах getSecurityInfo. Причем разных и рандомно.
Код
function CustomGetSecurityInfo(msg)
local class_code = msg["class_code"]
local sec_code = msg["code"]
utils.dprint("Get info "..class_code.." "..sec_code)
local res = getSecurityInfo (class_code, sec_code)
utils.dprint("Got info")
local r = {}
r["jstring"] = json.encode(res)
return r
end
В отладчике видно, что параметры правильные поступают, но терминал валится до появления строки "Got Info"
[5504] Get info PSAU RU000A0ZZXZ7
Терминал на этом месте падает. Причем на аналогичных предыдущих запросах функция возвращает необходимые данные.
Можно ли отсюда как-то разработчикам сообщить, или новую тему создавать надо?
Необходимо каждый день находить код обновляемого инструмента. Из данных имеется только лишь его префикс от короткого имени. Обычно делается следующим кодом:
Код
function findSecurity()
local mdt = 0
local now = os.time()
local foundcode = ""
for i = 0,getNumberOf("SECURITIES") - 1 do
local row = getItem("SECURITIES", i)
if(row.class_code == "PSAU") and (autolib.CheckAssetName(row.short_name) == true) then
--message(row.short_name)
local info = getSecurityInfo(row.class_code, row.code)
if info ~= nil then
local expdt = strDateToEpoch(info.mat_date)
--message(tostring(info) .. " " .. tostring(expdt) .. " " .. tostring(now))
if expdt > mdt and expdt > now then
mdt = info.mat_date
foundcode = row.code
--message(tostring(info.mat_date) )
end
end
end
end
if foundcode ~= "" then
autobuyerlib.LogU8(string.format("Найден инструмент %s", foundcode))
end
end
Проблема в том, что часто (процентов 20% случаев) запуск кода дает ошибку ACCESS VIOLATION. Есть ли иной способ решить задачу?
Lua скрипт выступает в роли сервера, в котором несколько клиентов могут вызвать CreateDataSource с одинаковыми параметрами. Вопрос в том, будет ли каждый новый вызов заново требовать данные с сервера?
Допустим, есть открытая таблица с множеством обновляемых параметров. И все они мне в колбэке скрипта OnParam не нужны, а нужен только один. Можно ли каким-то образом ограничить количество вызовов колбэка предварительной настройкой интересующих параметров? Если нет, то можно ли зарегистрировать пожелание на такой функционал.