Функция как получаю текущее число открытых позиций:
Код
-- QUIK Получить: текущее кол-во открытх позиций
function _QuikGetTotalnetByIndex(code)
for i = 0,getNumberOf("futures_client_holding") - 1 do
if getItem("futures_client_holding",i).sec_code == code then
return getItem("futures_client_holding",i).totalnet;
end;
end;
return 0;
end;
Сейчас 0 контрактов. Купили 2 контракта. Приходит ответ в функции в OnTrade() что куплено 2 контракта. Но если внутри данной функции сделать запрос на кол-во контрактов _QuikGetTotalnetByIndex() - то будет 0.
Если купить еще 3 контракта, и сделать запрос в OnTrade() - то он выведет значение 2. Складывается впечатление что таблица ограничений по клиентским счетам "futures_client_holding" обновляется после таблицы сделок, либо чего-то не понимаю?
Просто таблица futures_client_holding еще не обновилась. Изменение записей идут в потоке. Для каждой таблицы свой поток. Можно релиализовать обработку на событие изменения таблицы futures_client_holding или вести подсчет купленного самостоятельно.
Для общего развития хотелось бы понимать: Последовательность событий OnTrancReply(), OnOrder(), OnTrade(), имеют всегда жесткую последовательность исполнения, или же могут в разном порядке сработать?
Иван написал: Последовательность событий OnTrancReply(), OnOrder(), OnTrade(), имеют всегда жесткую последовательность исполнения, или же могут в разном порядке сработать?
Нет. Фиксированной последовательности нет. Скрипт следует писать так, чтобы он корректно работал при абсолютно любой последовательности вызова этих событий. Более того, OnOrder() и OnTrade() могут быть вызваны по несколько раз для одной и той же заявки и сделки.
Чисто теоретически OnTrancReply() вовсе может не быть вызван (например, терминал потерял связь после отправки транзакции), но будем считать, что это слишком экзотический случай, хотя и вполне реальный, такие сообщения на форуме были.
С этим не надо бороться, это нормальное поведение для event-driven архитектуры, с этим надо работать. Вы отправляете транзакцию (без немедленной ошибки) и уходите заниматься другими делами, а потом происходит что-то из: - явное подтверждение статуса транзакции (OnTransReply) - неявное подтверждение статуса транзакции (OnOrder, OnTrade, ...) - потеря соединения (OnDisconnected) - таймаут (т.е. никакого ответа вообще не получено за заданное время; это ваша задача, завести таймер) - крах скрипта (если ошибки ловите и обрабатываете, тут самое развеселье начнется) Все это может произойти в любом порядке и не один раз, к этому надо быть готовым и все. Заводите объект "транзакция номер id", по колбекам меняете его состояние. Когда состояние стало "консистентным" (все выполнено или все отклонено) - убиваете объект. Возможные дальнейшие события с этим id вас уже не волнуют, игнорируете их. В свою очередь объект "транзакция" может порождать или убивать объект "заявка", у того своя жизнь и свои события. В свою очередь объект "заявка" может влиять на объекты "сделка" и "позиция". Тут уже ближе к верхнему уровню, в конечном итоге все затевалось, чтобы изменить "позицию".
С этим не надо бороться, это нормальное поведение для event-driven архитектуры, с этим надо работать. Вы отправляете транзакцию (без немедленной ошибки) и уходите заниматься другими делами, а потом происходит что-то из: - явное подтверждение статуса транзакции (OnTransReply) - неявное подтверждение статуса транзакции (OnOrder, OnTrade, ...) - потеря соединения (OnDisconnected) - таймаут (т.е. никакого ответа вообще не получено за заданное время; это ваша задача, завести таймер) - крах скрипта (если ошибки ловите и обрабатываете, тут самое развеселье начнется) Все это может произойти в любом порядке и не один раз, к этому надо быть готовым и все. Заводите объект "транзакция номер id", по колбекам меняете его состояние. Когда состояние стало "консистентным" (все выполнено или все отклонено) - убиваете объект. Возможные дальнейшие события с этим id вас уже не волнуют, игнорируете их. В свою очередь объект "транзакция" может порождать или убивать объект "заявка", у того своя жизнь и свои события. В свою очередь объект "заявка" может влиять на объекты "сделка" и "позиция". Тут уже ближе к верхнему уровню, в конечном итоге все затевалось, чтобы изменить "позицию".
Что бы не обрабатывать №одной и той же заявки нашел такое решение.
Код
function OnTrade(trade)
-- Функция OnTrade() может высываться несколько раз...
if check_last_trade_num < trade_num then
check_last_trade_num = trade_num; -- Запомним номер последнего трейда
С этим не надо бороться, это нормальное поведение для event-driven архитектуры, с этим надо работать. Вы отправляете транзакцию (без немедленной ошибки) и уходите заниматься другими делами, а потом происходит что-то из: - явное подтверждение статуса транзакции (OnTransReply) - неявное подтверждение статуса транзакции (OnOrder, OnTrade, ...) - потеря соединения (OnDisconnected) - таймаут (т.е. никакого ответа вообще не получено за заданное время; это ваша задача, завести таймер) - крах скрипта (если ошибки ловите и обрабатываете, тут самое развеселье начнется) Все это может произойти в любом порядке и не один раз, к этому надо быть готовым и все. Заводите объект "транзакция номер id", по колбекам меняете его состояние. Когда состояние стало "консистентным" (все выполнено или все отклонено) - убиваете объект. Возможные дальнейшие события с этим id вас уже не волнуют, игнорируете их. В свою очередь объект "транзакция" может порождать или убивать объект "заявка", у того своя жизнь и свои события. В свою очередь объект "заявка" может влиять на объекты "сделка" и "позиция". Тут уже ближе к верхнему уровню, в конечном итоге все затевалось, чтобы изменить "позицию".
Что бы не обрабатывать №одной и той же заявки нашел такое решение.
Код
function OnTrade (trade)
-- Функция OnTrade() может высываться несколько раз...
if check_last_trade_num < trade_num then
check_last_trade_num = trade_num; -- Запомним номер последнего трейда
Сделал проверку в трех функциях: CheckLastNumOnTrade = 0; CheckLastNumOnOrder = 0; CheckLastNumOnStopOrder = 0;
Иван написал: Сделал проверку в трех функциях:CheckLastNumOnTrade = 0;CheckLastNumOnOrder = 0;CheckLastNumOnStopOrder = 0;
И отрезали себе всю логику. По ордеру в 10 контрактов пришел ответ "1 залит", вы списали ордер целиком и забыли про него. Если делать хорошо, то "просто" не получится, а если надо "просто", то и проблем нет, но и результат может удивить в какой-то момент (неприятно).
Иван написал: Последовательность событий OnTrancReply(), OnOrder(), OnTrade(), имеют всегда жесткую последовательность исполнения, или же могут в разном порядке сработать?
Нет. Фиксированной последовательности нет. Скрипт следует писать так, чтобы он корректно работал при абсолютно любой последовательности вызова этих событий. Более того, OnOrder() и OnTrade() могут быть вызваны по несколько раз для одной и той же заявки и сделки.
Чисто теоретически OnTrancReply() вовсе может не быть вызван (например, терминал потерял связь после отправки транзакции), но будем считать, что это слишком экзотический случай, хотя и вполне реальный, такие сообщения на форуме были.
Вот допустим прошла сделка, но Total еще не обновился. Можно ли как-то понять что после сделки и значение Total тоже актуализировалось. У меня бывают такие случаи что сделка прошла, а тотал еще не обновлен, а я уже использую его значение... Как быть?
Иван написал: Последовательность событий OnTrancReply(), OnOrder(), OnTrade(), имеют всегда жесткую последовательность исполнения, или же могут в разном порядке сработать?
Нет. Фиксированной последовательности нет. Скрипт следует писать так, чтобы он корректно работал при абсолютно любой последовательности вызова этих событий. Более того, OnOrder() и OnTrade() могут быть вызваны по несколько раз для одной и той же заявки и сделки.
Чисто теоретически OnTrancReply() вовсе может не быть вызван (например, терминал потерял связь после отправки транзакции), но будем считать, что это слишком экзотический случай, хотя и вполне реальный, такие сообщения на форуме были.
Вот допустим прошла сделка, но Total еще не обновился. Можно ли как-то понять что после сделки и значение Total тоже актуализировалось. У меня бывают такие случаи что сделка прошла, а тотал еще не обновлен, а я уже использую его значение... Как быть?
Добрый день.
Как уже сказали выше, данные едут разными потоками. Ограничения по фьючерсам едут с FORTS и не гарантии, что сразу после прихода сделки ограничения обновятся.
Возможно вам подойдет вариант проверять totalnet после вызова OnFuturesClientHolding()
Здравствуйте! У меня схожая проблема. Пишу скрипт, который после покупки, например, 3 лотов выставляет эти же 3 лота на продажу. Как понять, что totalnet обновился полностью? Сейчас проблема: - заявка на покупку исполняется, например, тремя сделками. - после первой сделки кол-во в покупке через getFuturesHolding уже отображается нулевым (будто все кол-во уже куплено) - но при этом общее кол-во через getFuturesHolding показывает, что куплен только 1 лот из 3.
В такой ситуации (при выставленной заявке на покупту 3 лотов) возможные возвращаемые значения getFuturesHolding должны быть такие: openbuys=3 и totalnet=0 openbuys=2 и totalnet=1 openbuys=1 и totalnet=2 openbuys=0 и totalnet=3
Вместо этого после первой сделки прилетает: openbuys=0 и totalnet=1
Если позже прочитать totalnet заново, то возвращается верное totalnet=3
Почему это происходит, и как это исправить? Спасибо
Смотрите сообщение выше, там есть ответ на Ваш вопрос:
Цитата
Egor Zaytsev написал: Добрый день. Как уже сказали выше, данные едут разными потоками. Ограничения по фьючерсам едут с FORTS и не гарантии, что сразу после прихода сделки ограничения обновятся.
Возможно вам подойдет вариант проверять totalnet после вызова OnFuturesClientHolding()
Поэтому рекомендуем воспользоваться функцией OnFuturesClientHolding().
В колбеке OnTrancReply результат сделки приходит раньше чем в OnOrder(), OnTrade(). так как OnTrancReply ответ сервера на транзакцию а OnOrder(), OnTrade() - это регистрация результата в соответствующих таблицах. Естественно, регистрация всегда делается на результат исполнения транзакции. ---------------- Поэтому Вы видите сначала то, что потом увидите в OnOrder(), OnTrade(). ============= Я использую ответ на транзакцию на принятие решения, а колбек регистрации на фиксацию состояния заявки. Все работает и быстро и правильно. --------------------- "... разруха не в клозетах, а в головах."