Владимир написал: Quikos, Я не знаю, что там за поле CreateDataSource - этим говном я никогда не пользовался и другим не советую. И пишу только на чистом луа - никаких API. Если Вам нужно вызвать строку - насрать, в какой таблице или переменной она лежит или является возвращаемым значением - попробуйте через load.
Владимир написал: Quikos, Не понимаю, что Вы, собственно, хотите. to call a string value? Для программирования данными я лично использую функцию load, и только для того, чтобы держать некоторые куски кода во внешних файлах. Вызывать строку как функцию здесь, кажется, не пробовал, но в JS частенько этим пользовался, иногда даже сооружая код этой функции (в смысле, строки) на лету. Скорее всего, это должно работать и в Lua.
В первом сдучае я вызываю метод Size() у таблицы CreateDataSource - только делаю в Lua C API - как показал в самом первом сообщении - и это работает.
Теперь мне нужно сделать "то же самое" - но только вызвать не метод у таблицы, а стркоове поле у таблицы возвращенной функцией getQuoteLevel2 - сделать нужно всев том же Lua C API - и вот аналогичный метод с вызовом метода Size() - уже не работает, видимо строковое поле таблицы нужно, как то по другому доставать из таблицы.
nikolz написал: Quikos , Скажите, что я ошибаюсь, но у меня складывается впечатление, что Вы кроме форума больше ничего не изучали по программированию на Си и Lua. Я прав?
Чтобы вызвать метод у таблицы, к примеру метод Size() у таблицы CreateDataSource - нужно сделать так:
Код
//index - номер таблицы в стеке Lua
lua_getfield(L, index, "Size"); //"Извлекаем" из "таблицы" функцию отвечающую за возвращения размера этой таблицы.
lua_pushvalue(L, index); //Помещаем копию обьекта таблицы на вершину стека.
int status_lua_pcall = lua_pcall(L, 1, 1, 0); //Вызываем функцию Size
Nikolay написал: Нет. Да и смысла нет, т.к. истории по стакану нет.
getQuoteLevel2 - просто получить текущий стакан на момент запроса. А OnQuote - признак, что стакан изменился. Только признак. Здесь нет такого понятие готовы данные или нет. Пришел колбек OnQuote - значит есть изменения в данных.
Просто, если нужно сделать срез стакана в произвольный момент времени - то в этом случае без колбека неудобно, нужно в цикле ждать появление данных.
Nikolay написал: Заказать поток на сервере - Subscribe_Level_II_QuotesПолучить данные о текущем состоянии, если данные заказаны успешно - getQuoteLevel2Колбек о изменении OnQuote можно использовать как триггер о необходимости повторного считывания данных. Обрабатавать данные в самом колбеке - не очень хорошая затея.
Я правильно понимаю, что саму getQuoteLevel2 - не возможно связать с каким то конкретным кобеком, чтобы он вызвался по мере готовности данных с сервера ? Только через OnQuote ?
Почему данный код вызывает ошибку: "attempt to index a nil value (local 'local_table_stock')" ??
Код
function main()
local my_class_code = "TQBR"
local my_class_paper = "SBER"
local Subscribe_Level_II__BOOLEAN = Subscribe_Level_II_Quotes(my_class_code, my_class_paper)
message("Subscribe_Level_II__BOOLEAN:" .. tostring(Subscribe_Level_II__BOOLEAN))
if Subscribe_Level_II__BOOLEAN == true then
local local_table_stock = getQuoteLevel2(class, sec)
message("bid_count:" .. tostring(local_table_stock.bid_count))
end
-------------------------
while not stopped do
sleep(1)
end
-------------------------
end -- end main()
OnQuote: я так понял - это глоабльная функция Квика, которая вызывается каждый раз на изменение во всех стаканах Квика, открытых и не открытых, всех классов и бумаг.
getQuoteLevel2: заказывает сам стакан по конкретному классу и бумаге и получает таблицу данных стакана, НО только, если стакан открыт в Квик, что очень печально и с какого перепуга нельзя сделать без открытого стакана ?
Subscribe_Level_II_Quotes: а вот эта функция мне что то совсем не понятна. В описании написано, что:
[quote]Функция заказывает на сервер получение стакана по указанному классу и бумаге.[/quote]
Но для работы OnQuote - это не требуется. Для getQuoteLevel2 - тоже вызов Subscribe_Level_II_Quotes - не требуется.
Так что в итоге делает Subscribe_Level_II_Quotes ?
Собственно, как и написано в названии темы - после вызова метода Close у обьекта CreateDataSource --> SetUpdateCallback больше не устанавливается.
-То есть я заказываю SetUpdateCallback у акции Сбера. -В колбек приходят обновляемые данные сбера. -В какой то момент я отписываюсь от SetUpdateCallback - вызывая метод Close(). Отписка проходит успешно, данные более не приходят в колбек. -После этого я уже вызываю CreateDataSource для акций Газпрома и зазываю SetUpdateCallback. -Ошибок нет - все вызовы функций и методов проходят успешно, но данные не приходят в колбек.
То есть резюмирую - единственный вызов метода Close() - вырубает Всю последующие заказы CreateDataSourc: SetUpdateCallback
Что то фигня получается, я подписываюсь на акцию к примеру Сбера - все окей - обновляемые данные приходят. Через некоторые время я отписываюсь от колбека и через несколько секунд опять подписываюсь, подписка проходит без ошибок, НО - колбек уже не вызывается, то есть обновляемые данные не хотят уже приходить.
Вот код демонстрирующий это:
Код
global_cntr=0;
function my_callback_CreateDataSource_(my_table_data_candle_, code_class_, code_paper_, interval_, idx)
message(code_paper_ ..":" .. interval_string_..":" ..tostring(my_table_data_history_candle_:C(idx)) )
if global_cntr == 13 then
my_table_data_history_candle_:Close() --отписываемся
message("CLOSE")
end
global_cntr=global_cntr+1
end
function main()
message("start")
local code_class_1= "TQBR"
local code_paper_1= "SBER"
local intervakla_1= INTERVAL_M1
local my_table_1, error_desc_1 = CreateDataSource(code_class_1, code_paper_1, intervakla_1)
------------------------Проверка на ошибки:-------------------
if error_desc_1 ~= nil then
message("1:" .. error_desc_1)
end
--------------------------------------------------------------
status = my_table_1:SetUpdateCallback(function(idx)my_callback_CreateDataSource_(my_table_1, code_class_1, code_paper_1, intervakla_1, idx) end)
while not stopped do
sleep(1)
if global_cntr == 14 then
message("START_2")
local code_class_1= "TQBR"
local code_paper_1= "SBER"
local intervakla_1= INTERVAL_M1
local my_table_2, error_desc_2 = CreateDataSource(code_class_1, code_paper_1, intervakla_1)
------------------------Проверка на ошибки:-------------------
if error_desc_2 ~= nil then
message("1:" .. error_desc_2)
end
--------------------------------------------------------------
status = my_table_2:SetUpdateCallback(function(idx)my_callback_CreateDataSource_(my_table_2, code_class_1, code_paper_1, intervakla_1, idx) end)
message(tostring(status))
global_cntr = global_cntr + 1
message("END")
break
end
end
-------------------------
while not stopped do
sleep(1)
end
-------------------------
end -- end main()
А Вы все с какой целью помогаете таким участникам, как я - если у вас у Всех - свои приносящие доход роботы/алгоритмы ? При этом постоянно между собой грызетесь :)
nikolz написал: если Вам интересно, то я использую свечи 30 мин 5 мин и 1 мин. кроме того, в алгоритме принятия решения участвуют данные дневных свечей, а также не закрытых гепов и уровни сопротивления (локальные экстремумы) На акциях основной 30 минут, за исключением начала торгов.
Спасибо. Остается еще два момента:
-1. Если в описании SetUpdateCallback: "Позволяет задать пользователю функцию обратного вызова для обработки изменившихся СВЕЧЕК", то почему, Callback - вызывается не только при изменении индекса всечи, но и цены в пределах этой свечи ? Разве тогда- это не нарушение принципа работы SetUpdateCallback - завленного в описании ?
-2.И возвращаясь к Вашему вопросу "Кто Вам сказал, что колбек прихода свечи отражает все изменения цены?" - я забыл, что в SetUpdateCallback - можно выставить интервал "INTERVAL_TICK" - что Теоретически будет означать отражение всех изменений цены.
А чтобы узнать изменения цены можно использовать колбек OnParam, можете сами периодически читать через getParamEx, или таблицу всех сделок, если нельзя пропускать ни одной сделки. А можете и сами просто читать ds:Close() - это и будет текущая цена на момент запроса.
--------------------- А свечу Вы можете читать по колбеку onParam или по колбеку OnAllTrade . И нет никакого цикла. --------------
Космонавт написал: Вопрос 1: почему OnParam не всегда срабатывает, хоть и было изменение цены? (у меня в ОнПарам фильтр - не реагировать если цена прежняя). Я бы отказался от других колбеков, раз они медленные, но получается ОнПарам иногда даёт сбои.
Sergey Gorokhov: OnParam обновляется срезами (раз в период), а не при изменении. Так было всегда и по другому настроить нельзя.
Вы получается не правы? То есть OnParam нельзя использовать для отслеживания изменения цены.
Quikos написал: 1)Ну так я тоже писал, что считаю подобный опрос в цикле - неправильным, некорректным, неэффективным. Опрашивая просто в цикле - во первых придется каждый раз заказывать ds:Size(). Во вторых - так вы 100% будете пропускать значения. 2)Насчет таблицы всех сделок - тоже писал, что не хочу запускать вручную в Квике что либо помимо скрипта.
но т.к. колбек ds самый медленный, то используя его Вы однозначно будете пропускать цены сделок
Не понимаю почему ? Может Вы имеете ввиду будет приходить с задержкой ? Принцип работы колбек ds- позволяет пропускать сделки ?
Nikolay написал: Вам уже уже писали, что чтобы понять, что пришел новый бар, надо всего лишь сравнить запомненное при прошлом опросе значение ds:Size() с новым. При этом можно опрашивать не постоянно, а с периодичностью заказанного интервала. А чтобы узнать изменения цены можно использовать колбек OnParam, можете сами периодически читать через getParamEx, или таблицу всех сделок, если нельзя пропускать ни одной сделки. А можете и сами просто читать ds:Close() - это и будет текущая цена на момент запроса.
1)Ну так я тоже писал, что считаю подобный опрос в цикле - неправильным, некорректным, неэффективным. Опрашивая просто в цикле - во первых придется каждый раз заказывать ds:Size(). Во вторых - так вы 100% будете пропускать значения. 2)Насчет таблицы всех сделок - тоже писал, что не хочу запускать вручную в Квике что либо помимо скрипта.
Quikos написал: Индекс свечи приходит в SetUpdateCallback. А размер таблицы data_source обновляется по мере прихода свечи.
В начальный момент у вас нет свечей , а размер таблицы не нулевой, так как в ней содержатся указатели на функции. Вы это хотя бы поняли ? ------------------------------ Покажите пример того, о чем говорите.
Да я это сразу учел. Я наверное некорректно задал, мне нужно было проверять свечи только после того, как они превысят первоначально запрошенный размер таблицы. И когда номер свечи будет будет боль размера Первоначально запрошенной таблицы при первом вызове SetUpdateCallback -то это значит уже пришли новые данные. Я наверное не полностью сформулировал вопрос в само начале.
колбек вызывается когда приходят новые свечи, т е те свечи которых нет в архиве. Это могут быть пропущенные свечи. ------------------- Чтобы читать лишь нужные свечи не нужен колбек.
Нужные свечи -это те которые приходят на событие изменение цены.
Quikos написал: Индекс свечи приходит в SetUpdateCallback. А размер таблицы data_source обновляется по мере прихода свечи.
В начальный момент у вас нет свечей , а размер таблицы не нулевой, так как в ней содержатся указатели на функции. Вы это хотя бы поняли ? ------------------------------ Покажите пример того, о чем говорите.
Да я это сразу учел. Я наверное некорректно задал, мне нужно было проверять свечи только после того, как они превысят первоначально запрошенный размер таблицы. И когда номер свечи будет будет боль размера Первоначально запрошенной таблицы при первом вызове SetUpdateCallback -то это значит уже пришли новые данные. Я наверное не полностью сформулировал вопрос в само начале.
Nikolay написал: Если Владимир сделал вывод, то, конечно, это приговор. Правда странно, почему же оно работает у остальных.
А вот и нет.
Склоняюсь, к мнению Владимира, что CreateDataSource SetUpdateCallbackcallback - действительно не стабильный.
Я лишь незначительно изменил Ваш код:
-за место акций SBER и GAZP - изменил на тот, который не открыт в Квике -у меня к примеру - это "PRMB". -И изменил "on_ds_action" - сделал, чтобы после первого вызова on_ds_action - вызывалась отписка от колбека ds:Close().
Код
local is_run = true
local function is_date(val)
local status = pcall(function() return type(val) == "table" and os.time(val); end)
return status
end
local function call_back_processor(action, context)
if not action then return end
return function(index)
action(index, context)
end
end
local function on_ds_action(index, context)
local time = is_date(context.ds:T(index)) and os.time(context.ds:T(index)) or nil
message(tostring(index) .. "\n" .. tostring(context.interval))
context.ds:Close()
end
local function create_ds(context, action)
if not context then return end
local ds, err = _G.CreateDataSource(context.class_code, context.sec_code, context.interval)
if not ds then
_G.message(err, 3)
return
end
if ds and action then
ds:SetUpdateCallback(call_back_processor(action, context))
end
context.ds = ds
return ds
end
function _G.main()
create_ds({sec_code = 'PRMB', class_code = 'TQBR', interval = _G.INTERVAL_W1}, on_ds_action) --VLHZ
create_ds({sec_code = 'PRMB', class_code = 'TQBR', interval = _G.INTERVAL_MN1}, on_ds_action)
while is_run do
_G.sleep(100)
end
end
function _G.OnStop()
is_run = false
end
А вот в чем "гамно" этого СreateDataSource::SetUpdateCallback.
Если Вы запустите - этот скрипт - Вы увидите следующее поведение: -В первый запуск скрипта - колбек вызовется два раз: один раз для интервала INTERVAL_MN1 и один раз для INTERVAL_MN1. Тут все логично и правильно. -Во второй запуск скрипта - колбек вызовется только ОДИН раз - только для одного интервала!
А теперь скажите, что СreateDataSource не "гамно" ?
Nikolay написал: Ну, видимо, потому, что пытаетесь произвести конкатенацию числа и строки my_table_data_history_candle_:Size() .. "\n"
Обратно работает, а вот число..строка уже нет
> print(5..'a') stdin:1: malformed number near '5..' > print('a'..5) a5
Лучше не злоупотреблять динамичностью языка. Либо просто ошиблись с расстановкой скобки для tostring. Также не понятно что это за переменные my_int_1 и my_int_2. Не вижу инициализации. А раз они nil, то соединяете строку с nil.
Дааа ннннннеееет. Я же пишу, что "callback вызывается ТОЛЬКО для сбера." То есть колбек срабатывает, но только заказанный последним.
Я понимаю, что "CreateDataSource гавно", но мне уже чисто из любопытства интересно. Я уже перешел чисто на Lua.
У кого нибудь работает CreateDataSource SetUpdateCallbackcallback - более, чем для одного инструмента ??
Вот простой тестовый код на чистом Lua:
Код
function my_callback_CreateDataSource_HISTORY_1(my_table_data_history_candle_, code_class_, code_paper_, interval_, interval_string_)
message("SIZE_TABLE:" ..tostring(my_table_data_history_candle_:Size() .. "\n" .. ":" .. code_paper_ ..":" .. interval_string_ ..":" ..my_int_1))
end
function my_callback_CreateDataSource_HISTORY_2(my_table_data_history_candle_, code_class_, code_paper_, interval_, interval_string_)
message("SIZE_TABLE:" ..tostring(my_table_data_history_candle_:Size() .. "\n" .. ":" .. code_paper_ ..":" .. interval_string_..":" ..my_int_2))
end
-----------------------------------------------------------------------------------------------------------int main:-----------------------------------------------------------------------------------------------------
function main()
local code_class_1= "TQBR"
local code_paper_1= "GAZP"
local intervakla_1= INTERVAL_MN1
local intervakla_string_1 = "INTERVAL_MN1"
my_table_1, error_desc_1 = CreateDataSource(code_class_1, code_paper_1, intervakla_1)
------------------------Проверка на ошибки:-------------------
if error_desc_1 ~= nil then
message("1:" .. error_desc_1)
end
--------------------------------------------------------------
my_table_1:SetUpdateCallback(function(idx)my_callback_CreateDataSource_HISTORY_1(my_table_1, code_class_1, code_paper_1, intervakla_1, intervakla_string_1) end)
local code_class_2= "TQBR"
local code_paper_2= "SBER"
local intervakla_2= INTERVAL_W1
local intervakla_string_2 = "INTERVAL_W1"
my_table_2, error_desc_2 = CreateDataSource(code_class_2, code_paper_2, intervakla_2)
------------------------Проверка на ошибки:-------------------
if error_desc_2 ~= nil then
message("2:" .. error_desc_2)
end
--------------------------------------------------------------
my_table_2:SetUpdateCallback(function(idx)my_callback_CreateDataSource_HISTORY_1(my_table_2, code_class_2, code_paper_2, intervakla_2, intervakla_string_2) end)
-------------------------
while not stopped do
sleep(1)
end
-------------------------
end -- end main()
То есть я просто заказываю SetUpdateCallback - для Газпрома и Сбера, но callback вызывается ТОЛЬКО для сбера. КТО НИБУДЬ получал callback - сразу более, чем по одному инстурменту ??
Владимир написал: Quikos, Я сам считаю свечи. От десятисекундных до часовых.
Так, а как узнать, что к примеру по Газпрому - изменилась цена акции ? Мне же нужно это событие как то отлавливать, плюс вместе с этим событием должно еще и приходить хотя бы время сделки.
Владимир написал: Quikos, Да плюньте Вы на этот CreateDataSource, это источник глюков и ничего более. Какая разница, что там происходит, если пользоваться этим всё равно невозможно?
А как тогда можно получить данные изменено свечи другим способом, когда цена инструмента меняется ?
Так возвращаюсь к вопросу - это так и должно быть, что вызов одного метода Сlose у Одного объекта CreateDataSource - отписывает все callback`и SetUpdateCallbackcallback- у ВСЕХ объектов CreateDataSource ?
Владимир написал: nikolz , это скрипт имеет дело с терминалом, а Quikos , как и я, имеем с ним дело только при нажатии кнопок "Запустить" или "Остановить". Вот сегодня утром я запустил скрипт на двух Квиках, вечером выключу, и больше я никакого дело с терминалом не имею.
Да, я это и имел ввиду :) Непонятно в чем nikolz нашел противоречие.
— Запомни мои слова: когда что тебе захочется — скажи только: «По щучьему веленью, по моему хотенью».
Странный какой. Наверное только это и запомнил ? :)
Владимир написал: nikolz, это скрипт имеет дело с терминалом, а Quikos, как и я, имеем с ним дело только при нажатии кнопок "Запустить" или "Остановить". Вот сегодня утром я запустил скрипт на двух Квиках, вечером выключу, и больше я никакого дело с терминалом не имею.
Да, я это и имел ввиду :) Непонятно в чем nikolz нашел противоречие.
Quikos написал: Что ж именно я напутал ? )))) Я прямым текстом так и написал - "Я не хочу иметь дело с терминалом, кроме одного единственного действия - запуска скрипта.".
Дело в том, что скрипт запускается в виртуальной машине луа (VM Lua) , она работает внутри терминала, а скрипт получает все данные через терминал. поэтому вне вашего желания, если используете скрипт, то значит имеете дело с терминалом .
Quikos написал:крипте. Я не хочу иметь дело с терминалом, кроме одного единственного действия - запуска скрипта. Колбек на то и колбек, что вызывается, когда готовы данные, как без него я узнаю, когда проверять данные ?
Кроме этого, вы можете узнать о приходе всех данных прочитав время и дату последней свечи.
Колбек на то и колбек, что вызывается, когда готовы данные, как без него я узнаю, когда проверять данные последней свечи ?
Quikos написал:крипте. Я не хочу иметь дело с терминалом, кроме одного единственного действия - запуска скрипта. Колбек на то и колбек, что вызывается, когда готовы данные, как без него я узнаю, когда проверять данные ?
вы что-то путаете. ----------------------- Терминал - это приложение QUIK, которое вы запускаете на компе. Без него вы не установите обмен данными с сервером. Поэтому и скрипт Вы запускаете в терминале и работает скрипт в терминале и данные вы получаете в терминале. ----------------------
Что ж именно я напутал ? )))) Я прямым текстом так и написал - "Я не хочу иметь дело с терминалом, кроме одного единственного действия - запуска скрипта.".
Владимир написал: Quikos, Это в теории. В реальности же на момент вызова данные готовы не всегда, а иногда и ни в одном из трёх вызовов на одно событие.
Вы можете подтвердить, что на момент вызова callback`а - пришла пуста таблица ?
В общем случае колбек - это функция, которая вызывается при наступлении события. Таким образом реализуется механизм асинхронного приема без ожидания. --------------- Следовательно, если Вам не надо обрабатывать каждое значение в момент его прихода с сервера в терминал, то и колбек вам не нужен. Более того, вы можете просто подписаться один раз через меню терминала и не заниматься этим в скрипте.
Я не хочу иметь дело с терминалом, кроме одного единственного действия - запуска скрипта. Колбек на то и колбек, что вызывается, когда готовы данные, как без него я узнаю, когда проверять данные ?
Владимир написал: Quikos, Да потому, что ГОВНО этот CreateDataSource! Концептуально, идеологически, алгоритмически, фактически, и вообще относится к разделу "Функции для работы с графиками". Что Вы вообще хотите узнать, наплодив чуть не половину новых веток за последнюю неделю-две? У Вас на 34 сообщения12 новых тем! Хотите получить работающий скрипт? Забудьте про это говно - с ним Вы не получите его НИКОГДА! Хотите поисследовать глюки Квика? Исследуйте на здоровье, только крайне желательно в ОДНОЙ ветке - я полагаю, что эта тема бесконечна и мало интересна кому-то, кроме Вас. Ещё что-то?
Ну согласен, тем наплодил не мало :) Но справедливости ради, в самом Lua скрипте - который непосредственно в квике запускаю - перезаписи не наблюдаю. А вот в Lua C api - наблюдаю.
SetUpdateCallbackcallback в Lua C api - перезаписывает заказы:
Из скрипта квика вызывается Сищная-функция: в нее соответственно автоматически передается или создается Lua-Стек:
Код
int my_callback(lua_State* L)
{
//Доп.пераметры извелкаем через lua_upvalueindex.
std::cout<<"interval_int:" <<interval_int <<std::endl;
}
void my_call_CreateDataSource(lua_State* L_, name_class_insrument, name_code_paper, interval_int)
{
lua_getglobal(L, "CreateDataSource");
lua_pushstring(L,_ name_class_insrument);
lua_pushstring(L_, name_code_paper);
lua_pushnumber(L_, interval_int);
int status_lua_pcall = lua_pcall(L, 3, 2, 0);
my_call_SetUpdateCallback(L_, my_callback, name_class_insrument, name_code_paper, interval_int); //Вызываем SetUpdateCallback и передаем в нее функцкиб обратного вызова и доп.параметры.
}
int ruc_cpp(lua_State* L_main)
{
lua_State* L_1 = lua_newthread(L_main); //Создаю "поток" связанный с главным стеком.
lua_State* L_2 = lua_newthread(L_main);
my_call_CreateDataSource(L_1 , "TQBR", "GAZP", "INTERVAL_H2");
my_call_CreateDataSource(L_2 , "TQBR", "GAZP", "INTERVAL_H4");
//-----------------------------------------------
for (int i = 0; i < 1000000; i++)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
//-----------------------------------------------
}
Приведенный код частично условный, чтобы не загромождать кодом страницу.
Но суть в том, что - я создаю два новых "потока" от главного Луа-стека: -Вызываю для каждого из двух созданных "потоков" - функцию CreateDataSource и навешиваю колбек через SetUpdateCallback. -Первый и примерно второй и третий - колбеки - выводят интервал "INTERVAL_H2" - то есть это тот интервал, который я запросил первым у CreateDataSource... -НО! Как только вызывается второй CreateDataSource для второго "потока" и навешивается callback - после этого любой вызываемый callback приходит только с интервалом "INTERVAL_H4" - что соотвевует второму вызову CreateDataSource - ТО ЕСТЬ произошло, как бы затирание подписки на колбек... -НО ПОЧЕМУ ? Ведь я создал два разных "потока" которые хоть и связаныс основным луа-стеком, но сами обладают свои стеком, в который я и записываю результа от CreateDataSource.
Nikolay написал: Чтобы получить исторические данные, да и текущие, не обязательно подписываться на колбек. Просто заказали данные, установив пустой колбек через SetEmptyCallback, дождались получения баров с сервера и можете делать с ними все что хотите. Пройтись итератором по ним, совершив действия хоть на каждом баре. А новый бар можно получить просто проверив, что размер Size() стал больше.
Колбек же нужен если надо обрабатывать каждую сделку (точнее каждый вызов, сделок больше может быть) и попутно еще получать данные бара. Но в большинстве случаев это не надо. Да и сделки лучше отслеживать по обезличенным сделкам, а не по колбеку источника баров.
Она синхронная ? То есть функция не вернет true - пока данные не будут загружены в таблицу ?? Если да, то проход по всем акциям займет немалое время вероятно.
Дело в том, что Вы не учитываете очень много моментов. когда Вы первый раз подписываетесь то на сервер уходит Ваша заявка. Не факт, что к моменту вашей отписке сервер исполнит вашу подписку, так как там есть очередь и транзакции идут пакетами и интернет имеет различные задержки для различных пакетов ну и т д. Поэтому Ваш финт не только не типичный прием, но и результат не предсказуемый может быть. При этом непонятно , что это дает и зачем так делать. А в документации QLUA нет указаний на подобные действия. --------------------- Поясните с какой целью Вы это делаете.
1)Цель получить исторические данные. А описываюсь я СРАЗУ после получения данных, потому что к примеру - я заказал данные по Газпрому к примеру - вызвался callback и в таблице возвращенной ранее от CreateDataSource - уже есть ВСЕ исторические свечи, НО callback от SetUpdateCallback- будет вызыватся каким то чертом ровно то кол-во раз, сколько есть свечей в таблице. В таблице которая уже заполнена ВСЕМИ историческими данными - поэтому я при первом получении callback`а и хочу отписаться, так как все данные уже есть и еще условно 3000 раз я не хочу чтобы callback вызывался.
2)И второй момент - я исхожу или исходил из того, что когда я отписываюсь от подписки, то я отписываюсь именно от заказа по конкретному интрументу-акции, а получается, что я отписываюсь вообще от всех заказаов на условно все акции на которые я подписался. Если это так, то это как то глупо, собственно глупо точно так же как и в п.1.
После вызова callback`а от SetUpdateCallback - я сразу отписываюсь от callback`а, но отписываюсь именно от как бы первого объекта CreateDataSource, но почему от отписка происходит от всех последующих от CreateDataSource.
Вот такой простенький код:
Код
function main()
local code_class_= "TQBR"
local code_paper_= "ZVEZ"
local interval_= INTERVAL_W1
my_table_, error_desc = CreateDataSource(code_class_, code_paper_, interval_)
------------------------Проверка на ошибки:-------------------
if error_desc ~= nil then
message(error_desc)
end
--------------------------------------------------------------
my_table_:SetUpdateCallback(function(idx)my_callback_CreateDataSource_HISTORY(my_table_, code_class_, code_paper_, intervakla_) end)
code_class_= "TQBR"
code_paper_= "ZVEZ"
interval_= INTERVAL_M15
local my_table_1, error_desc_1 = CreateDataSource(code_class_, code_paper_, interval_)
------------------------Проверка на ошибки:-------------------
if error_desc_1 ~= nil then
message(error_desc_1)
end
--------------------------------------------------------------
my_table_1:SetUpdateCallback(function(idx)my_callback_CreateDataSource_HISTORY(my_table_1, code_class_, code_paper_, intervakla_) end)
-------------------------
while not stopped do
sleep(1)
end
-------------------------
end -- end main()
То есть я вызываю CreateDataSource для двух значений, которые точно нужно заказывать на сервере.
На два значений вешаю callback`и.
Вызывается первый callback для my_table_ и сразу же отписываюсь от callback`а - НО отписка осуществляется и для таблицы my_table_1, то есть отписка осуществляется для всех ранее заказанных callback`ов для разных парамтеров.
1) Классы МЕНЕЕ удобны, чем структуры. К тому же, насколько я помню, они более функциональны. Я тогда говорил, что всё, что мне предложат на плюсах, я реализую на чистом Си, а вот то, что я напишу на Си, повторить на плюсах не сможет никто. 2) Я и не использую. И даже писал в 2001 году: Мужики! Мне просто страшно читать о проблемах, какие при этом возникают! Да на кой нужно такое счастье? Завязывайте вы с этими исключениями!
Ах, да - это же придурок стал заводить длкальные элементы в блоке! И тут же полезли проблемы с видимостью переменных и меток. Короче, в мусоропровод!
1)Классы БОЛЕЕ удобны, чем структуры. 2)Еще раз повторю: какое Вам дело, кто и как пишет свой код ? Вы случаем не принцесса, которая думает, что все должны делать, как хотите Вы :)