Обнаружил странное поведение при выставлении заявок на FORTS. Поле order_num, приходящее в колбеке OnTransReply, часто не совпадает со значением в таблице заявок квика, из-за этого не удается программно снять заявку. Тем не менее, бывают редкие случаи, когда эти значения совпадают, и тогда заявки снимаются. При этом обнаружил, что в поле result_msg номер заявки всегда верный. Вот реальные примеры совпадающих номеров и несовпадающих:
Обнаружил странное поведение при выставлении заявок на FORTS. Поле order_num, приходящее в колбеке OnTransReply, часто не совпадает со значением в таблице заявок квика, из-за этого не удается программно снять заявку. Тем не менее, бывают редкие случаи, когда эти значения совпадают, и тогда заявки снимаются. При этом обнаружил, что в поле result_msg номер заявки всегда верный. Вот реальные примеры совпадающих номеров и несовпадающих:
Подскажите, пожалуйста, в чем может быть проблема и как можно достоверно получить правильный номер заявки?
OnTransReply - это колбек на транзакцию, а не на выставление заявки. Номер заявки надо брать либо из OnOrder , либо из таблице заявок.
Пользователь
Сообщений: Регистрация: 29.06.2015
09.06.2023 19:57:04
В колбеке OnOrder тот же самый order_num, что и в OnTransReply, поэтому его для снятия заявки использовать не получится. А вот брать из таблицы действительно можно, только выглядит это очень уж коряво. И вопрос остается: почему в OnTransReply order_num не совпадает с тем, который в таблице заявок. И еще более удивительно, что иногда они все-таки совпадают. А вот для фондовой секции они совпадают всегда и я спокойно могу использовать order_num из данных, приходящих в OnTransReply.
QuantPro Platform
Пользователь
Сообщений: Регистрация: 30.01.2015
10.06.2023 07:32:41
В OnTransReply может и не быть order_num, так как это ответ сервера брокера на обработку транзакции. Первый раз этот ответ приходит раньше, чем ответ с сервера биржи. Это отмечено в документации:
На всякий случай отмечу, что иногда биржа не может снять/заменить даже реально существующую заявку и присылает сообщение "Невозможно снять/заменить заявку XXX. Попробуйте позже".
При этом номера заявок верные и торги по инструменту идут.
Проблему решает повторная отправка того же самого запроса на снятие/замену, возможно с минимальной задержкой.
Пользователь
Сообщений: Регистрация: 29.06.2015
11.06.2023 16:38:51
Цитата
nikolz написал: В OnTransReply может и не быть order_num, так как это ответ сервера брокера на обработку транзакции. Первый раз этот ответ приходит раньше, чем ответ с сервера биржи.
Действительно, Ваш ответ можно было бы принять, но есть нюанс. В поле result_msg номер заявки присутствует, и он всегда верный. Так что проблема явно на стороне квика, уж не знаю там, сервера или клиента. В моем первом сообщении Вы можете увидеть оба случая, когда номера совпадают и когда нет.
Спасибо, но это не тот случай. Попытки отправить по нескольку раз не увенчиваются успехом. А вот при подстановке значения из result_msg заявки прекрасно снимаются, собственно, что и следовало ожидать, так как они всегда совпадают со сначением из таблицы заявок. Пока мне пришлось закостылить регулярку и вытаскивать этот номер из result_msg, но согласитесь, что этот способ так себе решение. Все же хотелось услышать мнение кого-нибудь из разработчиков по данному вопросу.
написал: В OnTransReply может и не быть order_num, так как это ответ сервера брокера на обработку транзакции. Первый раз этот ответ приходит раньше, чем ответ с сервера биржи.
Действительно, Ваш ответ можно было бы принять, но есть нюанс. В поле result_msg номер заявки присутствует, и он всегда верный. Так что проблема явно на стороне квика, уж не знаю там, сервера или клиента. В моем первом сообщении Вы можете увидеть оба случая, когда номера совпадают и когда нет.
Верно, я его использую. Но это не документированное использование параметров колбека.
Пользователь
Сообщений: Регистрация: 30.01.2015
11.06.2023 17:55:51
относительно снятия заявок. Я тестировал выставление и снятие заявок на демо сервере. У меня все выставлялось и снималось на акциях фьючерсах и валютном счете.
Пользователь
Сообщений: Регистрация: 30.01.2015
11.06.2023 17:57:22
всего в тесте выставлял и снимал до 500 тысяч заявок и без проблем.
Пользователь
Сообщений: Регистрация: 20.03.2023
11.06.2023 18:06:44
А версия quik какая? Похоже, что где-то номер заявки в double складывается. А там точности не хватает.
Пользователь
Сообщений: Регистрация: 30.01.2015
11.06.2023 18:27:32
Цитата
paluke написал: А версия quik какая? Похоже, что где-то номер заявки в double складывается. А там точности не хватает.
тестировал на 9.7.1. Сейчас тесты делаю на 10.2.1.12
Пользователь
Сообщений: Регистрация: 30.01.2015
11.06.2023 18:29:15
Цитата
paluke написал: А версия quik какая? Похоже, что где-то номер заявки в double складывается. А там точности не хватает.
Вы ошибаетесь. Это не вопрос к разработчикам, а к документации на Lua 5.4.2 Рекомендую изучить sorce Lua 5.4.2 Если точки нет, то это целое и конвертируется через int64.
Пользователь
Сообщений: Регистрация: 30.01.2015
11.06.2023 19:16:58
ваш пример не корректный в нем есть неявный формат печати. Вы уверены что он 64 битный?
nikolz написал: ваш пример не корректный в нем есть неявный формат печати. Вы уверены что он 64 битный?
Если вопрос ко мне, то да, все значения 64-битные. К тому же, если бы имел место некорректный формат печати, то он был бы некорректен во всех случаях. Но это, как Вы можете видеть, не так.
написал: ваш пример не корректный в нем есть неявный формат печати. Вы уверены что он 64 битный?
Если вопрос ко мне, то да, все значения 64-битные. К тому же, если бы имел место некорректный формат печати, то он был бы некорректен во всех случаях. Но это, как Вы можете видеть, не так.
Я вроде бы выше написал в чем ошибка. Повторю, если не заметили. Ошибка теста выше в неправильном использовании оператора деления. Надо использовать целочисленное деление а не деление с плавающей точкой. ---- Все остальное правильно.
Пользователь
Сообщений: Регистрация: 20.03.2023
12.06.2023 09:30:37
Использование деления там специально чтобы проверить конвертацию в double и обратно в int64. Числа взял из первого сообщения. На самом деле при этом 1951785056590629888 сохраняет значение, а 1951785056590630794 превращается в 1951785056590630912.
Пользователь
Сообщений: Регистрация: 30.01.2015
12.06.2023 10:57:15
Цитата
paluke написал: Использование деления там специально чтобы проверить конвертацию в double и обратно в int64. Числа взял из первого сообщения. На самом деле при этом 1951785056590629888 сохраняет значение, а 1951785056590630794 превращается в 1951785056590630912.
Полагаю Вы знаете про ошибки округления, поэтому конвертация int64 в double и обратно не может быть всегда точной. ---------------- Более того, все это есть в документации по форматом и для этого не надо делить и умножать ------------------ Ликбез: ------------------- число 1951785056590629888, 1951785056590630794 -- это 19 значащих цифр а double хранит мантиссу лишь с точностью 15-17 значащих цифр. --------------------- Вы это и проверили - т е 15-17 значащих цифр мантиссы не могут всегда точно хранить 19 значащих цифр целого числа.
телепатов нет, поэтому, что Вы слышите, знаете лишь Вы . читайте документацию на Lua 5.4. Вроде Вам все объяснил на русском , черным по белому.
Пользователь
Сообщений: Регистрация: 20.03.2023
13.06.2023 10:06:24
Проверил у себя. На quik 10.1 order_num в OnTransReply имеет тип integer, и номер там без искажений, совпадает с тем что в result_msg. Автор, а брокер у вас какой?
Пользователь
Сообщений: Регистрация: 20.03.2023
13.06.2023 10:09:32
Цитата
paluke написал: Проверил у себя. На quik 10.1 order_num в OnTransReply имеет тип integer, и номер там без искажений, совпадает с тем что в result_msg. Автор, а брокер у вас какой?
Проверял на фьючерсах, на реальном счете, и номер там был длинный, в double нормально не помещается.
написал: Использование деления там специально чтобы проверить конвертацию в double и обратно в int64. Числа взял из первого сообщения. На самом деле при этом 1951785056590629888 сохраняет значение, а 1951785056590630794 превращается в 1951785056590630912.
Полагаю Вы знаете про ошибки округления, поэтому конвертация int64 в double и обратно не может быть всегда точной. ---------------- Более того, все это есть в документации по форматом и для этого не надо делить и умножать ------------------ Ликбез: ------------------- число 1951785056590629888, 1951785056590630794 -- это 19 значащих цифр а double хранит мантиссу лишь с точностью 15-17 значащих цифр. --------------------- Вы это и проверили - т е 15-17 значащих цифр мантиссы не могут всегда точно хранить 19 значащих цифр целого числа.
Если вам этой информации достаточно, чтобы точно убедится, что 1951785056590630912 не какое-то случайное значение, а результат округления 1951785056590630794 - я вас поздравляю. Я так в уме не могу, мне проверить надо было.
Пользователь
Сообщений: Регистрация: 29.06.2015
13.06.2023 10:32:38
Цитата
paluke написал: Проверил у себя. На quik 10.1 order_num в OnTransReply имеет тип integer, и номер там без искажений, совпадает с тем что в result_msg. Автор, а брокер у вас какой?
БКС. Проверял на разных версиях, везде одно и то же.
QuantPro Platform
Пользователь
Сообщений: Регистрация: 20.03.2023
13.06.2023 11:10:29
На всякий случай: для записи в лог номера в строки преобразуются функцией tostring()?
Пользователь
Сообщений: Регистрация: 29.06.2015
13.06.2023 12:00:28
У меня C++, преобразование идет напрямую из Lua Number в uint64_t, а потом уже пишется в лог. По всей видимости, дело действительно в ошибках преобразования из double в uint64_t, судя по Если это так, то возникает резонный вопрос к разработчикам - собираются ли они это исправлять и когда. Учитывая, что Lua не имеет целочисленных типов, а биржа транслирует значения за пределами значений double, тут видится два варианта: или разбивать число на две части и передавать в двух полях, или сделать просто строковое поле.
QuantPro Platform
Пользователь
Сообщений: Регистрация: 20.03.2023
13.06.2023 12:05:01
это ссылка на книгу по lua 5.0, там никаких int64 еще не было. Вы не на С++ а на lua проверьте. А то может вы С api неправильно используете (по доке от старой версии lua).
Пользователь
Сообщений: Регистрация: 27.01.2017
13.06.2023 12:23:16
Lua 5.3 introduces the integer subtype, which uses 64-bit integer by default.
From
The type number uses two internal representations, one called integer and the other called float. Lua has explicit rules about when each representation is used, but it also converts between them automatically as needed (see §3.4.3). Therefore, the programmer may choose to mostly ignore the difference between integers and floats or to assume complete control over the representation of each number. Standard Lua uses 64-bit integers and double-precision (64-bit) floats, but you can also compile Lua so that it uses 32-bit integers and/or single-precision (32-bit) floats. The option with 32 bits for both integers and floats is particularly attractive for small machines and embedded systems. (See macro LUA_32BITS in file luaconf.h.)
Раз введен новый подтип, то возвращаемые данные будут integer, для примера:
А раз так, то нет необходимости преобразовывать данные. Впрочем, наверно, Вы все это знаете.
Пользователь
Сообщений: Регистрация: 20.03.2023
13.06.2023 12:27:47
Так то в С тип lua_Number - это double. Не надо его использовать для номера заявки.
Пользователь
Сообщений: Регистрация: 20.03.2023
13.06.2023 12:30:02
Это в lua два подтипа. А в C api надо явно выбирать что использовать - lua_Number или lua_Integer. C не умеет "два в одном".
Пользователь
Сообщений: Регистрация: 29.06.2015
13.06.2023 12:30:47
Знаете, а Вы, скорее всего, правы. Я делаю преобразование с помощью lua_tonumber, а оказывается, что начиная с версии 5.3 lua_Integer - это 64-битный целый тип и можно использовать lua_tointeger. Большое спасибо за помощь, коллективный разум - это сила )
QuantPro Platform
Пользователь
Сообщений: Регистрация: 20.03.2023
13.06.2023 12:42:52
Вы бы сразу про С++ написали - быстрее бы проблему нашли.
Пользователь
Сообщений: Регистрация: 22.03.2016
19.06.2023 11:10:52
Чтобы не заморачиваться с запоминанием номера заявки, смотри ссылку
Пользователь
Сообщений: Регистрация: 29.06.2015
19.06.2023 20:48:25
Я видел эту ссылку, но мне не нужно снимать все заявки, мне нужно снять именно конкретную заявку и ловить по ней события. И благодаря помощи участников форума проблему мне удалось решить.