1 (2022-10-06 10:51:32 отредактировано dark184)

Тема: Общие вопросы по написанию скриптов LUA.

Всем доброго времени суток. Хотелось бы попросить админа перенести все мои вопросы, касающиеся написания скриптов на LUA в одну эту тему.
Тем временем следующий вопрос.
1. Пришло время снимать заявки. С выставлением заявок теперь вроде полный порядок(за исключением частичного исполнения заявки, но этот вопрос автоматически решится с реализацией снятия заявок, таков алгоритм), а вот со снятием имеются вопросы.
Само собой уже поизучал тему самостоятельно. Сейчас у меня есть такая функция KillOrder()

function KillOrder()

  uniq_trans_id = uniq_trans_id + 1
  local trans = {
          ["ACTION"] = "KILL_ORDER",
          ["CLASSCODE"] = CLASS,
          ["SECCODE"] = SEC,
          ["ORDER_KEY"] = tostring(current_order_num),
          ["TRANS_ID"] = tostring(uniq_trans_id)
                }
  local res = sendTransaction(trans)
  message("Kill : " .. res, 2)
end

Лишнее, не касающееся сути вопроса я вырезал, чтобы глаза не мозолило.
Для меня абсолютно очевидно, что однозначно нужны "ACTION", "TRANS_ID". В моем случае "TRANS_ID" уникален и его принципиально уже должно хватить для идентификации заявки. С "CLASSCODE" и "SECCODE" для выставления понятно, обязательны, а вот для снятия зачем? Опять же обязателен ли параметр "ORDER_KEY" при условии уникальности "TRANS_ID"? Почему спрашиваю. Я буду работать не с одной заявкой, а как минимум сразу с тремя, этого требует алгоритм. Причем если цена пойдет вверх и отрабатывает заявка на продажу, все остальные убиваются и цикл сначала. Если вниз то убиваются другие заявки. Отсюда проблема с получением "ORDER_KEY". К тому же я строю робота по принципу, ничего не хранить в памяти на случай сбоя, ибо если хранить все в памяти, в случае перезапуска робота данные теряем. Я всю информацию извлекаю из терминала при запуске робота, соответственно и строю всю логику исходя из этого. Вобщем, если обобщить, нужно ли мне отправлять "ORDER_KEY" для снятия заявки? Ибо с этим будут проблемы...
2. В связи с тем, что частичное исполнение заявок в моем случае крайне редкие, возник вопрос по битовым флагам. Касательно заявок с полным исполнением я их все изучил, проверил, и вот что получил:

mask_bits    = 7
                                            -- 0 - Заявка на покупку исполнена.
                                            -- 1 - Заявка на покупку активна.
                                            -- 2 - Заявка на покупку снята.
                                            -- 3 - 
                                            -- 4 - Заявка на продажу исполнена.
                                            -- 5 - Заявка на продажу активна.
                                            -- 6 - Заявка на продажу снята.
                                            -- 7 -

Значения 3 и 7 в десятичном, впрочем в шестнадцатиричном представлении будет тоже самое, они судя по описанию противоречат, так как 2 бит это покупка/продажа, то при этих значениях соответствующая заявка одновременно будет и активной и снятой. Поэтому я делаю вывод что они не используются вообще. Возможно ли каким то образом узнать о частичном исполнении заявки или искать пути обхода? И в каком состоянии будут эти флаги при том же частичном исполнении заявки?

2

Re: Общие вопросы по написанию скриптов LUA.

1. Не совсем понятно: что-то не работает, заявка не снимается?
Или вы ищите логику?

2. Про какой поле какой структуры речь?

3 (2022-10-06 11:03:19 отредактировано swerg)

Re: Общие вопросы по написанию скриптов LUA.

