Добрый вечер. Столкнулся с такой проблемой: написал скрипт, который должен работать так:
- если нет заявок, то создаем заявку для открытия позиции
- если есть заявка, то ни чего не делаем INFO[trade_data.sec_code]['tiks_waiting'] количество тиков
- если INFO[trade_data.sec_code]['tiks'] количество тиков прошло, то отменяем заявку
- если есть открытая позиция, то через INFO[trade_data.sec_code]['tiks'] количество тиков закрываем позицию.
Проблема в том, что событие OnAllTrade срабатывает не последовательно тик за тиком, а как-то параллельно. То есть может быть несколько тиков одновременно обрабатывает. Из-за этого мой скрипт может открыть сразу 5 позиций. Я пробовал при помощи таблицы INFO[trade_data.sec_code]['ignore_tiks'] сделать блокировку, но эта блокировка не помогает. Какие есть способы эту блокировку создать?
Код |
---|
is_run = true
-- глобальная таблица, в ней хранится информация о тиках и флаг блокировки
INFO = {
["SiU7"]={
['tiks']=4, -- Подсчет тиков, не надо трогать
['tiks_waiting']=4, -- подсчет тиков в ожидании сделки, не надо трогать
['ignore_tiks']=false, -- игнорируем тики, если выполняется какая-то операция, не надо руками трогать
['TIKS_IN_BAR']=10, -- Количество тиков в баре, можно изменять
['TIKS_NOTHING']=4, -- Количество тиков для запроса, можно изменять
['BARS']=5, -- Количество баров для анализа, можно изменять
['WAITING']=10}, -- Количество тиков после выставления заявки, можно изменять
}
TRADE_ACCOUNT = getItem("trade_accounts", 0) -- поменять цифру, если будет ругаться на счет
message(TRADE_ACCOUNT.trdaccid)
order_number = 1
function OnStop(signal)
stopped = true
end
function main()
while not stopped do
sleep(100)
end
end
-- Отменяем просроченную транзакцию, удаляется заявка
function cancel_transaction(trade_data, futures)
INFO[trade_data.sec_code]['tiks_waiting'] = 0
return
-- закрываем позицию, просто выставляется заявка на покупку
function close_position(trade_data, futures)
INFO[trade_data.sec_code]['tiks'] = 0
INFO[trade_data.sec_code]['tiks_waiting'] = 0
return
-- открываем позицию, просто выставляется заявка на продажу
function open_position(trade_data)
INFO[trade_data.sec_code]['tiks'] = 0
INFO[trade_data.sec_code]['tiks_waiting'] = 0
return
function OnAllTrade(trade_data)
if INFO[trade_data.sec_code] == nil then
return
end
if trade_data.sec_code ~= 'SiU7' then
return
end
local bind_available = false
-- сам способ пропускания тиков
if INFO[trade_data.sec_code]['ignore_tiks'] then
return
end
-- блок удаления неиспользованных заявок и закрытия сделок, если долго висит заявка
if getNumberOf("orders") > 0 then
for number_bind = 0, getNumberOf("orders") do
local futures = getItem("orders", number_bind)
if futures ~= nil and futures.sec_code == trade_data.sec_code and bit.band(futures["flags"], 1) == 1 then
-- удаление неиспользованной заявки
if INFO[trade_data.sec_code]['tiks_waiting'] >= INFO[trade_data.sec_code]['WAITING'] then
-- выставляем флаг запрета тиков, выполняем операцию отмены заявки, возвращаем обратно флаг запрета
INFO[trade_data.sec_code]['ignore_tiks'] = true
result = cancel_transaction(trade_data, futures)
INFO[trade_data.sec_code]['ignore_tiks'] = false
message('202')
if result == nil then
bind_available = false
else
message(result)
end
break
else
INFO[trade_data.sec_code]['tiks_waiting'] = INFO[trade_data.sec_code]['tiks_waiting'] + 1
bind_available = true
break
end
end
end
end
-- блок открытых позиций. Если подошло время, закрываем позиции
if not bind_available and getNumberOf("futures_client_holding") > 0 then
for index = 0, getNumberOf("futures_client_holding") do
local futures = getItem("futures_client_holding", index)
if futures ~= nil and futures.sec_code == trade_data.sec_code and futures.totalnet < 0 then
INFO[trade_data.sec_code]['tiks'] = INFO[trade_data.sec_code]['tiks'] + 1
bind_available = true
if INFO[trade_data.sec_code]['tiks'] >= (INFO[trade_data.sec_code]['TIKS_IN_BAR'] * INFO[trade_data.sec_code]['BARS']) then
-- выставляем флаг запрета тиков, выполняем операцию закрытия позиции, возвращаем обратно флаг запрета
INFO[trade_data.sec_code]['ignore_tiks'] = true
result = close_position(trade_data, futures)
INFO[trade_data.sec_code]['ignore_tiks'] = false
if result ~= nil then
message(result)
else
bind_available = false
end
else
INFO[trade_data.sec_code]['tiks'] = INFO[trade_data.sec_code]['tiks'] + 1
end
break
end
end
end
-- если есть заявка или открыта позиция, то позицию не открываем
if bind_available then
return
end
-- блок открытия позиций
INFO[trade_data.sec_code]['tiks_waiting'] = INFO[trade_data.sec_code]['tiks_waiting'] + 1
if INFO[trade_data.sec_code]['tiks_waiting'] >= INFO[trade_data.sec_code]['TIKS_NOTHING'] then
-- выставляем флаг запрета тиков, выполняем операцию открытия позиции, возвращаем обратно флаг запрета
INFO[trade_data.sec_code]['ignore_tiks'] = true
local result = open_position(trade_data)
INFO[trade_data.sec_code]['ignore_tiks'] = false
if result ~= nil then
message(result)
end
return
end
end
|