Серж пишет: А пока данное пожелание не реализовано, разумно ли вместо OnParam использовать функции CreateDataSource и SetUpdateCallback на каждый из отслеживаемых параметров? Не окажет ли это негативного влияния на производительность?
Здравствуйте, На производительность не должно оказать влияния, но с оговоркой что речь идет о разумном количестве заказываемых параметров.
Уделив этому вопросу некоторое время (на самом деле, потратив кучу времени), я пришёл к выводу, что созданный колбек по какому-либо параметру из ТТП через SetUpdateCallback всё равно будет вызываться при изменении любого параметра по данной бумаге. Т.е., получим тот же самый OnParam, только по конкретной бумаге. Но после получения колбека всё равно нужно проверять, был ли вызван этот колбек по изменению отслеживаемого параметра.
А теперь внимание вопрос: Sergey Gorokhov, почему вы не сказали, что для решения данного вопроса создание колбека через SetUpdateCallback не имеет смысла?
Надо делать так, как надо. А как не надо - делать не надо.
Разработчики подтвердили, что проблема имела место быть на сервере: на сервере отсутствовала часть сделок в ТВС, отсюда и графики имели не верные данные.
Цитата
Egor Zaytsev пишет: К сожалению, в данном месте нет механизма отслеживания некорректных данных на графиках.
Поскольку сервер не имеет механизма контроля корректности поступающих данных по обезличенным сделкам (отсюда - и по графикам), а разработчики технологично забили на данную проблему, то возникает закономерный вопрос: как пользователь может самостоятельно отслеживать корректность данных?
К сожалению, использовать предложенный мной вариант сравнивать суммарное количество бумаг из ТВС с параметром "Количеством бумаг в обезличенных сделках" из ТТП в большинстве случаев не представляется возможным из-за того, что в ТТП учитываются внесистемные сделки, которые не отражаются в ТВС. Есть у кого какие варианты, как проверить и в случае чего предупредить пользователя, что его обманывают?
Надо делать так, как надо. А как не надо - делать не надо.
Функции O, H, L, C, V, T Функции в качестве параметра принимают индекс свечи и возвращают соответствующее значение. Время свечи возвращается с точностью до миллисекунд в виде таблицы с полями: {year, month, day, week_day, hour, min, sec, ms, count}
Почему параметры sec и ms всегда равны нулю?
Надо делать так, как надо. А как не надо - делать не надо.
Старатель пишет: Кстати, со временем наблюдается всё увеличивающаяся разница между количеством сделок, посчитаных по OnAllTrade и OnParam (на демо не было). Очевидно, это из-за того, что в ТТП учитываются сделки, которые не отображаются в ТВС.
В Приложении "Значения полей параметров (столбцов) Таблицы текущих значений, Таблицы истории, Таблицы изменений параметров" описан параметр "Количество внесистемных сделок за сегодня". Но у себя в ТТП я такого параметра не нахожу. Плохо искал?
Надо делать так, как надо. А как не надо - делать не надо.
Дмитрий пишет: Я имел в виду для реализации задачи подсчета числа сделок в секунду
А, ну, да. По OnAllTrade будет точнее по любому. Я так и не понял, с чем у автора возникли проблемы: в пределах одной торговой секции OnAllTrade приходят в хронологическом порядке. Если не баловаться галочками в процессе подсчёта, да и то после подкачки дозаказанных сделок хронология восстанавливается.
Надо делать так, как надо. А как не надо - делать не надо.
sam063rus пишет: насчёт разницы в количестве коллбеков м/у OnParam и OnAllTrade: думаю. тут нет ничего удивительного - т.к. в OnParam - коллбек приходит на каждое изменение параметра
При сравнении с OnAllTrade я считал только колбеки OnParam, увеличивающие количество сделок.
Цитата
Michael Bulychev пишет: Сравнивать частоту обновлений стакана и таблицы текущих параметров не совсем корректно.
Согласен. Это я так, до кучи посчитал количество колбеков. Основной целью же было выяснить, что приходит раньше: OnParam или OnQuote с новой котировкой.
sam063rus, своё мнение, откуда брать данные, я выразил ещё здесь: если нам нужны только цена последней сделки и/или лучшего спроса/предложения, то эти данные лучше брать из ТТП, т.к. туда они поступают, чаще всего, раньше других.
Надо делать так, как надо. А как не надо - делать не надо.
Дмитрий пишет: А может картину искажает слишком большое время, заданное для разделения колбэков между пачками? И в итоге за этот интервал времени успевают на самом деле прийти две пачки или даже больше.
Уменьшил разницу до 5 мс, но это не изменило сути:
Кстати, со временем наблюдается всё увеличивающаяся разница между количеством сделок, посчитаных по OnAllTrade и OnParam (на демо не было). Очевидно, это из-за того, что в ТТП учитываются сделки, которые не отображаются в ТВС.
Цитата
Дмитрий пишет: Хотя насчет подсчета частоты хочу отметить, что сравнивать частоту обновлений стакана и ТТП по перечисленным параметрам не совсем корректно, т.к. 'BIDDEPTHT' и 'OFFERDEPTHT' отражают общий спрос и предложение, изменение которых может происходить и при неизменном стакане (т.к. стакан нам показывает не все заявки).
Согласен. Но изменения в стакане чаще всего происходят вблизи спреда.
Старатель пишет: И в сравнении с OnQuote ТТП даёт информацию об изменении лучших спроса и предложения чаще и раньше .
Хотелось бы понять почему... Может неправильно тестировали? Или все же техподдержка ошиблась?
Раннее я уже проводил исследования на эту тему. Код:
Скрытый текст
Код
local sClassCode, sSecCode = 'SPBFUT', 'SiM5'
local offer, bid
function OnQuote(class_code, sec_code)
if not bRun or sec_code ~= sSecCode then return end
local tStakan = getQuoteLevel2(class_code, sec_code)
local nOffer_Count, nBid_Count = tonumber(tStakan.offer_count), tonumber(tStakan.bid_count)
if nOffer_Count ~= 0 and nBid_Count ~= 0 then
local nOffer = tonumber(tStakan.offer[1].price)
local nBid = tonumber(tStakan.bid[nBid_Count].price)
if nOffer ~= offer then
_toLog('[OnQuote] offer='..nOffer)
offer = nOffer
end
if nBid ~= bid then
_toLog('[OnQuote] bid='..nBid)
bid = nBid
end
end
end
function OnParam(class_code, sec_code)
if not bRun or sec_code ~= sSecCode then return end
local Offer, Bid = getParamEx(class_code, sec_code, "OFFER"), getParamEx(class_code, sec_code, "BID")
Offer, Bid = tonumber(Offer.param_value), tonumber(Bid.param_value)
if Offer ~= offer then
_toLog('[OnParam] offer='..Offer)
offer = Offer
end
if Bid ~= bid then
_toLog('[OnParam] bid='..Bid)
bid = Bid
end
end
Запустил скрипт на "боевом" сервере по SiM5. Результаты несколько неожиданные:
Получается "пачки" OnAllTrade приходят даже реже, чем обновления в ТТП по параметру "NUMTRADES". К тому же позже.
Интереса ради написал скрипт, считающий колбеки OnQuote. Результат:
Счётчик Count в OnParam увеличивается на единицу при изменении одного из параметров: 'BID', 'OFFER', 'BIDDEPTH', 'BIDDEPTHT', 'OFFERDEPTH', 'OFFERDEPTHT' при условии, что между колбеками прошло более 33 мс (на случай одновременного изменения нескольких параметров)
И в сравнении с OnQuote ТТП даёт информацию об изменении лучших спроса и предложения чаще и раньше.
Надо делать так, как надо. А как не надо - делать не надо.
sam063rus пишет: теперь понятно зачем телефон: в общем, как я понял: берёшь телефон, платишь за него, подключаешь к компу, ставишь кучу непонятного софта и отправляешь куда-то за свой счёт с этого номера смс.
Тут ведь вопрос ещё в надёжности доставки самого сообщения: доставка e-mail или СМС через интернет менее надёжна, чем GSM.
Надо делать так, как надо. А как не надо - делать не надо.
sam063rus, по-моему вы "из мухи делаете слона". Если вам нужен счётчик сделок, то за отдельную плату я могу вам его написать. По OnAllTrade. Больше ничего не надо. Можно и по OnParam, но там точность будет не очень.
Надо делать так, как надо. А как не надо - делать не надо.
sam063rus пишет: Насчёт срезов - скажу так, имхо: параметры "время" в ТВС и TIME в ТТП - насколько я себе это представляю, - одинаковые по определению. и именно по ним построены таблицы. Так о каких тогда срезах можно говорить?
Ещё раз: в ТТП показываются не все сделки, а только часть, срезами один-несколько раз в сек. Поэтому сделки с 940 мс могли просто не попасть в таблицу, а попала, скажем следующая
Написал тестовый скрипт для подсчёта общего количества сделок по колбекам OnAllTrade и OnParam Результаты на демо-сервере по SBER:
Price - цена последней сделки Num Trades - количество сделок с момента запуска скрипта Time - время последней сделки, согласно колбеку Local Time - локальное время получения колбека Count - количество полученных колбеков: 1) для OnParam счётчик увеличивается при увеличении параметра NUMTRADES 2) для OnAllTrade: поскольку OnAllTrade приходят "пачками", то счётчик увеличивается при приходе новой "пачки" сделок при условии, когда между соседними колбеками прошло более 20 мс
Как видите, количество сделок совпадает. Количество колбеков немного отличается. Завтра проверю на боевом сервере.
Надо делать так, как надо. А как не надо - делать не надо.
Старатель пишет: Вы можете однозначно ответить все ли данные (1), (2) и (3) будут обработаны в колбеке GetPrice, заданном в SetUpdateCallback?
Только текущие.
Не знаю, что вы подразумеваете под словом "текущие", но основываясь на том, что очередь находится на сервере (блин, ну почему нельзя было сразу об этом сказать?!), я делаю вывод, что данные (1), (2) и (3) будут обработаны функцией-колбеком GetPrice()
Надо делать так, как надо. А как не надо - делать не надо.
Другими словами, между этими величинами не обязательно будеn разница ровно в 1 сек. И не обязательно они будут принадлежать к началу этих секунд, как вы делаете в OnAllTrade
Надо делать так, как надо. А как не надо - делать не надо.
sam063rus пишет: имелось ввиду, что проще было это всё смотреть и анализировать у себя в квике - на то скрипт и дан, а не через форум.
Что анализировать-то? Вы можете привести листинг со строками, где "всё портится"? Сидеть с запущенным скриптом перед терминалом и часами ждать неизвестно чего, как-то не хочется.
Надо делать так, как надо. А как не надо - делать не надо.
Sergey Gorokhov пишет: пока работает колбек, новые данные никуда не идут, они копятся в очереди.
Где физически находится эта очередь? На сервере? И данные ждут, когда откроется "портал", чтобы "спуститься" к клиенту? Пока работает колбек клиент не доступен для сервера?
Вы можете однозначно ответить все ли данные (1), (2) и (3) будут обработаны в колбеке GetPrice, заданном в SetUpdateCallback? Что-нибудь изменится, если колбек задать после обработки таблицы в цикле?
Код
function OnInit(script_path)
ds = CreateDataSource(ClassCode, SecCode, Interval)
-- тут приходят данные (1)
local function GetPrice(index)
Candles[index] = ds:C(index)
end
-- тут приходят данные (2)
for i = 1, ds:Size() do GetPrice(i) end
-- тут приходят данные (3)
ds:SetUpdateCallback(GetPrice)
end
Надо делать так, как надо. А как не надо - делать не надо.
Sergey Gorokhov пишет: Данные будут копиться в очереди. То есть поток данных как бы поставится на паузу. После окончания работы колбека, пропущенные данные сразу заедут.
Уже лучше. Т.е., клиент всё-таки их примет? Теперь хотелось бы узнать, если данные придут в таком порядке, как в примере, то куда они попадут после окончания работы OnInit?
Надо делать так, как надо. А как не надо - делать не надо.
Sergey Gorokhov пишет: Колбеки в QUIK идут в основном потоке терминала, поэтому никаких "тут приходят данные" просто не будет.
Объясните. Вот в OnInit() или любом другом колбеке реализован сложный алгоритм, который занимает длительное время. Пока колбек занят, сервер шлёт клиенту новую порцию данных. Что происходит с этими данными? Клиент их не принимает? И когда освободится сервер отправит эти же данные повторно?
Надо делать так, как надо. А как не надо - делать не надо.
Сергей Парахин пишет: Откуда брать цену, чтобы получить ее максимально быстро по сравнению с кодом на qpile (там я беру цену последней сделки из таблицы текущих параметров): 1) Также из таблицы текущих параметров 2) Из таблицы всех сделок, отфильтровав по нужному инструменту. 3) Напрямую из стакана. Только там будем сравнивать бид или оффер с параболиком, а не цену последней сделки. 4) Напрямую с графика цены через GetNumCandles и далее как в примере с индикаторами ?
По моим наблюдениям, если нужна цена последней сделки, то колбеки приходят примерно в таком порядке (чаще всего): 1) OnParam 2) OnAllTrade 3) SetUpdateCallback
Если нужны цены лучшего спроса/предложения, то (чаще всего): 1) OnParam 2) OnQuote
Надо делать так, как надо. А как не надо - делать не надо.
Можете изменить алгоритм таким образом, чтобы параллельный поток блокировался только в том случае, если происходит попытка одновременного доступа к модифицируемой таблице?
Надо делать так, как надо. А как не надо - делать не надо.
Sergey Gorokhov пишет: есть специальная процедура восстановления в случае сбоев. Если процедура выполняется то на клиентских терминалах данные перезакажутся.
Значит брокер в описываемой ситуации green_X5 не выполнил процедуру восстановления...
Цитата
Sergey Gorokhov пишет: Данные перезакажутся после следующего подключения. Да процедура включает рестарт сервера.
Т.е., максимум что мы (пользователи) можем сделать, это получать статические параметры при каждом вызове OnConnected()? Кстати, верно ли, что в OnConnected() уже можно получить списки всех классов (getClassesList), бумаг (getClassSecurities), их статические параметры (getSecurityInfo), доступные для данного аккаунта (при условии правильной загрузки шлюзов брокером)?
Надо делать так, как надо. А как не надо - делать не надо.
sam063rus пишет: Предлагаю сначала "решить вопрос с галками"
А что не так с галками? Галка, о которой речь ("Получать информацию по всем сделкам с текущего момента") призвана уменьшить трафик, если вы подключаетесь в течение торговой сессии, т.е. "старые" сделки в терминал не приходят. Как вы хотите получать данные этих сделок в скрипте?
Цитата
sam063rus пишет: Очевидно, чтоб докопаться до того где и главное, ЧТО это за "CQ01544135"
Очевидно, это предложение было адресовано не вам, а разработчикам.
И, да, вернёмся к первоначальному вопросу темы:
Код
function OnInit(script_path)
ds = CreateDataSource(ClassCode, SecCode, Interval)
-- тут приходят данные (1)
local function GetPrice(index)
Candles[index] = ds:C(index)
end
ds:SetUpdateCallback(GetPrice)
-- тут приходят данные (2)
for i = 1, ds:Size() do GetPrice(i) end
-- тут приходят данные (3)
end
Куда попадут данные (1), (2) и (3)?
Надо делать так, как надо. А как не надо - делать не надо.
Раз уж тут у нас получился "Вечер откровений" касательно работы функции CreateDataSource, то предлагаю вернуться к проблеме (CQ01544135), когда CreateDataSource не заказывает данные параметров с сервера, как изначально планировалось. Предлагаю создать новую функцию, предназначенную непосредственно для заказа параметров бумаг, аналог меню "Связь - Списки...", и не завязывать получение этих параметров на CreateDataSource.
Т.е., если нужно получить только последнее значение параметра (без истории) через getParamEx или колбек OnParam, то заказывать данные с помощью новой функции. Если нужна истории параметров, то CreateDataSource.
Надо делать так, как надо. А как не надо - делать не надо.
Sergey Gorokhov пишет: Описанной проблемы не должно было быть, есть специальная процедура восстановления в случае сбоев. Если процедура выполняется то на клиентских терминалах данные перезакажутся.
Данные на клиентских терминалах перезакажутся в какой момент? После переподключения к серверу или независимо от этого? Процедура восстановления включает рестарт сервера?
up
Надо делать так, как надо. А как не надо - делать не надо.
Сергей Радченко пишет: поставил в 32 строке local param=tostring(Settings.line[1].Name) все равно возвращает ошибку: ...\LuaIndicators\file03.lua:32: attempt to index field 'line' (a nil value)
Очевидно, на этот вопрос должны ответить сотрудники техподдержки QUIK
Надо делать так, как надо. А как не надо - делать не надо.
Sergey Gorokhov пишет: есть ли у Вас конкрентое предложение в изменении текущего поведения?
Я думаю, это от вас должны исходить предложения, как должен повести себя робот в подобной ситуации. Поскольку ваш терминал вместо nil возвращает number, string или table, то иногда по возвращаемым значениям (как в этом случае) нельзя понять, является ли это значение корректным или имеет место сбой.
Надо делать так, как надо. А как не надо - делать не надо.
Sergey Gorokhov пишет: Описанной проблемы не должно было быть, есть специальная процедура восстановления в случае сбоев. Если процедура выполняется то на клиентских терминалах данные перезакажутся.
Данные на клиентских терминалах перезакажутся в какой момент? После переподключения к серверу или независимо от этого? Процедура восстановления включает рестарт сервера?
Надо делать так, как надо. А как не надо - делать не надо.
Если все сделки заказаны до начала торговой сесссии, то в рамках класса (точнее, торговой площадки) сделки поступают в хронологическом порядке. Либо, если один или несколько бумаг одного класса дозаказаны в течение торговой сессии, то после докачки старых данных новые сделки также поступают в хронологическом порядке.
Цитата
sam063rus пишет: синхронизация соблюдается только в рамках одного тикера.
Можете привести примеры конкретных ситуаций, когда в рамках одного класса синхронизация не соблюдается?
Надо делать так, как надо. А как не надо - делать не надо.
sam063rus пишет: если есть интерес к этой теме - впоследствии выложу для всех.
Позвольте поинтересоваться: ваш индикатор будет изменяться от 0 в начале секунды до общего количества сделок, произведённых за текущую секунду? И в начале следующей секунды сбрасывается снова в ноль? И что он будет показывать?
Надо делать так, как надо. А как не надо - делать не надо.