Подскажите, если я хочу запустить несколько роботов, как можно обеспечить уникальность ID транзакций? Или каким образом сделать так, чтобы каждый робот мог отсеивать "свои" заявки в коллбэках при условии, что работает несколько роботов, часть из которых, возможно, сделана не мной? Фильтрации по коду инструмента мне недостаточно, т.к. я хочу, чтобы разные роботы могли работать по одному инструменту (с разными настройками), при этом у них могут пересекаться идентификаторы транзакций.
Если есть доступ к скрипту. где-то в самом начале до main() поставить trans_id = os.time();
перед выставлением заявки function MyOpenPosition() -- Выставляет заявку на открытие позиции trans_id = trans_id + 1; -- Получает ID для следующей транзакции -- Заполняет структуру для отправки транзакции local Transaction={ ACCOUNT = ACCOUNT_CODE, -- Код счета ------------------------ ----------------------- TRANS_ID = tostring(trans_id) -- ID транзакции }; local Res = sendTransaction(Transaction); -- Отправляет транзакцию end; -- Функция вызывается терминалом, когда приходит новая информация таблицы заявок function OnOrder(order) -- Если пришла информация по нашей транзакции if order.trans_id == trans_id then --именно наша заявка order_num = order.order_num; --номер заявки flag_OnOder = true; --флаг именно наша заявка end; end;
Если есть доступ к скриптам, то надёжней будет нечто вроде global_trans_id = trans_id * 10 + robot_id trans_id = trans_id + 1
Если роботов до 10 включительно - умножаем trans_id на 10, до 100 - на 100 и т.д.
Ну и разбирать обратно это проще простого, пришёл ответ на транзакцию с global_trans_id - берём остаток от деления на 10 (100, 1000, etc) и обрабатываем только если совпадает с текущим robot_id.
Спасибо. Подскажите, а как комментарий добавить при отправке транзакции и где его потом считывать?
Интересно, есть ли у роботов какой-нибудь уникальный идентификатор, который заранее доступен в системе и который можно было бы использовать в качестве уникального комментария?
Цитата
Максим написал: Если есть доступ к скриптам, то надёжней будет нечто вроде global_trans_id = trans_id * 10 + robot_id trans_id = trans_id + 1
Да, тоже думал о таком подходе. Немного напрягает то, что надо нумеровать вручную роботов (лишние телодвижения для пользователя). И это не спасает в случае, когда в систему загружены посторонние роботы. Хотя на практике таких случаев будет скорее всего настолько мало, что ими можно будет пренебречь, упомянув в документации о необходимой осторожности.
Максим написал: Если есть доступ к скриптам, то надёжней будет нечто вроде global_trans_id = trans_id * 10 + robot_id trans_id = trans_id + 1
Если роботов до 10 включительно - умножаем trans_id на 10, до 100 - на 100 и т.д.
Ну и разбирать обратно это проще простого, пришёл ответ на транзакцию с global_trans_id - берём остаток от деления на 10 (100, 1000, etc) и обрабатываем только если совпадает с текущим robot_id.
Можно сделать так. Перед формированием номера транзакции (trans_id) проверять его с существующими номерами в таблице заявок через getItem(). При совпадении изменять.
Илья написал: И это не спасает в случае, когда в систему загружены посторонние роботы.
На сколько я понял ответы разработчиков, то чужие ID (не ваших роботов) Вы не увидите, так как вы работаете в терминале и вам доступны только ваши сделки (только ваши ID), чужие сделки вы не сможете никак перепутать со своими. Если конечно я правильно понял вашу мысль.
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Suntor написал: Предлагаю разработчикам Quik добавить в систему потокобезопасную функцию выделения новых идентификаторов транзакций.
Код
NUMBER AllocTransID()
...и таким образом закрыть этот вопрос раз и навсегда. Можно зарегистрировать это предложение?
Просьба уточнить, как по вашему данная функция решит проблему и что именно она должна сделать?
Данная функция должна выделять уникальный числовой идентификатор транзакции в рамках одной запущенной копии рабочего места Quik.
Скрипт Lua получает вызовы OnTransReply (и других событий) на транзакции посланные из других скриптов Lua, и в целом идущие от: • Lua • Trans2quik.dll • QPILE • динамическая загрузка транзакции из файла
Если идентификатор транзакции в одном скрипте Lua совпадёт в таким же в другом скрипте Lua, то возникнет путаница, когда чужие ответы будут приняты за свои. Такого быть не должно. Функция AllocTransID() должна гарантировать уникальность получаемого идентификатора между всеми типами клиентов Quik.
Suntor написал: Предлагаю разработчикам Quik добавить в систему потокобезопасную функцию выделения новых идентификаторов транзакций.
Код
NUMBER AllocTransID()
...и таким образом закрыть этот вопрос раз и навсегда. Можно зарегистрировать это предложение?
Просьба уточнить, как по вашему данная функция решит проблему и что именно она должна сделать?
Данная функция должна выделять уникальный числовой идентификатор транзакции в рамках одной запущенной копии рабочего места Quik.
Скрипт Lua получает вызовы OnTransReply (и других событий) на транзакции посланные из других скриптов Lua, и в целом идущие от: • Lua • Trans2quik.dll • QPILE • динамическая загрузка транзакции из файла
Если идентификатор транзакции в одном скрипте Lua совпадёт в таким же в другом скрипте Lua, то возникнет путаница, когда чужие ответы будут приняты за свои. Такого быть не должно. Функция AllocTransID() должна гарантировать уникальность получаемого идентификатора между всеми типами клиентов Quik.
Добрый день. Следует понимать, что такая функция будет доступна только скриптам. Возможно пересечение идентификаторов со скриптами которые такую функцию не используют, скриптами QPILE и внешними транзакциями. Ну и рестарт терминала приведет к сбросу счетчика.
Чтобы при рестарте терминала счётчик не сбрасывался, я у себя реализовал такую схему: 1) для значений счётчика выделяется достаточно широкий диапазон чисел от a до b: [a, b); 2) периодически, скажем, раз в минуту, значение счётчика сохраняется на диск в файл; 3) при запросе номера транзакции в скрипте текущее значение счётчика увеличивается на 1 и, если оно становится равно b, то оно приравнивается a; 4) при старте скрипта значение счётчика считывается из файла и увеличивается достаточно большую на величину c и аналогичным образом приводится в диапазон [a, b), чтобы не было пересечений номеров транзакций, которые были посланы после того, как значение счётчика сохранялось в файл.
При такой схеме каждому скрипту выделяется свой диапазон номеров и исключаются повторения из-за сбоев и падений терминала.
Типичные значения в моих скриптах: a = 123 000 000, b = 124 000 000, c = 1000.
Поскольку сейчас планируется сделать номера глобальными для копии терминала, то описанная выше схема потребует выделения всего одного диапазона. Значение c и периодичность записи на диск имеет смысл вынести в конфигурационный файл.
Тот же вопрос всплыл с новым аспектом. Заявки, поданные через терминал руками, теперь имеют связанные транзакции, у которых есть ID. И теперь совсем не ясно как роботу отличить свои транзакции от ручных. Идеи?
Максим написал: Тот же вопрос всплыл с новым аспектом. Заявки, поданные через терминал руками, теперь имеют связанные транзакции, у которых есть ID. И теперь совсем не ясно как роботу отличить свои транзакции от ручных. Идеи?
Для этого лучше использовать brokerref = комментарий транзакции
Так а туда брокер код клиента подставляет. Мне квик на разных счетах у разных брокеров от 11 до 13 лимит на длину делает. Вместе с кодом клиента выходит 20 макс длина. Если код клиента будет большой, вплоть до 20 (вряд ли, но всё же)? Выходит и не воткнёшь туда transaction id. И как с ФР быть? https://forum.quik.ru/messages/forum10/message30624/topic3423/#message30624 Проверил своих брокеров, вроде везде пропускает камент, но что у других?
Я делаю так: ------------------------------ назначаем роботам номера например num_bot=134548 а текущее значение id=125657 -номер транзакции ----------- формирует для отправки серверу trans_id=id+(num_bot<<31) --------------- из принятого c сервера trans_id й транзакции с сервера вычисляем num_bot=trans_id>>31 id=trans_id&0xffffffff ----------------- По такой схеме, Вы можете иметь более миллиарда роботов, которые могут послать более миллиарда уникальных транзакций
Я делаю так: ------------------------------ назначаем роботам номера например num_bot=134548 а текущее значение id=125657 -номер транзакции ----------- формирует для отправки серверу trans_id=id+(num_bot<<31) --------------- из принятого c сервера trans_id й транзакции с сервера вычисляем num_bot =trans_id>>31 id=trans_id&0xffffffff ----------------- По такой схеме, Вы можете иметь более миллиарда роботов, которые могут послать более миллиарда уникальных транзакций
У меня похожая схема, но сгенерированные номера транзакции могут быть от 111. В десятичной системе: transid + botid + botidlen. В итоге номера перекрываются. Но даже если я просто взведу старший бит как признак моей транзакции, нет никаких гарантий, что Квик не выдаст и такой большой trans id. Хотелось бы надёжного решения, а выходит только какая-то магия. В этом-то и проблема.
Я делаю так: ------------------------------ назначаем роботам номера например num_bot=134548 а текущее значение id=125657 -номер транзакции ----------- формирует для отправки серверу trans_id=id+(num_bot<<31) --------------- из принятого c сервера trans_id й транзакции с сервера вычисляем num_bot =trans_id>>31 id=trans_id&0xffffffff ----------------- По такой схеме, Вы можете иметь более миллиарда роботов, которые могут послать более миллиарда уникальных транзакций
У меня похожая схема, но сгенерированные номера транзакции могут быть от 111. В десятичной системе: transid + botid + botidlen. В итоге номера перекрываются. Но даже если я просто взведу старший бит как признак моей транзакции, нет никаких гарантий, что Квик не выдаст и такой большой trans id. Хотелось бы надёжного решения, а выходит только какая-то магия. В этом-то и проблема.
В моем варианте ничего не перекрывается Более того квик не выдаст такие trans_id, так как для номера робота 1 и id=1 , trans_id =2147483649 Диапазон номеров роботов и id от 1 до двух миллиардов
Откуда вы знаете, что не выдаст? Завтра они начнут для ручных транзакций выдавать last_seen_trans_id + 1 и привет. Ваша система тоже рухнет. Моя тоже какое-то время держалась, пока они ноль возвращали.
Максим написал: Откуда вы знаете, что не выдаст? Завтра они начнут для ручных транзакций выдавать last_seen_trans_id + 1 и привет. Ваша система тоже рухнет. Моя тоже какое-то время держалась, пока они ноль возвращали.
Будет завтра -будет завтрак. Можете и дальше гадать.