Build 060.23: integrate Trade Stream Acquisition
This commit is contained in:
1419
docs/migrations/build_060_23.md
Normal file
1419
docs/migrations/build_060_23.md
Normal file
File diff suppressed because it is too large
Load Diff
845
docs/migrations/build_060_23_architecture.md
Normal file
845
docs/migrations/build_060_23_architecture.md
Normal file
@@ -0,0 +1,845 @@
|
||||
# Build 060.23 — Trade Stream Acquisition Integration Architecture
|
||||
|
||||
**Статус:** Architecture Approved
|
||||
|
||||
**Build:** 060.23
|
||||
|
||||
**Название:**
|
||||
Trade Stream Acquisition Integration
|
||||
|
||||
---
|
||||
|
||||
# 1. Назначение Build
|
||||
|
||||
Build 060.23 завершает построение инфраструктурного слоя Acquisition для Trades Feed.
|
||||
|
||||
После Build 060.22 Runtime уже обладает собственной сервисной моделью управления инфраструктурными командами:
|
||||
|
||||
- Runtime Commands;
|
||||
- Runtime Events;
|
||||
- Runtime Service;
|
||||
- Runtime Protocols.
|
||||
|
||||
Однако в настоящий момент Runtime полностью изолирован от существующего Acquisition Layer.
|
||||
|
||||
Trades Feed продолжает работать как синхронный REST Feed:
|
||||
|
||||
```
|
||||
REST document
|
||||
↓
|
||||
TradesHandler
|
||||
↓
|
||||
Trade
|
||||
```
|
||||
|
||||
а Runtime существует отдельно:
|
||||
|
||||
```
|
||||
Runtime Commands
|
||||
Runtime Events
|
||||
Runtime Service
|
||||
```
|
||||
|
||||
В результате отсутствует единая точка, которая соединяет:
|
||||
|
||||
- Runtime;
|
||||
- Subscription API;
|
||||
- WebSocket Adapter;
|
||||
- Consistency Layer.
|
||||
|
||||
Именно эту задачу решает Build 060.23.
|
||||
|
||||
---
|
||||
|
||||
# 2. Цели Build
|
||||
|
||||
Build вводит единый сервис интеграции Trade Stream.
|
||||
|
||||
Новый сервис становится входной точкой всей Runtime Acquisition Pipeline.
|
||||
|
||||
После завершения Build поток данных приобретает следующий вид:
|
||||
|
||||
```
|
||||
Subscribe()
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Subscription Builder
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Acquisition Runtime Service
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
WebSocket Runtime
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Unified Adapter
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Trade
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Consistency Controller
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Trade | None
|
||||
```
|
||||
|
||||
При этом Build намеренно не реализует:
|
||||
|
||||
- production WebSocket;
|
||||
- reconnect;
|
||||
- heartbeat;
|
||||
- receive loop;
|
||||
- runtime scheduler;
|
||||
- recovery.
|
||||
|
||||
Все перечисленные компоненты остаются предметом следующих Build.
|
||||
|
||||
---
|
||||
|
||||
# 3. Архитектурная цель
|
||||
|
||||
Главная задача Build —
|
||||
|
||||
полностью отделить инфраструктуру Runtime
|
||||
от обработки Trade.
|
||||
|
||||
После Build Runtime больше не знает:
|
||||
|
||||
- что такое Trade;
|
||||
- что такое Feed;
|
||||
- что такое Consistency;
|
||||
- что такое Recovery.
|
||||
|
||||
Runtime работает исключительно с инфраструктурными командами.
|
||||
|
||||
Вся логика Trade переносится в отдельный слой Acquisition Integration.
|
||||
|
||||
---
|
||||
|
||||
# 4. Архитектурные принципы
|
||||
|
||||
Build следует тем же принципам, которые используются во всей новой архитектуре Acquisition.
|
||||
|
||||
## 4.1 Single Responsibility
|
||||
|
||||
Runtime отвечает исключительно за инфраструктуру соединения.
|
||||
|
||||
Trade Integration отвечает исключительно за обработку Trade Stream.
|
||||
|
||||
Consistency отвечает исключительно за целостность последовательности сделок.
|
||||
|
||||
Recovery отвечает исключительно за восстановление пропущенных данных.
|
||||
|
||||
Ни один слой не должен смешивать собственную ответственность с соседними.
|
||||
|
||||
---
|
||||
|
||||
## 4.2 Dependency Direction
|
||||
|
||||
Все зависимости направлены только вниз.
|
||||
|
||||
```
|
||||
Trade Stream Acquisition Service
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Runtime Service
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Runtime Protocols
|
||||
```
|
||||
|
||||
Обратные зависимости запрещены.
|
||||
|
||||
Runtime не может импортировать Acquisition.
|
||||
|
||||
---
|
||||
|
||||
## 4.3 Exchange Independence
|
||||
|
||||
Trade Integration не знает ничего о Dzengi.
|
||||
|
||||
Exchange-specific логика уже локализована внутри:
|
||||
|
||||
```
|
||||
DzengiUnifiedWebSocketAdapter
|
||||
```
|
||||
|
||||
Build не добавляет новых exchange-specific условий.
|
||||
|
||||
---
|
||||
|
||||
## 4.4 Canonical Pipeline
|
||||
|
||||
После Build существует единственный допустимый путь обработки Trade:
|
||||
|
||||
```
|
||||
Raw Message
|
||||
|
||||
↓
|
||||
|
||||
Unified Adapter
|
||||
|
||||
↓
|
||||
|
||||
Trade
|
||||
|
||||
↓
|
||||
|
||||
Consistency
|
||||
|
||||
↓
|
||||
|
||||
Trade
|
||||
```
|
||||
|
||||
Любые альтернативные пути считаются нарушением архитектуры.
|
||||
|
||||
---
|
||||
|
||||
# 5. Новые компоненты
|
||||
|
||||
Build вводит два новых компонента.
|
||||
|
||||
```
|
||||
trade_stream_acquisition_protocol.py
|
||||
|
||||
trade_stream_acquisition_service.py
|
||||
```
|
||||
|
||||
Оба файла располагаются внутри:
|
||||
|
||||
```
|
||||
src/
|
||||
└── market_data/
|
||||
└── acquisition/
|
||||
```
|
||||
|
||||
Build намеренно не изменяет существующие Feed.
|
||||
|
||||
Feed остаются независимыми клиентами Acquisition Layer.
|
||||
|
||||
---
|
||||
|
||||
# 6. Новая ответственность Acquisition Layer
|
||||
|
||||
После Build Acquisition становится полноценным координатором Runtime Pipeline.
|
||||
|
||||
Именно Acquisition теперь отвечает за:
|
||||
|
||||
- отправку Runtime Command;
|
||||
- получение Trade;
|
||||
- передачу Trade в Consistency;
|
||||
- возврат согласованного результата.
|
||||
|
||||
Runtime при этом остаётся полностью инфраструктурным компонентом.
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
# 7. Архитектура зависимостей
|
||||
|
||||
После завершения Build зависимости между компонентами приобретают следующий вид.
|
||||
|
||||
```
|
||||
+------------------------------------+
|
||||
| Trade Stream Acquisition Service |
|
||||
+------------------------------------+
|
||||
│ │
|
||||
│ │
|
||||
▼ ▼
|
||||
+---------------------------+ +---------------------------+
|
||||
| Acquisition Runtime | | Dzengi Unified Adapter |
|
||||
| Service | +---------------------------+
|
||||
+---------------------------+ │
|
||||
│ │
|
||||
│ ▼
|
||||
│ Quote | Trade | Candle
|
||||
│
|
||||
▼
|
||||
+---------------------------+
|
||||
| Runtime Protocols |
|
||||
+---------------------------+
|
||||
│
|
||||
▼
|
||||
Runtime Infrastructure
|
||||
|
||||
|
||||
Trade
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Trade Stream Consistency Controller
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Trade | None
|
||||
```
|
||||
|
||||
Таким образом Runtime перестаёт знать о типах рыночных данных.
|
||||
|
||||
Trade остаётся полностью внутри слоя Acquisition.
|
||||
|
||||
---
|
||||
|
||||
# 8. Обработка подписок
|
||||
|
||||
Новый сервис становится единственной точкой открытия Trade Stream.
|
||||
|
||||
Внешние компоненты больше не должны самостоятельно создавать Runtime Commands.
|
||||
|
||||
Правильная последовательность выглядит следующим образом.
|
||||
|
||||
```
|
||||
symbols
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
build_trade_subscribe_command()
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
SubscribeCommand
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
AcquisitionRuntimeService.dispatch()
|
||||
```
|
||||
|
||||
Сам сервис не сериализует сообщения.
|
||||
|
||||
Он использует уже существующий Subscription Builder.
|
||||
|
||||
Build не изменяет формат WebSocket сообщений.
|
||||
|
||||
---
|
||||
|
||||
# 9. Обработка входящих сообщений
|
||||
|
||||
Второй обязанностью нового сервиса становится обработка входящего транспортного сообщения.
|
||||
|
||||
Полная последовательность обработки выглядит следующим образом.
|
||||
|
||||
```
|
||||
Raw WebSocket Document
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
DzengiUnifiedWebSocketAdapter
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Quote
|
||||
Trade
|
||||
CandleCloseEvent
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
isinstance(result, Trade)
|
||||
|
||||
│
|
||||
|
||||
├──────────────► нет
|
||||
│
|
||||
│
|
||||
▼
|
||||
|
||||
Trade Stream Consistency Controller
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Trade | None
|
||||
```
|
||||
|
||||
Если адаптер возвращает:
|
||||
|
||||
```
|
||||
Quote
|
||||
```
|
||||
|
||||
или
|
||||
|
||||
```
|
||||
CandleCloseEvent
|
||||
```
|
||||
|
||||
сообщение считается неподходящим для данного сервиса.
|
||||
|
||||
Build не выполняет никаких дополнительных преобразований.
|
||||
|
||||
---
|
||||
|
||||
# 10. Взаимодействие с Consistency
|
||||
|
||||
Trade Integration не реализует собственную проверку последовательности.
|
||||
|
||||
Вся ответственность делегируется существующему компоненту.
|
||||
|
||||
```
|
||||
Trade
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
TradeStreamConsistencyController.accept()
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Trade | None
|
||||
```
|
||||
|
||||
Если Controller возвращает:
|
||||
|
||||
```
|
||||
None
|
||||
```
|
||||
|
||||
это означает корректный дубликат.
|
||||
|
||||
Никаких дополнительных действий сервис не выполняет.
|
||||
|
||||
Если Controller возбуждает исключение:
|
||||
|
||||
- TradeConsistencyError;
|
||||
- TradeOrderingError;
|
||||
|
||||
исключение полностью передаётся вызывающей стороне.
|
||||
|
||||
Build не изменяет модель ошибок Consistency Layer.
|
||||
|
||||
---
|
||||
|
||||
# 11. Взаимодействие с Runtime
|
||||
|
||||
Trade Stream Acquisition Service использует Runtime исключительно как инфраструктурный компонент.
|
||||
|
||||
Допустимыми являются только следующие Runtime Commands.
|
||||
|
||||
```
|
||||
ConnectCommand
|
||||
|
||||
DisconnectCommand
|
||||
|
||||
SubscribeCommand
|
||||
|
||||
UnsubscribeCommand
|
||||
|
||||
SendTextCommand
|
||||
|
||||
SendBinaryCommand
|
||||
```
|
||||
|
||||
Никакие Runtime Events в Build 060.23 не анализируются.
|
||||
|
||||
Publisher продолжает существовать исключительно как инфраструктурный контракт.
|
||||
|
||||
---
|
||||
|
||||
# 12. Использование Unified Adapter
|
||||
|
||||
Build намеренно использует существующий:
|
||||
|
||||
```
|
||||
DzengiUnifiedWebSocketAdapter
|
||||
```
|
||||
|
||||
а не специализированный Trade Adapter.
|
||||
|
||||
Причины данного решения:
|
||||
|
||||
• уже существует единая точка обработки WebSocket сообщений;
|
||||
|
||||
• отсутствует дублирование маршрутизации;
|
||||
|
||||
• Runtime остаётся полностью независимым от типа сообщения;
|
||||
|
||||
• в будущем Runtime сможет одинаково обслуживать:
|
||||
|
||||
- Quotes;
|
||||
- Trades;
|
||||
- Candles.
|
||||
|
||||
Таким образом новый сервис использует уже сформированную архитектуру, а не создаёт отдельную ветку обработки Trade.
|
||||
|
||||
---
|
||||
|
||||
# 13. Публичный API сервиса
|
||||
|
||||
Build вводит минимальный публичный интерфейс.
|
||||
|
||||
```python
|
||||
class TradeStreamAcquisitionServiceProtocol(Protocol):
|
||||
|
||||
async def subscribe(
|
||||
self,
|
||||
symbols: tuple[str, ...],
|
||||
*,
|
||||
correlation_id: str | None = None,
|
||||
) -> None:
|
||||
...
|
||||
|
||||
def handle_message(
|
||||
self,
|
||||
document: object,
|
||||
) -> Trade | None:
|
||||
...
|
||||
```
|
||||
|
||||
Оба метода являются частью единой ответственности сервиса.
|
||||
|
||||
Никаких дополнительных методов Build не вводит.
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
# 14. Architecture Decision Records (ADR)
|
||||
|
||||
## ADR-060.23-001
|
||||
|
||||
Trade Stream Integration располагается исключительно внутри слоя Acquisition.
|
||||
|
||||
### Причина
|
||||
|
||||
Runtime является инфраструктурным компонентом и не должен знать о типах рыночных данных.
|
||||
|
||||
### Следствие
|
||||
|
||||
Runtime никогда не импортирует:
|
||||
|
||||
- Trade;
|
||||
- Trades Feed;
|
||||
- Consistency;
|
||||
- Recovery;
|
||||
- Unified Adapter.
|
||||
|
||||
---
|
||||
|
||||
## ADR-060.23-002
|
||||
|
||||
Trade обрабатывается только после прохождения Unified Adapter.
|
||||
|
||||
### Причина
|
||||
|
||||
В системе уже существует единая exchange-specific точка преобразования транспортных сообщений.
|
||||
|
||||
```
|
||||
DzengiUnifiedWebSocketAdapter
|
||||
```
|
||||
|
||||
Build не создаёт альтернативных маршрутов обработки.
|
||||
|
||||
---
|
||||
|
||||
## ADR-060.23-003
|
||||
|
||||
Trade Stream Acquisition Service является единственной точкой подписки Trade Runtime.
|
||||
|
||||
### Причина
|
||||
|
||||
Внешние компоненты не должны самостоятельно формировать Runtime Commands.
|
||||
|
||||
Все команды создаются посредством существующих Subscription Builder.
|
||||
|
||||
---
|
||||
|
||||
## ADR-060.23-004
|
||||
|
||||
Trade Stream Acquisition Service не хранит состояние Trade Stream.
|
||||
|
||||
### Причина
|
||||
|
||||
Сервис выполняет исключительно координацию.
|
||||
|
||||
Состояние распределено между специализированными компонентами:
|
||||
|
||||
- Runtime Session;
|
||||
- Subscription Manager;
|
||||
- Trade Stream Consistency Controller.
|
||||
|
||||
Build не вводит нового состояния.
|
||||
|
||||
---
|
||||
|
||||
## ADR-060.23-005
|
||||
|
||||
Trade Stream Acquisition Service не публикует Trade.
|
||||
|
||||
### Причина
|
||||
|
||||
В проекте отсутствует утверждённая инфраструктура публикации канонического Trade Stream.
|
||||
|
||||
До появления такого компонента сервис возвращает:
|
||||
|
||||
```
|
||||
Trade | None
|
||||
```
|
||||
|
||||
не принимая решений о дальнейшей маршрутизации данных.
|
||||
|
||||
---
|
||||
|
||||
# 15. Что не входит в Build
|
||||
|
||||
Настоящий Build сознательно не включает:
|
||||
|
||||
- реализацию WebSocket Transport;
|
||||
- реализацию WebSocket Session;
|
||||
- production Subscription Manager;
|
||||
- receive loop;
|
||||
- reconnect;
|
||||
- heartbeat;
|
||||
- scheduler;
|
||||
- Runtime Recovery;
|
||||
- публикацию Runtime Events;
|
||||
- публикацию Trade;
|
||||
- хранение Trade;
|
||||
- обработку Quote;
|
||||
- обработку Candle;
|
||||
- изменение существующего Trades Feed;
|
||||
- изменение MarketDataRunner;
|
||||
- изменение market_stream.py;
|
||||
- изменение ExchangeWebSocketClient.
|
||||
|
||||
Все перечисленные задачи относятся к следующим Build.
|
||||
|
||||
---
|
||||
|
||||
# 16. План реализации
|
||||
|
||||
Реализация выполняется в несколько последовательных шагов.
|
||||
|
||||
## Этап 1
|
||||
|
||||
Создание нового контракта
|
||||
|
||||
```
|
||||
trade_stream_acquisition_protocol.py
|
||||
```
|
||||
|
||||
Контракт описывает публичный API сервиса.
|
||||
|
||||
---
|
||||
|
||||
## Этап 2
|
||||
|
||||
Создание реализации
|
||||
|
||||
```
|
||||
trade_stream_acquisition_service.py
|
||||
```
|
||||
|
||||
Сервис получает через конструктор зависимости:
|
||||
|
||||
- AcquisitionRuntimeServiceProtocol;
|
||||
- DzengiUnifiedWebSocketAdapter;
|
||||
- TradeStreamConsistencyProtocol.
|
||||
|
||||
---
|
||||
|
||||
## Этап 3
|
||||
|
||||
Интеграция подписки
|
||||
|
||||
Добавляется метод:
|
||||
|
||||
```
|
||||
subscribe(...)
|
||||
```
|
||||
|
||||
который:
|
||||
|
||||
- строит SubscribeCommand;
|
||||
- передаёт его Runtime Service;
|
||||
- не содержит exchange-specific логики.
|
||||
|
||||
---
|
||||
|
||||
## Этап 4
|
||||
|
||||
Интеграция обработки сообщений
|
||||
|
||||
Добавляется метод:
|
||||
|
||||
```
|
||||
handle_message(...)
|
||||
```
|
||||
|
||||
Последовательность обработки:
|
||||
|
||||
```
|
||||
document
|
||||
|
||||
↓
|
||||
|
||||
Unified Adapter
|
||||
|
||||
↓
|
||||
|
||||
Trade
|
||||
|
||||
↓
|
||||
|
||||
Consistency
|
||||
|
||||
↓
|
||||
|
||||
Trade | None
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Этап 5
|
||||
|
||||
Покрытие тестами
|
||||
|
||||
Добавляются unit-тесты:
|
||||
|
||||
- проверка соответствия Protocol;
|
||||
- проверка dispatch подписок;
|
||||
- проверка обработки Trade;
|
||||
- проверка игнорирования Quote;
|
||||
- проверка игнорирования Candle;
|
||||
- проверка передачи Trade в Consistency;
|
||||
- проверка возврата None для корректного дубликата;
|
||||
- проверка проброса исключений Consistency;
|
||||
- проверка отсутствия скрытого состояния.
|
||||
|
||||
---
|
||||
|
||||
# 17. Definition of Done
|
||||
|
||||
Build считается завершённым после выполнения следующих условий.
|
||||
|
||||
✓ создан Protocol Trade Stream Acquisition Service;
|
||||
|
||||
✓ создана реализация сервиса;
|
||||
|
||||
✓ Runtime интегрирован через AcquisitionRuntimeServiceProtocol;
|
||||
|
||||
✓ Unified Adapter используется как единственная точка преобразования сообщений;
|
||||
|
||||
✓ Consistency используется как единственная точка проверки последовательности сделок;
|
||||
|
||||
✓ сервис не содержит exchange-specific логики;
|
||||
|
||||
✓ сервис не содержит собственного состояния;
|
||||
|
||||
✓ сервис не содержит логики reconnect;
|
||||
|
||||
✓ сервис не содержит логики recovery;
|
||||
|
||||
✓ сервис не взаимодействует с legacy Runtime;
|
||||
|
||||
✓ сервис полностью покрыт unit-тестами;
|
||||
|
||||
✓ существующие тесты Runtime, Feeds, Consistency и Recovery продолжают успешно проходить без изменений.
|
||||
|
||||
---
|
||||
|
||||
# 18. Архитектурное состояние после Build
|
||||
|
||||
После завершения Build 060.23 инфраструктура Acquisition приобретает завершённую форму.
|
||||
|
||||
```
|
||||
Subscription Builder
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Trade Stream Acquisition Service
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Acquisition Runtime Service
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Runtime Protocols
|
||||
|
||||
────────────────────────────────────
|
||||
|
||||
Raw WebSocket Message
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
DzengiUnifiedWebSocketAdapter
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Trade
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Trade Stream Consistency Controller
|
||||
|
||||
│
|
||||
|
||||
▼
|
||||
|
||||
Trade | None
|
||||
```
|
||||
|
||||
Таким образом завершается построение сервисного слоя интеграции Runtime и Acquisition.
|
||||
|
||||
Следующий этап — **Build 060.24 — Reconnect & Runtime Recovery**, в рамках которого будет реализовано управление жизненным циклом WebSocket-соединения, автоматическое восстановление подписок и интеграция Recovery Layer с Runtime Infrastructure.
|
||||
Reference in New Issue
Block a user