Создание "вечного робота".

Страницы: 1
RSS
Создание "вечного робота"., Переподключение QUIK и Lua-скрипта на следующий день.
 
Добрый день! Ситуация следующая: виртуальный сервер, на нем QUIK, включил скрипт на Lua. На следующий день, после переподключения QUIK скрипт останавливается с ошибкой attempt to index? (a nil value) на строке проверки условия
Код
if ((my_position==0)and(ind==0)and(t[1].close > tt1[0].close)) then      
      ... 
end

точнее на проверке условия (t[1].close > tt1[0].close) (пробовал вынести это условие на отдельную строку, ошибка возникает при проверке именно этого условия).

t[1].close - цена закрытия предыдущей полностью сформировавшейся свечи (5М)
tt1[0].close - предпредыдущее значение индикатора PriceChannel(upper)
Заказываю последние свечи:  t,n,i=getCandlesByIndex("Si_price", 0, N-3, 3), таким образом t[2].close - текущая цена, t[1].close -цена закрытия предыдущей свечи, t[0].close - цена закрытия предпредыдущей свечи.

До переподключения (т.е. всю ночь и до 9:55 (пробовал переподключаться и в 10:16) ) скрипт был запущен, после переподключения QUIK - выключается с ошибкой attempt to index? (a nil value).

скрипт QPILE-подобный, т.е.  пересчитывается каждые 1.5 секунды:
Код
function main()   
   to_log("main_started"
   --message("connection state is " .. tostring(isConnected()), 3)   
   while is_run do
      stime=getSTime() or tonumber(os.date("%H%M%S")
       if ((stime>100030 and stime<184500) or (stime>190030 and stime<235000))  then --не считаем вне сессии   
         if (isConnected()) then
            sleep(1500)
            robot()
         end
         if (isConnected()~=1) then
            to_log("not connected"      
         end
      end         
   end
end

Как исправить ошибку?
Надеюсь, что это моя ошибка в коде, а не что -то из этой (http://forum-archive.quik.ru/forum/lua/122929/122929/) серии.
 
Добрый день,
1) tt1[0]
В Lua принято индексы таблицы начинать с 1. иначе неправильно работает # (размер массива).  

2) попробуйте так:
if ( t~=nil and  tt1~=nil  and  #t>0  and   (my_position==0) and (ind==0) and (t[1].close > tt1[0].close)) then  
 
Цитата
Николай Камынин пишет:
В Lua принято индексы таблицы начинать с 1. иначе неправильно работает # (размер массива).
В QLUA это не принято:

Цитата
getCandlesByIndex

Функция предназначена для получения информации о свечках по идентификатору (заказ данных для построения графика плагин не осуществляет, поэтому для успешного доступа нужный график должен быть открыт).

Формат вызова:

TABLE t, NUMBER n, STRING l getCandlesByIndex (STRING tag, NUMBER line, NUMBER first_candle, NUMBER count)

Параметры:

tag – строковый идентификатор графика или индикатора,
line – номер линии графика или индикатора. Первая линия имеет номер 0,
first_candle – индекс первой свечки. Первая (самая левая) свечка имеет индекс 0
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата

Возвращаемые значения:
  • t – таблица, содержащая запрашиваемые свечки
Где индексы свечек также начинаются с нуля. (В документации об этом почему-то не сказано)
Надо делать так, как надо. А как не надо - делать не надо.
 
пардон,
давно не пользуюсь этой функцией,
поэтому забыл про данный ляп в QLUA.
 
Такая же проблема (ошибка по nil) после обрывов связи хотя проверка на соединение проводится, т.е. если связи нет параметры не должны запрашиваться. Как избежать остановки скрипта при кратковременных обрывах связи?
function main()
     while not stopped do
if (isConnected()==1 and GetServerTimeNumber()~=nil) then
if TimeJob() then  
qtnF=getQuoteLevel2 (ClassCode, nFuture)
bid=qtnF.bid[qtnF.bid_count-0].price
                       ...
                       ...
else
                       ...
                       ...

end
end
sleep(200)
collectgarbage()
end
end
 
Цитата
lergen пишет:
после обрывов связи хотя проверка на соединение проводится, т.е. если связи нет параметры не должны запрашиваться.
Если isConnected()=1, это ещё не значит, что необходимые параметры доступны в таблицах.

Цитата
lergen пишет:
Как избежать остановки скрипта при кратковременных обрывах связи?
Для начала посмотреть номер строки, где возникает ошибка.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Серж пишет:
Для начала посмотреть номер строки, где возникает ошибка.
Ошибка будет вот здесь;
bid=qtnF.bid[qtnF.bid_count-0].price
 
например так:
---------------------------
local qtnF=getQuoteLevel2 (ClassCode, nFuture)

if qtnF~=nil then
     local  bid_=qtnF.bid;  
local  bid_count=qtnF.bid_count;
      if  bid~=nil and bid_count~=0  then
        bid=bid_[bid_count].price
--делаем что надо
--
      end
end
 
isConnected()==1 уже запущен

Но еще не прогружен:
class_code=getSecurityInfo("",seccode).class_code
scale=getSecurityInfo("",seccode) .scale

Как быть с этими запросами?
Они тоже выдают ошибку
 
class_code нужно задавать самому, т.к. нет гарантий, что getSecurityInfo будет всегда возвращать тот класс, который вы подразумеваете.
Надо делать так, как надо. А как не надо - делать не надо.
 
local class_code=(getSecurityInfo("",seccode).class_code or "SPBFUT" )
Чтобы в первые секунды прога не "слетела", думаю можно и так?
Вроде правильно написал,  если не ошибаюсь,
 
1) getSecurityInfo может вернуть nil, если список бумаг ещё не загружен, тогда получите ошибку: "attempt to index a nil value"
2) если seccode содержится в нескольких классах, то getSecurityInfo может вернуть не тот class_code, который вы ожидаете
3) если вы знаете код класса, тогда зачем getSecurityInfo("",seccode).class_code ?
Надо делать так, как надо. А как не надо - делать не надо.
 
