rodionos (Автор тем)

Выбрать дату в календареВыбрать дату в календаре

Страницы: 1
Ежедневный экспорт таблицы обезличенных сделок в СУБД
 
Коллеги, приглашаем воспользоваться новой интеграцией СУБД Axibase с терминалом QUIK для архивирования таблицы обезличенных сделок.

https://axibase.com/docs/atsd/finance/ru/quik.html
Интеграция проверена эксплуатацией с QUIK 8.2+ в течение 1 года с сохранением 35-40 млн сделок в день.

Для справки, количество сделок во всех режимах на МосБирже 22.03.2021 составило 4024356.

Если возникнут вопросы - пишите в теме или в ЛС.
Экспорт alltrades (обезличенных сделок) в нереляционную СУБД с SQL
 
Коллеги, приглашаем к использованию новой интеграции СУБД Axibase с терминалом QUIK.

Интеграция проверена эксплуатацией в течение 1 года с сохранением 35-40 млн сделок в день. QUIK 8.2+

https://axibase.com/docs/atsd/finance/ru/quik.html

Рекомендуем в начале настроить ежедневную выгрузку скриптом export_alltrades.lua
После этого включить ODBC драйвер.  Комбинация обоих механизмов позволяет практически исключить пробелы в истории сделок.

Практическое применение - backtesting, оптимизация алгоритов в части выставления заявок.

Использование СУБД бесплатное. Будем признательны за обратную связь. На хорошие вопросы постараюсь отвечать в течение дня.
Почему в стратегии на ФР нельзя использовать параметры waprice (а также marketprice2, marketpricetoday, prevwaprice, priceminusprevwa)
 
При разработке новых тестов на получаемые по итогам дня статистики обнаружился такой факт:

Код
waprice ~= ROUND(valtoday/voltoday/sec_price_step,0)*sec_price_step

При этом несоответствие наблюдается для отдельных инструментов и разброс в отдельных случаях весьма существенный. С дататипами переменных и округлением не связано.

Как оказалось, waprice акций который раньше воспринимался как тот же дневной vwap данного класса, оказался гораздо хитрее. А именно, выяснилось, что при расчете waprice биржа "cмешивает" сделки не только из класса TQBR но и из других классов, в частности из РПС (с ЦК и без) и неполные лоты. Объем в режиме неполных лотов малый, до 500 тысяч рублей в день, а РПС - это 2 млрд рублей в день, что достаточно для точечного вредительства алгоритмам.

Подробности в расследовании по ссылке, но краткий вывод такой - используйте valtoday/voltoday.

waprice лежит в основе marketprice2, marketpricetoday, prevwaprice, priceminusprevwa - соответственно эти параметры также затронуты.
Нулевые значения PRICEMIN и PRICEMAX
 

22.06 параметры PRICEMIN и PRICEMAX равны нулю.

Возможно это связано с тем, что сегодня состоится доп. сессия на фондовом рынке и произошло обновление Квик-серверов у брокеров (Финам, Сбербанк).

Как рекомендуется решать задачу получения диапазона допустимых значений для инструментов, например класса TQBR:

Код
2020-06-22 10:59:03.067028,INFO: p PRICEMAX : {param_image=0.0, param_type=1, param_value=0.000000, result=1}
2020-06-22 10:59:03.067028,INFO: p PRICEMIN : {param_image=0.0, param_type=1, param_value=0.000000, result=1}
Параметр VOLUME из AUCTSTATS - ожидаемый объем в ходе аукциона
 
В каком параметре транслируется ожидаемый объем в ходе аукциона (фаза сбора заявок, открытие)?
Согласно документации, это должен быть VOLUME, но он постоянно nil.
При этом AUCTPRICE возвращает корректное значение.

http://ftp.moex.com/pub/ClientsAPI/ASTS/Bridge_Interfaces/MarketData/Equitie­s35_Info_Russian.htm#t0_1
Определение текущего режима торгов на аукионе открытия
 
После окончания фазы сбора заявок (случайно в 09:59:30+) на аукционе открытия наблюдаю, что TRADINGSTATUS остается на 3 (открыта) и при этом ENDTIME (время окончания фазы) иногда проставлено иногда нет.Существует ли надежный способ узнать, можно ли выставлять заявку во время аукциона открытия?
Замена заявки на ФР при помощи Order Cancel/Replace Request (G)
 