Общая рекомендация по поводу применения tostring() (например, tostring(uniq_trans_id)

В поля транзакции надо писать правильные строковые (текстовые) представления параметров.

Начиная с Lua53 числовые переменные могут быть как дробными, так и целочисленными. При этом каким-либо образом различить их в скрипте - с ходу нельзя. Нельзя задать тип. И нельзя гарантировать, что в каком-то месте вы получите именно переменную целочисленного типа или дробного.

При этом tostring(uniq_trans_id) в случае, если uniq_trans_id друг окажется дробной переменной (фактически double), нам вернет значение с точкой и нулем в конце. Например, 123.0. И это будет уже некорректный параметр для транзакции.

Надежнее будет делать так (для точно целочисленных значений):

tostring(math.floor(uniq_trans_id))

Можно написать свою функцию, куда это все завернуть.

4

Re: Общие вопросы по написанию скриптов LUA.

1. Нет, заявки снимаются, это проверенная функция. Если кратко, то какие поля обязательные. В частности интересует "ORDER_KEY", т.к. именно с его получением будут проблемы. Точнее думается мне не с самим получением, а скорее с необоснованным разрастанием кода чтобы их получить. Хотелось бы избавиться от этого поля и обойтись самым минимумом "ACTION", "CLASSCODE", "SECCODE", "TRANS_ID". Все это мне известно даже в случае любых сбоев в работе скрипта. А вот "ORDER_KEY", в отличие от "TRANS_ID"(его я формирую в строгом соответствии своей системе), формирует брокер по своей системе. Соответственно его надо выдергивать из терминала, а по сути он мне вообще не нужен.
2. Вот про эти, взято из справки.

Флаги для таблиц «Заявки», «Заявки на внебиржевые сделки»

Флаг установлен Значение 
бит 0 (0x1)  Заявка активна, иначе – не активна  
бит 1 (0x2)  Заявка снята. Если флаг не установлен и значение бита «0» равно «0», то заявка исполнена  
бит 2 (0x4)  Заявка на продажу, иначе – на покупку  
бит 3 (0x8)  Заявка лимитированная, иначе – рыночная  
бит 4 (0x10)  Исполнить заявку по разным ценам  
бит 5 (0x20)  Исполнить заявку немедленно или снять (FILL OR KILL)  
бит 6 (0x40)  Заявка маркет-мейкера. Для адресных заявок – заявка отправлена контрагенту  
бит 7 (0x80)  Скрытая заявка  
бит 8 (0x100)  Снять остаток  
бит 9 (0x200)  Айсберг-заявка  
бит 10 (0x400)  Заявка отклонена торговой системой  
бит 20 (0x100000)  Поле «linkedorder» заполняется номером стоп-заявки  

5

Re: Общие вопросы по написанию скриптов LUA.

swerg пишет:

Надежнее будет делать так (для точно целочисленных значений):

tostring(math.floor(uniq_trans_id))

Спасибо, принял. Пока проблем именно с этим не возникало. Зато возникала проблема в обратном направлении, т.е. когда получаю строку из таблицы, например, с uniq_trans_id и вывожу в мессенж, вместо ожидаемого целого получаю как раз double. Т.е. ожидаю 83560, а в сообщении вижу 83560.0. И как раз по моему после обновления, хотя не уверен. smile

6

Re: Общие вопросы по написанию скриптов LUA.

1. Не надо искать логику.
Транзакция уезжает на биржу, на бирже тоже очень много легаси-софта, там разное может быть. Более того, в разных режимах торгов требования по обязательности параметров транзакций тоже могут оказаться разные даже для одинаковых по смыслу/действию транзакция.
Если ваш код работает в нужных вам режимах - ну и замечательно, пользуйтесь им.
Хотите на каком-то поле "сэкономить" - проверьте, срабатывают в вашей ситуации транзакции без этого поля, отсюда сделайте вывод по его обязательности.

Из "собственной практики" в данном случае что-то подсказать не смогу.

7 (2022-10-06 11:29:48 отредактировано swerg)

Re: Общие вопросы по написанию скриптов LUA.

2.

Значения 3 и 7 в десятичном, впрочем в шестнадцатиричном представлении будет тоже самое, они судя по описанию противоречат,

Противоречат чему? у вас напротив этих значений нет описания.
Вообще, в битовых полях лучше именно биты и проверять нужные, а не полные значения.

Судя по справке, я интерпретирую значения флагов следующим образом:
3 - заявка на покупку снята не исполненной.
7 - заявка на продажу снята не исполненной.

Причем заявки рыночные?? (нет бита 3) как тогда они могут быть сняты.
Вы точно получаете именно такие значения поля флагов из таблицы заявок? ну как-то странно, по описанию, что выставлены биты "активна" и "снята"; снята заявка вроде как неактивна, но, возможно, тут тоже "не надо искать логику, так получилось у биржи" smile )

8 (2022-10-06 12:43:56 отредактировано dark184)

Re: Общие вопросы по написанию скриптов LUA.

