Добрый день.
Столкнулся со проблемой написания бота, который бы работал автономно без контроля со стороны человека.
Документ
"Использование Lua в Рабочем месте QUIK" предлагает нам целых три подхода написания скриптов.
Первый
"Вся необходимая логика описывается в области <BODY>" для торговых ботов не подходит.
Рссмотрим 2 и 3 подходы на примере простейшей, казалось бы, задачи: определение текущих открытых позиций.
2. Вся необходимая логика описывается в функции с предопределенным именем main().Код |
---|
local LIMIT_KIND = 0
local pos = {}
local run = true
function OnStop()
run = false
end
local function go()
local s = ""
for sec_code, bal in pairs(pos) do
s = s .. sec_code .. ": " .. bal .. "\n"
end
message(s)
end
local function getPosition()
for i = 0, getNumberOf("depo_limits")-1 do
local limit = getItem("depo_limits", i)
if limit.limit_kind == LIMIT_KIND then
pos[limit.sec_code] = limit.currentbal
end
end
for i = 0, getNumberOf("futures_client_holding")-1 do
local limit = getItem("futures_client_holding", i)
if limit.type == 0 then
pos[limit.sec_code] = limit.totalnet
end
end
end
function main()
while isConnected() ~= 1 and run do sleep(100) end
while getNumberOf("depo_limits") == 0 and run do
-- Таблица "позиции по инструментам" не может быть пустой, в ней должна быть хотя бы одна запись
-- Но точное количество записей в таблице не известно, поэтому такой подход работает некорректно
sleep(100)
end
-- С таблицей futures_client_holding сложней, она может быть пустой или не пустой... -- Что делать в этом случае?
if run then
getPosition()
go()
end
end |
3. Событийная модель.Код |
---|
local LIMIT_KIND = 0
local pos = {}
local run = true
function OnStop()
run = false
end
local function go()
local s = ""
for sec_code, bal in pairs(pos) do
s = s .. sec_code .. ": " .. bal .. "\n"
end
message(s)
end
local function getPosition()
for i = 0, getNumberOf("depo_limits")-1 do
local limit = getItem("depo_limits", i)
if limit.limit_kind == LIMIT_KIND then
pos[limit.sec_code] = limit.currentbal
end
end
for i = 0, getNumberOf("futures_client_holding")-1 do
local limit = getItem("futures_client_holding", i)
if limit.type == 0 then
pos[limit.sec_code] = limit.totalnet
end
end
end
function main()
if isConnected() == 1 and getNumberOf("depo_limits") ~= 0 then
getPosition()
else
while isConnected() ~= 1 and run do sleep(100) end
while not get_position and run do sleep(100) end -- Когда уже можно считать, что ВСЕ позиции загружены?
end
if run then go() end
end
function OnDepoLimit(limit)
if limit.limit_kind == LIMIT_KIND then
pos[limit.sec_code] = limit.currentbal
get_position = true -- ???
end
end
function OnFuturesClientHolding(limit)
-- Этот колбек вобще может не прийти, т.к. позиций на срочном рынке может и не быть
if limit.type == 0 then
pos[limit.sec_code] = limit.totalnet
end
end |
Оба скрипта корректно работают, будучи запущенными, когда клиент подключён к серверу и все позиции загружены.
Т.е., нужен контороль со стороны человека, чтобы убедиться, что скрипт определил текущие позиции правильно, и бот может торговать.
Ув. разработчики., могли бы вы оказать поддержку в доработке скрипта, чтобы он корректно работал в любой штатной
* ситуации?
* Здесть имеется ввиду, что ТС биржи и сервер брокера работают штатно, без сбоев.