Есть ли возможность отправить на биржу транзакцию, которая произведет замену заявки (изменение цены)?
Сейчас использую NEW_ORDER и KILL_ORDER в sendTransaction для замены.


Из документа биржи:
 
Код
Сообщение Order Cancel/Replace Request (G) используется для изменения параметров заявки. Обработка приказа Order Cancel/Replace Request (G) – атомарная операция, то есть другие приказы не могут обрабатываться между снятием исходной заявки и регистрацией новой. Время обработки сообщения (время ожидания ответа) Order Cancel Replace превышает время ожидания ответа при регистрации новой заявки, но меньше суммарного времени обработки пары приказов Order Cancel Request + New order single. Среднее время доставки приказа Order Cancel Replace от клиента во входную очередь ядра торговой системы не отличается от времени доставки приказов других типов (New Order Single или Order Cancel Request). 
Имя поля 'Тип события активации заявки' в специальном формате
 
Для указания типа по остатку в специальном формате можно использовать поле execution_condition:
Код
  local transaction = {
    trans_id    = '123',
    account     = '******',
    action      = 'NEW_ORDER',
    classcode   = 'TQBR',
    seccode     = 'GAZP',
    operation   = 'B',
    quantity    = '2',
    price       = '245.00',
    type        = 'L',
    execution_condition='FILL_OR_KILL'  
}

Есть ли соответствующее поле для подачи заявки в аукцион?

В универсальном формате tri это указывается как:

Код
transaction['Тип события активации заявки'] = 'Заявка в аукцион закрытия'
Механизм исполнения заявки с типом "По одной цене"
 
Обработка лимитной заявки с типом "По одной цене" предполагает несколько сценариев.
Один из таких сценариев - это дефицит количества во встречных заявках по наилучшей цене.

Допустим, что есть встречные заявки на продажу:

- 261.10 x 10
- 260.00 x 5

Отправляем заявку на покупку "По одной цене":
+ 262.00 x 20

Данная заявка на покупку приведет к сделке на 5 бумаг по 260.00, при этом остаток будет поставлен в очередь в книге заявок по цене первой сделки 260.00.
Состояние книги после частичного исполнения:

- 261.10 x 10
+ 260.00 x 15

После отправки транзакции с этим признаком
Код
transaction['Тип по цене'] = 'По одной цене'
transaction['Цена'] = '262.0'

в терминал Квик приходит событие OnOrder, в котором цена указана 260.00, при этом заявка является частично исполненной.
1) Сохраняется ли в таблице Order информация об исходной лимитной цене (262), или эта информация утрачивается?
2) В какой момент (сервер Quik, терминал Quik, биржа) происходит данное "уточнение" цены заявки.
3) Для каких стратегий может быть полезен данный тип заявки?
Отправка заявки айсберг с использованием полей на англ. языке
 
В скрипте используются имена полей на английском языке.
Терминал на русском языке. При выводе в tri вижу следующее:
Код
TRANS_ID=1;CLASSCODE=TQBR;ACTION=Ввод айсберг заявки;Торговый счет=NNNN;К/П=Купля;Тип=Лимитная;
Тип по цене=По разным ценам;Тип по остатку=Поставить в очередь;Тип ввода значения цены=По цене;Назначение заявки=По умолчанию;
Тип события активации заявки=Обычная заявка;Режим=TQBR;Инструмент=AFLT;Цена=99.90;Лоты=110;Примечание=;Объем заявки=0.00;
Код внешнего пользователя=;Время активации=;Доп. инфо=;Фирма торгового счета=;Видимое количество=100;

При отправке транзакции получаю ошибку:

   -  Не указано значение поля "Лоты"

https://forum.quik.ru/messages/forum10/message39864/topic3902/#message39864

Код
local transaction = {}transaction['TRANS_ID'] = '400001'
transaction['ACTION'] = 'NEW_ORDER'
transaction['CLASSCODE'] = 'TQBR'
transaction['SECCODE'] = 'AFLT'
transaction['ACCOUNT'] = 'NNNNNN'
transaction['OPERATION'] = 'B'
transaction['PRICE'] = '99.90'
transaction['TYPE'] = 'L'
transaction['Lots'] = '110'
transaction['Visible quantity'] = '100'

Есть ли варианты решения проблемы?
Минимальный размер видимой части у айсберга
 
Коллеги, есть ли возможность в параметрах инструмента увидеть это значение?
По умолчанию это 100 лотов, но в таблице А-5 приведены исключения: https://fs.moex.com/files/5877/32604Из интерфейса Квик мне непонятно - проводится ли проверка на клиенте или на сервере биржи?
Добавление параметра lasttrade в LUA getParamEx
 
