# спецификация на сервис l2.volumeTrader
> **Автоматизированная система тестирования торговой биржи на исторических данных**
## :question: Постановка
Необходимо создать систему, имитирующую многопользовательское тестирование биржи на исторических данных, собираемых с внешних бирж.
#### Источники данных
Как правило биржи имеют rest и ws api, тк данные которые мы хотим собирать обновляются с коротким интервалом, оптимально использовать ws api. Помимо первоисточников, данные можно собирать с агрегаторов[^cmc]
[^cmc]:Внешние агрегаторы биржевых данных: https://coinmarketcap.com/api/documentation/v1/
https://www.kaiko.com/pages/kaiko-pricing
https://min-api.cryptocompare.com/documentation
1. ***Binance***
> [DOC](https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md), **OHLCV** : `<symbol>@kline_<interval>`
> **L2 orderbook**: `<symbol>@depth<levels>`
3. ***Coinbase***
> [DOC](https://docs.pro.coinbase.com/?javascript#overview), **OHLCV & L2**: ```{
"type": "subscribe",
"product_ids": [
"BTC-ETH",
],
"channels": [
"level2",
"ticker",
]
}```
5. ***Bitfinex***
> [DOC](https://docs.bitfinex.com/v2/docs/ws-general), **OHLCV** : `{
"event": "subscribe",
"channel": "ticker",
"symbol": "tBTCUSD"
}`
> **L2 orderbook**: ```{
"event": "subscribe",
"channel": "book",
"symbol": "tBTCUSD",
"prec": "P0",
"freq": "F0",
"len": 25
}```
## :floppy_disk: Функционал
Управление системой происходит через ее API сервис. Отчеты система публикует в телеграм бот, сервис сбора метрик и лог-файл.
**:inbox_tray: На входе задаем параметры :**
1. Пара
2. Количество паралельных ботов, максимальное
3. Деривация, максимальная
4. Биржа, донор данных(определенная или несколько из них)
5. Режим тестирования(обычный/форсированный);
> дать опциональную возможность задать требуемый ***промежуток времени***, с которого берем срез данных для тестирования и параметр - ***пиковая нагрузка или коэфицент форсирования***, если необходимо сжать ордербук данные во времени(для получения большей нагрузке за еденицу времени.
**:100: Что должна уметь делать система :**
1. Пойти на api биржи, получить исторические данные(ohlcv и l2 orderbook) к заданной паре и сохранить их в персистентное хранилище в виде срезов с заданным интервалом(30 сек), это лайфтайм система - собирает данные в прок.
2. Вместе с сырыми данными считаем и складываем в базу объемы ордеров разных типов(обладающих разными наборами атрибутов/подробнее - ниже/)
3. В случае запроса тестирования - сообщить бирже необходимое состояние ордербука на начало тестирования и запустить требуемый режим тестирования на сохраненных или транслируемых данных.
4. При прекращении или прерывании тестирования сообщить результаты в бот телеги.
### 2.1. Сбор данных и рачет объемов разных типов ордеров ордеров:
#### Заявки к бирже обладают тремя атрибутами:
1. :heavy_dollar_sign: **Сторона рынка**: На покупку/На продажу
2. :heavy_check_mark: **Тип ордера**: Лимитные/Маркет
3. :monkey: **Действие ордера**: Добавление/Удаление
#### Исходя из этого заявки делятся на разные типы ордеров, объемы по которым считаем исходя из следующей логики:
* :fish: Объемы по лимитные ордерам(заявки добавленные или удаленные в тело стакана) считаем по l2 orderbook data feed, принимаем за факт что внутри периода между снимками данных нет разно-направленных заявок на одном уровне ордербука.
* :moneybag: Объемы по маркет ордерам(заявки исполненные с шапки стакана) считаем по l2 datafeed + ohlcv data feed + O - уровень цен открытия периода, H - максимальная цена в периоде, L - минимальная цена в периоде, С - цена при закрытии периода, V - объем сделок(маркет ордеров).
**Важно!!** не допустить расхождения накопленного состояния между тестируемым ордербуком и ордербуком дата-провайдера > проверяем что l2 data feed на начало периода + посчитанные объемы в периоде = l2 data feed на конец периода.
### 2.2.:broken_heart: Торговля
Перед началом работы нагрузочного бота необходимо составить коллекцию ордеров каждого типа исходя из имеющихся данных(расчитанных объемов для каждого типа ордера, полученных при сборе исторических данных) и заданных настроек(количества акторов, предельная деревация объема среднего ордера).
### Перед стартом
Протокол подготовки биржи перед стартом - нужно сообщить необходимый ордербук необходимы для старта тестирования. Его берем из базы - снапшот ордербука, снятый перед срезом используемым для расчета.
#### Режимы работы бота:
##### 1. Стандартный
> копирование объемов торговле заданным количеством акторов исходя из сообщенных биржей ohlcv и l2 orderbook. Режим без заданного времени останова, но с заданным временем старта(срез начала использования исторических данных).
##### 2. Форсированный
> Нагрузочное тестирования заданным количеством акторов на накопленных историческими данными, сжатыми во времени в соответствии с требуемой нагрузкой или коэфицентом форсирования(мультипликатор). Не может быть включен в постоянном режиме, тк обречен истощить датасорс.
### 2.3. Отчетность
#### 2.3.1. Telegram bot
После выработки или остановки тестирования сообщить короткий отчет в телеграм бот:
> **⚡test № 124 is stopped:**
>
> | min latency, ms | mean latency, ms | 99% latency, ms | throughput level, tps |
> | -------- | -------- | -------- | -------- |
> | 1 | 2 | 1.9 | 100-120k |
> | 1.1 | 2.1 | 2.0 | 120-160k |
> **🕑 Test started**: 13:55:12(+5GMT)
> **⌛ Test duration**: 8.251 sec
> **🔀 Orders posted**: 2.500.000 pcs
> **💩 Orders declined**: 123 pcs
> **🚄 Throughput achieved**: 2.500.000 tps
Уровни пропускной способности выбрать автоматически при смещении уровня деривации 99% latency на x%(x задаем в конфиге);
**Либо**, если стандартные инструменты языка не позволяют сегментировать данные - сгенерировать и выгрузить график отношения "99% latency" к "Throughput" + выгрузить абсолютные цифры полученные при тестировании:
> **⚡test №123 are finished:**
> 
> ---
> | Metric | Count | Unit |
> | -------- | -------- | -------- |
> | **🕑 Test started** | 13:55:12 | hh:mm:ss(+5GMT) |
> | **⌛ Test duration** | 8.251 | sec |
> | **🔀 Orders posted** | 251.000 | pcs |
> | **💩 Orders declined** | 125 | pcs |
> | **😎 Min latency** | 0.8 | ms |
> | **😅 Mean latency** | 1 | ms |
> | **🙃 99% latency** | 0.9 | ms |
> | **🚄 Throughput achieved** | 2.500.000 | tps |
Пример POST запроса, отправки отчета в бот:
```bash
curl -v \
--data-urlencode "chat_id=$CHAT_ID" \
--data-urlencode "parse_mode=Markdown" \
--data-urlencode "text=| min latency, ms | mean latency, ms | 99% latency, ms | errors, pcs | throughput level, tps | "$'\n'" | -------- | -------- | -------- | -------- | -------- | "$'\n'" | $MIN_LATENCY | $AVG_LATENCY | $TAIL_LATENCY | $ERRORS_COUNT | $THROUGHPUT_LEVEL | "$'\n'" Test duration : 8000s" \
"https://api.telegram.org/bot$BOT_TOKEN/sendMessage"
```
#### 2.3.2. Metrics & logs
**TBA**[^TBA]
Помимо отчета в телеграм, необходимо:
1. транслировать метрики в централизированную систему сбора метрик на базе influxDB.
2. транслировать лог сообщений в JSON лог файл.
[^TBA]: Этот раздел будет уточнятся
## :dancers: REST API
### :one: Доступ к текущему состоянию сервиса
* /get_stat
### :two: Запрос на старт тестирования
* /start_test
### :three: Запрос на остановку тестирования
* /stop_test
### :four: Запрос отчета к тестированию
* /get_report