Тема: 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 свечек ждешь по пол часа - вот это треш.
А у арки все нормально, как всегда.