1. Понял, буду пробовать.
2. Заявки лимитные конечно же.
Суть вопроса не в этом. Как ведут себя эти флаги при частичном исполнении лимитной заявки(либо же есть другие флаги, либо их просто напросто не существует. В справке я их не нашел)? Например, есть лимитка на 25 лотов. По каким то причинам, неважно каким, она исполнилась только частично, например, не 25, а 15 лотов купилось, остальные 10 остались висеть. Теперь роботу надо принять решение, ждать дальше или убить заявку с остатком. Вот и думаю как это организовать с прицелом на будущее. В будущем еще планирую обрабатывать этим же роботом заявки, выставленные или снятые вручную(именно поэтому я и стал заморачиваться с флагами). Это необходимо мне, если вдруг посчитаю необходимым вручную подкорректировать работу робота, но это на следующем этапе написания.

Противоречат чему? у вас напротив этих значений нет описания.

Вообще здравому смыслу, заявка не может быть одновременно и активной, и снятой. Да и пробовал я читать эти флаги во всех возможных вариантах, значений 3 и 7 нет. А вот прочитать флаги у частично исполненной заявки мне так до сих пор и не удалось. Возможно что эти значения и интерпретируются как частично исполненные...

Вообще, в битовых полях лучше именно биты и проверять нужные, а не полные значения.

Так вобщем проблем не вижу честно говоря

if bit.band(flag,0х7) == 0х0 then   -- Маскируем ненужные биты и сравниваем
  message("Покупка свершилась!")
end

Лично код не проверял, но думаю как то так. На си постоянно подобным образом поступаю, правда там вообще нет битовых операций smile Шестнадцатиричные числа всегда применяю при таких операциях, это визуально отделяет битовые операции от математики. Да и удобнее это.

9

Re: Общие вопросы по написанию скриптов LUA.

Чтобы проверить признак "частичного исполнения", надо смотреть в поля qty и balance

-- выставили заявку на 25 лотов, тогда
qty = 25
balance = 25

-- исполнилась заявка на 15 лотов, 10 осталось, тогда
qty = 25
balance = 10

10

Re: Общие вопросы по написанию скриптов LUA.

Да и пробовал я читать эти флаги во всех возможных вариантах, значений 3 и 7 нет.

Замечательно, тогда и противоречий нет, раз не бывает таких значений.

if bit.band(flag,0х7) == 0х0 then 

Но здесь вы проверяете сразу 3 бита, а не один; вернее проверяете, что все три младших бита не установлены.
Это именно то, что вы хотели проверить?

На си постоянно подобным образом поступаю, правда там вообще нет битовых операций

Где нет битовых операций? в Си??

11

Re: Общие вопросы по написанию скриптов LUA.

Замечательно, тогда и противоречий нет, раз не бывает таких значений.

Я не писал, что не бывает, я написал что не смог подловить частично исполненную заявку. Вот и спрашиваю, или не подловить такую заявку по флагам, или значения 3 и 7 характеризуют как раз такой случай. Вобщем при случае проверю, заложу в робота код, а там уже может и подловится. smile

Но здесь вы проверяете сразу 3 бита

В данном случае немного не корректная формулировка. Я проверяю не три бита по сути, а состояние заявки на покупку или продажу. А эти три бита как раз и указывают что это заявка на покупку и она исполнена. Зачем в этом случае проверять все три бита по отдельности? Если мне надобно узнать только состояние, то маска будет 0х3...

Где нет битовых операций? в Си??

Ну конечно же. Есть битовые ОПЕРАТОРЫ. Но взять отдельный бит в слове вы не сможете никак, только слово целиком и выделить/сбросить/поднять/сравнить нужный бит. Тем не менее это останется все тем же словом. Но если flag & 0xF0 назвать битовой операцией, тогда да. Хотя в моем понимании битовая операция, это нечто другое. Хотя я любитель, поэтому не претендую на истину. В любом случае даже на Си нужно работать не с самими битами, а со словом и накладывать маску... Мы в любом случае не можем спросить сразу flag.0 (переменная flag, нулевой бит) равен 1 без "предварительных ласк".
Ну разве что булева переменная, но думаю тут зависит уже от компилятора.

12 (2022-10-06 14:09:39 отредактировано swerg)

Re: Общие вопросы по написанию скриптов LUA.

dark184 пишет:

Но если flag & 0xF0 назвать битовой операцией, тогда да

В смысле практического применения это не отличимо, считаю smile

dark184 пишет:

flag.0 (переменная flag, нулевой бит) равен 1 без "предварительных ласк".

