Имеем следующий код (только отрывок который интересует, функции отправки и снятия заявок - 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
Пользователь
Сообщений: Регистрация: 28.11.2016
14.09.2017 12:38:26
Так же следует отметить, выставление заявки происходит при выполнении условия, вообще ячейку таблицы с "Wait" на "Active" я хотел меня в OnOrder, где флаг заявки бы указывал на то, что она активна, но пока приходит ответ от OnOrder OnParam успевает выставить порядка 4х заявок, тоже беда :(
Что делает функция killAllOrders? Если перебирает данные в таблице заявок, то да, пока заявка там не появится функция естественно ее не увидит. То что заявка появляется не в момент отправки транзакции, это нормально, ведь даже у света есть скорость. Как вариант, можно ловить ответ на транзакцию в OnTransReply и отправлять транзакцию на снятие там.
Пользователь
Сообщений: Регистрация: 28.11.2016
15.09.2017 06:28:01
Вся моя проблема в том, что OnParam может прийти несколько раз по одному и тому же инструменту, когда OnOrder только раз. Проблему нескольких приходов решил с помощью добавления новой колонки таблицы и записи туда переменных, как в коде, но может возникнуть вот такая проблема, как можете посоветовать её решить? :(
--Функция выполнилась, транзакция отправлена, переменная "а" меняется на "Активна", но заявка ещё не пришла
1. Функция OnParam
Если а == "ждать" тогда
ОтправитьТранзакцию
а = "Активна"
ИначеЕсли а == "Активна" Тогда
НайтиТранзакцию
Отменить
ОтправитьНовуюТранзакцию
Конец
--Переменная "а" уже "Активна", но функция "НайтиТранзакцию" её не найдет
2. Функция OnParam Если а == "ждать" тогда
ОтправитьТранзакцию
а = "Активна"
ИначеЕсли а == "Активна" Тогда
НайтиТранзакцию
Отменить
ОтправитьНовуюТранзакцию
Конец
В таком ключе OnTransReply быстрее отработает?
Сергей,подскажите, у отправленной транзакции есть мой уникальный ID, можно ли отследить данную транзакцию и успеть её отменить до того как она улетела на биржу? Какие варианты может принимать аргумент ACTION="NEW_ORDER" в транзакции?
Пользователь
Сообщений: Регистрация: 30.01.2015
15.09.2017 07:16:30
Надо строить робота на основе событийной модели, тогда таких проблем не будет. Т е робот - это конечный автомат, который полностью описывается набором его состояний. Поэтому надо фиксировать эти состояния и программировать условия перехода из одного состояния в другое.
Пользователь
Сообщений: Регистрация: 28.11.2016
15.09.2017 07:31:26
Цитата
Николай Камынин написал: Надо строить робота на основе событийной модели, тогда таких проблем не будет. Т е робот - это конечный автомат, который полностью описывается набором его состояний. Поэтому надо фиксировать эти состояния и программировать условия перехода из одного состояния в другое.
Я с Вами полностью согласен, но в lua нет событийности, всё зависит от стека функций об.вызова, как они придут и потока всего два и основной стек находится в одном потоке.
Пользователь
Сообщений: Регистрация: 28.11.2016
15.09.2017 07:48:29
Sergey Gorokhov, может мне использовать цикл while внутри onParam? Сделать какую-нибудь переменную в значение false и, если транзакция прошла, ждать пока не появится заявка в таблице с флагом активна?
Или она не прилетит в таблицу пока OnParam не закончится?
Пользователь
Сообщений: Регистрация: 23.01.2015
15.09.2017 08:52:30
Цитата
Александр Правилов написал: Сергей,подскажите, у отправленной транзакции есть мой уникальный ID, можно ли отследить данную транзакцию и успеть её отменить до того как она улетела на биржу?
Как Вы себе это представляете? отправить транзакцию на отмену быстрее чем транзакцию на выставление? Скорость транзакции никак контролировать нельзя.
Цитата
Александр Правилов написал: Какие варианты может принимать аргумент ACTION="NEW_ORDER" в транзакции?
Посмотрите документацию на терминал QUIK, "Раздел 6. Совместная работа с другими приложениями" - "6.11 Импорт транзакций"
Цитата
Александр Правилов написал: может мне использовать цикл while внутри onParam?
Из описания вообще не понятно зачем Вам OnParam
Пользователь
Сообщений: Регистрация: 28.11.2016
15.09.2017 09:17:05
Sergey Gorokhov,в OnParam я получаю необходимые мне данные по инструменту, цена, максимальная цена, средняя цена, цена последняя, цена закрытия и т.п.
И исходя уже из полученных данных выполняю определенные математические операции и сравнения.
Пользователь
Сообщений: Регистрация: 02.07.2015
15.09.2017 09:30:53
Цитата
Александр Правилов написал: И исходя уже из полученных данных выполняю определенные математические операции и сравнения.
Если Вы добавите цикл в OnParam то терминал у Вас просто зависнет и все. Чем не устраивает предложенный ранее вариант?
Цитата
Sergey Gorokhov написал: ловить ответ на транзакцию в OnTransReply и отправлять транзакцию на снятие там.
Пользователь
Сообщений: Регистрация: 28.11.2016
15.09.2017 10:28:56
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. Состояние же робота необходимо хранить в таблице состояний - это уже особенности алгоритма. Луа позволяет все это сделать.
Пользователь
Сообщений: Регистрация: 28.11.2016
15.09.2017 12:56:26
Николай Камынин, не согласен с вами, колбэками управлять нельзя, они приходят как приходят, посмотрите мой пример выше, как разрулить эту ситуацию?
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
Пользователь
Сообщений: Регистрация: 30.01.2015
15.09.2017 13:37:53
Цитата
Александр Правилов написал: Николай Камынин , не согласен с вами, колбэками управлять нельзя, они приходят как приходят, посмотрите мой пример выше, как разрулить эту ситуацию?
А где Я Вам говорил, что колбеками надо управлять(ужас какой-то). Колбеки - это функции, которые вызываются системой ( в данном случае тарминалом КВИК) при наступлении определенного события. Т е они сообщают вам о событиях в КВИКЕ и ВСЕ. --------------------- Когда робот отсылает заявку - то он переходит из состояния - "послать" в состояние - "ждать ответа". А у Вас нет этих состояний т е Вашему роботу все по... Вот он у вас и шлет кучу заявок и ничего не ждет. Ну как-то так получается...
Пользователь
Сообщений: Регистрация: 23.01.2015
15.09.2017 14:07:29
Цитата
Александр Правилов написал: в row=getItem("orders",i) пишет - improperly formatted XML data
В говорят что проблема может быть из за кодировки Файл скрипта должен быть строго в ANSI, а по Вашему примеру кода видно что у Вас это не так.
Пользователь
Сообщений: Регистрация: 30.01.2015
16.09.2017 06:26:41
Цитата
Александр Правилов написал: Николай Камынин , не согласен с вами, колбэками управлять нельзя, они приходят как приходят, посмотрите мой пример выше, как разрулить эту ситуацию?
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
исправьте кодировку редактора.
Пользователь
Сообщений: Регистрация: 28.11.2016
16.09.2017 09:33:06
Николай Камынин, если с кодировкой что-то не то, почему остальной код работает? Николая, подскажите кучочек кода, как перевести в состояние ожидания ответа по заявке?
В режиме отладки, в Decoda, выполняю изменение параметров в функции (один и тот же сеанс)
Если getItem("Orders",i) тогда ошибка xml Если getItem("Trades",i) тогда всё ок и трейды выдает
Пользователь
Сообщений: Регистрация: 28.11.2016
17.09.2017 11:49:00
Код
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
Пользователь
Сообщений: Регистрация: 28.11.2016
17.09.2017 11:56:19
Sergey Gorokhov,выяснил такой момент, за пятницу было 16 заявок, getItem("orders",i) отрабатывает когда заявка была исполнена, если снята, то показывает ошибку xml
Пользователь
Сообщений: Регистрация: 23.01.2015
18.09.2017 10:15:14
Александр Правилов, Вы читали ссылку которая приведена выше? Там ведь тоже была речь про decoda Может быть стоит взглянуть на описанные там рекомендации.
Пользователь
Сообщений: Регистрация: 28.11.2016
18.09.2017 10:21:01
Sergey Gorokhov, какой среду разработки вы могли бы порекомендовать?
Да, я переходил по ссылке, но её уже не существует, вылетает просто на форум.
Не соглашусь в этом плане относительно decod'a, ибо я в режиме онлайн могу запросить вместо заявок - сделки и всё будет ок. и если я в режиме онлайн игнорируя эту ошибку пропишу через точку row.order_num к примеру, число выдастся, поэтому в принципе работать можно
Пользователь
Сообщений: Регистрация: 23.01.2015
18.09.2017 10:26:17
Цитата
Александр Правилов написал: Sergey Gorokhov, какой среду разработки вы могли бы порекомендовать?
Ту, в которой Вам будет удобно.
Цитата
Александр Правилов написал: Да, я переходил по ссылке, но её уже не существует, вылетает просто на форум.
Ссылка работает, специально проверили на разных компьютерах. У Вас что то не так с браузером?
Цитата
Александр Правилов написал: Не соглашусь в этом плане относительно decod'a, ибо я в режиме онлайн могу запросить вместо заявок - сделки и всё будет ок. и если я в режиме онлайн игнорируя эту ошибку пропишу через точку row.order_num к примеру, число выдастся, поэтому в принципе работать можно
Это легко проверить, запустив код без decoda
Пользователь
Сообщений: Регистрация: 28.11.2016
18.09.2017 10:30:31
Sergey Gorokhov,какая ещё среду позволяет запускать отладку кода подключаясь к квику?
Перепроверю ещё раз ссылку, с браузером всё ок
Пользователь
Сообщений: Регистрация: 23.01.2015
18.09.2017 10:31:53
Цитата
Александр Правилов написал: Sergey Gorokhov,какая ещё среду позволяет запускать отладку кода подключаясь к квику?
Попробуйте поискать в интернете. У нас нет какого-либо списка подобного ПО.
Пользователь
Сообщений: Регистрация: 30.01.2015
18.09.2017 11:47:08
Цитата
Александр Правилов написал: Николай Камынин , если с кодировкой что-то не то, почему остальной код работает? Николая, подскажите кучочек кода, как перевести в состояние ожидания ответа по заявке?
Общий подход работы робота на основе событийной модели следующий. ------------------------ В начале описываете таблицу возможных состояний робота. Например у меня есть таблица состояния заявок, таблица состояния стоп-заявок ну и т д. Эти таблицы в отличии от таблиц квика содержат лишь активные заявки. ------------------------------------------- Когда посылаете заявку то пишите в конец таблицы запись о том что послали заявку в систему Когда собираетесь послать заявку то проверяете состояние последней записи в таблице состояния заявок Если там указано что заявка отправлена брокеру ( т е еще нет подтверждения что она на бирже) то пропускаете отправку новой. ----------------------------- Ну и т д
Пользователь
Сообщений: Регистрация: 28.11.2016
18.09.2017 13:17:29
Sergey Gorokhov,можно ли в колбэке OnParam указать код, который поставит OnParam в ожидание прихода другого события, например OnTransReply? Можно ли хоть как-то добиться асинхронности колбэков или какой-нибудь "псевтоасинхронности". на гл.странице сайта квика есть пример, где отправляется транзакция и отслеживается, но там сделано хитро, транзакция отправляется в main, там то понятно, разные потоки, main работает и параллельно приходят колбэки. А как быть если отправить в OnParam?
немного нашел информацию про event, якобы ожидает прихода события, может есть что-то подобное?
Пользователь
Сообщений: Регистрация: 28.11.2016
18.09.2017 13:19:15
Николай Камынин,Да дело не в таблице состояний, это не то. Этот способ режет скорость. После отправки транзакции в OnParam есть ещё код и пока этот код не выполнится, не придет ответ от OnTransReply и OnOrder, а надо получить ответы еще при выполнении кода в OnParam.
Если Вы остановите колбек, то у Вас зависнет терминал. Именно потому что колбеки идут в одном потоке терминала QUIK и никак это изменить нельзя. Решение - выставить ожидание в main, а в колбеках использовать флаги, которые будут влиять на поведение цикла в main
Александр Правилов написал: Николай Камынин ,Да дело не в таблице состояний, это не то. Этот способ режет скорость. После отправки транзакции в OnParam есть ещё код и пока этот код не выполнится, не придет ответ от OnTransReply и OnOrder, а надо получить ответы еще при выполнении кода в OnParam.
Пока исполняется OnParam никакие новые данные с сервера не могут быть обработаны. Поэтому НЕВОЗМОЖНО находясь в onParam получить ответ OnTransReply и OnOrder, Полагаю Вы это поняли. ----------------------------
Пользователь
Сообщений: Регистрация: 30.01.2015
18.09.2017 18:37:46
Более того, ответ на свою транзакцию Вы будете получать в среднем не ранее чем через 0.1 -0.2 мс. А это очень даже не мгновенно.
Пользователь
Сообщений: Регистрация: 30.01.2015
18.09.2017 18:38:30
Пардон, опечатка. Более того, ответ на свою транзакцию Вы будете получать в среднем не ранее чем через 0.1 -0.2 сек. А это очень даже не мгновенно.
Пользователь
Сообщений: Регистрация: 28.11.2016
19.09.2017 06:57:23
Николай Камынин, в этом то самая и большая проблема, в невозможности получить ответ, пока не закончится OnParam или не подождать в OnParam, к примеру через event.timer или event.pull, могу ошибаться. Ну да ладно, что-нибудь придумаю, благо для текущего алгоритма, скорость не является приоритетной.
Пользователь
Сообщений: Регистрация: 02.07.2015
19.09.2017 07:32:46
Цитата
Александр Правилов написал: в этом то самая и большая проблема, в невозможности получить ответ, пока не закончится OnParam или не подождать в OnParam, к примеру через event.timer или event.pull, могу ошибаться.
Да не в этом проблема. А в неверном построении алгоритма. Николай уже неоднократно обращал на это внимание, но посыл не доходит.
Еще раз: не нужно в callback-функциях что-то делать и чего-то ждать. это тормозит терминал. Максимум нужно выставить флаги или признаки, и выйти. А уже основной цикл внутри main() эти флаги должен обнаружить и принять какие-то решения.
Пользователь
Сообщений: Регистрация: 30.01.2015
19.09.2017 07:37:15
Цитата
Александр Правилов написал: Николай Камынин , в этом то самая и большая проблема, в невозможности получить ответ, пока не закончится OnParam или не подождать в OnParam, к примеру через event.timer или event.pull, могу ошибаться. Ну да ладно, что-нибудь придумаю, благо для текущего алгоритма, скорость не является приоритетной.
Вы очевидно не понимаете, что это в принципе невозможно в КВИК, так как принятый ответ обрабатывается в том же потоке, где работает функция OnParam. т е ядро процессора (поток) занят этой функцией и обработка новых данных будет после ее завершения. а других потоков для обработки новых данных в КВИКЕ не выделяется т е это так сделан КВИК. Поэтому, если очень хочется, то надо отказываться от КВИК и подключаться прямо к бирже.
Пользователь
Сообщений: Регистрация: 30.01.2015
19.09.2017 07:44:41
есть два варианта ускорить прием ответа. 1) отказаться от onParam 2) во всех колбеках поставить запуск новых потоков и выход из колбека В этом случае будет максимально быстро выходить из OnParam и др колбеков.
Пользователь
Сообщений: Регистрация: 28.11.2016
19.09.2017 08:44:13
Николай Камынин, как можно организовать второй вариант? Есть какая-нибудь рекомендуемая литература? От OnParam не откажусь, не нашел альтернативы в получении специфических параметров.
Пользователь
Сообщений: Регистрация: 28.11.2016
19.09.2017 08:47:56
Imersio Arrigo, где в main нужно организовывать очередной цикл для поддержания работы скрипта? Ну как то тоже не интересно.
Николай Камынин, да я уже понял, что квик так сделан, и уже принял неизбежность формирования таблицы необходимых мне состояний, просто всё это увеличит кол-во проверяемых условий и общую нагрузку на объем кода.
Предложу свои решения. 1. Возможно Вам подойдет задание особых параметров заявки - Fill or kill или Kill balance, которые в случае неисполнения уничтожаются автоматически. 2. У меня каждая заявка / позиция выставляется с формированием уникальной для него таблицы с несколькими полями, куда записываются уникальный идентификатор транзакции, номер заявки на сервери биржи и другие параметры, например placed = true - если получен "положительный" (status = 3) отклик в OnTransReply. Там же фильтруются и вторичные отклики: инфа о полученных откликах сохраняется, если вновь приходит сообщение с тем же номером заявки, что уже приходил ранее, оно игнорируется как повторное. Конструкция сложная, но неизбежная в нашей ситуации
Пользователь
Сообщений: Регистрация: 28.11.2016
21.09.2017 06:24:23
Иван Ру, спасибо, я уже понял, что доп.таблицы мне не избежать, буду продумывать как это всё лучше организовать. Kill balance это снятие заявки, если выполнена частично?
Пользователь
Сообщений: Регистрация: 28.11.2016
21.09.2017 13:27:57
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
Пользователь
Сообщений: Регистрация: 23.01.2015
21.09.2017 13:28:53
Александр Правилов, с помощью функции getNumberOf нельзя получить количество строк в созданной скриптом таблице
Пользователь
Сообщений: Регистрация: 23.01.2015
21.09.2017 13:33:24
Александр Правилов, Для получения количества строк в созданной таблице есть другая функция GetTableSize
Пользователь
Сообщений: Регистрация: 28.11.2016
21.09.2017 18:38:53
Sergey Gorokhov,ага, посмотрел... а вот серчайтем не будет работать...ну да ладно :)
Пользователь
Сообщений: Регистрация: 04.09.2016
21.09.2017 21:35:48
Цитата
Александр Правилов написал: Иван Ру , спасибо, я уже понял, что доп.таблицы мне не избежать, буду продумывать как это всё лучше организовать. Kill balance это снятие заявки, если выполнена частично?