Скрипт ниже выставляет заявку при старте, а при нажатии на кнопку "Остановить" снимает ее.
Код
IS_RUN = true
IS_STOPPING = false
ORDER_NUM = ''
function main()
-- ставим заявку
local t =
{
CLASSCODE = 'TQBR',
SECCODE = 'MVID',
ACTION = 'NEW_ORDER',
ACCOUNT = 'L01-00000F00',
CLIENT_CODE = 'DEMO915',
TYPE = 'L',
OPERATION = 'B',
QUANTITY = '1',
PRICE = '393',
TRANS_ID = '1'
}
sendTransaction(t)
while IS_RUN do
-- выполнение скрипта останавливается - снимаем заявку
if IS_STOPPING then
local t =
{
CLASSCODE = 'TQBR',
SECCODE = 'MVID',
ACTION = 'KILL_ORDER',
ORDER_KEY = tostring(ORDER_NUM),
TRANS_ID = '1'
}
sendTransaction(t)
for i=1,25 do sleep(200) end -- ждем 5 сек. в надежде что OnOrder отработает снятую заявку
end
--
sleep(500);
end
end
function OnStop()
IS_STOPPING = true
SLEEP_TIME = 50;
end
function OnOrder(order)
ORDER_NUM = order.ordernum
message(tostring(IS_STOPPING))
end
А это вывод в окне сообщений:
Получается, что после нажатия "Остановить" OnOrder уже не отрабатывает. Это ошибка или так должно быть? Версия квик 7.14.1.7
Пользователь
Сообщений: Регистрация: 23.01.2015
16.11.2017 18:31:56
Цитата
nero333 написал: Получается, что после нажатия "Остановить" OnOrder уже не отрабатывает. Это ошибка или так должно быть?
Если остановить скрипт то он остановит свою работу, все логично.
Пользователь
Сообщений: Регистрация: 07.09.2017
16.11.2017 19:01:39
Он не остановит работу, ведь main продолжает работать. Что вы посоветуете сделать, как выйти из main-a только удостоверившись, что все заявки сняты (а это можно сделать только по результатам колбека OnOrder)?
И кстати, с таблицами такая же ситуация, после нажатия на "Остановить" я уже не могу корректно запустить SetCell - он просто ждет 5 секунд и содержимое ячейки не меняет.
Пользователь
Сообщений: Регистрация: 31.01.2015
17.11.2017 06:28:22
Цитата
nero333 написал: Он не остановит работу, ведь main продолжает работать. Что вы посоветуете сделать, как выйти из main-a только удостоверившись, что все заявки сняты (а это можно сделать только по результатам колбека OnOrder)?
У меня используется следующая схема. Скрипт создаёт окно, где отображается информация о его работе (позиции, прибыли/убытки и др.). Если его закрывают нажатием на крестик в правом верхнем углу окна, то скрипт понимает, что окно закрыто (IsWindowClosed(windowId) == true), поднимает флаг, аналогичный Вашему IS_STOPPING, снимает необходимые заявки, закрывает файлы, в которые шла запись и т.п., после чего завершает исполнение функции main. Получается, что использование крестика в правом верхнем углу окна -- это штатный выход из скрипта, а нажатие кнопки "Остановить" в окне скриптов -- аварийный выход.
Пользователь
Сообщений: Регистрация: 07.09.2017
17.11.2017 16:30:24
, спасибо, это хорошая идея, думаю реализовать что-то подобное. Вопрос был к разработчикам относительно кнопки "Остановить", аварийный выход - это всё-таки когда скрипт падает с выводом ошибки в поле "Ошибки выполнения скрипта".
Пользователь
Сообщений: Регистрация: 23.01.2015
17.11.2017 16:57:07
Цитата
nero333 написал: _sk_, спасибо, это хорошая идея, думаю реализовать что-то подобное. Вопрос был к разработчикам относительно кнопки "Остановить", аварийный выход - это всё-таки когда скрипт падает с выводом ошибки в поле "Ошибки выполнения скрипта".
Кнопка "Остановить" это не аварийный выход, а просто остановка скрипта. Принудительная (в Вашем термине "аварийная") остановка происходит не по нажатию кнопки, а по истечении таймаута 5 сек. И это не зависит от того что в это время делает main, что-бы Вы туда не написали скрипт принудительно завершится. Таймаут можно изменить, это делается в return события OnStop (см документацию QLUA.chm) Если Вам что-то нужно снять заявки перед остановкой скрипта, делайте это в самом OnStop
Пользователь
Сообщений: Регистрация: 07.09.2017
17.11.2017 17:17:02
Цитата
Sergey Gorokhov написал: Кнопка "Остановить" это не аварийный выход, а просто остановка скрипта. Принудительная (в Вашем термине "аварийная") остановка происходит не по нажатию кнопки, а по истечении таймаута 5 сек. И это не зависит от того что в это время делает main, что-бы Вы туда не написали скрипт принудительно завершится. Таймаут можно изменить, это делается в return события OnStop (см документацию QLUA.chm) Если Вам что-то нужно снять заявки перед остановкой скрипта, делайте это в самом OnStop
Я могу и в main-е снять заявки, вопрос не в этом был, а в том, почему OnOrder не отрабатывает после остановки. Запустите скрипт из начала темы, сразу все станет понятно. Строка message(tostring(IS_STOPPING)) должна была бы выводить true в конце, если бы OnOrder отрабатывал.
Попробовал перенести снятие заявки в OnStop, как вы написали, - всё то же, не работает OnOrder.
nero333 написал: _sk_, спасибо, это хорошая идея, думаю реализовать что-то подобное. Вопрос был к разработчикам относительно кнопки "Остановить", аварийный выход - это всё-таки когда скрипт падает с выводом ошибки в поле "Ошибки выполнения скрипта".
Кнопка "Остановить" это не аварийный выход, а просто остановка скрипта. Принудительная (в Вашем термине "аварийная") остановка происходит не по нажатию кнопки, а по истечении таймаута 5 сек. И это не зависит от того что в это время делает main, что-бы Вы туда не написали скрипт принудительно завершится. Таймаут можно изменить, это делается в return события OnStop (см документацию QLUA.chm) Если Вам что-то нужно снять заявки перед остановкой скрипта, делайте это в самом OnStop
OnStop -- это последний коллбэк, который будет вызван при остановке скрипта. Однако, чтобы корректно сделать всё, что необходимо для снятия отправленных заявок в общем случае, не получится. Например, если транзакция на постановку заявки отправлена, OnTransReply ещё не пришёл, а пришёл OnStop. Как снять заявку, если мы ещё не знаем и не узнаем её orderNum? Никак.
Кроме того, в OnStop делать завершение неудобно, т.к. логика обработки находится в main-потоке.
Именно поэтому нормальная практика прерывания потока в многопоточном программировании состоит в уведомлении другого потока о том, что надо завершить работу. Эта практика и была предложена.
Пользователь
Сообщений: Регистрация: 07.09.2017
23.11.2017 13:40:02
, а сможете ли вы запустить скрипт из другого потока и, если да, то каким образом?
Пользователь
Сообщений: Регистрация: 31.01.2015
24.11.2017 06:40:00
Цитата
nero333 написал: , а сможете ли вы запустить скрипт из другого потока и, если да, то каким образом?
Скрипт -- это некий код, часть из которого исполняется в main-потоке, а часть в потоке коллбэков. Запускается скрипт кнопкой "Запустить". После этого начинает выполняться код main() и время от времени будут вызываться коллбэки. Фраза "запустить скрипт из другого потока" кажется некорректной.
Пользователь
Сообщений: Регистрация: 07.09.2017
24.11.2017 11:06:45
Вопрос снимается за отсутствием ответа, запишем это в пользу минусов и ошибок quik.