std::bitset в C++

Но это так, в порядке off-top

13

Re: Общие вопросы по написанию скриптов LUA.

В смысле практического применения это не отличимо, считаю

Абсолютно верно

std::bitset в C++

Так это в С++, хотя может и в Си есть, но это как я и написал, с "предварительными ласками" smile Причем я более чем уверен, это реализовано при помощи побитового "ИЛИ" и соответствующей маски smile

14 (2022-10-06 17:40:25 отредактировано dark184)

Re: Общие вопросы по написанию скриптов LUA.

Сейчас обдумываю как отрабатывать частично исполненные заявки. Посмотрел в сторону колбэка OnOrder(), в его описании достаточно расплывчато прописано "при получении новой заявки или при изменении параметров существующей заявки.". Если с новой заявкой более менее, как минимум для рыночных и лимиток точно, то расплывчатое "при изменении параметров существующей" следует понимать параметры самой таблицы(такие как balance, value и прочие) или что-то еще???
1. OnOrder(TABLE order), опять же мне не понятно, в таблице будет только изменившаяся заявка или будут все до единой, что придется их перебрать по образу и подобию? Хотя в этом случае теряется смысл колбэка.

function DL()
    local n = getNumberOf("depo_limits")
    local quantity    = 0
    local price        = 0
    local block        = 0
    local y            = 0
    for y = 0, n-1 do
        trade = getItem("depo_limits", y)
        if    (trade.client_code == CLIENT_CODE)            and    
            (trade.sec_code ==    SEC)            and
            (trade.trdaccid == TRADE_ACC)        and
            (trade.limit_kind == 2)            then
                quantity    = Rounding(trade.currentbal, 0)
                price        = Rounding(trade.wa_position_price, PRICE_SCALE)
                block        = Rounding(trade.locked_sell, 0)    
                break
    end
   end
    return quantity, price, block
end

15

Re: Общие вопросы по написанию скриптов LUA.

Почему же расплывчато?
OnOrder будет вызываться для новой заявки и при изменении параметров заявки. Статуса заявки (исполнена, снята), баланса при частичном исполнении и т.д.

16 (2022-10-07 10:13:40 отредактировано kalikazandr)

Re: Общие вопросы по написанию скриптов LUA.

Ребята, привет!
Сорян, что вмешиваюсь, но если порыться по форуму, то тут полно решений.
На транс_ид вообще не нужно обращать внимания, т.к. на нем логику невозможно построить без костылей
сразу прописываете
для новой заявки:
trans_id = "777"

для снятия заявки
trans_id = "666"

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

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

17 (2022-10-08 18:40:52 отредактировано dark184)

Re: Общие вопросы по написанию скриптов LUA.

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

Я строю логику робота не опираясь на это. Мне в принципе пофик на потерю заявки. У меня стратегия ограничения убытков на этом выстроена. Если я нахожу точку входа и покупка совершается, но цена идет вниз, то два раза усредняюсь на процент, который готов потерять. Если опять цена уходит вниз, робот после двух усреднений тормозит... Далее я сам уже решаю что делать, продавать с убытком, заморозить на время или дальше усреднить.
Лично я вообще стараюсь исключить из робота такие факторы, как потеря заявки. Все что мне нужно я беру из таблиц квика, такие как depo_limit и прочие. Пока так, возможно позже роботом буду ставить тейки в таких случаях, а возможно и робота научу продавать с убытком самостоятельно.

18

Re: Общие вопросы по написанию скриптов LUA.

Сейчас на выходных, пока биржа закрыта торгую на демо счете. Стоит квикджуниор. У меня вопрос, вот эта функция не хочет брать данные из

function DL()
    local n = getNumberOf("depo_limits")
    local quantity    = 0
    local price        = 0
    local block        = 0
    local y            = 0
    for y = 0, n-1 do
        trade = getItem("depo_limits", y)
        if    (trade.client_code == CLIENT_CODE)            and    
            (trade.sec_code ==    SEC)            and
            (trade.trdaccid == TRADE_ACC)        and
            (trade.limit_kind == 0)            then
                quantity    = Rounding(trade.currentbal, 0)
                price        = Rounding(trade.wa_position_price, PRICE_SCALE)
                block        = Rounding(trade.locked_sell, 0)    
                break
    end
   end
    return quantity, price, block
end

