Мгновенная отмена заявки

Страницы: 1
RSS
Мгновенная отмена заявки
 
Коллеги, добрый день!

Имеем следующий код (только отрывок который интересует, функции отправки и снятия заявок - 100% рабочие, проверено):

Дело в том, что заявка выставляется и попадает в систему, но следующая за выставлением заявки функция отмены всех заявок не отрабатывает, я так понимаю, потому что заявка ещё не попала в таблицу квика по скорости.
Если функцию отмены перенести в колбэк OnOrder - она снимется.

При тесте,что до запуска скрипта уже есть активные заявки, снимаются все, кроме только что отправленной.

Вопрос - есть возможность как-то быстро снять заявку только-что выставленную? или придется ждать завершения всего кода в OnParam, только после этого отработает OnOrder и я смогу её снять?
Код
function OnParam (class, sec)
.......
if Delta > 0.9 and CurentActiveOrder.image == "Wait" then
        
        --Отправляем заявку
        local id,ms = sendLimit(class,sec,"S",string.format(AUCTPRICE),1,account,client_code,"Коммент")
        --Помещаем в ячейку необходимую фразу
        tbl:SetValue(line_count_table[sec],'ЕстьЗаявка', string.format("Active"))
        --Тут же отменяем все заявки
        local trid,ms = killAllOrders(nil)
end
 
