Closed serebrennikovvitaly closed 2 years ago
При сильном желании экспериментировать с передачей заведомо некорректных данных в терминал, лучше использовать базовый функционал QUIK, а не методы, являющиеся производными, которые созданы для облегчения/упрощения написания кода. Под "базовым" функционалом, я подразумеваю функцию "SendTransaction". Справку по ее использованию можете подсмотреть в справке по QLua.
Попробовал все-таки штатно решить, прошел дебаггером в движок QuikSharp. Так вот, ошибка логическая в функции SendOrder!
После получения ошибки от квика, при попытке в строке 134 получить номер ордера через GetOrder_by_transID, order_result оказывается == null.
И далее, в строке 147 такого условия не находится и соответственно, set не становится = true и далее не выходит из бесконечного цикла в строке 128
Надо добавить такое условие в строку 147
Если в 147 строке добавить установку set = true, при условии, что order_result == null, то мы выйдем из цикла, без ошибки, т.е. будем считать, что заявка успешно выставлена. Но суть проблемы я понял. Подумаю на досуге как лучше обыграть эту ситуацию.
Решил примерно так:
Добавил флаг в переменную класса
добавил в функцию GetOrder_by_transID выставление этого флага по окончанию выполнения
Добавил в функцию SendOrder условие выход из цикла по флагу и возврат order_result, а также до-кучи order_result.TransID = res; перед выводом из SendOrder
Если нужно, то приложил файл To-Be OrderFunctions.zip
Версия 2.0.1
Не самое удачное решение. Цикл появился из-за того, что после отправки транзакции, может пройти некоторое время, прежде чем в терминале появится информация по заявке. Если считать, что при отсутствии информации после первого же запроса заявки нет, то будем сталкиваться с выставлением заявок, думая, что их нет. Помню, как в какой-то момент это привело к выставлению нескольких десятков заявок на покупку какой-то бумаги, в течении буквально нескольких секунд. Адреналина мне тогда хватило по самые уши. Нужно другое решение, но пока у меня нет возможности заняться этим вопросом.
Предлагаю тогда такой вариант. На тесте работает (и выставляет заявки и возвращает ошибки).
Проверяем, если в словаре транзакции содержится текст ошибки, то создаем пустой ордер с текстом ошибки
Перед выходом отписываемся от колбэка, чистим словарь, возвращаем TransID
в SendTransaction запись в словарь ставим перед вызовом транзакции
Приведите, пожалуйста, пример параметров заявки, при которых у Вас функция гарантированно уходила в бесконечный цикл. Я не уверен в оптимальности Вашего решения. По хорошему, ошибку отправки транзакции необходимо отлавливать в методе "SendTransaction", и дальше работать с полученным результатом. Желательно, без дополнительных подписок на события (если это возможно).
например при закрытии биржи в выходные. Квик отдает ошибку - инструмент не торгуется. Или например если баланс с учетом покупки будет отрицательным. Уходит в бесконечный цикл даже на тестовых примерах из quiksharp
В общем, в SendTransaction обработать эту ошибку не удается, т.к. по сути команда отправки транзакции считается успешно выполненной. Нашел у себя старую реализацию контроля подобных ошибок, в чуть более простом варианте, чем у Вас. Предварительное тестирование показало успешный результат. После боевого тестирования (на реально работающем роботе, выставляющим не единичные заявки), выложу фикс.
Тоже сталкивался, что иногда из-за некоректных данных от квика (неверное отображение позиции по инструменту или деньгам) после отправки заявки программа виснет. В терминале квика ошибки "превышена позиция по деньгам" и "запрет на операцию шорт". Буду благодарен, если выложите фикс
Боевое тестирование в процессе. Скорее всего вечером будет фикс.
Фикс выложил.
Большое спасибо, буду тестировать
Спасибо за патч, все работает! Можно закрывать тикет
Подскажите как обработать ошибку от quik? После любой команды: SendLimitOrder, SendMarketOrder, отправляемых заведомо с ошибкой (например, мало денег или биржа закрыта или другие) - процесс останавливается с ожиданием ответа.
При этом, quik сразу в сообщениях отдает ошибку, также ошибку вижу в TransReply, в том числе и текст ошибки. Но SendLimitOrder и SendMarketOrder зависают на неопереденный срок.
Это воспроизводится и в тестовом примере, трассировка не идет дальше команды SendLimitOrder. И не получаю ни сам ордер (так как он не создан) и исключения не возникает. Также TransID не известен, хотя в TransReply приходит.
Как решить этот вопрос?