Отработка OnOrder после остановки скрипта

Страницы: 1
RSS
Отработка OnOrder после остановки скрипта
 
Здравствуйте.

Скрипт ниже выставляет заявку при старте, а при нажатии на кнопку "Остановить" снимает ее.
Код
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
 
Цитата
nero333 написал:
Получается, что после нажатия "Остановить" OnOrder уже не отрабатывает. Это ошибка или так должно быть?
Если остановить скрипт то он остановит свою работу, все логично.
 
Он не остановит работу, ведь main продолжает работать. Что вы посоветуете сделать, как выйти из main-a только удостоверившись, что все заявки сняты (а это можно сделать только по результатам колбека OnOrder)?

И кстати, с таблицами такая же ситуация, после нажатия на "Остановить" я уже не могу корректно запустить SetCell - он просто ждет 5 секунд и содержимое ячейки не меняет.
 
Цитата
nero333 написал:
Он не остановит работу, ведь main продолжает работать. Что вы посоветуете сделать, как выйти из main-a только удостоверившись, что все заявки сняты (а это можно сделать только по результатам колбека OnOrder)?
У меня используется следующая схема. Скрипт создаёт окно, где отображается информация о его работе (позиции, прибыли/убытки и др.). Если его закрывают нажатием на крестик в правом верхнем углу окна, то скрипт понимает, что окно закрыто (IsWindowClosed(windowId) == true), поднимает флаг, аналогичный Вашему IS_STOPPING, снимает необходимые заявки, закрывает файлы, в которые шла запись и т.п., после чего завершает исполнение функции main. Получается, что использование крестика в правом верхнем углу окна -- это штатный выход из скрипта, а нажатие кнопки "Остановить" в окне скриптов -- аварийный выход.
 
_sk_, спасибо, это хорошая идея, думаю реализовать что-то подобное. Вопрос был к разработчикам относительно кнопки "Остановить", аварийный выход - это всё-таки когда скрипт падает с выводом ошибки в поле "Ошибки выполнения скрипта".
 
Цитата
nero333 написал:
_sk_, спасибо, это хорошая идея, думаю реализовать что-то подобное. Вопрос был к разработчикам относительно кнопки "Остановить", аварийный выход - это всё-таки когда скрипт падает с выводом ошибки в поле "Ошибки выполнения скрипта".

Кнопка "Остановить" это не аварийный выход, а просто остановка скрипта.
Принудительная (в Вашем термине "аварийная") остановка происходит не по нажатию кнопки, а по истечении таймаута 5 сек.
И это не зависит от того что в это время делает main, что-бы Вы туда не написали скрипт принудительно завершится.
Таймаут можно изменить, это делается в return события OnStop (см документацию QLUA.chm)
Если Вам что-то нужно снять заявки перед остановкой скрипта, делайте это в самом OnStop
 
Цитата
Sergey Gorokhov написал:
Кнопка "Остановить" это не аварийный выход, а просто остановка скрипта.
Принудительная (в Вашем термине "аварийная") остановка происходит не по нажатию кнопки, а по истечении таймаута 5 сек.
И это не зависит от того что в это время делает main, что-бы Вы туда не написали скрипт принудительно завершится.
Таймаут можно изменить, это делается в return события OnStop (см документацию QLUA.chm)
Если Вам что-то нужно снять заявки перед остановкой скрипта, делайте это в самом OnStop
Я могу и в main-е снять заявки, вопрос не в этом был, а в том, почему OnOrder не отрабатывает после остановки. Запустите скрипт из начала темы, сразу все станет понятно. Строка message(tostring(IS_STOPPING)) должна была бы выводить true в конце, если бы OnOrder отрабатывал.

Попробовал перенести снятие заявки в OnStop, как вы написали,  - всё то же, не работает OnOrder.
 
Цитата
Sergey Gorokhov написал:
Цитата
nero333   написал:
_sk_, спасибо, это хорошая идея, думаю реализовать что-то подобное. Вопрос был к разработчикам относительно кнопки "Остановить", аварийный выход - это всё-таки когда скрипт падает с выводом ошибки в поле "Ошибки выполнения скрипта".
Кнопка "Остановить" это не аварийный выход, а просто остановка скрипта.
Принудительная (в Вашем термине "аварийная") остановка происходит не по нажатию кнопки, а по истечении таймаута 5 сек.
И это не зависит от того что в это время делает main, что-бы Вы туда не написали скрипт принудительно завершится.
Таймаут можно изменить, это делается в return события OnStop (см документацию QLUA.chm)
Если Вам что-то нужно снять заявки перед остановкой скрипта, делайте это в самом OnStop
OnStop -- это последний коллбэк, который будет вызван при остановке скрипта. Однако, чтобы корректно сделать всё, что необходимо для снятия отправленных заявок в общем случае, не получится. Например, если транзакция на постановку заявки отправлена, OnTransReply ещё не пришёл, а пришёл OnStop. Как снять заявку, если мы ещё не знаем и не узнаем её orderNum? Никак.

Кроме того, в OnStop делать завершение неудобно, т.к. логика обработки находится в main-потоке.

Именно поэтому нормальная практика прерывания потока в многопоточном программировании состоит в уведомлении другого потока о том, что надо завершить работу. Эта практика и была предложена.
 
_sk_, а сможете ли вы запустить скрипт из другого потока и, если да, то каким образом?
 
Цитата
nero333 написал:
_sk_ , а сможете ли вы запустить скрипт из другого потока и, если да, то каким образом?
Скрипт -- это некий код, часть из которого исполняется в main-потоке, а часть в потоке коллбэков. Запускается скрипт кнопкой "Запустить". После этого начинает выполняться код main() и время от времени будут вызываться коллбэки. Фраза "запустить скрипт из другого потока" кажется некорректной.
 
Вопрос снимается за отсутствием ответа, запишем это в пользу минусов и ошибок quik.
Страницы: 1
Читают тему
Наверх