В скрипте ниже, после вызова второго CreateDataSource() не работает колбэк. Тестировалось на QUIK 9.5.0.42, lua 5.3.5 Проверьте кто-нибудь на последней версии Квик, есть ли этот баг?
Код
stopped = false
ClassCode = "TQBR"
SecCode = "GAZP"
function OnStop(row)
stopped = true
end
function main()
ds = CreateDataSource("QJSIM", "GAZP", INTERVAL_M1)
ds: SetUpdateCallback (cb)
ds: Close()
ds = CreateDataSource("QJSIM", "GAZP", INTERVAL_M1)
ds: SetUpdateCallback (cb)
while not stopped do
end
end
function cb( index )
local t = ds:T(index)
local _str = string.format("#%d of %d\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f %02d.%02d.%04d %02d:%02d:%02d.%04d\n",
index, ds:Size(),ds:O(index), ds:H(index), ds:L(index),
ds:C(index), ds:V(index),
t.day, t.month, t.year, t.hour, t.min, t.sec, t.ms)
message(_str)
end
Тэги 336, 387 и некоторые другие также приходят вне группы. Тоже видно на скриншоте. В документации к FCC и Адаптеру, указано, что они должны быть в группе тэг 268
На скриншоте видно, что первая часть полей из Инструмента находится за пределами группы, 2ая часть в самой группе. Могу предположить, что первая часть тоже должна быть в группе. Прошу прокомментировать.
Суть проблемы описана в заголовке. Ниже привожу запросы и ответы клиента-сервера:
Код
Запрос на исполнение сделки
20220906-14:19:19.044 : 8=FIX.4.29=19935=D34=5849=CLIENT152=20220906-14:19:19.04356=QFCC1=L01-00000F0011=CORID-1662473923-121=122=838=1040=244=26348=GAZP54=159=060=20220906-17:19:19.042100=MICEX109=E151041=MC010020000010=105
Ответ с данными по заявке
20220906-14:19:19.062 : 8=FIX.4.29=34835=849=QFCC56=CLIENT134=9452=20220906-14:19:1937=220906-TQBR-3246518839611=CORID-1662473923-1109=E1517=220906-TQBR-ZR6cYu-0-BdM0520=0150=039=01=L01-00000F0022=848=GAZP100=MICEX207=MICEX54=138=10151=1014=040=244=26315=SUR59=032=031=0.0000006=060=20220906-14:19:18.30321=15015=52245017=-3:00:005002=324651883965060=610=104
Запрос на получение сделок по заявке
20220906-14:19:19.063 : 8=FIX.4.29=10835=AD34=5949=CLIENT152=20220906-14:19:19.06256=QFCC11=CORID-1662473923-1568=TRID-1662473923-16569=4910=126
Ответ с ошибкой
20220906-14:19:19.064 : 8=FIX.4.29=9235=349=QFCC56=CLIENT134=9552=20220906-14:19:1945=5958=Unsupported message type373=1110=239
Пробовал подставлять в тэг 11 разные значение и всегда один ответ : Unsupported message type.
Здравствуйте. Столкнулся с нелогичной работой Security Definition Request. На примере USD000000TOD@CETS_GAME
При получении всех бумаг приходит вся информацию по данной бумаге, но если сделать запрос только по этой бумаге, то приходит ответ с ошибкой Security is locked now, try later.
"Fix Client Connector" предлагает работать по протоколу FIX 4.2, но спецификация больше схожа с FIX4.4, т.к. FIX4.2 - отсутствуют сообщения "Request for Positions", "Request for Positions Ack", "Position Report" (возможно другие, еще не всё проверил). Это вызывает большие проблемы, если использовать фреймворк, такой как quickfix и аналогичные, потому что для каждой спецификации у него описан свой набор классов и методов. Т.е. включив в работу протокол FIX42, программист не может использовать готовые классы для обработки Request for Positions, Request for Positions Ack, Position Report, т.к. они есть только в FIX44, но включив в работу протокол FIX44, возникают ошибки, тк протокол не соответствует версии на сервере.
Сейчас приходится колхозить, переносить классы и методы из фикс44 в фикс42, что сильно затрудняет разработку и адаптацию под вашу спецификацию FIX.
Предложение Добавить в FCC возможность подключаться по протоколу FIX44(а лучше FIX5+). Т.е. не меняя функционал FCC добавить возможность получать ответы с тегом 8=FIX.4.4 и 8=FIX.4.2(для созданных систем).
В документации для SecurityDefinition в место <Инструмент> заменить на тег 100, т.к. при указании <Инструмент> я ожидаю, что данная структура будет присутствовать (заполнена).
Хотелось бы чтобы при наличии поля <Инструмент> всегда возвращалась заполненная структура как ниже: <component name='Instrument'> <field name='Symbol' required='N' /> <field name='IDSource' required='N' /> \\\ здесь не обязательный параметр, т.к. может отсутствовать в ответе <field name='SecurityID' required='N' /> \\\ так же может отсутствовать <field name='ExDestination' required='N' /> </component> Я бы в нее еще добавил код рынка.
Это очень удобно конвертировать в структуру данных на С++, С# и т.п. Хотя сейчас я её дополняю самостоятельно из полей сообщения SecurityDefinition.
Здравствуйте. Заказывают стакана GAZP@TQBR, а получаю GAZP@MICEX. Я понимаю, что это одно и тоже, но по какому признаку в ответе в теге 100 указывается либо код рынка, либо код класса? Что первично для FCC: код рынка или код класса?
FCC Security Definition возвращает данные с пустым значением кода 48, хотя в документации указано, что по нему происходит идентификация инструмента. (версия руководство 3.6)
Пробую делать так, выводится только первый message: (Lua 5.3)
Код
stopped = false
function OnStop(row)
stopped = true
end
function main()
sec = getSecurityInfo("TQBR", "GAZP")
message(sec["name"])
message(sec["type"])
end
Здравствуйте! В таблице "Инструменты" не нашел параметр отвечающий за тип бумаги (фьючерс, опцион, др) Как определить к какому типу относится данный инструмент?
Здравствуйте. Сегодня установил QUIK Junior 9.7.0.14 для отладки своих программ, но при поптыке подключится к процессу QUIK просто закрывается. В боевой версии квика 9.5.0.42 такой проблемы нет.
Работает левый lua скрипт и мой. Оба скрипта подписываются на стаканы. Если остановить левый lua-скрипт, то он описывает от всех стаканов, включая стакан моего скрипта. Сейчас я в цикле проверяют подписку и заново подписываюсь, но хотелось бы это делать по событию "Отмена стакана"
Прошу внести данную возможность в функционал квика.
После onTransReply() вызывается onDepoLimit() c теми же значениями, что и до SendTransaction(). Изменения в onDepoLimit() происходят только после вызова onOrder(). Правильно ли я понимаю, что меняются какие-то внутренние параметры в depo_limits ?
На сколько я понял, проблема заключалась в синхронизации потоков main() и onQuote(). Дело в том, что при чтении таблицы в событии onQuote(), одновременно в теле main() вызывалась функция sleep(1000) в результате стек портился и функция lua_next в onQuote обращалась по неправильному адресу. В результате этого, возникало исключение и возвращало на вершину стека время в милисекундах, которое я задавал в sleep(). Если я не прав, поправьте меня.
Сейчас все работает как часы! Николай, спасибо! Я уже больше месяца решаю эту проблему =). Пошел отмечать =)
Николай Камынин, Вы продвинули меня вперед по проблеме. Я сменил sleep(1000) на sleep(999). Изменился вывод ошибки на 999. Что это может значить я пока не понимаю.
Решил проверить получение стакана из lua скрипта. Ниже мой код.
Код
function main()
while not stopped do sleep(1000) end
end
function OnQuote(class_code, sec_code)
tb=getQuoteLevel2(class_code, sec_code)
for i=1,tb.bid_count,1 do
b = tb.bid[i].price
q = tb.bid[i].quantity
end
for i=1,tb.offer_count,1 do
b = tb.bid[i].price << на эту строку ругается "test.lua:43: attempt to index field '?' (a nil value)"
q = tb.bid[i].quantity
end
end
Запускаем данный код, открываем 10 стаканов и ждем пока рынок начнет сильное движение. В результате получаем ошибку скрипта
Код
test.lua:43: attempt to index field '?' (a nil value)
Ошибка иногда выскакивает сразу, иногда в течении 10 минут. Проверьте, кто-нибудь у себя.
Николай, я сделал как вы написали. Тип кода всегда равен 4, т.е. строка. Надеюсь я правильно Вас понял. Constantin, спасибо за замечания, исправил код как Вы написали. Это помогло убрать вылеты КВИКА.
Более детальное изучение показало, что во время чтения ячейки price или quantity при выполнении функции while (lua_next(st, top4) != 0) qlua.dll вызывает исключение: First-chance exception at 0x07306684 (qlua.dll) in info.exe: 0xC0000005: Access violation reading location 0x0000001C. First-chance exception at 0x75B0C41F in info.exe: Microsoft C++ exception: cSEHException at memory location 0x00C7C778.
После этого, событие int lua_OnQuote(lua_State *st) вызывается повторно и оно содержит на вершине стека значение 1000.
Данная проблема возникает, то при интенсивном изменении стакана, например при падении рынка.
Ниже привожу мой код получения стакана на с++. Проверьте, пожалуйста, кто может. Будет ли возникать данная ошибка у вас. Может я в коде что-то не то делаю?
Код
typedef map<string, string> ROW;
typedef map<int, ROW> TABL;
int lua_OnQuote(lua_State *st)
{
try
{
int top = lua_gettop(st);
if (top == 0) return 0;
string sec_code = lua_tostring(st, -1);// qlua.ToString(-1); // код бумаги
string class_code = lua_tostring(st, -2);// qlua.ToString(-2);// код класса
//Quote quote = qlua.getQuoteLevel2(class_code, sec_code);
top = lua_gettop(st);
lua_getglobal(st, "getQuoteLevel2");
lua_pushstring(st, class_code.c_str());
lua_pushstring(st, sec_code.c_str());
lua_pcall(st, 2, 1, 0);
int top2 = lua_gettop(st);
lua_pushnil(st);
string key; // ключ
int bid_count;
int offer_count;
TABL bid; // массив bid
TABL offer; // массиы offer
while (lua_next(st, top2) != 0) {
int type = lua_type(st, -1);
if (type == LUA_TNUMBER) key = to_string(lua_tointeger(st, -2));
else key = lua_tostring(st, -2);
type = lua_type(st, -1);
switch (type)
{
case LUA_TSTRING:
if (key == "bid_count") bid_count = lua_tointeger(st, -1);
else offer_count = lua_tointeger(st, -1);
break;
case LUA_TTABLE:
int top3 = lua_gettop(st);
int len;
if (key == "bid") len = bid_count;
else len = offer_count;
for (int j = 1; j <= len; j++)
{
lua_rawgeti(st, top3, j);
// получаем ячейки стакана
int top4 = lua_gettop(st);
lua_pushnil(st);
ROW row;
while (lua_next(st, top4) != 0) {
string key2 = lua_tostring(st, -2);
row[key2] = lua_tostring(st, -1);
lua_pop(st, 1);
}
if (key == "bid") bid[j] = row;
else offer[j] = row;
lua_pop(st, 1);
}
break;
}
lua_pop(st, 1);
}
lua_pop(st, 1);
if (0 != top - lua_gettop(st) - 1) LOG_ERROR << "Lua stack is changed!\n getTop=" << lua_gettop(st);
}
catch (...)
{
LOG_ERROR << "Ошибка в стакане";
//lua_unlock(_luafix.lua);
}
return 0;
}
В отладчике в поле Output появляются следующие строки: First-chance exception at 0x07306684 (qlua.dll) in info.exe: 0xC0000005: Access violation reading location 0x0000001C. First-chance exception at 0x75B0C41F in info.exe: Microsoft C++ exception: cSEHException at memory location 0x00C7C778.
Приветствую. Подскажите, где можно скачать файл спецификацию по вашему FIX-серверу? Точнее файл FIX50SP2.xml с вашими дополнениями к описанию протокола.
Sergey Gorokhov пишет: Уточните, а не в С++ тоже появляется 1000?
Думаю, в самом Lua все будет работать. Мне интересно, что это за номер, с чем это может быть связано? Та же проблема ранее была при открытии стакана с включенной панелью инструментов.
Цитата
может быть проблема в _luafix?
По поводу _luafix -- это класс-обертка стандартных функций lua и qlua. Возможно проблема в ней, но мне не понятен смыл ошибки, по-этому не знаю где искать проблему.
Периодически выводится ошибка "1000". Подскажите, это может значить? Появление ошибки хаотичное.
Мой код в С++
Код
int lua_OnQuote(lua_State *st)
{
int top = _luafix.GetTop();
if (top == 0) return 0;
string sec_code = _luafix.ToString(-1); // код бумаги
string class_code = _luafix.ToString(-2);// код класса
TABLEQuote quote = _luafix.getQuoteLevel2(class_code, sec_code);
_luafix.Pop(1);
_luafix.sendQuote(quote); // здесь отправка стакана в торговый робот
return 0;
}
В данном примере переменная sec_code иногда имеет значение = 1000.