Транзакции на снятие Лимит. заявки

Страницы: 1
RSS
Транзакции на снятие Лимит. заявки
 
Есть участок кода:
function DeleteAllProfit(acc, emit, class, file, prevString) --ФУНКЦИЯ УДАЛЕНИЯ ВСЕХ ТЕЙК-ПРОФИТОВ
   local N = getNumberOf("orders")
   local count = 0
   for i = 0, N - 1 do
       local row = getItem("orders", i)
       if (row.account == acc and row.sec_code == emit and row.class_code == class) then
           if (bit.band(row.flags,1) > 0) then
               local keyNumber = row.order_num
               DeleteProfitByNumber(emit, class, keyNumber, file, prevString)
               count = count + 1
           end
       end
   end
return count
end

function DeleteProfitByNumber(emit, class, keyNumber, file, prevString) --ФУНКЦИЯ УДАЛЕНИЯ ЗАЯВКИ ПО НОМЕРУ
transaction = { ["CLASSCODE"] = class,
                       ["SECCODE"] = emit,
                       ["TRANS_ID"] = "123",
                       ["ACTION"] = "KILL_ORDER",
                       ["ORDER_KEY"] = tostring(keyNumber),
                       ["CLIENT_CODE"] = "accountSL",
                      }
sendTransaction(transaction)
end

Вопрос: почему при вызове функции "DeleteAllProfit " заявка удаляется правильно, но одновременно выскакивает ошибка в Квике:Ошибка снятия заявки. [GW][14] "Не найдена заявка для удаления"?  
 
Скрин
 
Возможно, Ваш кусок кода тоже в цикле. После отправки заявки на снятие изменения в самой таблице происходят не сразу. Изменения еще не произошли, а Вы по следующему шагу цикла(который Вами не представлен) видите, что заявка еще активна. Хотя заявка на снятие уже отправлена на предыдущем шаге.
Попробуйте после
DeleteProfitByNumber(emit, class, keyNumber, file, prevString)
поставить задержку с ожиданием в таблице заявок реакции на эту функцию.
 
Функция вызывается вот этим кодом:

if (PosNow == 0 or (PosNow ~= 0 and SignFunc(PosNow) ~= SignFunc(PrevPos)))then
   DeleteAllProfit(MyAccount, Emit, Class, FileLog,  "Удаление ПРОФИТА при перевороте или нулевой позе")
end

Если текущая поза равна нулю или был переворот позиции, то удаляются все профиты.
 
Поставил задержку (пробовал от 1 до 5 секунд) теперь вот что выдает:
 
Станислав, У меня давно стоит снятие несработавших заявок через 3 минуты, при этом я ищу заявку в таблице "orders" и, если она всё ещё активна, подаю команду KILL_ORDER. Исполнение команды не контролирую никак - считаю, что как-нибудь будет снята. Так вот: мой личный "рекорд", когда заявка сработала, будучи либо уже неактивной на момент снятия либо после получения команды на снятие, составляет СЕМНАДЦАТЬ С ПОЛОВИНОЙ МИНУТ!!!
 
Цитата
Станислав написал:
Поставил задержку (пробовал от 1 до 5 секунд) теперь вот что выдает:
очевидно, Вы неправильно организовали процесс снятия заявки.
-------------------
рассказываю упрощенно как сделано у меня. Тестировал на выставлении и снятии заявок в цикле.
Всего было выставлено и снято 200 тысяч заявок по 200 инструментам без подобных сообщений .
---------------
Выставление и снятие заявок реализуется по похожим алгоритмам.
Необходимо обрабатывать состояние не только заявки но и транзакции.
Чтобы не перебирать таблицу заявок, а для 200 тысяч заявок упаритесь это делать,
я веду учет индексов активных заявок по каждому инструменту, а также индексы активных транзакций.
Процедура подачи или снятия заявок состоит из двух блоков.
-----------------  
Логика процесса такая.
Из таблицы активных заявок выбирается та, которую надо снять.
Она отмечается меткой, что мы ее снимаем.
Формируем транзакцию и отправляем на сервер.
по транзакции возможны две ошибки
При ее проверке терминалом и при ее проверке сервером.
Если возникает ошибка, то транзакция удаляется и снимается отметка с заявки.
процесс повторяется снова.
---------------
Так как инструментов много и заявки по ним выставляются асинхронно , то для транзакций организована очередь на исполнение.
---------------
Если сервер выставил заявку на биржу то приходит сообщение в колбек транзакции
Это сообщение приходит раньше чем сообщение о снятии в таблицу заявок.
Я использую это сообщение как сигнал снятие заявки, но обрабатываю сообщение о снятии которое приходит в колбек заявки
и отмечаю что заявка снята окончательно и удаляю ее из таблицы активных заявок.
------------------
В результате , заявка снимается за время как правило не более десятых долей секунды.
--------------
Количество инструментов  практически не влияет на скорость исполнения.
 
