Тема: OnOrder() срабатывает несколько раз на одну заявку!

начинаю осваивать ЛУа, поробовал код, который для примера был приведен , у меня почему то сообщения два раза подряд отображаются.
То есть, я даю в терминал одну заявку, скрипт отправляет два сообщения, получается что функция на одну заявку два раза срабатывает.
Ниже код, подскажите пожалуйста , что я упускаю

is_run = true

function main()
    while is_run do
        sleep(50)
    end;
end

function OnStop()
    is_run = false
end

function OnOrder(trade_data)
    n = getNumberOf("orders")
    t = getItem("orders", n-1)
    summ=t.value
    instr=t.sec_code
    kl_to_serv= summ..'  '..instr
    message ("instrument " .. tostring(kl_to_serv))
   
end

2

Re: OnOrder() срабатывает несколько раз на одну заявку!

Потому что OnOrder() вызывается как на появление заявки, так и на изменение её параметров. Снятие заявки, формирование по ней сделки - это изменение параметров заявки.

Кроме того не стоит забывать, что иногда на самом деле никаких параметров у заявки может и не измениться, но OnOrder() вызывается, есть такая особенность.

3

Re: OnOrder() срабатывает несколько раз на одну заявку!

dkostiunin пишет:

function OnOrder(trade_data)
    n = getNumberOf("orders")
    t = getItem("orders", n-1)
    summ=t.value
    instr=t.sec_code
    kl_to_serv= summ..'  '..instr
    message ("instrument " .. tostring(kl_to_serv))
end

Выделенное - лишнее. В качестве параметра в OnOrder(order) уже передаётся готовая таблица с параметрами этой самой заявки (которая может быть и не последней по индексу)

4

Re: OnOrder() срабатывает несколько раз на одну заявку!

swerg пишет:

Кроме того не стоит забывать, что иногда на самом деле никаких параметров у заявки может и не измениться, но OnOrder() вызывается, есть такая особенность.

больше всего, конечно, бесит колбэк datasource. на одну сделку он вызывается до 11 раз, а все изменения по ней происходят перед первым вызовом, то есть делается 10 бесполезных вызовов. ну, компьютер быстрый, чо, пусть трудится.

5 (2020-02-28 15:50:34 отредактировано dkostiunin)

Re: OnOrder() срабатывает несколько раз на одну заявку!

переделал

is_run = true

function main()
    while is_run do
        sleep(50)
    end;
end

function OnStop()
    is_run = false
end

function OnOrder(trade_data)
    summ=trade_data.value
    instr=trade_data.sec_code
    kl_to_serv= summ..'  '..instr
    message ("instrument " .. tostring(kl_to_serv))
   
end

в сообщения приходит именно последняя заявка, но все равно два раза дублируется

6 (2020-02-28 15:54:11 отредактировано toxa)

Re: OnOrder() срабатывает несколько раз на одну заявку!

dkostiunin пишет:

вот это я не понял ((которая может быть и не последней по индексу)  -  теми двумя строками я не гарантированно получу последнюю заявку?

вы получите последнюю заявку по номеру, но не последнюю по обновлению.

дело в том, что заявки - таблица, в которой строки могут обновляться в любом порядке. если вы поставили заявку 1, затем поставили заявку 2, а потом сняли заявку 1, то OnOrder() будет вызвана три раза: после добавления заявки 1, после добавления заявки 2 и после снятия заявки 1.

ваш же код при добавлении заявки 1 вернет заявку 1, при добавлении заявки 2 вернет заявку 2, а при снятии заявки 1 вернет тоже заявку 2, а по смыслу должен 1.

используйте параметры, передаваемые в OnOrder() - это позволит вам достать из таблицы заявок именно ту заявку, с которой произошло какое-то действие. собственно, и доставать ничего не нужно, так как в параметры эта заявка и передается.

7

Re: OnOrder() срабатывает несколько раз на одну заявку!

dkostiunin пишет:

в сообщения приходит именно последняя заявка, но все равно два раза дублируется

напечатайте номер заявки, balance и ext_order_status, затем ставьте-снимайте в произвольном порядке свои заявки и вам все станет понятно.

8

Re: OnOrder() срабатывает несколько раз на одну заявку!

dkostiunin пишет:

переделал

в сообщения приходит именно последняя заявка, но все равно два раза дублируется

Да, потому что OnOrder() может срабатывать несколько раз на 1 заявку.
Если вам нужно, чтобы ваш код работал только 1 раз - то можно запоминать номера заявок, чтобы не было повторных вызовов.

В начало кода  (где is_run) добавьте строку

t_orders = {}

и в начало OnOrder() добавьте код:

function OnOrder(trade_data)
  if t_orders[trade_data.order_num] then
    return
  end

  t_orders[trade_data.order_num] = true

...далее ваш код...

9

Re: OnOrder() срабатывает несколько раз на одну заявку!

Огромное спасибо!
Сэкономили кучу времени !
Сейчас приходит одно сообщение, когда появялется новая заявка, когда ее снимаешь, то сообщение не приходит.
Если не сложно, хотел уточнить, правильно ли я понял , как все работает. Потому что все равно один ньюанс не понимаю.

Вначале создали пустую таблицу.

ставим заявку,

начиает работу функция OnOrder

проверяется условие, если существует в таблице индекс в виде номера заявки, тогда функция завершается без исполнения всяких действий.

Так как таблица пустая, то при постановке новой заявки условие игнорируется,

выполняется запись в таблицу , где индекс это номер заявки, а значение это логическое True

затем выполняется код по формированию сообщения.

А далее , еще раз вызывается функция OnOrder, но при проверке условия находится запись в таблиуе с номером заявки. и фунция завершается без исполнения кода - от я это и не понимаю, зачем функция второй раз то вызывается?

10

Re: OnOrder() срабатывает несколько раз на одну заявку!

еще один вопрос, я этот код хотел использовать для передачи в телеграм бот инфы о заявки, это у меня работает, но
передавать то желательно не Код инструмента заявки , а в идеале сокращенное наименование инструмента.

В документации есть функция getItem , но в описании параметров таблицы заявок не вижу параметров с наименованиями, возможно все таки как то наименование получать? Ведь в самих таблицах такие поля есть

11

Re: OnOrder() срабатывает несколько раз на одну заявку!

swerg пишет:

В начало кода  (где is_run) добавьте строку

t_orders = {}

и в начало OnOrder() добавьте код:

function OnOrder(trade_data)
  if t_orders[trade_data.order_num] then
    return
  end

  t_orders[trade_data.order_num] = true

...далее ваш код...

Так не пойдет) Фишка в том, что на новую заявку будет вызван OnOrder 2 раза и на каждое следующее изменение заявки 1 раз.
Два раза по новой заявке вызывается в связи с двойной регистрацией на сервере квик и в ТС.
По этому, если мы видим первый раз заявку с номером №###, то не обрабатываем это событие никак, но регистрируем ее номер, а уже последующие события обрабатываем все, вплоть до ее снятия или исполнения.
потом ее нужно забыть так, что бы после дисконекта больше ее не обрабатывать, т.к. она уже забыта, а события по ней получим повторно.