Возвращает все в нулях. Срок расчетов я выставил Т0, вроде других здесь и нет. Все остальные то, что дали при оформлении демо счета. Причем эта же функция прекрасно работает на реальных торгах. Это ограничение квикджуниор или у меня руки кривоватые? Таблица лимитов по бумагам, как я понимаю она и есть depo_limits, по Т0 все отображает правильно. При этом таблица состояния счета вообще пустая, какой бы срок расчетов я не выбрал.

19 (2022-10-10 09:04:51 отредактировано swerg)

Re: Общие вопросы по написанию скриптов LUA.

Вы посмотрите что же вам на самом деле возвращает
trade = getItem("depo_limits", y)
Лимиты с какими параметрами там? Может вы их по ошибке отсекаете каким-то условием.

Кроме того, возможно, на квикджуниор другие коды классов.

20 (2022-10-10 08:51:36 отредактировано dark184)

Re: Общие вопросы по написанию скриптов LUA.

возможно на квикджуниор другие коды классов

Да, коды классов другие QJSIM.
За выходные разобрался. По ошибке вместо торгового счета указал счет депо. Правда нафига я прописал счет депо вообще не пойму smile Вообще, рассчитывал прописать торговый счет, прописал депо, а в памяти плотно отложилось, что прописал торговый. Вобщем взрыв мозга smile

21

Re: Общие вопросы по написанию скриптов LUA.

Назрел такой вопрос. Долго обдумывал алгоритм, накидал на бумаге, тестировал вручную, анализировал... вобщем если реализовывать все в скрипте, получится громоздко, много отладки. Ищу способ реализовать попроще. Т.е. большую часть переложить не на скрипт, а на сам квик. Вобщем, что из исходных данных. Робот выдает сигнал на покупку и выставляет лимитированную заявку в терминал. При ее исполнении я получаю данные о средней цене покупки, исполненном количестве. Также получаю данные о заблокированном количестве на продажу(т.е. по факту это говорит роботу о выставленной заявке на продажу). Вот с этого момента хотя бы часть неплохо было бы перенести на сам квик. Т.е. заявка на покупку исполнена, робот получил вышеуказанные данные. Теперь его задача выставить заявку на продажу, при этом необходимо выставить еще две заявки на покупку по этому же инструменту. НО! После выставления всех заявок возможны варианты:
1. Цена пошла вверх и сделка закрылась. Теперь надо снять активные заявки на покупку.
2. Цена пошла вниз и сработала еще одна заявка на покупку. Теперь надо заменить заявку на продажу, просто пересчитав цену.
3. Цена упала еще раз и сработала вторая и последняя заявка на покупку, действие аналогичное, замена с пересчетом цены продажи.
Возможно ли такой алгоритм переложить на сам квик? Т.е. отталкиваясь от первой заявки робота все(ну или почти все) остальное переложить на плечи квика? Или все таки придется потратить пару дней на программирование и отладку?

22

Re: Общие вопросы по написанию скриптов LUA.

Нет. Все это вам надо прописывать руками.
(можно попробовать теоретически поискать среди условных заявок или как они в квике зазываются "стоп заявок", но скорее всего нужного вам вы не найдете)

dark184 пишет:

Робот выдает сигнал на покупку и выставляет лимитированную заявку в терминал. При ее исполнении я получаю данные о средней цене покупки, исполненном количестве. Также получаю данные о заблокированном количестве

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

23 (2022-10-12 11:20:40 отредактировано dark184)

Re: Общие вопросы по написанию скриптов LUA.

сразу может прийти в статусе "исполнена"

Поэтому я не проверяю статус заявки, ориентируюсь на OnTransReply и OnTrade, а блокированные под продажу/покупку, пока использую под восстановление состояния робота при разрыве соединения, начала торговой сессии, перезапуска скрипта и прочих гадостей.
А, забыл. Еще использую эту информацию для опознования частично исполненных заявок. Правда функцию надо чуть доработать киллордером, но пока руки не дошли.

24

Re: Общие вопросы по написанию скриптов LUA.

dark184 пишет:

сразу может прийти в статусе "исполнена"

Поэтому я не проверяю статус заявки, ориентируюсь на OnTransReply и OnTrade, а блокированные под продажу/покупку, пока использую под восстановление состояния робота при разрыве соединения, начала торговой сессии, перезапуска скрипта и прочих гадостей.
А, забыл. Еще использую эту информацию для опознавания частично исполненных заявок. Правда функцию надо чуть доработать киллордером, но пока руки не дошли.

