Как в не рабочий день биржи производить отладку qlua скрипта для quik?
или в выходной день положено отдыхать?))
а если серьезно?

require"QL"
log = "sbrf.log"
seccode = "SRM6"
lots_in_trade = 80
accnt = ""
better = -5
chart = "sberbankxxx"
is_run = true
prev_datetime = {}
len = 100
basis = 9
k_bal = {0,1,2,3}
sell = false
buy = false
id = 0
first = true
function trade_signal(shift)
number_of_candles = getNumCandles(chart)
bars_temp,res,legend = getCandlesByIndex(chart,0,number_of_candles-2*len-shift,2*len)
bars={}
i=len
j=2*len
while i>=1 do
if bars_temp[j-1].datetime.hour>=10 then
sk=true
if bars_temp[j-1].datetime.hour==18 and bars_temp[j-1].datetime.min==45 then
sk=false
end
if sk then
bars[i]=bars_temp[j-1]
i=i-1
end
end
j=j-1
end
t = len+1
do_sell = false
do_buy = true
value = 0
if do_sell then value = 1 end
if do_buy then value = -1 end
toLog(log,"value="..value.." on candle: "..bars[len].datetime.year.."-"..bars[len].datetime.month.."-"..bars[len].datetime.day.." "..bars[len].datetime.hour..":"..bars[len].datetime.min.." O="..bars[len].open.." H="..bars[len].high.." L="..bars[len].low.." C="..bars[len].close.." V="..bars[len].volume)
return value
end
function mysplit(inputstr, sep)
if sep == nil then
sep = "%s"
end
local t={} ; i=1
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
t[i] = str
i = i + 1
end
return t
end
function OnInit(path)
log=getScriptPath()..'\\'..log
toLog(log,"==========OnInit: START")
toLog(log,"==========OnInit: FINISH")
end
function OnStop()
is_run = false
toLog(log,"==========OnStop: script finished manually")
end
function CheckBit(flags, bit)
-- Проверяет, что переданные аргументы являются числами
if type(flags) ~= "number" then error("Ошибка!!! Checkbit: 1-й аргумент не число!"); end;
if type(bit) ~= "number" then error("Ошибка!!! Checkbit: 2-й аргумент не число!"); end;
local RevBitsStr = ""; -- Перевернутое (задом наперед) строковое представление двоичного представления переданного десятичного числа (flags)
local Fmod = 0; -- Остаток от деления
local Go = true; -- Флаг работы цикла
while Go do
Fmod = math.fmod(flags, 2); -- Остаток от деления
flags = math.floor(flags/2); -- Оставляет для следующей итерации цикла только целую часть от деления
RevBitsStr = RevBitsStr ..tostring(Fmod); -- Добавляет справа остаток от деления
if flags == 0 then Go = false; end; -- Если был последний бит, завершает цикл
end;
-- Возвращает значение бита
local Result = RevBitsStr :sub(bit+1,bit+1);
if Result == "0" then return 0;
elseif Result == "1" then return 1;
else return nil;
end;
end;
function killorders(ccode,scode)
for i=0,getNumberOf("orders")-1,1 do
local t=getItem("orders", i)
if t ~= nil and type(t) == "table" then
if( t.seccode == scode and CheckBit(t.flags, 0) == 1) then
local transaction={
["TRANS_ID"]=tostring(math.random(2000000000)),
["ACTION"]="KILL_ORDER",
["CLASSCODE"]=ccode,
["SECCODE"]=scode,
["ACCOUNT"] = accnt,
["ORDER_KEY"]=tostring(t.ordernum),
}
res=sendTransaction(transaction)
end
end
end
end
function killstoporders(ccode,scode)
for i=0,getNumberOf("stop_orders")-1,1 do
local t=getItem("stop_orders", i)
if t ~= nil and type(t) == "table" then
if( t.seccode == scode and CheckBit(t.flags, 0) == 1) then
local transaction={
["TRANS_ID"]=tostring(math.random(2000000000)),
["ACTION"]="KILL_STOP_ORDER",
["CLASSCODE"]=ccode,
["SECCODE"]=scode,
["ACCOUNT"] = accnt,
["STOP_ORDER_KEY"]=tostring(t.ordernum),
}
res=sendTransaction(transaction)
end
end
end
end
function main()
toLog(log,"==========main: START")
while is_run do
if isConnected() == 1 then
ss = getInfoParam("SERVERTIME")
if string.len(ss) >= 5 then
hh = mysplit(ss,":")
str=hh[1]..hh[2]
h = tonumber(str)
if (h>=1000 and h<1400) or (h>=1405 and h<1845) or (h>=1905 and h<2350) then
if first then
for ti = 50,2,-1 do trade_signal(ti) end
if buy and not sell then message(seccode.." Current state: green and buy",1) end
if sell and not buy then message(seccode.." Current state: red and sell",1) end
if buy and sell then message(seccode.." ERROR: green and red",1) end
if not buy and not sell then message(seccode.." WARNING: nothing",1) end
first = false
end
prev_candle = getPrevCandle(chart,0)
if not isEqual(prev_candle.datetime,prev_datetime) then
current_value = trade_signal(1)
if current_value ~= 0 then
optn = "B"
if current_value==1 then optn = "S" end
curvol=0
no=getNumberOf("FUTURES_CLIENT_HOLDING")
if no>0 then
for i=0,no-1,1 do
im=getItem("FUTURES_CLIENT_HOLDING", i)
if im.sec_code==seccode then
curvol=im.totalnet
end
end
end
trvol = -current_value*lots_in_trade-curvol
if trvol ~= 0 then
killorders("SPBFUT",seccode)
killstoporders("SPBFUT",seccode)
f = io.open(getScriptPath().."\\sbrf2_pos.txt","r")
sbrf2_pos=f:read("*n")
f:close()
f = io.open(getScriptPath().."\\sbrf3_pos.txt","r")
sbrf3_pos=f:read("*n")
f:close()
pr,n,l = getCandlesByIndex ("futsber", 0, getNumCandles("futsber")-1, 1)
local trans =
{
["ACTION"] = "NEW_ORDER",
["CLASSCODE"] = "SPBFUT",
["SECCODE"] = seccode,
["ACCOUNT"] = accnt,
["OPERATION"] = optn,
["PRICE"] = toPrice(seccode,pr[0].close+current_value*better),
["QUANTITY"] = tostring(math.abs(curvol-sbrf2_pos-sbrf3_pos)),
["TRANS_ID"] = tostring(getTradeDate().month*100+getTradeDate().day+id)
}
id = id+1
--res = sendTransaction(trans)
message(seccode.." Send : " .. res, 2)
toLog(log,"Send: ".. res)
for btr=0,200,5 do
local trans =
{
["ACTION"] = "NEW_STOP_ORDER",
["CLASSCODE"] = "SPBFUT",
["SECCODE"] = seccode,
["ACCOUNT"] = accnt,
["OPERATION"] = optn,
["PRICE"] = toPrice(seccode,pr[0].close-current_value*btr),
["STOPPRICE"] = toPrice(seccode,pr[0].close-current_value*(btr+better)),
["QUANTITY"] = tostring(6),
["TRANS_ID"] = tostring(getTradeDate().month*100+getTradeDate().day+id),
["EXPIRY_DATE"] = "GTC"
}
id = id+1
--res = sendTransaction(trans)
message(seccode.." Send : " .. res, 2)
toLog(log,"Send: ".. res)
end
if current_value == 1 then
message(seccode..' RED: buy->sell',1)
toLog(log,"RED signal")
else
message(seccode..' GREEN: sell->buy',1)
toLog(log,"GREEN signal")
end
else
if current_value == 1 then
message(seccode..' RED: buy->sell',1)
toLog(log,"RED signal, but nothing to do")
else
message(seccode..' GREEN: sell->buy',1)
toLog(log,"GREEN signal, but nothing to do")
end
end
else
if buy and not sell then toLog(log,"Nothing to do. Current state: green and buy",1) end
if sell and not buy then toLog(log,"Nothing to do. Current state: red and sell",1) end
if buy and sell then toLog(log,"Nothing to do. ERROR: green and red",1) end
if not buy and not sell then toLog(log,"Nothing to do. WARNING: nothing",1) end
end
prev_datetime = prev_candle.datetime
end
end
end
end
sleep(5*1000)
end
toLog(log,"==========main: FINISH")
end
















