Прошу пожалуйста подтвердить, что это ошибка или что это корректное поведение Квика:
Заказываю данные через CreateDataSource:SetUpdateCallback():
Запускаю Квик: -Загружаю скрипт. -Запускаю скрипт. -Скрипт вызывает CreateDataSource. -CreateDataSource возвращает нулевую таблицу, что говорит о том, что данные придут позже в колбек. -Колбек больше НИКОГДА не вызывается ... проверка размера таблицы в цикле - так же не дает результата, а точнее размер таблицы всегда нулевой - хоть крути цикл минуту, хоть 10 минут.
Выгружаю Скрипт и СРАЗУ же его запускаю - данные сразу же начинают приходить.
Вот простейший скрипт подтверждающий это поведение:
Код
Версия Квика 9.7.1.10
function my_callback_CreateDataSource(my_table_data_, code_class_, code_paper_)
message(code_paper_) //В первый запуск скрипта - НИКОГДА не вызывается.
end
-----------------------------------------------------------------------------------------------------------int main:-----------------------------------------------------------------------------------------------------
function main()
local code_class1 = "TQBR"
local code_paper1 = "GAZP"
local interval1 = INTERVAL_TICK
local code_class2 = "TQBR"
local code_paper2 = "SBER"
local interval2 = INTERVAL_TICK
----------------------------------------------------------------------Вызов CreateDataSource_1------------------------------------------------------------------------------
local my_table1, error_desc1 = CreateDataSource(code_class1, code_paper1, interval1) --Вызываем собственно CreateDataSource
------------------------Проверка на ошибки:-------------------
if error_desc1 ~= nil then
message("Error")
end
--------------------------------------------------------------
message(tostring(my_table1.Size())) //В первый запуск скрипта - размер табилцы ВСЕГДА нулевой - сколько бы времени не ожидал.
if my_table1.Size() == 0 then
message("data requested from the server")
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------Вызов CreateDataSource_2------------------------------------------------------------------------------
local my_table2, error_desc2 = CreateDataSource(code_class2, code_paper2, interval2) --Вызываем собсвенно CreateDataSource
------------------------Проверка на ошибки:-------------------
if error_desc2 ~= nil then
message("Error")
end
--------------------------------------------------------------
message(tostring(my_table2.Size())) //В первый запуск скрипта - размер табилцы ВСЕГДА нулевой - сколько бы времени не ожидал.
if my_table2.Size() == 0 then
message("data requested from the server")
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
my_table1:SetUpdateCallback(function(idx)my_callback_CreateDataSource(my_table_data1, code_class1, code_paper1) end)
my_table2:SetUpdateCallback(function(idx)my_callback_CreateDataSource(my_table_data2, code_class2, code_paper2) end)
Прошу пожалуйста подтвердить, что это ошибка или что это корректное поведение Квика:
Заказываю данные через CreateDataSource:SetUpdateCallback():
Запускаю Квик: -Загружаю скрипт. -Запускаю скрипт. -Скрипт вызывает CreateDataSource. -CreateDataSource возвращает нулевую таблицу, что говорит о том, что данные придут позже в колбек. -Колбек больше НИКОГДА не вызывается ... проверка размера таблицы в цикле - так же не дает результата, а точнее размер таблицы всегда нулевой - хоть крути цикл минуту, хоть 10 минут.
Выгружаю Скрипт и СРАЗУ же его запускаю - данные сразу же начинают приходить.
Вот простейший скрипт подтверждающий это поведение:
Версия Квика 9.7.1.10
Код
function my_callback_CreateDataSource(my_table_data_, code_class_, code_paper_)
message(code_paper_) //В первый запуск скрипта - НИКОГДА не вызывается.
end
-----------------------------------------------------------------------------------------------------------int main:-----------------------------------------------------------------------------------------------------
function main()
local code_class1 = "TQBR"
local code_paper1 = "GAZP"
local interval1 = INTERVAL_TICK
local code_class2 = "TQBR"
local code_paper2 = "SBER"
local interval2 = INTERVAL_TICK
----------------------------------------------------------------------Вызов CreateDataSource_1------------------------------------------------------------------------------
local my_table1, error_desc1 = CreateDataSource(code_class1, code_paper1, interval1) --Вызываем собственно CreateDataSource
------------------------Проверка на ошибки:-------------------
if error_desc1 ~= nil then
message("Error")
end
--------------------------------------------------------------
message(tostring(my_table1.Size())) //В первый запуск скрипта - размер табилцы ВСЕГДА нулевой - сколько бы времени не ожидал.
if my_table1.Size() == 0 then
message("data requested from the server")
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------Вызов CreateDataSource_2------------------------------------------------------------------------------
local my_table2, error_desc2 = CreateDataSource(code_class2, code_paper2, interval2) --Вызываем собсвенно CreateDataSource
------------------------Проверка на ошибки:-------------------
if error_desc2 ~= nil then
message("Error")
end
--------------------------------------------------------------
message(tostring(my_table2.Size())) //В первый запуск скрипта - размер табилцы ВСЕГДА нулевой - сколько бы времени не ожидал.
if my_table2.Size() == 0 then
message("data requested from the server")
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
my_table1:SetUpdateCallback(function(idx)my_callback_CreateDataSource(my_table_data1, code_class1, code_paper1) end)
my_table2:SetUpdateCallback(function(idx)my_callback_CreateDataSource(my_table_data2, code_class2, code_paper2) end)
Прошу пожалуйста подтвердить, что это ошибка или что это корректное поведение Квика:
Заказываю данные через CreateDataSource:SetUpdateCallback():
Запускаю Квик: -Загружаю скрипт. -Запускаю скрипт. -Скрипт вызывает CreateDataSource. -CreateDataSource возвращает нулевую таблицу, что говорит о том, что данные придут позже в колбек. -Колбек больше НИКОГДА не вызывается ... проверка размера таблицы в цикле - так же не дает результата, а точнее размер таблицы всегда нулевой - хоть крути цикл минуту, хоть 10 минут.
Выгружаю Скрипт и СРАЗУ же его запускаю - данные сразу же начинают приходить.
Вот простейший скрипт подтверждающий это поведение:
Код
function my_callback_CreateDataSource(my_table_data_, code_class_, code_paper_)
message(code_paper_) //В первый запуск скрипта - НИКОГДА не вызывается.
end
-----------------------------------------------------------------------------------------------------------int main:-----------------------------------------------------------------------------------------------------
function main()
local code_class1 = "TQBR"
local code_paper1 = "GAZP"
local interval1 = INTERVAL_TICK
local code_class2 = "TQBR"
local code_paper2 = "SBER"
local interval2 = INTERVAL_TICK
----------------------------------------------------------------------Вызов CreateDataSource_1------------------------------------------------------------------------------
local my_table1, error_desc1 = CreateDataSource(code_class1, code_paper1, interval1) --Вызываем собственно CreateDataSource
------------------------Проверка на ошибки:-------------------
if error_desc1 ~= nil then
message("Error")
end
--------------------------------------------------------------
message(tostring(my_table1.Size())) //В первый запуск скрипта - размер табилцы ВСЕГДА нулевой - сколько бы времени не ожидал.
if my_table1.Size() == 0 then
message("data requested from the server")
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------Вызов CreateDataSource_2------------------------------------------------------------------------------
local my_table2, error_desc2 = CreateDataSource(code_class2, code_paper2, interval2) --Вызываем собсвенно CreateDataSource
------------------------Проверка на ошибки:-------------------
if error_desc2 ~= nil then
message("Error")
end
--------------------------------------------------------------
message(tostring(my_table2.Size())) //В первый запуск скрипта - размер табилцы ВСЕГДА нулевой - сколько бы времени не ожидал.
if my_table2.Size() == 0 then
message("data requested from the server")
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
my_table1:SetUpdateCallback(function(idx)my_callback_CreateDataSource(my_table_data1, code_class1, code_paper1) end)
my_table2:SetUpdateCallback(function(idx)my_callback_CreateDataSource(my_table_data2, code_class2, code_paper2) end)
Прошу пожалуйста подтвердить, что это ошибка или что это корректное поведение Квика:
Заказываю данные через CreateDataSource:SetUpdateCallback():
Запускаю Квик: -Загружаю скрипт. -Запускаю скрипт. -Скрипт вызывает CreateDataSource. -CreateDataSource возвращает нулевую таблицу, что говорит о том, что данные придут позже в колбек. -Колбек больше НИКОГДА не вызывается ... проверка размера таблицы в цикле - так же не дает результата, а точнее размер таблицы всегда нулевой - хоть крути цикл минуту, хоть 10 минут.
Выгружаю Скрипт и СРАЗУ же его запускаю - данные сразу же начинают приходить.
Вот простейший скрипт подтверждающий это поведение:
Код
function my_callback_CreateDataSource(my_table_data_, code_class_, code_paper_)
message(code_paper_) //В первый запуск скрипта - НИКОГДА не вызывается.
end
-----------------------------------------------------------------------------------------------------------int main:-----------------------------------------------------------------------------------------------------
function main()
local code_class1 = "TQBR"
local code_paper1 = "GAZP"
local interval1 = INTERVAL_TICK
local code_class2 = "TQBR"
local code_paper2 = "SBER"
local interval2 = INTERVAL_TICK
----------------------------------------------------------------------Вызов CreateDataSource_1------------------------------------------------------------------------------
local my_table1, error_desc1 = CreateDataSource(code_class1, code_paper1, interval1) --Вызываем собственно CreateDataSource
------------------------Проверка на ошибки:-------------------
if error_desc1 ~= nil then
message("Error")
end
--------------------------------------------------------------
message(tostring(my_table1.Size())) //В первый запуск скрипта - размер табилцы ВСЕГДА нулевой - сколько бы времени не ожидал.
if my_table1.Size() == 0 then
message("data requested from the server")
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------Вызов CreateDataSource_2------------------------------------------------------------------------------
local my_table2, error_desc2 = CreateDataSource(code_class2, code_paper2, interval2) --Вызываем собсвенно CreateDataSource
------------------------Проверка на ошибки:-------------------
if error_desc2 ~= nil then
message("Error")
end
--------------------------------------------------------------
message(tostring(my_table2.Size())) //В первый запуск скрипта - размер табилцы ВСЕГДА нулевой - сколько бы времени не ожидал.
if my_table2.Size() == 0 then
message("data requested from the server")
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
my_table1:SetUpdateCallback(function(idx)my_callback_CreateDataSource(my_table_data1, code_class1, code_paper1) end)
my_table2:SetUpdateCallback(function(idx)my_callback_CreateDataSource(my_table_data2, code_class2, code_paper2) end)
Подскажите почему sendTransaction - не хочет работать.
Вызываю sendTransaction:
Во простой скрипт:
Код
function OnTransReply(Table_)
message(tostring(Table_.trans_id) .. ":" .. tostring(Table_.status) .. ":" .. tostring(Table_.result_msg) .. ":" .. tostring(Table_.client_code))
end
function main()
transaction_table =
{
CLIENT_CODE="XXXXX",
TYPE="M",
TRANS_ID="7",
CLASSCODE="TQBR",
SECCODE="GAZP",
ACTION="NEW_ORDER",
OPERATION="B",
PRICE="0",
QUANTITY="1"
}
local result = sendTransaction(transaction)
//Проверяю на ошибку:
if result ~= nil then
if res ~= "" then
message("Error:"..result )
end
end
-------------------------
while not stopped do
sleep(1)
end
-------------------------
end
sendTransaction - Завершается ошибкой: "Не указано значение поля "Торговый счет" Что за торговый счет такой ? И почему он требуется ? В ОПИСАНИИ обязательных параметрах sendTransaction - ОТСУТСТВУЕТ значение "торговый счет" для фондового рынка.
Подскажите почему sendTransaction - не хочет работать.
Вызываю sendTransaction:
Во простой скрипт:
Код
function OnTransReply(Table_)
message(tostring(Table_.trans_id) .. ":" .. tostring(Table_.status) .. ":" .. tostring(Table_.result_msg) .. ":" .. tostring(Table_.client_code))
end
function main()
transaction_table =
{
CLIENT_CODE="XXXXX",
TYPE="M",
TRANS_ID="7",
CLASSCODE="TQBR",
SECCODE="GAZP",
ACTION="NEW_ORDER",
OPERATION="B",
PRICE="0",
QUANTITY="1"
}
local result = sendTransaction(transaction)
//Проверяю на ошибку:
if result ~= nil then
if res ~= "" then
message("Error:"..result )
end
end
-------------------------
while not stopped do
sleep(1)
end
-------------------------
end
sendTransaction - Завершается ошибкой: "Не указано значение поля "Торговый счет"
Что за торговый счет такой ? Где его найти ? И почему он требуется ? В обязательных параметрах sendTransaction - я не нашел "торгового счета" для фондового рынка.
Подскажите, есть к примеру callback`и - OnQuote, OnAllTrade - которые вызываются самим Квиком.
Я пытаюсь их объявить Lua C api:
Код
static int global_callback__OnQuote(lua_State* L)
{
std::cout << "global_callback__OnQuote" << std::endl;
return 0;
}
int main()
{
lua_pushcfunction(L, global_callback__OnQuote); //Помещаю Си-шную функцию в стек.
lua_setglobal(L, "OnQuote"); //Присваиваю ей глобальное имя.
}
Вроде бы должно работать, но функция не вызывается. Получение стаканов предварительно естественно заказана, да и в самом квике открыты, да и обычный Lua-скрипт с OnQuote - тоже работает. Но из dll-ки не хочет почему то.
Функция getBuySellInfoEx возвращает два параметра:
Цитата
is_long_allowed = 1; //Признак того, является ли бумага разрешенной для покупки на заемные средства. Возможные значения: «1» – разрешена, «0» – не разрешена. is_short_allowed = 1; //Признак того, является ли бумага разрешенной для покупки на заемные средства. Возможные значения: «1» – разрешена, «0» – не разрешена.
То есть бумага для которой я запрашивал getBuySellInfoEx - имеет возможность торговли с плечом.
Но параметр так же возвращенный функцией getBuySellInfoEx:
Параметр Тип Описание money_open_limit NUMBER Входящий лимит по денежным средствам money_limit_locked_nonmarginal_value NUMBER Стоимость немаржинальных бумаг в заявках на покупку money_limit_locked NUMBER Заблокированное в заявках на покупку количество денежных средств money_open_balance NUMBER Входящий остаток по денежным средствам money_current_limit NUMBER Текущий лимит по денежным средствам money_current_balance NUMBER Текущий остаток по денежным средствам money_limit_available NUMBER Доступное количество денежных средств
Вызвал функцию getMoney() - она вернула условно следующие значения:
Там где нули пока что не интересует, там, где 1000 руб - функия вернула корректно, при условии, что у меня не было открытых позиций.
Я специально купил одну акцию и стоиомсть портфеля начала соовтевтнно изменятся, но при вызове getMoney() - возвращается все та же - 1000. Я закрыл сделку - стоимость изменилась - условно стала 998, но при вызове getMoney() - возвращается все та же - 1000.
Это так и должно быть ? Если да, то, как тогда получить кол-во доступных средств на конкретный данный момент в который вызвается getMoney() ? Под доступными средвами я имею ввиду, если у меня была 1000 на счете, я купил одну какую то акцию по 100 рублей - дсотупно мне стало 900, вот как эти 900 получить ?
Заказываю тики через CreateDataSource:SetUpdateCallback().
Запускаю Квик: -Загружаю скрипт. -Запускаю скрипт. -Скрипт вызывает CreateDataSource. -CreateDataSource возвращает нулевую таблицу, что говорит о том, что данные придут позже в колбек. -Колбек больше НИКОГДА не вызывается.
Выгружаю Скрипт и СРАЗУ же его запускаю - данные сразу же начинают приходить.
У функции getMoney() - какие то не понятные параметры, которая она принимает:
из примера:
Цитата
-- Параметры для запроса берутся из таблицы "Лимиты по дененым средствам" -- client_code = "Код клиента" -- firmid = "Фирма" -- tag = "Группа" -- currcode = "Валюта"
У меня в таблице лимиты по денежным средствам - из перечисленного есть только код клиента, который я естественно и так знаю. Все остальное вообще не понятно ничего.
Что за фирма ? Что за группа ? Кармен или машина времени ? Валюта ?? Что валюта ? Рубли? Так и писать РУБЛИ ??
Для кого это описание написано ? Для ясновидящих ? А зачем оно им ?
OnDisconnected: Функция вызывается терминалом QUIK при отключении от сервера QUIK.
isConnected: Функция предназначена для определения состояния подключения клиентского места к серверу. Возвращает «1», если клиентское место подключено и «0», если не подключено.
Когда я запрашиваю SetUpdateCallback от CreateDataSource - по тикам - из приход строго упорядоченные ?
То есть не может быть ситуации:
Это два последних тика для 29 минуты:
-вызвался callback - пришел тик, время условно: 15:29:59 - теоретически этот тик должен относится к последней сделке на данный конкретный момент. -вызвался callback - пришел тик, время условно: 15:29:59 - теоретически этот тик должен относится к последней сделке на данный конкретный момент, НО фактически этот тик относится к сделке, которая была ДО предыдущего тика.
То есть не может быть такой ситуации, что я учту второй тик - как цену закрытия 29 минуты, НО фактически цена закрытия - будет в первом тике - так как именно он относится к последней сделке в этой 29 минуте. ?
Подскажите пожалуйста, когда я запрашиваю таблицу исторических свечей через CreateDataSource, то таблица сразу приходит заполненная окончательным размером или размер меняется по мере заполнения ?
Теоретически таблица сразу должна заполнится итоговым размером. Правильно ?
-Соединение установлено -Скрипт получает каждые данные изменившейся цены и дату/время и упаковывает в свечи по интервалу. -Предположим произошел дисконнект Квика. -Через 5 минут произошел опять коннект и данные опять начали приходить, но прежде, чем принимать после дисконнекта данные - нужно заполнить 5 минутный пропущенный промежуток. -А для этого, нужно как то определить, что произошел ре-коннект.
Собственно вопрос: если я заказываю стакан с помощью Subscribe_Level_II_Quotes, после отключения скрипта - он автоматически будет отписан, то есть эквивалентен вызову Unsubscribe_Level_II_Quotes ?
-вот я вызываю CreateDataSource -в отдельном потоке запускаю функцию - которая каждые 100 мс - проверяю размер таблицы -Как только размер таблицы (к примеру данные запрашивались на сервере) становится больше 0, то значит данные таблицы свечей получены -Завершаю функцию.
Вроде бы все нормально, но есть случай - когда по какому то инструменту/акции - просто нету вообще свечей, то есть акция есть - а торгов по ней вообще на данный момент еше не было. И в итоге получается, что функция будет крутится вечно, так как размер таблицы будет всегда возвращаться нулевым.
Возможно ли, как то определить - что нулевой размер таблицы - это не потому что данные с севера еще не пришли, а потому что размер таблицы - нулевой - Фактически, потому что данных свечей по акции физически еще не существует.
Подскажите, возможна ли остановка и запуск скрипта из другого скрипта ?
К примеру так: первый скрипт следит за соединение Квика - если соединение разрывается, то первый скрипт останавливает второй скрипт. Первый скрипт ждет пока восстановится соединение и как только соединение восстанавливается первый скрипт запускает второй скрипт.
В какой то рандомный момент работы dll-скрипта - вызов функции lua_pcall() - просто вешает Квик. Это не обязательно первый вызов lua_pcall - это именно рандомный вызов. То есть Квик просто зависает и все - не ошибок ничего - просто виснет и все.Причем lua_pcall() - не возвращается, то есть код после lua_pcall - не выполянется. Квик тупо виснет в какой то момент именно на lua_pcall() и дальше Квик уже ничего не выполняет. И как тут разобраться в чем проблема ? Квик даже дамп ошибки не создаёт.
Чтобы вызвать метод у таблицы, к примеру метод Size() у таблицы CreateDataSource - нужно сделать так:
Код
//index - номер таблицы в стеке Lua
lua_getfield(L, index, "Size"); //"Извлекаем" из "таблицы" функцию отвечающую за возвращения размера этой таблицы.
lua_pushvalue(L, index); //Помещаем копию обьекта таблицы на вершину стека.
int status_lua_pcall = lua_pcall(L, 1, 1, 0); //Вызываем функцию Size
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()
Я понимаю, что "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 - сразу более, чем по одному инстурменту ??
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.
После вызова 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`ов для разных парамтеров.
Квик ПАДАЕТ от простейшего кода - тупо ЗАКРЫВАЕТСЯ:
В квике Lua-скрипт:
Код
function main()
Quik_Lua_connector= require("Quik_Lua_connector")
Quik_Lua_connector.run_Cpp()
-------------------------
while not stopped do
sleep(1)
end
-------------------------
end
То есть из Квика запускаю функцию run_Cpp из .dll:
function main()
Quik_Lua_connector= require("Quil_Lua_connector_work_TEST")
Quik_Lua_connector.TestFunc_run_WinConsole_for_dll()
Quik_Lua_connector.run_Cpp()
-------------------------
while not stopped do
sleep(1)
end
-------------------------
end
В С++ соответственно:
Код
static int run_Cpp(lua_State* Lua_stek)
{
lua_State* L = luaL_newstate();
if (L == NULL)
{
std::cout << "L == NULL" << std::endl; //Ошибки нет.
}
lua_getglobal(L, "CreateDataSource");
lua_pushstring(L, "TQBR");
lua_pushstring(L, "GAZP");
lua_pushnumber(L, "INTERVAL_MN1");
std::cout << "Size_stack:" << lua_gettop(L) << std::endl; //Размер 4 - как и должно быть
int status_lua_pcall = lua_pcall(L, 3, 2, 0);
if(status_lua_pcall != 0)
{
std::cout<<"Error"<<std::endl; //attempt to call a nil value
}
}
То есть я хочу использовать автоматически не созданный при вызове функции run_Cpp - Lua стек, а создать своей новый - через luaL_newstate. Стек создается, он не равен нулю. В стек добавляются элементы - то есть он рабочий. Но, как я вызываю lua_pcall - то lua_pcall завершается ошибкой "attempt to call a nil value".
Со автоматически созданный стеком Lua_stek - никаких ошибок нет, все работает.
При вызове SetUpdateCallback по умолчанию передать туда доп. параметры нельзя:
Код
function my_callback_(index)
--index - индекс свечи в таблице my_table, НО сама таблица по умолчанию не приходит, что просто дикость.
end
local my_table = CreateDataSource(code_class, code_paper_ interval)
my_table :SetUpdateCallback(my_callback_)
Но, передать доп. параметры в callback - можно с помощью такой контракции, в данном случае я не знаю, что она означает на Lua, просто подсмотрел на данном форуме:
Код
function my_callback_(my_table_, param1, param2, index)
--Теперь тут доступны переданные дополнительные параметры...my_table_, param1, param2 - помимо стандартного index
end
local my_table = CreateDataSource(code_class, code_paper_ interval)
parametr_1 = "1"
parametr_2 = "2"
my_table :SetUpdateCallback(function(idx)my_callback_(my_table,parametr_1, parametr_2, idx) end)
И теперь параметры замечательно переданы в callback SetUpdateCallback.
И вот подскажите пожалуйста, а можно ли подобное провернуть в Си ??
И с одной стороны все нормально, my_callback_ - вызывается, НО с другой стороны - я ожидаю там увидеть таблицу запалённую данными свечей, а приходит строка:
Код
1
2
3
4
5
6
...
итд
Такое ощущение, как будто бы похоже на размер таблицы, но в какой то момент это число доходит до 3007 и после этого так и приходит 3007 с последующими вызовами my_callback_ .
Непосредственно в скрипте Lua в квике такой странности не наблюдается, все работает нормально. Что это может быть ?
Подскажите пожалуйста, есть ли пример, как вызывать функцию к примеру SetUpdateCallback с передачей в нее параметров ?
Ну то есть, вот аналог код в Lua:
Код
local my_table_= CreateDataSource(code_class_, code_paper_, interval)
my_table_:SetUpdateCallback(function(idx)my_callback_(my_table_, code_class_, code_paper_, interval) end)
Код
function my_callback_(my_table_, code_class, code_paper, interval)
...код
end
Код
//В L - на вершине стека уже находится таблица возвращенная CreateDataSource.
lua_getfield(L, -1, "SetUpdateCallback"); //"Извлекаем" на вершину стека из "таблицы" функцию SetUpdateCallback.
Теперь нужно поместить в стек последовательно параметры функции SetUpdateCallback, но тут уже не могу понять: - как поместить function(idx) - как поместить my_callback_
Не могу понять, где должна быть объявлена моя функция callback ?
В Lua скрипте и тогда мне ее нужно просто получить через Lua_global или же в C++ ?
Подскажите, кто нибудь сталкивался с такой проблемой ?
Простейший пример:
Скрипт Lua:
Код
function main()
Quik_Lua_connector = require("Quik_Lua_connector")
Quik_Lua_connector.run_CPP()
-------------------------
while not stopped do
sleep(1)
end
-------------------------
end
С++:
Код
#include "my_func.h"
extern "C"
{
#include "lauxlib.h"
#include "lua.h"
}
#pragma comment(lib,"C:\\Users\\lua54.lib")
int forLua_run_CPP(lua_State* L)
{
int status - my_func(L);
return 0;
}
my_func.h: отдельным файлом:
Код
#pragma once
extern "C"
{
#include "lauxlib.h"
#include "lua.h"
}
int my_func(lua_State* L)
{
int my_int =5;
return my_int ;
}
Соответственно - все компилируется, запускаю скрипт в Квике и квик сообщает об ошибке:
Код
error loading module 'Quik_Lua_connector' from file 'C:\SBERBANK\QUIK_x64_KA\Quik_Lua_connector.dll':
Не найдена указанная процедура.
И вся проблема из за того, что я подключим хедеры Lua в отдельном my_func.h. Если я убираю include из my_func.h. и соответвенно убирают "lua_State* L" из параметров функции, то все работает.
Вызов простой функции Lua из С++ ВСЕГДА приводит к ошибке:
Lua_code:
Код
function my_func_Lua()
message("my_func_Lua")
end
function main()
Quik_Lua_connector = require("Quik_Lua_connector_TEST")
Quik_Lua_connector_TEST()
-------------------------
while not stopped do
sleep(1)
end
-------------------------
end
C++ код:
Код
static int Quik_Lua_connector_TEST(lua_State* L)
{
std::cout << "Start" << std::endl;
lua_getglobal(L, "my_func_Lua"); // получаю функцию
//Проверяю, что на вершине стека находится теперь именно функция: int status_lua_is_function = lua_isfunction(L, -1);
std::cout << "status_lua_is_function:" << status_lua_is_function << std::endl; //return 1 - значит Lua функция.
int status = lua_pcall(L, 0, 0, 0); //Вызываю функцию без аргументов и бещ возвратного значения.
if (status != 0)
{
std::cout << "error:" << lua_tostring(L, -1) << std::endl; //ОШИБКА: error in error handling
}
}
lua_pcall ВСЕГДА завершается ошибкой "error in error handling"
local my_table_ = CreateDataSource(code_class_, code_paper_, interval)
local size_table = my_table_:Size() //Гарантировано не равно нулю.
Отправляю в dll в Си:
Код
Quik_Lua_connector.get_data_frim_Lua(size_table)
В dll принимаю:
Код
static int forLua_get_data_frim_Lua(lua_State* L)
{
std::cout << "Size:" << lua_tonumber(L, -1) << std::endl; //Снимаю данные с вершины стека. Все выводится на косноль нормально.
}
Теперь я хочк передать не отдельный параметр полученной таблицы my_table_, а сразу всю таблицу:
Отправляю в dll в Си:
Код
Quik_Lua_connector.get_data_frim_Lua(size_table)
В dll принимаю:
Код
static int forLua_get_data_frim_Lua(lua_State* L)
{
lua_pushnumber(L, 1); //Добавляю в стек номер индекса переданной таблицы к элементу которой я хочу получить доступ. lua_gettable(L, 1); //Помещает на вершину стека переданной таблицы - расположенная по 1 элементу в стеке, и индексу в самой таблице - по номеру элемента с вершины стека, то есть с номера "1", которая я добавил строчкой выше.
lua_getfield(L, -1, "Size"); //Теперь беру значение из стека с вершины стека, то есть то значние, которое я извлек из таблицы по индексу "1" (грубо говоря первая свеча) и извлекаю из него поле с заданным именем "Size" и значение этого поля помещается на вершину стека.
std::cout << "Size:" << lua_tonumber(L, -1) << std::endl; //Беру значение с вершины стека и получаю дулю с маслом или ошибку "unrecognized exception" в самом квике.
}
То есть передать обычную таблицу в виде массива из Lua в Си и получить доступ к значнеием - не составляет проблемы, а передача таблицы с ключом и плучение доступа по ключу не работает в Квике.