Так же следует отметить, выставление заявки происходит при выполнении условия, вообще ячейку таблицы с "Wait" на "Active" я хотел меня в OnOrder, где флаг заявки бы указывал на то, что она активна, но пока приходит ответ от OnOrder OnParam успевает выставить порядка 4х заявок, тоже беда :(  
 
Александр Правилов,

Что делает функция killAllOrders?
Если перебирает данные в таблице заявок, то да, пока заявка там не появится функция естественно ее не увидит.
То что заявка появляется не в момент отправки транзакции, это нормально, ведь даже у света есть скорость.
Как вариант, можно ловить ответ на транзакцию в OnTransReply и отправлять транзакцию на снятие там.
 
Вся моя проблема в том, что OnParam может прийти несколько раз по одному и тому же инструменту, когда OnOrder только раз.
Проблему нескольких приходов решил с помощью добавления новой колонки таблицы и записи туда переменных, как в коде, но
может возникнуть вот такая проблема, как можете посоветовать её решить? :(

Опишу некую ситуацию:
Стек вызовов
1 OnParam
2 OnParam
3 OnOrder (или OnTransReply)
Код
--Функция выполнилась, транзакция отправлена, переменная "а" меняется на "Активна", но заявка ещё не пришла
1. Функция OnParam 
 Если а == "ждать" тогда
 ОтправитьТранзакцию
 а = "Активна"
 ИначеЕсли а == "Активна" Тогда
 НайтиТранзакцию
 Отменить
 ОтправитьНовуюТранзакцию
 Конец

--Переменная "а" уже "Активна", но функция "НайтиТранзакцию" её не найдет
2. Функция OnParam  Если а == "ждать" тогда
 ОтправитьТранзакцию
 а = "Активна"
 ИначеЕсли а == "Активна" Тогда
 НайтиТранзакцию
 Отменить
 ОтправитьНовуюТранзакцию
 Конец
В таком ключе OnTransReply быстрее отработает?

Сергей,подскажите, у отправленной транзакции есть мой уникальный ID, можно ли отследить данную транзакцию и успеть её отменить до того как она улетела на биржу?
Какие варианты может принимать аргумент ACTION="NEW_ORDER" в транзакции?
 
Надо строить робота на основе событийной модели, тогда таких проблем не будет.
Т е робот - это конечный автомат, который полностью описывается набором его состояний.
Поэтому надо фиксировать эти состояния и программировать условия перехода из одного состояния в другое.
 
Цитата
Николай Камынин написал:
Надо строить робота на основе событийной модели, тогда таких проблем не будет.
Т е робот - это конечный автомат, который полностью описывается набором его состояний.
Поэтому надо фиксировать эти состояния и программировать условия перехода из одного состояния в другое.
Я с Вами полностью согласен, но в lua нет событийности, всё зависит от стека функций об.вызова, как они придут и потока всего два и основной стек находится в одном потоке.
 
Sergey Gorokhov, может мне использовать цикл while внутри onParam? Сделать какую-нибудь переменную в значение false и, если транзакция прошла, ждать пока не появится заявка в таблице с флагом активна?

Или она не прилетит в таблицу пока OnParam не закончится?
 
Цитата
Александр Правилов написал:
Сергей,подскажите, у отправленной транзакции есть мой уникальный ID, можно ли отследить данную транзакцию и успеть её отменить до того как она улетела на биржу?

Как Вы себе это представляете? отправить транзакцию на отмену быстрее чем транзакцию на выставление?
Скорость транзакции никак контролировать нельзя.

Цитата
Александр Правилов написал:
Какие варианты может принимать аргумент ACTION="NEW_ORDER" в транзакции?

Посмотрите документацию на терминал QUIK, "Раздел 6. Совместная работа с другими
приложениями" - "6.11 Импорт транзакций"

Цитата
Александр Правилов написал:
может мне использовать цикл while внутри onParam?
Из описания вообще не понятно зачем Вам OnParam
 
Sergey Gorokhov,в OnParam я получаю необходимые мне данные по инструменту, цена, максимальная цена, средняя цена, цена последняя, цена закрытия и т.п.

И исходя уже из полученных данных выполняю определенные математические операции и сравнения.
 
Цитата
Александр Правилов написал:
И исходя уже из полученных данных выполняю определенные математические операции и сравнения.
И заявка там же подается?
 
Александр Правилов,

Если Вы добавите цикл в OnParam то терминал у Вас просто зависнет и все.
Чем не устраивает предложенный ранее вариант?
Цитата
Sergey Gorokhov написал:
ловить ответ на транзакцию в OnTransReply и отправлять транзакцию на снятие там.
 
Sergey Gorokhov, дело в том, что не обязательно транзакция должна отмениться сразу, оно может должна отмениться в следующий раз

К примеру

Условие: если b > c тогда отправить транзакцию, если c > b тогда отменить (b,c -какие то параметры бумаги)

Стек вызовов:
OnParam
OnParam
OnTransReply
Код
-- OnParam - Отправилась транзакция

b = 5,  c =3
Если b > c Тогда
ОтправитьТранзакцию (Цена = B)
ИначеЕсли c > b Тогда
ОтменитьАктивнуюТранзакцию
ОтправитьТранзакцию( Цена = С)

--2. OnParam - Меняется b и c, а транзакция ещё не дошла

b = 3,  c =5
Если b > c Тогда
ОтправитьТранзакцию (Цена = B)
ИначеЕсли c > b Тогда
ОтменитьАктивнуюТранзакцию       -- Отменять нечего и выставится ещё одна заявка (задвоится)
ОтправитьТранзакцию( Цена = С)

--3. OnTransReply -- По сути уже не нужна
 
Цитата
Александр Правилов написал:
Цитата
Николай  Камынин   написал:
Надо строить робота на основе событийной модели, тогда таких проблем не будет.
Т е робот - это конечный автомат, который полностью описывается набором его состояний.
Поэтому надо фиксировать эти состояния и программировать условия перехода из одного состояния в другое.
Я с Вами полностью согласен, но в lua нет событийности, всё зависит от стека функций об.вызова, как они придут и потока всего два и основной стек находится в одном потоке.
Именно библиотека QLUA и дает Вам механизм событий в виде колбеков, что принципиально отличает ее от QPILE.
Состояние же робота необходимо хранить в таблице состояний - это уже особенности алгоритма. Луа позволяет все это сделать.
 
Николай Камынин, не согласен с вами, колбэками управлять нельзя, они приходят как приходят, посмотрите мой пример выше, как разрулить эту ситуацию?

Sergey Gorokhov,  Сергей, подскажите другой момент, что то не получается получить таблицу заявок, в чем может быть ошибка?

в row=getItem("orders",i) пишет - improperly formatted XML data
Код
 for i=1,getNumberOf("orders") do
   
        local row=getItem("orders",i)
   if row ~= nil and row[sec_code]==sec then

         local trid,ms = killOrder(row[order_num],sec,class)
             if trid ~= nil then
                  tbl:SetValue(line_count_table[sec],'ÅñòüÇàÿâêà', string.format("Cancel"))
                  tbl:SetValue(line_count_table[sec],'ÖåíàÇàÿâêè', string.format("0"))
             end
   end
end
 
Цитата
Александр Правилов написал:
Николай  Камынин  , не согласен с вами, колбэками управлять нельзя, они приходят как приходят, посмотрите мой пример выше, как разрулить эту ситуацию?
А где Я Вам говорил, что колбеками надо управлять(ужас какой-то).
Колбеки - это функции, которые вызываются системой ( в данном случае тарминалом КВИК) при наступлении определенного события.
Т е они сообщают вам о событиях в КВИКЕ и ВСЕ.
---------------------
Когда робот отсылает заявку - то он переходит из состояния - "послать" в состояние - "ждать ответа".
А у Вас нет этих состояний т е Вашему роботу все по... Вот он у вас и шлет кучу заявок и ничего не ждет.
Ну как-то так получается...
 
Цитата
Александр Правилов написал:
в row=getItem("orders",i) пишет - improperly formatted XML data

В интернете говорят что проблема может быть из за кодировки
Файл скрипта должен быть строго в ANSI, а по Вашему примеру кода видно что у Вас это не так.
 
Цитата
Александр Правилов написал:
Николай  Камынин  , не согласен с вами, колбэками управлять нельзя, они приходят как приходят, посмотрите мой пример выше, как разрулить эту ситуацию?

Sergey Gorokhov  ,  Сергей, подскажите другой момент, что то не получается получить таблицу заявок, в чем может быть ошибка?

в row=getItem("orders",i) пишет - improperly formatted XML data
Код
    for  i =  1 , getNumberOf ( "orders" )  do 
   
         local  row =  getItem ( "orders" ,i)
    if  row ~ =   nil   and  row[sec_code] =  = sec  then 

          local  trid,ms  =  killOrder(row[order_num],sec,class)
              if  trid ~ =   nil   then 
                  tbl: SetValue (line_count_table[sec],'ÅñòüÇàÿâêà',  string.format ( "Cancel" ))
                  tbl: SetValue (line_count_table[sec],'ÖåíàÇàÿâêè',  string.format ( "0" ))
              end 
    end 
 end 
  
исправьте кодировку редактора.
 
Николай Камынин, если с кодировкой что-то не то, почему остальной код работает? Николая, подскажите кучочек кода, как перевести в состояние ожидания ответа по заявке?
 
Sergey Gorokhov, переделал скрипт

В режиме отладки, в Decoda, выполняю изменение параметров в функции (один и тот же сеанс)

Если getItem("Orders",i) тогда ошибка xml
Если getItem("Trades",i) тогда всё ок и трейды выдает  
 
Код
is_run = true

function main()

    for i=1,getNumberOf("orders") do
   local row=getItem("orders",i)
   local row=getItem("trades",i)
    end

end 

function OnStop(s)
  is_run = false
  message ("fr", 2)
 
end
 
Sergey Gorokhov,выяснил такой момент, за пятницу было 16 заявок, getItem("orders",i) отрабатывает когда заявка была исполнена, если снята, то показывает ошибку xml
 
Александр Правилов,
Вы читали ссылку которая приведена выше?
Там ведь тоже была речь про decoda
Может быть стоит взглянуть на описанные там рекомендации.
 
Sergey Gorokhov, какой среду разработки вы могли бы порекомендовать?

Да, я переходил по ссылке, но её уже не существует, вылетает просто на форум.

Не соглашусь в этом плане относительно decod'a, ибо я в режиме онлайн могу запросить вместо заявок - сделки и всё будет ок. и если я в режиме онлайн игнорируя эту ошибку пропишу через точку row.order_num к примеру, число выдастся, поэтому в принципе работать можно  
 
Цитата
Александр Правилов написал:
Sergey Gorokhov, какой среду разработки вы могли бы порекомендовать?
Ту, в которой Вам будет удобно.

Цитата
Александр Правилов написал:
Да, я переходил по ссылке, но её уже не существует, вылетает просто на форум.
Ссылка работает, специально проверили на разных компьютерах. У Вас что то не так с браузером?

Цитата
Александр Правилов написал:
Не соглашусь в этом плане относительно decod'a, ибо я в режиме онлайн могу запросить вместо заявок - сделки и всё будет ок. и если я в режиме онлайн игнорируя эту ошибку пропишу через точку row.order_num к примеру, число выдастся, поэтому в принципе работать можно
Это легко проверить, запустив код без decoda
 
Sergey Gorokhov,какая ещё среду позволяет запускать отладку кода подключаясь к квику?

Перепроверю ещё раз ссылку, с браузером всё ок
 
Цитата
Александр Правилов написал:
Sergey Gorokhov,какая ещё среду позволяет запускать отладку кода подключаясь к квику?

Попробуйте поискать в интернете.
У нас нет какого-либо списка подобного ПО.
 
Цитата
Александр Правилов написал:
Николай  Камынин  , если с кодировкой что-то не то, почему остальной код работает? Николая, подскажите кучочек кода, как перевести в состояние ожидания ответа по заявке?
Общий подход работы робота на основе событийной модели следующий.
------------------------
В начале описываете таблицу возможных состояний робота.
Например у меня есть  таблица состояния заявок, таблица состояния стоп-заявок ну и т д.
Эти таблицы в отличии от таблиц квика содержат лишь активные заявки.
-------------------------------------------
Когда посылаете заявку то пишите в конец таблицы запись о том что послали заявку в систему
Когда собираетесь послать заявку то проверяете состояние последней записи в таблице состояния заявок
Если там указано что заявка отправлена брокеру ( т е еще нет подтверждения что она на бирже) то пропускаете отправку новой.
-----------------------------
Ну и т д
 
 
Sergey Gorokhov,можно ли в колбэке OnParam указать код, который поставит OnParam в ожидание прихода другого события, например OnTransReply? Можно ли хоть как-то добиться асинхронности колбэков или какой-нибудь "псевтоасинхронности". на гл.странице сайта квика есть пример, где отправляется транзакция и отслеживается, но там сделано хитро, транзакция отправляется в main, там то понятно, разные потоки, main работает и параллельно приходят колбэки. А как быть если отправить в OnParam?

немного нашел информацию про event, якобы ожидает прихода события, может есть что-то подобное?
 
Николай Камынин,Да дело не в таблице состояний, это не то. Этот способ режет скорость. После отправки транзакции в OnParam есть ещё код и пока этот код не выполнится, не придет ответ от OnTransReply и OnOrder, а надо получить ответы еще при выполнении кода в OnParam.
 
Александр Правилов,

Если Вы остановите колбек, то у Вас зависнет терминал. Именно потому что колбеки идут в одном потоке терминала QUIK и никак это изменить нельзя.
Решение - выставить ожидание в main, а в колбеках использовать флаги, которые будут влиять на поведение цикла в main
 
Sergey Gorokhov, спасибо :(  
 
Цитата
Александр Правилов написал:
Николай  Камынин  ,Да дело не в таблице состояний, это не то. Этот способ режет скорость. После отправки транзакции в OnParam есть ещё код и пока этот код не выполнится, не придет ответ от OnTransReply и OnOrder, а надо получить ответы еще при выполнении кода в OnParam.
Пока исполняется OnParam никакие новые данные с сервера не могут быть обработаны.
Поэтому НЕВОЗМОЖНО находясь в onParam получить ответ OnTransReply и OnOrder,
Полагаю Вы это поняли.
----------------------------
 
Более того, ответ на свою транзакцию Вы будете получать в среднем не ранее чем через  0.1 -0.2 мс.
А это очень даже не мгновенно.
 
Пардон, опечатка.
Более того, ответ на свою транзакцию Вы будете получать в среднем не ранее чем через  0.1 -0.2 сек.
А это очень даже не мгновенно.
 
Николай Камынин, в этом то самая и большая проблема, в невозможности получить ответ, пока не закончится OnParam или не подождать в OnParam, к примеру через event.timer или event.pull, могу ошибаться. Ну да ладно, что-нибудь придумаю, благо для текущего алгоритма, скорость не является приоритетной.  
 
Цитата
Александр Правилов написал:
в этом то самая и большая проблема, в невозможности получить ответ, пока не закончится OnParam или не подождать в OnParam, к примеру через event.timer или event.pull, могу ошибаться.
Да не в этом проблема. А в неверном построении алгоритма.
Николай уже неоднократно обращал на это внимание, но посыл не доходит.

Еще раз: не нужно в callback-функциях что-то делать и чего-то ждать. это тормозит терминал.
Максимум нужно выставить флаги или признаки, и выйти.
А уже основной цикл внутри main() эти флаги должен обнаружить и принять какие-то решения.
 
Цитата
Александр Правилов написал:
Николай  Камынин  , в этом то самая и большая проблема, в невозможности получить ответ, пока не закончится OnParam или не подождать в OnParam, к примеру через event.timer или event.pull, могу ошибаться. Ну да ладно, что-нибудь придумаю, благо для текущего алгоритма, скорость не является приоритетной.
Вы очевидно не понимаете, что это в принципе невозможно в КВИК, так как принятый ответ обрабатывается в том же потоке, где работает функция OnParam. т е ядро процессора (поток) занят этой функцией и обработка новых данных будет после ее завершения. а других потоков для обработки новых данных в КВИКЕ не выделяется т е это так сделан КВИК.
Поэтому, если очень хочется, то надо отказываться от КВИК и подключаться прямо к бирже.
 
есть два варианта ускорить прием ответа.
1) отказаться от onParam
2) во всех колбеках поставить запуск новых потоков и выход из колбека
В этом случае будет максимально быстро выходить из OnParam и др колбеков.
 
Николай Камынин, как можно организовать второй вариант? Есть какая-нибудь рекомендуемая литература? От OnParam не откажусь, не нашел альтернативы в получении специфических параметров.
 
Imersio Arrigo, где в main нужно организовывать очередной цикл для поддержания работы скрипта? Ну как то тоже не интересно.

Николай Камынин,  да  я уже понял, что квик так сделан, и уже принял неизбежность формирования таблицы необходимых мне состояний, просто всё это увеличит кол-во проверяемых условий и общую нагрузку на объем кода.
 
Цитата
Александр Правилов написал:
OnTransReply
Предложу свои решения.
1. Возможно Вам подойдет задание особых параметров заявки - Fill or kill или Kill balance, которые в случае неисполнения уничтожаются автоматически.
2. У меня каждая заявка / позиция выставляется с формированием уникальной для него таблицы с несколькими полями, куда записываются уникальный идентификатор транзакции, номер заявки на сервери биржи и другие параметры, например placed = true  - если получен "положительный" (status = 3) отклик в OnTransReply. Там же фильтруются и вторичные отклики: инфа о полученных откликах сохраняется, если вновь приходит сообщение с тем же номером заявки, что уже приходил ранее, оно игнорируется как повторное. Конструкция сложная, но неизбежная в нашей ситуации
 
Иван Ру, спасибо, я уже понял, что доп.таблицы мне не избежать, буду продумывать как это всё лучше организовать. Kill balance это снятие заявки, если выполнена частично?
 
Sergey Gorokhov, с помощью функции getNumberOf нельзя получить количество строк в созданной скриптом таблице? Сначала показалось, что работает, но видимо показалось :(

Таблица создается, выводится, заполняется (относительно работы с таблицей внешняя библиотека норм работает)

В сount всегда -1
Код
require"QL"

is_run = true

 tblord=QTable:new()
 tblord:SetCaption('Таблица')
 tblord:AddColumn('Security_',QTABLE_STRING_TYPE,15)
 tblord:AddColumn('NameStock_',QTABLE_STRING_TYPE,50)
 tblord:Show()



function main()

   while is_run do
   
      line=tblord:AddLine()
      rand2 = random(1,1000)
      tblord:SetValue(line,'Security_', rand2 )
      tblord:SetValue(line, 'NameStock_', rand2)
      count = getNumberOf("tblord") 
      sleep(500)
   end 
   
end 
 
Александр Правилов,
с помощью функции getNumberOf нельзя получить количество строк в созданной скриптом таблице
 
Александр Правилов,
Для получения количества строк в созданной таблице есть другая функция GetTableSize
 
Sergey Gorokhov,ага, посмотрел... а вот серчайтем не будет работать...ну да ладно :)
 
Цитата
Александр Правилов написал:
Иван Ру  , спасибо, я уже понял, что доп.таблицы мне не избежать, буду продумывать как это всё лучше организовать. Kill balance это снятие заявки, если выполнена частично?
Да
Страницы: 1
Читают тему
Наверх