Добрый день! Я недавно начал интересоваться программированием Луа скриптов для Квика, недавно написал свой скрипт. В нём он использует 2 базы данных: Одну для записи всех транзакций, чтобы пользователь мог их отслеживать, а вторую для записи "Покупок" Чтобы сам скрипт мог отлеживать текущий лимит и цены за которые он делал транзакции. Суть скрипта довольна проста: В случае роста если до этого цена падала, он сравнивает цены из второй базы данных и если ни одно число не равно текущей цене - он покупает, в случае падения если до этого цена росла и хотя бы одно число из второй базы данных меньше текущей цены - чтобы скрипт продавал и вычеркивал эту строку из базы данных. По какой-то причине когда я запускаю скрипт, он не сравнивает никакие цены, соответственно не работает корректно. Помогите мне пожалуйста, я недавно начал и в подобном плохо разбраюсь.
Сам скрипт:
unction OnInit()
--Настройки, изменять при надобности.--
class = "QJSIM" -- Тип интсрумента
sec = "SBER" -- Код интсрумента
account = "NL0011100043" -- Номер аккаунта, тут всё понятно
LotSize = 1 -- Кол-во лотов в заявке.
step = 0.01 -- Шаг цены.
limit = 10 -- Лимит торговли
tid = 0 -- Не трогать!
trz_comment = "FIFO-3 --> " -- Не трогать.
price = nil -- Не трогать.
uprice = nil
dprice = nil
TradeNums = {}
sfilename = "fifobuys"
SellPrice = nil
KillLine = nil
pp = nil
secondfile = io.open('fifobuys.csv', 'r+');
file = io.open("FifoTrades.csv", "r+");
end
function LimitSpot(operation, SpotPrice)
tid = tid+1
transaction={
["TRANS_ID"]=tostring(tid),
["ACTION"]="NEW_ORDER",
["CLASSCODE"]=class,
["SECCODE"]=sec,
["OPERATION"]=operation,
["QUANTITY"]=tostring(LotSize),
["PRICE"]=tostring(SpotPrice),
["ACCOUNT"]=tostring(account),
["EXECUTION_CONDITION"]="PUT_IN_QUEUE", -- тип заявки лимитная
}
res = sendTransaction(transaction)
if res ~= '' then
message(trz_comment..'Transaction Error! '..res)
else
message(trz_comment..'Transaction Success! ID = '..tid)
end
end
function math_round( roundIn , roundDig ) -- первый аргумент число для округления, второй - количество знаков после запятой
local mul = 10^roundDig
return ( math.floor( ( roundIn * mul ) + 0.5 )/mul )
end
function main()
do_main = true
message(trz_comment.."Start.")
climit = 0
while do_main do
sleep(1000)
end
end
function OnParam(class1, sec1)
if class1 == class and sec1 == sec then
local F = 0
local current_line = 0
price = math_round(getParamEx(class, sec, "offer").param_value, 2)
if uprice ~= nil and dprice ~= nil then
if price >= uprice then
for line in secondfile:lines() do
if tonumber(line) == uprice and pp == 0 then F = F+1; end
end
if F == 0 and limit ~= climit then LimitSpot('B', uprice); end
uprice = uprice + step
dprice = dprice + step
message('price++ -> '..uprice)
pp = 1
else if price <= dprice then
for line in secondfile:lines() do
current_line = current_line + 1
if tonumber(line) < dprice and pp == 1 then LimitSpot('S', dprice ); remove_line_from_csv(sfilename, current_line); break end
end
dprice = dprice-step
uprice = uprice-step
message('Price-- -> '..dprice)
pp = 0
end
end
end
end
end
function OnTrade(trade)
if trade.sec_code == sec and trade.class_code == class then
if uprice == nil then
uprice = trade.price + step
dprice = trade.price - step
end
t = bit.band(tonumber(trade['flags']),4) -- 1 = sell 0 = buy
if t == 0 then message(trz_comment.."buy "..trade.price); Op = "Buy"; climit = climit + 1;
secondfile:write(trade.price..'\n');
secondfile:flush();
else message(trz_comment.."Sell "..trade.price); climit = climit - 1; Op = "Sell";
end
for i=#TradeNums,1,-1 do
if TradeNums[i] == trade.trade_num then return; end;
end
-- Если мы здесь, значит сделка не была найдена в числе уже записанных
-- Добавляет в массив номер новой сделки
TradeNums[#TradeNums + 1] = trade.trade_num;
-- Вычисляет операцию сделки
-- Создает строку сделки для записи в файл ("Дата и время;Код класса;Код бумаги;Номер сделки;Номер заявки;Операция;Цена;Количество\n")
local TradeLine = os.date("%c", os.time(trade.datetime))..";"..
trade.class_code..";"..
trade.sec_code..";"..
trade.trade_num..";"..
trade.order_num..";"..
Op..";"..
trade.price..";"..
trade.qty.."\n";
-- Записывает строку в файл
file:write(TradeLine);
-- Сохраняет изменения в файле
file:flush();
end
end
function remove_line_from_csv(filename, line_to_remove)
secondfile:close()
local input_file = io.open(filename..".csv", "r")
if not input_file then
print("Ошибка открытия файла для чтения")
return false
end
local temp_filename = filename .. ".tmp"
local output_file = io.open(temp_filename, "w")
if not output_file then
print("Ошибка открытия временного файла для записи")
input_file:close()
return false
end
local line_number = 1
for line in input_file:lines() do
if line_number ~= line_to_remove then
output_file:write(line .. "\n")
end
line_number = line_number + 1
end
input_file:close()
output_file:close()
-- Удаляем старый файл и переименовываем временный
os.remove(filename..'.csv')
os.rename(temp_filename, filename..".csv")
message("deleted")
secondfile = io.open(filename..'.csv', 'r+')
end
Сам скрипт:
unction OnInit()
--Настройки, изменять при надобности.--
class = "QJSIM" -- Тип интсрумента
sec = "SBER" -- Код интсрумента
account = "NL0011100043" -- Номер аккаунта, тут всё понятно
LotSize = 1 -- Кол-во лотов в заявке.
step = 0.01 -- Шаг цены.
limit = 10 -- Лимит торговли
tid = 0 -- Не трогать!
trz_comment = "FIFO-3 --> " -- Не трогать.
price = nil -- Не трогать.
uprice = nil
dprice = nil
TradeNums = {}
sfilename = "fifobuys"
SellPrice = nil
KillLine = nil
pp = nil
secondfile = io.open('fifobuys.csv', 'r+');
file = io.open("FifoTrades.csv", "r+");
end
function LimitSpot(operation, SpotPrice)
tid = tid+1
transaction={
["TRANS_ID"]=tostring(tid),
["ACTION"]="NEW_ORDER",
["CLASSCODE"]=class,
["SECCODE"]=sec,
["OPERATION"]=operation,
["QUANTITY"]=tostring(LotSize),
["PRICE"]=tostring(SpotPrice),
["ACCOUNT"]=tostring(account),
["EXECUTION_CONDITION"]="PUT_IN_QUEUE", -- тип заявки лимитная
}
res = sendTransaction(transaction)
if res ~= '' then
message(trz_comment..'Transaction Error! '..res)
else
message(trz_comment..'Transaction Success! ID = '..tid)
end
end
function math_round( roundIn , roundDig ) -- первый аргумент число для округления, второй - количество знаков после запятой
local mul = 10^roundDig
return ( math.floor( ( roundIn * mul ) + 0.5 )/mul )
end
function main()
do_main = true
message(trz_comment.."Start.")
climit = 0
while do_main do
sleep(1000)
end
end
function OnParam(class1, sec1)
if class1 == class and sec1 == sec then
local F = 0
local current_line = 0
price = math_round(getParamEx(class, sec, "offer").param_value, 2)
if uprice ~= nil and dprice ~= nil then
if price >= uprice then
for line in secondfile:lines() do
if tonumber(line) == uprice and pp == 0 then F = F+1; end
end
if F == 0 and limit ~= climit then LimitSpot('B', uprice); end
uprice = uprice + step
dprice = dprice + step
message('price++ -> '..uprice)
pp = 1
else if price <= dprice then
for line in secondfile:lines() do
current_line = current_line + 1
if tonumber(line) < dprice and pp == 1 then LimitSpot('S', dprice ); remove_line_from_csv(sfilename, current_line); break end
end
dprice = dprice-step
uprice = uprice-step
message('Price-- -> '..dprice)
pp = 0
end
end
end
end
end
function OnTrade(trade)
if trade.sec_code == sec and trade.class_code == class then
if uprice == nil then
uprice = trade.price + step
dprice = trade.price - step
end
t = bit.band(tonumber(trade['flags']),4) -- 1 = sell 0 = buy
if t == 0 then message(trz_comment.."buy "..trade.price); Op = "Buy"; climit = climit + 1;
secondfile:write(trade.price..'\n');
secondfile:flush();
else message(trz_comment.."Sell "..trade.price); climit = climit - 1; Op = "Sell";
end
for i=#TradeNums,1,-1 do
if TradeNums[i] == trade.trade_num then return; end;
end
-- Если мы здесь, значит сделка не была найдена в числе уже записанных
-- Добавляет в массив номер новой сделки
TradeNums[#TradeNums + 1] = trade.trade_num;
-- Вычисляет операцию сделки
-- Создает строку сделки для записи в файл ("Дата и время;Код класса;Код бумаги;Номер сделки;Номер заявки;Операция;Цена;Количество\n")
local TradeLine = os.date("%c", os.time(trade.datetime))..";"..
trade.class_code..";"..
trade.sec_code..";"..
trade.trade_num..";"..
trade.order_num..";"..
Op..";"..
trade.price..";"..
trade.qty.."\n";
-- Записывает строку в файл
file:write(TradeLine);
-- Сохраняет изменения в файле
file:flush();
end
end
function remove_line_from_csv(filename, line_to_remove)
secondfile:close()
local input_file = io.open(filename..".csv", "r")
if not input_file then
print("Ошибка открытия файла для чтения")
return false
end
local temp_filename = filename .. ".tmp"
local output_file = io.open(temp_filename, "w")
if not output_file then
print("Ошибка открытия временного файла для записи")
input_file:close()
return false
end
local line_number = 1
for line in input_file:lines() do
if line_number ~= line_to_remove then
output_file:write(line .. "\n")
end
line_number = line_number + 1
end
input_file:close()
output_file:close()
-- Удаляем старый файл и переименовываем временный
os.remove(filename..'.csv')
os.rename(temp_filename, filename..".csv")
message("deleted")
secondfile = io.open(filename..'.csv', 'r+')
end