Имеется таблица orders
, в которой отражаются все именения по заявкам клиентов на бирже. В таблице есть поля:
id
— автоинкрементaccount_id
— идентификатор счёта (клиента)timestamp_ns
— значениеtime.time_ns()
события (всё как в жизни, почти всегда монотонно)side
—BUY
илиSELL
price
— (Decimal) цена, по которой стоит заявка на покупку или продажуsize
— на какое количество стоит заявка с этого момента (0 означает, что заявки от этого клиента с этой стороны по этой цене больше нет)
За день количество записей в таблице может достигать миллионов.
Среди клиентов есть маркет-мейкеры. Их задача — создавать привлекательный рынок, то есть чтоб всегда можно было прийти и купить или продать актив по разумной цене. Если маркет-мейкер выполняет условие программы, то биржа выплачивает ему вознаграждение. Условие выполняется в данный момент времени, если мы берём заявки макет-мейкера совокупным размером MM_SIZE (int) с самой привлекательной ценой (минимальная для SELL и маскимальная для BUY) и разница между максимальной ценой заявок на продажу и минимальной на покупку в этих совокупностях составляет не более SPREAD базисных пунктов (int, 1 базисный пункт = 0.01%).
Пример. Параметры программы: MM_SIZE=5, SPREAD=2000. Заявки маркет-мейкера в какой-то момент времени:
| BUY SELL
11.0 | 5
10.5 | 3
9.5 | 5
9.0 | 9
Для MM_SIZE=5 на покупку нам нужно взять 5 заявок по цене 9.5
. На продажу — 3 заявки по цене 10.5
и 2 по 11.0
. Итого мы получаем спред: (11.0 - 9.5) / 10.0 * 10000 = 1500
базисных пункта (здесь 10.0
— средняя цена между лучшими заявками на покупку и продажу). Полученные 1500 меньше требуемых 2000, значит маркет-мейкер условие программы в данный момент выполняет.
Нужно написать функцию, которая по заданному account_id
маркет-мейкера и дате определяет, какую часть времени (доля) за эти сутки клиент выполнял условия программы.
Возможное усложнение. Есть ещё одна таблица trading_status
, в которой сохраняется информация, когда торги шли и когда они были остановлены. Поля:
id
— автоинкрементtimestamp_ns
— значениеtime.time_ns()
события (всё как в жизни, почти всегда монотонно)status
—TRADING
илиHALTED
.
При расчёте программы нужно учитывать только те промежутки, когда шли торги.