Работа с OnOrder

Страницы: 1
RSS
Работа с OnOrder
 
простенький робот со скользяшками.
интересующие куски кода:


Код
TRANS_ID = 1

function main()
   while is_run do
        sleep(350)
        robot()
   end
end

function robot()
   --сигнал на вход
   if (price ~= 0) and (need_order) and (quantity_total() < Maximum_quantity) and (quantity_total() > 0-Maximum_quantity) then --проверка на цену, необходимость выставления заявки и что текущее количество не больше разрешенного для лонга/шорта
      SetOrder("B", price, 1) --выставляем заявку
      need_order = false --условие, что есть заявка, то новую не ставим
   end
end

function SetOrder(type, price, qua) -- подать заявку
    Status =  tonumber(getParamEx(ClassCode,  SecCode, "status").param_value);    
    if (Status ~= 1) then 
        writeToLog("Status of " .. SecCode .. " is " .. Status)
        return
    end    
    if  (qua == 0) then
        writeToLog("QUANTITY is 0")
        return
    end
    
    if  (price == 0) then
        writeToLog("Price is 0")
        return
    end
    
    local    trans = {
      ["CLASSCODE"]=ClassCode,
      ["SECCODE"]=SecCode,
      ["ACTION"]="NEW_ORDER",
      ["ACCOUNT"]=ACCOUNT,
      ["CLIENT_CODE"]=CLIENT_CODE,
      ["TYPE"]="L",
      ["OPERATION"]=type,
      ["QUANTITY"]=tostring(qua),
      ["PRICE"]=tostring(price),
      ["TRANS_ID"]=TRANS_ID
                    }        
    local res = sendTransaction(trans)
end

function OnOrder(trans_reply) -- обработка  событий по заявке
    nord = trans_reply["order_num"]  -- номер заявки ORDERNUM    
    
    if nord==nil or nord==0 or nord=="0" then
        message("Заявка не выставилась",1)
        need_order = true
        return        
    elseif tostring(trans_reply["trans_id"]) == tostring(TRANS_ID) then        
        writeToLog(table2string(trans_reply))
        if trans_reply["flags"] == 24 or trans_reply["flags"] == 26 or trans_reply["flags"] == 28 then
            if trans_reply["balance"] == 0 then
                need_order = true --здесь условие, что выставленная заявка выполнилась и дальше контроль только на превышение разрешенного от депо
            end
        end
    end
    
end

вопрос у меня следующего характера. сигналы получаю по идентификатору скользяшки.
НО! функция OnOrder срабатывает три или четыре раза с одинаковыми флагами
вот возвращаемая таблица по функции

withdraw_datetime={week_day=1;hour=0;ms=0;mcs=0;day=1;month=1;sec=0;year=1601;
min=0;};price=10242;value_entry_type=0;balance=0;repo_value_balance=0;value=20
484;qty=2;passive_only_order=0;class_code=SPBFUT;activation_time=0;userid=*****;expiry=-1;flags=28;linkedorder=0;ordernum=********;sec_code=SRH6;s
ide_qualifier=0;client_code=********;firmid=SPBFUT;datetime={week_day=2;hour=13
;ms=937;mcs=937000;day=15;month=12;sec=52;year=2015;min=13;};yield=0;reject_re
ason=;capacity=0;acnt_type=0;repo2value=0;start_discount=0;min_qty=0;ext_order
_flags=0;exec_type=0;order_num=******;repovalue=0;repoterm=0;accruedint=0
;account=******;seccode=SRH6;uid=******;brokerref=********;exchange_code=;settl
ecode=;price2=0;trans_id=1;bank_acc_id=;

и таких строчек несколько. соответственно несколько.
временами заявка срабатывает, а таблица FUTURES_CLIENT_HOLDINGS не обновляет количество в позиции и выставляется новая заявка, которая превышает лимит по возможному количеству.
возврат количества