12

Re: OnOrder() срабатывает несколько раз на одну заявку!

toxa пишет:

больше всего, конечно, бесит колбэк datasource. на одну сделку он вызывается до 11 раз, а все изменения по ней происходят перед первым вызовом, то есть делается 10 бесполезных вызовов. ну, компьютер быстрый, чо, пусть трудится.

ага) главное учитывать, что будет дополнительно 9+ одинаковых вызовов, а не реально новых сделок по одной цене))
Вот реально что бесит, это как datasource получает опционы, данных по ним тупо нет. 200-300 баров минуточных можно ждать от полу-часа до конца сессии либо открыть нужный график и сделать перезаказ данных с перегрузкой терминала, но это помогает только для этого графика. Открываешь другой график - та же песня. Ладно их вообще нет, неликвид же, ну и должна функция вернуть значение:
ds, err = CreateDateSourse()
ds = table
err = "Не было сделок по инструменту, хочешь быть первым?)))"
Ну реально же сделок может не быть, но когда они есть, а 200-300 свечек ждешь по пол часа - вот это треш.
А у арки все нормально, как всегда.

13 (2023-06-09 20:18:49 отредактировано alex.a)

Re: OnOrder() срабатывает несколько раз на одну заявку!

swerg пишет:
dkostiunin пишет:

переделал

в сообщения приходит именно последняя заявка, но все равно два раза дублируется

Да, потому что OnOrder() может срабатывать несколько раз на 1 заявку.
Если вам нужно, чтобы ваш код работал только 1 раз - то можно запоминать номера заявок, чтобы не было повторных вызовов.

В начало кода  (где is_run) добавьте строку

t_orders = {}

и в начало OnOrder() добавьте код:

function OnOrder(trade_data)
  if t_orders[trade_data.order_num] then
    return
  end

  t_orders[trade_data.order_num] = true

...далее ваш код...

Уважаемый swerg,

Спасибо за предложенное решение. Была такая же проблема с повторяющимися сообщениями, только в функции OnTrade(trade). Протестировал на массиве из 2 тикеров. Работает нормально, без повторений сообщений.
Скажите, пожалуйста, может, есть какие-либо подводные камни из-за этих добавленных строк кода? Типа увеличения времени работы кода, еще чего-либо...

14

Re: OnOrder() срабатывает несколько раз на одну заявку!

alex.a,
так-то достаточно ожидаемая вещь, что любые добавленные строки к коду добавляют время его работы smile

"Подводные камни" - так-то их нет. Ну разве что надо принимать во внимание, что все же повторные вызовы - они не просто так случаются, они случаются из-за того, что некоторые параметры дозаполняются, т.е. изменяются. Да, это вовсе не во все повторные вызовы происходит, более того, основные параметры гарантированно заполняется сразу при первом же вызове. Но что такое "основные параметры" - штука тёмная и неоднозначная. Соответственно если выяснится, что в первый раз у вас не всегда заполняются какие-то параметры, которые вы используете - значит просто так откидывать все последующие вызовы для вашего алгоритма не получится, придется дождаться тот вызов, где будет заполнен требуемый параметр. Но это всё из практики надо смотреть по конкретному алгоритму. Скорее всего  все используемые вами параметры будут заполнены всегда при первом же вызове. Но на это надо обращать внимание при отладке.