Обнаружил странное поведение при выставлении заявок на FORTS. Поле order_num, приходящее в колбеке OnTransReply, часто не совпадает со значением в таблице заявок квика, из-за этого не удается программно снять заявку. Тем не менее, бывают редкие случаи, когда эти значения совпадают, и тогда заявки снимаются. При этом обнаружил, что в поле result_msg номер заявки всегда верный. Вот реальные примеры совпадающих номеров и несовпадающих:
Обнаружил странное поведение при выставлении заявок на FORTS. Поле order_num, приходящее в колбеке OnTransReply, часто не совпадает со значением в таблице заявок квика, из-за этого не удается программно снять заявку. Тем не менее, бывают редкие случаи, когда эти значения совпадают, и тогда заявки снимаются. При этом обнаружил, что в поле result_msg номер заявки всегда верный. Вот реальные примеры совпадающих номеров и несовпадающих:
В колбеке OnOrder тот же самый order_num, что и в OnTransReply, поэтому его для снятия заявки использовать не получится. А вот брать из таблицы действительно можно, только выглядит это очень уж коряво. И вопрос остается: почему в OnTransReply order_num не совпадает с тем, который в таблице заявок. И еще более удивительно, что иногда они все-таки совпадают. А вот для фондовой секции они совпадают всегда и я спокойно могу использовать order_num из данных, приходящих в OnTransReply.
В OnTransReply может и не быть order_num, так как это ответ сервера брокера на обработку транзакции. Первый раз этот ответ приходит раньше, чем ответ с сервера биржи. Это отмечено в документации:
На всякий случай отмечу, что иногда биржа не может снять/заменить даже реально существующую заявку и присылает сообщение "Невозможно снять/заменить заявку XXX. Попробуйте позже".
При этом номера заявок верные и торги по инструменту идут.
Проблему решает повторная отправка того же самого запроса на снятие/замену, возможно с минимальной задержкой.
nikolz написал: В OnTransReply может и не быть order_num, так как это ответ сервера брокера на обработку транзакции. Первый раз этот ответ приходит раньше, чем ответ с сервера биржи.
Действительно, Ваш ответ можно было бы принять, но есть нюанс. В поле result_msg номер заявки присутствует, и он всегда верный. Так что проблема явно на стороне квика, уж не знаю там, сервера или клиента. В моем первом сообщении Вы можете увидеть оба случая, когда номера совпадают и когда нет.
Спасибо, но это не тот случай. Попытки отправить по нескольку раз не увенчиваются успехом. А вот при подстановке значения из result_msg заявки прекрасно снимаются, собственно, что и следовало ожидать, так как они всегда совпадают со сначением из таблицы заявок. Пока мне пришлось закостылить регулярку и вытаскивать этот номер из result_msg, но согласитесь, что этот способ так себе решение. Все же хотелось услышать мнение кого-нибудь из разработчиков по данному вопросу.
nikolz написал: В OnTransReply может и не быть order_num, так как это ответ сервера брокера на обработку транзакции. Первый раз этот ответ приходит раньше, чем ответ с сервера биржи.
Действительно, Ваш ответ можно было бы принять, но есть нюанс. В поле result_msg номер заявки присутствует, и он всегда верный. Так что проблема явно на стороне квика, уж не знаю там, сервера или клиента. В моем первом сообщении Вы можете увидеть оба случая, когда номера совпадают и когда нет.
Верно, я его использую. Но это не документированное использование параметров колбека.
относительно снятия заявок. Я тестировал выставление и снятие заявок на демо сервере. У меня все выставлялось и снималось на акциях фьючерсах и валютном счете. https://forum.quik.ru/forum10/topic7930/
Вы ошибаетесь. Это не вопрос к разработчикам, а к документации на Lua 5.4.2 Рекомендую изучить sorce Lua 5.4.2 Если точки нет, то это целое и конвертируется через int64.
nikolz написал: ваш пример не корректный в нем есть неявный формат печати. Вы уверены что он 64 битный?
Если вопрос ко мне, то да, все значения 64-битные. К тому же, если бы имел место некорректный формат печати, то он был бы некорректен во всех случаях. Но это, как Вы можете видеть, не так.
nikolz написал: ваш пример не корректный в нем есть неявный формат печати. Вы уверены что он 64 битный?
Если вопрос ко мне, то да, все значения 64-битные. К тому же, если бы имел место некорректный формат печати, то он был бы некорректен во всех случаях. Но это, как Вы можете видеть, не так.
Я вроде бы выше написал в чем ошибка. Повторю, если не заметили. Ошибка теста выше в неправильном использовании оператора деления. Надо использовать целочисленное деление а не деление с плавающей точкой. ---- Все остальное правильно.
Использование деления там специально чтобы проверить конвертацию в double и обратно в int64. Числа взял из первого сообщения. На самом деле при этом 1951785056590629888 сохраняет значение, а 1951785056590630794 превращается в 1951785056590630912.
paluke написал: Использование деления там специально чтобы проверить конвертацию в double и обратно в int64. Числа взял из первого сообщения. На самом деле при этом 1951785056590629888 сохраняет значение, а 1951785056590630794 превращается в 1951785056590630912.
Полагаю Вы знаете про ошибки округления, поэтому конвертация int64 в double и обратно не может быть всегда точной. ---------------- Более того, все это есть в документации по форматом и для этого не надо делить и умножать ------------------ Ликбез: ------------------- число 1951785056590629888, 1951785056590630794 -- это 19 значащих цифр а double хранит мантиссу лишь с точностью 15-17 значащих цифр. --------------------- Вы это и проверили - т е 15-17 значащих цифр мантиссы не могут всегда точно хранить 19 значащих цифр целого числа.
Проверил у себя. На quik 10.1 order_num в OnTransReply имеет тип integer, и номер там без искажений, совпадает с тем что в result_msg. Автор, а брокер у вас какой?
paluke написал: Проверил у себя. На quik 10.1 order_num в OnTransReply имеет тип integer, и номер там без искажений, совпадает с тем что в result_msg. Автор, а брокер у вас какой?
Проверял на фьючерсах, на реальном счете, и номер там был длинный, в double нормально не помещается.
paluke написал: Использование деления там специально чтобы проверить конвертацию в double и обратно в int64. Числа взял из первого сообщения. На самом деле при этом 1951785056590629888 сохраняет значение, а 1951785056590630794 превращается в 1951785056590630912.
Полагаю Вы знаете про ошибки округления, поэтому конвертация int64 в double и обратно не может быть всегда точной. ---------------- Более того, все это есть в документации по форматом и для этого не надо делить и умножать ------------------ Ликбез: ------------------- число 1951785056590629888, 1951785056590630794 -- это 19 значащих цифр а double хранит мантиссу лишь с точностью 15-17 значащих цифр. --------------------- Вы это и проверили - т е 15-17 значащих цифр мантиссы не могут всегда точно хранить 19 значащих цифр целого числа.
Если вам этой информации достаточно, чтобы точно убедится, что 1951785056590630912 не какое-то случайное значение, а результат округления 1951785056590630794 - я вас поздравляю. Я так в уме не могу, мне проверить надо было.
paluke написал: Проверил у себя. На quik 10.1 order_num в OnTransReply имеет тип integer, и номер там без искажений, совпадает с тем что в result_msg. Автор, а брокер у вас какой?
БКС. Проверял на разных версиях, везде одно и то же.
У меня C++, преобразование идет напрямую из Lua Number в uint64_t, а потом уже пишется в лог. По всей видимости, дело действительно в ошибках преобразования из double в uint64_t, судя по https://www.lua.org/pil/2.3.html Если это так, то возникает резонный вопрос к разработчикам - собираются ли они это исправлять и когда. Учитывая, что Lua не имеет целочисленных типов, а биржа транслирует значения за пределами значений double, тут видится два варианта: или разбивать число на две части и передавать в двух полях, или сделать просто строковое поле.
https://www.lua.org/pil/2.3.html это ссылка на книгу по lua 5.0, там никаких int64 еще не было. Вы не на С++ а на lua проверьте. А то может вы С api неправильно используете (по доке от старой версии lua).
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, для примера:
Знаете, а Вы, скорее всего, правы. Я делаю преобразование с помощью lua_tonumber, а оказывается, что начиная с версии 5.3 lua_Integer - это 64-битный целый тип и можно использовать lua_tointeger. Большое спасибо за помощь, коллективный разум - это сила )
Я видел эту ссылку, но мне не нужно снимать все заявки, мне нужно снять именно конкретную заявку и ловить по ней события. И благодаря помощи участников форума проблему мне удалось решить.