колбеки заявок и транзакций исполняются примерно за 1...5 мкс
 
В итогу у меня все работает примерно в 100- 1000 раз быстрее, чем у Вас.
 
nikolz, Лапуль, по пунктам:

1. Заявки подаются для того, чтобы по ним происходили сделки - так поступают все нормальные трейдеры (кукловодов и идиотов в расчёт не берём).

2. Если "всего было выставлено и снято 200 тысяч заявок по 200 инструментам", то это суходроч с заявками без сделок, что означает либо что Вас вообще не интересуют сделки либо у Вас нет хоть сколько-нибудь нормального алгоритма выставления заявок.

3. Фраза "Необходимо обрабатывать состояние не только заявки но и транзакции" глупа. Лично я не обрабатываю ни то, ни другое - это называется "искать на свою задницу приключений" - хотя бы потому, что системный софт в Квике просто ужасен, и крайне желательно сократить общение с ним до минимально необходимого количества (лично у меня это прерывание OnTrade и обращение к таблице orders, что я считаю самым оптимальным вариантом из всех возможных).

4. Перебирать таблицу заявок на 200 тысяч заявок - идиотизм, и не потому, что "упаритесь это делать", а потому, что это ИДИОТИЗМ!

5. Где Вы выкопали "таблицу активных заявок"? Таблица "orders" - это таблица ВСЕХ заявок - активных, неактивных, исполненных, частично исполненных или снятых.

6. Любой нормальный человек ведёт учёт своих активных заявок по каждому инструменту - это нетрудно: количество таких заявок лично у меня очень редко превышает 1-2 десятка даже при тысячах обслуживаемых тикеров. Что же касается ИНДЕКСОВ активных заявок - а откуда Вы их, собссно, знаете? ID заявки формируется не Вами, в отличие от ID транзакции (что есть ещё один идиотизм: обеспечение уникальности идентификатора транзакции возлагается на юзера, а в 99 случаях из 100 это малоквалифицированные программисты вроде Вас).

7. Идиотизмом также являются решения как повеситься на все возможные прерывания, так и беготня по всем таблицам по которым можно бегать: нормальные люди снимают заявки ПО ТАЙМЕРУ! Это даёт возможность плевать сто раз на то, будет ли заявка принята или отвергнута кем бы то ни было: если она не привела к сделке, значит, она неудачная (по ЛЮБЫМ причинам). И с какого бодуна "из таблицы активных заявок выбирается та, которую надо снять"? Вы что, сами не знаете заявки, которую хотите снять? А на кой тогда Вы вообще ведёте свой учёт своих активных заявок? Ах, Вы айдишки её не знаете? Да, бывает такое - У МЕНЯ бывает, поскольку я вешаюсь только на OnTrade, и если по заявке не было ни одной сделки, я этого не знаю и знать не могу. Именно в таких случаях (очень редких случаях, поскольку более 90% моих заявок исполняются в течение пары секунд) я и лезу в таблицу "orders", чтобы узнать ID заявки, которую я хочу снять, если она до сих пор активна - как правило, это менее 10 раз в сутки. При этом выполнение команды на снятие я вообще никак не контролирую - смысла нет: вдруг она исполнилась именно в тот момент, когда я подал транзакцию на снятие или команда эта по каким-либо причинам не прошла. А потому скрипт сразу же после отправки команды считает, что заявка снята (в подавляющем большинстве случаев это так и есть), но паспорт заявки из стека не удаляет до конца сессии - если вдруг эта "снятая" заявка сработает, мы будем знать, что это именно НАША заявка сработала. Если же заявка исполнена полностью (что опять-таки происходит в подавляющем большинстве случаев), то нам вообще плевать, что там кто по этому поводу думает - мы тут же можем удалять и паспорт из стека - ну, придут дубли этой же сделки - игнорируем: заявка больше НЕ НАША.