Код
function quantity_total() --подсчет количество позиций
    local q_total=0
    
    for i = 0,getNumberOf("FUTURES_CLIENT_HOLDINGS") - 1 do
        if getItem("FUTURES_CLIENT_HOLDINGS",i).sec_code == SecCode then -- ЕСЛИ строка по нужному инструменту           
            q_total = getItem("FUTURES_CLIENT_HOLDINGS",i).totalnet
            if q_total== nil then
                return 0
            else
                return q_total -- возвращаем количество позиций
            end
       end;
    end;
    return 0
end

как мне контролировать, чтобы только одна заявка заявка выставлялась?
 
Сохранять номера заявок, для которых был вызов OnOrder.
Кстати, почитайте еще раз справку. OnOrder - это получение терминалом заявки от биржи или изменение каких-то параметров заявки.
А ответ на транзакцию (trans_reply) ловится в событии OnTransReply.
 
делал и на OnTransReply. но не прокатило по такой же причине. переделал на OnOrder.
Цитата
swerg пишет:
охранять номера заявок, для которых был вызов OnOrder.
для чего мне номер заявки? заявка будет одна. мне надо чтобы после выполнения роботу разрешить выставлять новые.

Цитата
swerg пишет:
Кстати, почитайте еще раз справку. OnOrder - это получение терминалом заявки от биржи или изменение каких-то параметров заявки.
цитата из руководства:
Цитата
2.2.4 OnOrder
Функция вызывается терминалом QUIK при получении новой заявки или при изменении
параметров существующей заявки.
догадываюсь что отличие OnOrder от OnTransReply в том, что первый для заявок, второй для всех транзакций (Стоп-заявки, заявки и т.д.)

но в свое время ознакомился с http://forum-archive.quik.ru/forum/lua/113513/113513/
и понравилось то, что "Имейте ввидк, что "OnTransReply может просто не прийти" - цитата сотрудников ARQA. "

оказывается я не одинок. https://forum.quik.ru/forum10/topic996/

идея такая: получил сигнал. выставил заявку. получить колбек по исполнению заявки и значит можно делать новые заявки при сигнале.
при торговле на часовом таймфрейме я могу получать сигналы в течении этого часа и робот может молотить заявки пока не придет обновление о количестве.
 
Ну, не получить OnTransReply - это сильно капец что должно произойти, хоть и возможно.
А "исполнилась заявка" - это значит сделку надо ловить, вообще-то. OnTrade.

По поводу номера заявки: так вы просто сохраните номер заявки, полученный в OnOrder, и если придёт еще один OnOrder с тем же номером заявки - ничего не делайте. сразу выходите из обработчика.
 
Цитата
swerg пишет:
Ну, не получить OnTransReply - это сильно капец что должно произойти, хоть и возможно.
А "исполнилась заявка" - это значит сделку надо ловить, вообще-то. OnTrade.

По поводу номера заявки: так вы просто сохраните номер заявки, полученный в OnOrder, и если придёт еще один OnOrder с тем же номером заявки - ничего не делайте. сразу выходите из обработчика.
логика программы вроде такая:
OnTransReply - колбек на все транзакции (заявки, стоп-заявки и т.д.)
OnOrder - колбек на постановку заявки или изменение состояния заявки (поставилась, исполнена, отменена, частично исполнена, удалена и т.д.)
OnTrade - колбек на сделку.

OnTransReply не подходит, так как будет вызываться чаще и не вызывается на ручные заявки.
OnTrade - не подходит, так как надо проверять по заявке еще и остаток.
по логике мне нужен колбек на OnOrder, чтобы поймать изменение заявки на Исполнена, чтобы разрешить постановку новых заявок. в том числе (позже) обрабатывать мои ручные заявки.
 
Ну т.е. проблема ваша решена, в смысле ответ получен? или что-то еще не понятным осталось?
 
Цитата
swerg пишет:
Ну т.е. проблема ваша решена, в смысле ответ получен? или что-то еще не понятным осталось?
фактически да. пришлось изобретать костыли
 
Может покажете на примере?
 
не получается избавиться от повторных колбеков OnTrade. Поясните пожалуйста, как с этим быть?
 
Здравствуйте,
Избавиться от повторных колбэков в OnTrade нельзя.
Вы можете только предусмотреть их игнорирование в коде, например сравнивая номер сделки.
 
