Периодически выводится ошибка "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.
Хороший хостинг
Пользователь
Сообщений: Регистрация: 23.01.2015
06.02.2015 16:17:31
Уточните, а не в С++ тоже появляется 1000?
Пользователь
Сообщений: Регистрация: 30.01.2015
06.02.2015 17:30:27
может быть проблема в _luafix?
Пользователь
Сообщений: Регистрация: 06.02.2015
07.02.2015 13:08:50
Цитата
Sergey Gorokhov пишет: Уточните, а не в С++ тоже появляется 1000?
Думаю, в самом Lua все будет работать. Мне интересно, что это за номер, с чем это может быть связано? Та же проблема ранее была при открытии стакана с включенной панелью инструментов.
Цитата
может быть проблема в _luafix?
По поводу _luafix -- это класс-обертка стандартных функций lua и qlua. Возможно проблема в ней, но мне не понятен смыл ошибки, по-этому не знаю где искать проблему.
Здравствуйте, К сожалению нам тоже не известно что это за ошибка 1000. Если напрямую, без C++ в Lua, все работает, значит проблема не в Quik
Пользователь
Сообщений: Регистрация: 06.02.2015
17.02.2015 14:11:25
В отладчике в поле 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.
Что это может означать,
Хороший хостинг
Пользователь
Сообщений: Регистрация: 06.02.2015
17.02.2015 15:22:41
Ниже привожу мой код получения стакана на с++. Проверьте, пожалуйста, кто может. Будет ли возникать данная ошибка у вас. Может я в коде что-то не то делаю?
Код
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;
}
На сколько становится понятно, Вы говорите что проблема заключается в появлении значения "1000" в переменной sec_code. Если так, нужно смотреть выше, что попадает в эту переменную и от куда оно туда попадает, а не то где Вы с ней работаете.
Пользователь
Сообщений: Регистрация: 30.01.2015
18.02.2015 09:13:34
if (top == 0) return 0; поставьте здесь проверку значения на вершине стека на тип кода или вывод в лог файл string sec_code = lua_tostring(st, -1);// qlua.ToString(-1); // код бумаги
Пользователь
Сообщений: Регистрация: 31.01.2015
18.02.2015 11:38:05
Для начала замени
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);// код класса
на
if (top < 2) return 0;
string class_code = lua_tostring(st, 1);// qlua.ToString(-2);// код класса string sec_code = lua_tostring(st, 2);// qlua.ToString(-1); // код бумаги
Это, скорее всего, никак не повлияет на результат, но будет более правильно.
Далее пошло множество енумераторов, в которых надо надо напрягаться, чтобы разобраться. А это лень. Может попроще написать?
Пользователь
Сообщений: Регистрация: 06.02.2015
18.02.2015 13:03:31
, я сделал как вы написали. Тип кода всегда равен 4, т.е. строка. Надеюсь я правильно Вас понял. , спасибо за замечания, исправил код как Вы написали. Это помогло убрать вылеты КВИКА.
Более детальное изучение показало, что во время чтения ячейки 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.
Данная проблема возникает, то при интенсивном изменении стакана, например при падении рынка.
Хороший хостинг
Пользователь
Сообщений: Регистрация: 06.02.2015
18.02.2015 14:41:29
Решил проверить получение стакана из 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 минут. Проверьте, кто-нибудь у себя.
Хороший хостинг
Пользователь
Сообщений: Регистрация: 31.01.2015
18.02.2015 15:04:23
NiKO, посмотри какие типы имеют bid_count и offer_count. Quik любит возвращать многие числовые параметры в строковом виде. Интересно как это повлияет на цикл. Возможно никак. Можно попробовать преобразовать tonumber(), если тип строковый.
А так у тебя во втором цикле ошибка: замени "tb.bid[i]" на "tb.offer[i]".
Пользователь
Сообщений: Регистрация: 30.01.2015
18.02.2015 15:42:55
А сделайте такой тест вместо sleep(1000) напишите sleep(999)
Пользователь
Сообщений: Регистрация: 30.01.2015
18.02.2015 15:44:38
, последний Ваш тест это про другую ошибку т е отсутствие данных по стакану она известна надо проверять на nil
Пользователь
Сообщений: Регистрация: 30.01.2015
18.02.2015 15:46:41
В целом проблема понятно, проверяйте типы данных и значения на nil. И будет Вам счастье.
Пользователь
Сообщений: Регистрация: 06.02.2015
18.02.2015 16:28:58
, Вы продвинули меня вперед по проблеме. Я сменил sleep(1000) на sleep(999). Изменился вывод ошибки на 999. Что это может значить я пока не понимаю.
Хороший хостинг
Пользователь
Сообщений: Регистрация: 06.02.2015
18.02.2015 18:29:05
Всех благодарю за помощь. Проблема решилась заменой
Код
_luafix.DoStr("while not stopped do sleep(999) end";
на
Код
while (_stopped) { Sleep(999);
Получилось:
Код
int lua_main(lua_State*st)
{
//_luafix.DoStr("while not stopped do sleep(999) end";
while (_stopped) { Sleep(999);
return 1;
}
Хороший хостинг
Пользователь
Сообщений: Регистрация: 30.01.2015
18.02.2015 18:29:43
это значит, что на вершине стека лежит эта константа. попробуйте поставить проверку типа после вызова функции обращения к стакану. lua_pcall(st, 2, 1, 0); весьма возможно что функция ничего не вернула или вернула nil, а вы пытаетесь что-то извлекать из стека.
Пользователь
Сообщений: Регистрация: 06.02.2015
18.02.2015 22:53:18
На сколько я понял, проблема заключалась в синхронизации потоков main() и onQuote(). Дело в том, что при чтении таблицы в событии onQuote(), одновременно в теле main() вызывалась функция sleep(1000) в результате стек портился и функция lua_next в onQuote обращалась по неправильному адресу. В результате этого, возникало исключение и возвращало на вершину стека время в милисекундах, которое я задавал в sleep(). Если я не прав, поправьте меня.
Сейчас все работает как часы! Николай, спасибо! Я уже больше месяца решаю эту проблему =). Пошел отмечать =)