8. Интернет - такая штука, что никто В ПРИНЦИПЕ не может гарантировать, что "это сообщение приходит раньше чем сообщение о снятии в таблицу заявок", и закладываться на это в алгоритме - очередной идиотизм.

Занялись бы Вы лучше чем-нибудь полезным, лапуль. Ну не Ваша это зона "программирование", ну не Ваша.  :wink:  
 
Это все, конечно, замечательно, но может кто-нибудь скинет этот кусок кода, который нормально умеет снимать заявки? (если не жалко конечно)
 
Код, снимающий заявки у Вас написан, какой бы он ни был.

А далее есть вопросы организации последовательности вызовов методов. Необходимо учитывать, что скрипт работает на клиенте, а ответы приходят с сервера. Т.е. время ответа неизвестно.
Далее, если используете колбеки, то необходимо учитывать, что последовательность их прихода не гарантирована. Также, раз у нас клиент-сервер, то изменение состояния ордера после отправки транзакции на снятие, не придет мгновенно. Т.е. если транзакция на снятие ушла без ошибок, то пока не придет ответ или не прочитаете новое состояние ордера, отправлять новую транзакцию нельзя. Иначе возникнет ситуация когда отправили транзакцию на снятие, не дождались ответа и отправили новую.

Поэтому просто кусок кода ничего не даст.
 
В общем пока здесь демагогию разводили, код заработал как-то сам, причем правильно)) Не знаю как это получилось.. Всем спасибо за ответы :lol:  
 
Nikolay, Всё ещё хуже: что последовательность их прихода не гарантирована - это полбеды, это, так сказать, пройденный этап. Вот фрагмент одного моего исследования подобных ситуаций:

Трижды прерывания о сделках приходили уже после снятия соответствующих заявок:
17:46:52 заявка подана, 17:50:19 снята, 17:52:41 пришла колода прерываний (почти 6 минут)
17:56:16 заявка подана, 17:59:47 снята, 18:02:57 пришла колода прерываний (более 6 минут)
18:12:32 заявка подана, 18:15:57 снята, 18:30:01 пришла колода прерываний (17.5 минут!!!)

Ещё более интересно, что прерывания по двум заявкам пришли БЕЗ уведомления об их снятии:
15:39:22 заявка подана, 15:51:59 пришла колода прерываний (12 минут).
15:45:27 заявка подана, 15:46:38 пришла колода прерываний (1 минута 11 секунд!!!)

Здесь важно вот что: я подаю транзакцию на снятие заявки только в том случае, если она активна. В первых трёх случаях снимаемая заявка была ещё не исполнена (или исполнена, но Квик об этом не знал). В четвёртом случае она была НЕ активна, и Квик об этом ЗНАЛ! Знал, паскуда, и 9 минут молчал! Возможен и другой вариант: скрипт не нашёл этой заявки в таблице заявок, но в этом случае Квик не успел обновить таблицу за ТРИ минуты после получения команды от скрипта, что совсем уж ПЦ! Наконец, последний вариант: заявку-то он нашёл (ID транзакций совпали), но стандартная функция получения данных из таблицы getItem глюкнула и предоставила неверные данные либо глюкнуло ещё что-то, и данные в таблице изначально были неверными.

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