Как для метода OnAllTrade создать глобальную блокировку?

Страницы: 1
RSS
Как для метода OnAllTrade создать глобальную блокировку?
 
Добрый вечер. Столкнулся с такой проблемой: написал скрипт, который должен работать так:
  1. если нет заявок, то создаем заявку для открытия позиции
  2. если есть заявка, то ни чего не делаем INFO[trade_data.sec_code]['tiks_waiting'] количество тиков
  3. если INFO[trade_data.sec_code]['tiks'] количество тиков прошло, то отменяем заявку
  4. если есть открытая позиция, то через 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
 
Проблема Вашего алгоритма в том, что Вы не контролируете состояние робота.
Чтобы не открывать кучу позиций надо реализовать контроль .
Например, если Вы послали заявку на открытие позиции,
то надо отслеживать это состояние и блокировать дальнейшую работу робота,
пока не поступит сигнал о выставлении либо отклонении вашей заявки.
и т д. Все состояния (события) надо контролировать.
------------------------
относительно  OnAllTrade
Это колбек событий. Но события (сделки) приходят пакетом т е сделки с различным временем в одном пакете поступят одновременно.
Если хотите синхронизировать их возникновение то надо обрабатывать время сделки.
 
Спасибо за ответ. Реализовал так алгоритм:

В событии OnAllTrade идет подсчет количества тиков. И все.

В функцию main перенесена вся остальная логика.

Сейчас все выполняется синхронно.
Страницы: 1
Читают тему
Наверх