а просто getSTime() нельзя использовать для проверки подключения?
 
Для проверки подключения рекомендую делать так:

if getInfoParam("SERVERTIME")==""  then
--подключения нет
else
--подключение есть
end
 
Скорее всего проблема была в том, что робот "просчитывался" до того как в с сервера были получены необходимые данные. После добавления проверок условий типа
Код
local N=getNumCandles("Si_price")  
t,n,i=getCandlesByIndex("Si_price", 0, N-3, 3)  

if ((N>1) and (type(t) =='table') )then ..  
скрипт больше не отрубается.
 
Цитата
Николай Камынин пишет:
например так:
---------------------------
local qtnF=getQuoteLevel2 (ClassCode, nFuture)

if qtnF~=nil then
local bid_=qtnF.bid;
local bid_count=qtnF.bid_count;
if bid~=nil and bid_count~=0 then
bid=bid_[bid_count].price
--делаем что надо
--
end
end
Спасибо - помогло. А вот с проверкой времени сервера не прошел вариант.
 
Цитата
Евгений пишет:
а просто getSTime() нельзя использовать для проверки подключения?
А в QLua или в QPILE есть такая функция?
 
в библиотеке QL есть. Это просто причесанный getInfoParam("SERVERTIME").
 
Цитата
Denis Denisenko написал:
local N=getNumCandles("Si_price")  
t,n,i=getCandlesByIndex("Si_price", 0, N-3, 3)  

if ((N>1) and (type(t) =='table') )then ..  
Отличное решение. Как сделать тоже самое для индикатора, к примеру RSI? Выдаёт ошибку в последней строке - unexpected symbol near '  '.
 
Цитата
Цитата
lergen написал:
Такая же проблема (ошибка по nil) после обрывов связи хотя проверка на соединение проводится, т.е. если связи нет параметры не должны запрашиваться. Как избежать остановки скрипта при кратковременных обрывах связи?
function main()
     while not stopped do
if (isConnected()==1 and GetServerTimeNumber()~=nil) then
if TimeJob() then  
qtnF=getQuoteLevel2 (ClassCode, nFuture)
bid=qtnF.bid[qtnF.bid_count-0].price
                       ...
                       ...
else
                       ...
                       ...

end
end
sleep(200)
collectgarbage()
end
end
Интернет-соединение и соединение с торговым сервером - не одно и то же. Интернет соединение может быть, а соединения с сервером - нет, если не введен пароль или ночью. В таком случае можно и не получить данные таблиц. Я проверяю наличие соединения с сервером пытаясь считать время сервера, если значение возвращаемых полей nil -- значит соединения с сервером нет.
Страницы: 1
Читают тему
Наверх