здрасте.
жесть какая wink
в вашем случае нужна структура, которая будет только покупать, на разных уровнях, но выставляться лимитка на следующем ценовом уровне будет только после полного исполнения верхнего уровня. уровней может быть много, динамических или статических, можно раскинуть сетку хоть до шага цены и делением сетки в шаг цены.
и структура, которая будет работать на закрытие позиции, т.е. работать с заявкой на продажу - выставлять/изменять текущее кол-во лотов/цену.

для такой конструкции вам понадобится 2 уникальных составных ключа, которые имеют общую составляющую "класс_код_инструмента"(эт по минимуму, неплохо вкрутить в ключ - код клиента, счет, краткое название стратегии) -  по одному ключу для заявок на покупку и заявок на продажу.
оба ключа должны быть известны обеим структурам для разделения обязанностей, т.к. структуры могут быть выполнены в разных луа-машинах
и да, ключи должны получаться из полей таблиц(заявки/сделки) и колбэков одинаковым алгоритмом:
"260026_TQBR_SBER_B1" - где B1 => B - стратегия, 1 - покупка, 2 - продажа
"260026_TQBR_SBER_B2"
B1/B2 пихаете в описание заявки при выставлении - поле brokerref, остальные параметры - как душе угодно и какие угодно.

25

Re: Общие вопросы по написанию скриптов LUA.

жесть какая

Согласен, жесть"ковато" wink Но! Изначально задумка была именно такая, как вы описываете, с поправкой на мелочи(типа алгоритма формирования уникального trans id), но концепция именно такая. Вот только в таком случае логгирования было не избежать. И вот первая же неприятность в виде синего экрана смерти (ну винда, сами понимаете)... Лог был испорчен, честно говоря не помню уже, сам файл был поврежден или данные не все записались... В общем пришлось исправлять все вручную. Благо сбойнул только один робот из пары десятков. И благо еще успел исправить вручную, следующий торговый день был бы убыточный. Помните, когда и сколько сбер обваливался? И вот после каждого такого обвала казалось что вот все, дно достигнуто. НО! каждый раз оттуда стучали smile Вот как раз вроде перед вторым обвалом сбой и произошел. Благо я сейчас по выходным на демо счете сижу и на нем же отлаживаю(правда на демо счете есть серьезные нюансы, так что окончательная отладка только на реальных торгах), а по рабочим дням не даю роботам больших сумм пока не удостоверюсь 100% в безотказности и безглючности робота.
В общем жесть, НО! работает безотказно. При любом сбое робот восстанавливает свое состояние независимо ни от чего, пусть это будет отключение питания, синий экран смерти, конец торговой сессии, разрыв соединения. Да, есть шероховатости в алгоритме(все это мои косяки, что то не предусмотрел сразу, где то банально ошибся), есть даже ошибочка, изредка робот пытается уйти в шорт(шорт я пока не использую и он заблокирован специально от таких моментов, позже скорее всего открою), ну и реализовать много чего надо еще. Скорее всего буду полностью переписывать алгоритм всего робота, ибо когда с полгода назад начинал его писать, вообще еще не думал о тех функциях, к необходимости реализации которых пришел в результате анализа работы роботов. В данный момент мой старый алгоритм не очень подходит для того, что сейчас реализую. В частности в первую очередь надо сейчас продумать изменение и определение текущего состояния робота с учетом как раз новых задуманных возможностей.
В общем я сознательно строю весь алгоритм таким образом, чтобы не логгировать, а всю необходимую информацию забирать оттуда, где она есть всегда и она всегда достоверна. Например, как я присваиваю уникальный номер транзакции.
Если робот теряет уникальный номер по любой причине, он сначала читает таблицу заявок, если она не пустая, выбирает из нее заявки по своему инструменту, находит последний(т.е. наибольший) уникальный номер и берет его +1 себе на заметку. Причем сознательно не различает снятые, активные или исполненные, в данном случае нужно только восстановить уникальный номер. Если же заявок нет вообще, то начинаем сначала...
Подобную функцию использую для восстановления состояния робота. Если в портфеле что то есть по инструменту и нет заблокированных на куплю/продажу, делаем вывод что надо продавать. Если все по нулям, то начинаем сначала. Если портфель пуст и есть блокированные на покупку, делаем вывод что заявка на куплю активна, ну и чтением таблицы заявок это подтверждаем... Ну и так далее.
Вообщем опираюсь исключительно на данные из терминала, ибо они хранятся не у меня.