Функция getParamEx уже предоставляет доступ к информации о последней сделке, а именно о ее цене, количестве и времени.
Однако при высокочастной торговле, когда почти одновременно происходит большое количество сделок, эти параметры не дают однозначной идентификации сделки.
Предлагаю добавить поле lasttrade, которое будет содержать trade_num сделки.
Также рассмотреть вопрос об увеличении точности времени последней сделки до долей секунды. Речь идет о поле time.

Эта информация (микросекунды) уже транслируется в таблице alltrades.
OnTrade flags - направленность сделки
 
По второму биту flags таблицы trades (или OnTrade) я получаю информацию, купли ли терминал инструмент или продал.

бит 2 (0x4) Заявка на продажу, иначе – на покупку. Данный флаг для сделок и сделок для исполнения определяет направление сделки (BUY/SELL)

Можно ли также из flags достать информацию о направленности сделки, то есть была это продажа по биду или покупка по офферу?

По сути необходимо значение нулевого бита так как он проставлен для этой сделки в AllTrades (обезличенные сделки).

Скорость обработки заявок при помощи OnTransReply gate_reply_time
 
Используя разных брокеров (Сбер и Финам) обнаружил, что разница между полями date_time и gate_reply_time зависит от брокера.
В одном случае gate_reply_time всегда больше date_time, в другом случае наоборот.
Что же все-таки означает это поле? В документации указано, что это "Дата и время получения шлюзом ответа на транзакцию".
Тогда не совсем понятно почему оно предшествует date_time, да и само поле date_time требует уточнения.
Является ли это поле временем получения транзакции Quik сервером у брокера?
В целом планирую использовать дельту между gate_reply_time и date_time для целей мониторинга и выбора оптимального Квик сервера в зависимости от стратегии.
Сервисные функции для отключения терминала типа disconnect()
 
Для мониторинга ключевых показателей использую выделенный скрипт.
Торговые стратегии реализованы в отдельных скриптах.

Есть определенные пороги, при превышении которых небходимо остановить исполнение всех lua скриптов, кроме контрольного.
Также необходимо при определенных условиях отсоединить терминал.

Контекст: для тех кто не сталкивался с доп. вознаграждением биржи за гиперактивные торговые алгоримты, советую ознакомиться и поставить на мониторинг!

Из сервисных функций есть isConnected. Функции disconnect() похоже нет. Сейчас вызывается os.exit(), но это брутально.
Есть ли еще варианты, которые следует изучить?
SearchItems - потокобезопасная итерация
 
Я пользуюсь нижеприведенным вариантом для получения подвыборки строк из таблицы, в данном примере из таблицы orders.
Код
function find_active_orders(class_code, sec_code)

    function matchItem(_flags, _class_code, _sec_code)
      return bit.band(_flags, 0x1) ~= 0
        and _class_code == class_code
        and _sec_code == sec_code
    end

    local indexes = SearchItems("orders", 0, getNumberOf("orders")-1, matchItem, "flags,class_code,sec_code")
    if indexes == nil then return {} end
    local res = {}
    for i=1, #indexes do
      local item = getItem("orders", indexes[i])
      if matchItem(item.flags, item.class_code, item.sec_code) then
        res[#res+1] = item
      end
    end
    return res
end

В строке if matchItem(item.flags, item.class_code, item.sec_code) then я дополнительно проверяю, что полученная заявка соответствует изначальному фильтру на случай, если таблица orders будет изменена и в нее будут добавлены новые заявки в произвольном порядке.

Два вопроса:

1) Необходима ли повторная проверка или можно полагаться, что а) строки не удаляются,  б) новые заявки помещаются в конец таблицы и в) порядок строк не меняется в течение торгового дня? Если так, применима ли такая модель ко всем таблицам в Quik (строки никогда не удаляются, новые добавляются в конец, порядок строк зафиксирован).

2) По ходу биржевого дня количество строк в таблице постоянно увеличивается и доходит до 20000, в результате постоянного изменения лимитных заявок по цене (снять старую, выставить новую по другой цене). При этом активных заявок только несколько сотен. При каком размере таблицы имеет смысл задуматься о производительности функции find_active_orders и как ее можно было ускорить для случая когда практически все заявки неактивные?
Страницы: 1
Наверх