Цитата
просто сохраните номер заявки, полученный в OnOrder, и если придёт еще один OnOrder с тем же номером заявки - ничего не делайте. сразу выходите из обработчика.
Можете примерно показать, как это выглядит на луа?
 
bulat,
Код
transactions = {};

function OnOrder(order)
    if (transactions[order.order_num]) then
        return;
    end
    transactions[order.order_num] = true;

    -- .....
end
 
Вячеслав, отчасти помогло), вместо 3-4 стало   1-2
 
Я уже писал как решать данную проблему.
Повторю еще раз.
Надо контролировать изменение лимитов.
И при их изменении шевелиться с заявками.
тогда будет по ... сколько раз у вас сработает OnOrder
 
Цитата
Надо контролировать изменение лимитов.
И при их изменении шевелиться с заявками.

1. Гарантированно ли при изменении лимита в системе всегда уже есть информация по заявке (сделке), вызвавшей его (лимита) изменение?
2. При постановке (исполнении) нескольких заявок подряд зачастую лимит может измениться только один раз.  
 
 один ... может задать столько вопросов,
на которые 100 умных затрахаются отвечать.
-------------------------
Это сладкое слово - ХАЛЯВА.
 
Пример Вячеслава  работает, проблема была в логике
спасибо.
 
Кажется я понял, что колбэк функция возвращает два состояния заявки - старое и новое

Заявка на Покупку
Дата                                     Номер                  Флаг Dec/Hex/Bin
Thu Aug 13 21:55:00 2020: 26203598248162  25 / #19 / 00011001
Thu Aug 13 21:55:00 2020: 26203598248162  25 / #19 / 00011001
Thu Aug 13 22:12:43 2020: 26203598248162  25 / #19 / 00011001
Thu Aug 13 22:12:43 2020: 26203598248162  26 / #1A / 00011010

Заявка на Продажу
Дата                                     Номер                  Флаг Dec/Hex/Bin
Thu Aug 13 21:56:27 2020: 26203598274028  29 / #1D / 00011101
Thu Aug 13 21:56:27 2020: 26203598274028  29 / #1D / 00011101
Thu Aug 13 22:24:21 2020: 26203598274028  29 / #1E / 00011101
Thu Aug 13 22:24:21 2020: 26203598274028  30 / #1E / 00011110

В случае первого появления заявки оба состояния новые
В случае последующих изменений старое+новое состояние
 
Цитата
Вадим написал:
Кажется я понял, что колбэк функция возвращает два состояния заявки - старое и новое

Заявка на Покупку
Дата                                     Номер                  Флаг Dec/Hex/Bin
Thu Aug 13 21:55:00 2020: 26203598248162  25 / #19 / 00011001
Thu Aug 13 21:55:00 2020: 26203598248162  25 / #19 / 00011001
Thu Aug 13 22:12:43 2020: 26203598248162  25 / #19 / 00011001
Thu Aug 13 22:12:43 2020: 26203598248162  26 / #1A / 00011010

Заявка на Продажу
Дата                                     Номер                  Флаг Dec/Hex/Bin
Thu Aug 13 21:56:27 2020: 26203598274028  29 / #1D / 00011101
Thu Aug 13 21:56:27 2020: 26203598274028  29 / #1D / 00011101
Thu Aug 13 22:24:21 2020: 26203598274028  29 / #1E / 00011101
Thu Aug 13 22:24:21 2020: 26203598274028  30 / #1E / 00011110

В случае первого появления заявки оба состояния новые
В случае последующих изменений старое+новое состояние
Воспринимайте колбек, как сигнал на бесчисленное множество событий, из которых Вам надо очень малое число.
Поэтому не надо пытаться их все понять.
---------------
Надо всегда ставить фильтр лишь того, что нужно.
Остальное - игнорировать.
В реалии  событий может быть хоть тысяча, но вам нужно лишь два.
Вместо того , чтобы выяснять что это за событие, определитесь что же конкретно нужно Вам.
-----------------------
В итоге роботу будут безразличны  все события в мире, кроме тех, которые нужны Вам.
Страницы: 1
Читают тему (гостей: 1)
Наверх