Ошибка при чтении стакана

Страницы: 1
RSS
Ошибка при чтении стакана
 
В последнее время в робот периодически выдает ошибку чтения стакана и падаете.
Не может прочитать поле price вот в таком коде (ошибка "attempt to index field &"  в строках bidPrice = ... ; offerPrice = ...). Не спрашиваю как ее избежать, как ее обработать чтобы скрипт не падал? Как видите опробовал уже и разные проверочные условия, почему-то все-равно проскакивает...


function bidoffCalc(value) -- value -- таблица-объект с данными об инструменте, включая ссылку на базовый актив и его параметры (tShares.value)
Subscribe_Level_II_Quotes(value.cod, value.sec)
value.tbl =  getQuoteLevel2(value.cod, value.sec) --считываем стакан
-- расчитываем bid ask
local indexBid = tonumber(value.tbl.bid_count);
local indexAsk = tonumber(value.tbl.offer_count);
local bidPrice = 0
local offerPrice = 0
 if indexBid ~= nil then
  if value.tbl.bid then
   bidPrice = tonumber(value.tbl.bid[indexBid].price)  -- !!!!!!!!!!! где-то здесь появляться ссылка на несуществующую переменную выпадает ошибка attemp to index
  end
 end
if indexAsk ~= nil then
if value.tbl.offer then -- если существует соответствующее значение
  offerPrice = tonumber(value.tbl.offer[1].price)
 end
end
return bidPrice, offerPrice -- NUMBER
end
 
В lua есть 2 функции, pcall и xpcall, для перехвата ошибок, которые могут возникнуть при исполнении кода. Посмотрите в документации к языку lua. Например, здесь http://www.lua.ru/doc/5.1.html даётся описание обеих этих функций.
 
Может так?

if value and value.tbl and value.tbl.bid and value.tbl.bid[indexBid] then
    bidPrice = tonumber(value.tbl.bid[indexBid].price)
end

После этого bidPrice будет либо числом либо nil.
 
Цитата
vgi написал:
Может так?

if value and value.tbl and value.tbl.bid and value.tbl.bid[indexBid] then
    bidPrice = tonumber(value.tbl.bid[indexBid].price)
end

После этого bidPrice будет либо числом либо nil.
Пробовал, все-равно ошибка периодически проскакивает. Все-таки хочу понять - как ее обрабатывать, чтобы скрипт не падал, буду изучать ссылку приведенную выше.  
 
Ещё (у меня очень редко) бывает, что терминал глючит и тогда корректный lua-код начинает работать некорректно. Ощущение, что при долгой или интенсивной работе терминала изредка происходят какие-то внутренние ошибки, после чего ссылки на некоторые функции и поля таблиц портятся. Чтобы этого избежать, перезапускаю терминал раз в 2-3 дня.

Надеюсь, что в Вашем случае это, всё-таки, ошибка программиста, и можно это исправить. Попробуйте переписать код так, чтобы не было вот таких фрагментов:
Код
value.tbl.bid[indexBid].price
а были примерно такие:
Код
local tbl = value.tbl
local bids = tbl.bid
local price = bids[indexBid].price
Это позволит локализовать ошибку и избавит от многократных обращений к таблицам (см. повторяющиеся фрагменты типа value.tbl.bid, это, к тому же, замедляет код).

Также, если indexBid равен 0 или nil, то стакан частично или полностью пустой.

А зачем Вам "дальний край" стакана value.tbl.bid[indexBid].price ? Обычно value.tbl.bid[1].price более важное значение.
 
В документации есть нюанс, в который трудно поверить, но тем не менее работает именно так, как написано.  Читаем внимательно про getQuoteLevel2():
Цитата
При отсутствии и спроса и предложения функция возвращает таблицу без параметров bid и offer.
Имеется ввиду, что нет ни спроса, ни предложения.  Буквально.  Если же предложение есть, а спроса нет, то:
Цитата
bid_count  STRING  Количество котировок покупки. При отсутствии спроса возвращается значение «0»
и
Цитата
bid  TABLE  Котировки спроса (покупки). При отсутствии спроса возвращается пустая строка
Внезапно!

В вашем случа видимо происходит следующее (кстати, Subscribe_Level_II_Quotes() можно и нужно делать только один раз, а ни при каждом вызове):
Код
if indexBid ~= nil then  -- 0 ~= nil - истина
   if value.tbl.bid then  -- пустая строка в Lua это истина
      bidPrice = tonumber(value.tbl.bid[indexBid].price)  -- пытаемся индексировать не таблицу, а строку - ошибка 
 
Цитата
_sk_ написал:
А зачем Вам "дальний край" стакана value.tbl.bid[indexBid].price ? Обычно value.tbl.bid[1].price более важное значение.
Это место как раз правильное.  Стакан тупо упорядочен по цене, об удобстве никто не думал, поэтому лучшее предложение в начале массива offer (наименьшая цена), а лучший спрос - в конце массива bid (наибольшая цена).
 
Цитата
kroki написал:
Цитата
_sk_   написал:
А зачем Вам "дальний край" стакана value.tbl.bid[indexBid].price ? Обычно value.tbl.bid[1].price более важное значение.
Это место как раз правильное.  Стакан тупо упорядочен по цене, об удобстве никто не думал, поэтому лучшее предложение в начале массива offer (наименьшая цена), а лучший спрос - в конце массива bid (наибольшая цена).

Спасибо kroki , Вы совершенно верно описали мой резон. Замечание ваше перепроверю на практике.
Я обнаруживал забавное явление. Моя программа дважды в секунду считывает стакан и ведет подсчет неудачных попыток считывания. Я обнаружил, что даже на ликвидных акциях приблизительно в одном случае из двухста попытка считать стакан оказывается неудачной, точнее приходят пустые данные. В любых ситуациях, даже при широком канале. Интересно, с чем это связано?
Страницы: 1
Читают тему
Наверх