По следам этого поста скрипт на qlua, называется «Светофор».
Суть скрипта- отслеживать дистанцию до «дна», которое представляет собой лои 2008 года+накопленная инфляция.
Подсветка строк:
зеленым- цена ниже уровня инфляции
желтым — до дна менее 50%
красным — до дна более 80%
В чем не смог разобраться:
как получить лой 2008 года по акции (вбито вручную)
как получить полное название компаний (вбито вручную)
как сортировать таблицу (ctrl+клик не помогает)
кто знает — подскажите!
Как это выглядит в Квике:

Бэктест на проливе 2014 года:
Код:
-- Обьявляем переменные
sIsRun=true;
sDate=0;
sDno=0;
sDistance=0;
--Инфляция 2009-2016
sInflation=88.77;
-- Массив с названием компаний
aTickerName= {"Сбербанк", "Газпром", "Лукойл",
"ГМКНорНик", "Система",
"Аэрофлот", "Роснефть", "Транснф",
"ФСК ЕС", "РусГидро", "СеверСталь",
"Новатек", "Магнит", "Татнефть",
"Сургнфтз-п", "М.видео", "ИнтерРАО",
"НЛМК", "ММК", "Россети",
"Ростел", "МТС", "Уркалий"}
-- Массив с тикерами
aTickerList = {"SBER", "GAZP", "LKOH",
"GMKN", "AFKS",
"AFLT", "ROSN", "TRNFP",
"FEES", "HYDR", "CHMF",
"NVTK", "MGNT", "TATN",
"SNGSP", "MVID", "IRAO",
"NLMK", "MAGN", "RSTI",
"RTKM", "MTSS", "URKA"};
-- Массив с лоями 2008 года
aTickerLow2008={14, 86, 740,
1228, 4.5,
20, 94, 6728,
0.054, 0.4, 80,
50, 312, 32.63,
5.16, 24, 0.54,
20, 4.5, 0.6,
14, 100, 25};
function main()
-- Создает таблицу
CreateTable();
-- Основной цикл
while sIsRun do
-- Дата и время
sDate=getInfoParam('TRADEDATE').." "..getInfoParam('SERVERTIME');
-- Перебираем компании: k -порядковый номер, v - название тикера
for k,v in pairs(aTickerList) do
-- Крайняя цена
sBID=tonumber(getParamEx("TQBR", v, "LAST").param_value);
-- Расчетное дно
sDno=math.floor(((aTickerLow2008[k]*(sInflation+100))/100)*100)/100;
-- Сколько до дна %
sDistance=math.floor((100-((sDno*100)/sBID))*100)/100;
-- Вставляем данные в табличку
SetCell(t_id, k, 0, tostring(sDate));
SetCell(t_id, k, 1, tostring(aTickerName[k]));
SetCell(t_id, k, 2, tostring(v));
SetCell(t_id, k, 3, tostring(sBID));
SetCell(t_id, k, 4, tostring(sDno));
SetCell(t_id, k, 5, tostring(sDistance));
-- Раскрашиваем желтым
if sDistance<50 then
Yellow(k);
end;
-- Раскрашиваем красным
if sDistance>80 then
Red(k);
end;
-- Раскрашиваем зеленым
if sDistance<0 then
Green(k);
end;
end;
-- Спим
sleep(50000);
end;
end;
--- Функция создает таблицу
function CreateTable()
-- Получает доступный id для создания
t_id = AllocTable();
-- Добавляет 6 колонок
AddColumn(t_id, 0, "Дата", true, QTABLE_INT_TYPE, 15);
AddColumn(t_id, 1, "Название", true, QTABLE_INT_TYPE, 15);
AddColumn(t_id, 2, "Ticker", true, QTABLE_INT_TYPE, 15);
AddColumn(t_id, 3, "BID", true, QTABLE_INT_TYPE, 15);
AddColumn(t_id, 4, "Расчетное дно", true, QTABLE_INT_TYPE, 15);
AddColumn(t_id, 5, "Сколько до дна (%)", true, QTABLE_INT_TYPE, 15);
-- Создаем
t = CreateWindow(t_id);
-- Даем заголовок
SetWindowCaption(t_id, "Компании");
-- Добавляет строку
for k,v in pairs(aTickerList) do
InsertRow(t_id, k);
end
end;
--- Функции по раскраске ячеек таблицы
function Red(col)
for i=0, 5 do
SetColor(t_id, col, i, RGB(255,168,164), RGB(0,0,0), RGB(255,168,164), RGB(0,0,0));
end;
end;
function Green(col)
for i=0, 5 do
SetColor(t_id, col, i, RGB(157,241,163), RGB(0,0,0), RGB(157,241,163), RGB(0,0,0));
end;
end;
function Yellow(col)
for i=0, 5 do
SetColor(t_id, col, i, RGB(249,247,172), RGB(0,0,0), RGB(249,247,172), RGB(0,0,0));
end;
end;
-- Функция вызывается когда пользователь останавливает скрипт
function OnStop()
sIsRun = false;
end;
ссылка на скрипт
P.S.: не является рекомендацией к покупке/продаже акций, использование программы на ваш страх и риск.
Кросспост rffx.ru