Часто при MOVE_ORDERS заявки от сервера прилетает такое сообщение. Это происходит, если изменять заявку по номеру, полученному из OnTransReply, не дожидаясь OnOrder. С чего вдруг я не могу заменить заявку?!! Ведь заявка существует в ТС, я получил номер заявки.
Незнайка, Я никогда не делаю MOVE_ORDERS, вообще не пользуюсь ни OnTransReply, ни OnOrder, но несколько раз в неделю прилетает такое сообщение (только не "заменить", а "снять"). При этом заявки прекрасно снимаются вручную. Я тоже не понимаю, "с чего вдруг я не могу снять заявку", но меня это совершенно не беспокоит. А, ну да - я уже писал об этом в сентябре: Иногда приходят сообщения "Вы не можете снять данную заявку" - убей, не понимаю, почему: сделок по ней не было. А скрипту это дело по барабану: послал KILL_ORDER - и даже не контролирует, исполнилась ли эта команда или нет, считает, что раз он дал приказ, значит будет снята. Заявки у меня все лимитированные, так что пофиг, что там за "движение в котировках". Ну, сработает позже как "левая" заявка - делов-то? Или не сработает - снимется по окончанию сессии. Или я сам сниму, вручную, если окажусь поблизости от компа. Зачем с этим бороться?
предлагаем Вам обновить версию терминала до актуальной версии (9.2.2) и проверить, сохранится ли проблема. За обновлением необходимо обратиться к брокеру.
пока терминал не получит заявку, транзакция исполнена не будет. Вы получаете ошибку о невозможности заменить заявку, потому что не дожидаетесь onOrder.
OnTransReply, помимо номера заявки, возвращает ещё и поле status, которое может показывать, что, например, транзакция была отвергнута ТС. Подробнее об этом написано в Qlua.chm.
Чтобы решить возникшую проблему, предлагаем добавить логику проверки в скрипт, чтобы поле status было равно "3", что сигнализирует о выполнении транзакции.
Daniil Pozdnyakov написал: OnTransReply, помимо номера заявки, возвращает ещё и поле status, которое может показывать, что, например, транзакция была отвергнута ТС.
Цитата
Daniil Pozdnyakov написал: добавить логику проверки в скрипт, чтобы поле status было равно "3"
Во-первых, проверка поля status давно есть. Во-вторых, если транзакция была отвергнута ТС, то order_num = 0.
Так это не у меня проблема, а у вас с сервером какая-то шляпа. Заявка выставлена в торговую систему биржи. Сервер прислал номер заявки в OnTransReply, но утверждает "Вы не можете заменить заявку". С чего вдруг?
Могли бы Вы прислать скрипт, на котором проблема воспроизводится? Также просьба уточнить, данная ошибка появляется постоянно при попытке заменить заявку или какие-то заявки меняются (то есть транзакция срабатывает), а какие-то нет ?
Daniil Pozdnyakov, сам скрипт прислать не могу. Но вы можете воспользоваться, например, этим:
Код
local run = true
function OnStop()
run = false
end
local trans_id, order_num
function OnTransReply(trans_reply)
if trans_reply.trans_id == trans_id then
if trans_reply.status == 3 and trans_reply.order_num > 0 then
order_num = trans_reply.order_num
end
end
end
function main()
trans_id = getUniqTransID()
local err = sendTransaction{
TRANS_ID = tostring(trans_id),
ACTION = "NEW_ORDER",
ACCOUNT = account,
CLASSCODE = class_code,
SECCODE = sec_code,
OPERATION = "B",
TYPE = "L",
PRICE = price,
QUANTITY = "1"
}
if err ~= "" then
message(err, 3)
return
end
local n = 0
while run and n < 100 do
if order_num then
trans_id = getUniqTransID()
if sendTransaction{
TRANS_ID = tostring(trans_id),
ACTION = "MOVE_ORDERS",
CLASSCODE = class_code,
SECCODE = sec_code,
MODE = "0",
FIRST_ORDER_NUMBER = tostring(order_num),
FIRST_ORDER_NEW_PRICE = price,
FIRST_ORDER_NEW_QUANTITY = "1"
} == "" then
order_num = nil
n = n + 1
else trans_id = nil end
end
sleep(1)
end
end
Обратите внимание, что статус транзакции и номер заявки, выставленной в торговую систему, проверяются.
Цитата
Daniil Pozdnyakov написал: данная ошибка появляется постоянно при попытке заменить заявку или какие-то заявки меняются (то есть транзакция срабатывает), а какие-то нет ?
Если использовать присланный Вами скрипт, то проблема актуальна - ошибка, о которой ведётся речь, воспроизводится (См. скриншот 1). Однако было замечено, что если увеличить sleep, например вместо 1 поставить 1000, то ошибка не появляется (См. скриншот 2).
Основываясь на этом, предлагаем в Вашей реализации увеличить sleep.
Мне кажется, что не стоит решать эту проблему увеличением sleep. Надежнее сделать проверку наличия заявки по номеру в таблице заявок (или через OnOrder, как и предлагал админ). Получение номера заявки по OnTransReply не гарантирует появление заявки в таблице заявок без задержек. А если в таблице заявок этой заявки нет, то и переставлять нечего.
Обычно такого рода задачи необходимо решать асинхронно, т.к. время ожидания недетерминировано. Заявка может появится в системе и через 200 мс и через 10 минут. Поэтому либо надо делать бесконечный цикл, что плохо, т.к. блокирует исполнение всего кода, либо ждать выполнения, периодически опрашивая: есть ответ, ордер - нет, ждем дальше.
Т.к. язык нам не предоставляет возможность сделать это асинхронно, т.е. не блокируя поток выполнения, то это можно сделать через очередь заданий.
Подаете транзакцию, создаете некий объект задача, зафиксировав все необходимое для дальнейшей проверки ее статуса и помещаете в очередь эту задачу.
Дальше выполняете какой-то другой код, не ожидая ответа, например отправить еще одну транзакцию. Для примера, надо отправить 200 транзакций по разным инструментам. Если ждать на каждой, то такая задача будет выполнятся очень долго. А так мы отправили эти 200 транзакций и поместили в очередь задачи для каждой.
Пришли колбеки, нашли задачу для этой транзакции, поставили признаки в зависимости от результата. Если не используете колбеки, то уже при опросе задачи сами проверяете, есть ли ордер как результат транзакции. Нет - ждем дальше.
Опрос задач в очереди - это вызов с нужной периодичностью метода, перебирающего активные задачи и проверяющий их. Выполнена, ошибка - отработали действия при выполнении, ошибке и убрали из очереди задачу.
Т.о. у вас очередь задач очистится по мере выполнения. Какие-то быстро, какие-то медленнее. Решать можно и через корутины и просто через цикл перебора очереди.
В вашем примере у Вас счетчик 100 при задержке 1 мс. Т.е. Вы ожидаете, что ответ придет через 100 мс. Но он ведь может прийти через 500, а может и через 50. Код менять же не будете каждый раз.