Build 060.23: integrate Trade Stream Acquisition
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
# app/src/market_data/acquisition/trade_stream_acquisition_protocol.py
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
"""
|
||||
Публичный контракт интеграции Trade Stream в Acquisition Layer.
|
||||
|
||||
Build 060.23 вводит единую сервисную границу между:
|
||||
|
||||
- Trade Subscription Layer;
|
||||
- Acquisition Runtime Service;
|
||||
- Unified WebSocket Adapter;
|
||||
- Trade Stream Consistency.
|
||||
|
||||
Контракт не определяет production WebSocket transport, receive-loop,
|
||||
reconnect, recovery, хранение или публикацию канонических Trade.
|
||||
"""
|
||||
|
||||
from typing import Protocol, runtime_checkable
|
||||
|
||||
from src.market_data.acquisition.models.trade import Trade
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class TradeStreamAcquisitionServiceProtocol(Protocol):
|
||||
"""
|
||||
Контракт сервиса интеграции Trade Stream.
|
||||
|
||||
Сервис отвечает за:
|
||||
|
||||
- передачу команды подписки в Acquisition Runtime;
|
||||
- преобразование одного входящего WebSocket-документа;
|
||||
- передачу канонического Trade в Consistency Layer;
|
||||
- возврат согласованного Trade либо None для дубликата.
|
||||
|
||||
Сервис не владеет WebSocket lifecycle и не запускает receive-loop.
|
||||
"""
|
||||
|
||||
async def subscribe(
|
||||
self,
|
||||
symbols: tuple[str, ...],
|
||||
*,
|
||||
correlation_id: str | None = None,
|
||||
) -> None:
|
||||
"""
|
||||
Передать в Acquisition Runtime команду подписки Trade Stream.
|
||||
|
||||
Args:
|
||||
symbols:
|
||||
Символы торговых инструментов для подписки.
|
||||
|
||||
correlation_id:
|
||||
Необязательный идентификатор транспортного запроса.
|
||||
При отсутствии значение создаётся Subscription Builder.
|
||||
"""
|
||||
...
|
||||
|
||||
def handle_message(
|
||||
self,
|
||||
document: object,
|
||||
) -> Trade | None:
|
||||
"""
|
||||
Обработать один входящий WebSocket-документ.
|
||||
|
||||
Args:
|
||||
document:
|
||||
Сырой документ, полученный из WebSocket Runtime.
|
||||
|
||||
Returns:
|
||||
Канонический Trade после проверки согласованности;
|
||||
None, если сообщение не относится к Trade либо является
|
||||
корректным дубликатом.
|
||||
"""
|
||||
...
|
||||
@@ -0,0 +1,111 @@
|
||||
# app/src/market_data/acquisition/trade_stream_acquisition_service.py
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
"""
|
||||
Сервис интеграции Trade Stream с инфраструктурой Acquisition Runtime.
|
||||
|
||||
Build 060.23 вводит сервисную границу между:
|
||||
|
||||
- Trade Subscription Layer;
|
||||
- Acquisition Runtime Service;
|
||||
- Unified WebSocket Adapter;
|
||||
- Trade Stream Consistency.
|
||||
|
||||
На текущем этапе реализована передача команды подписки.
|
||||
Обработка входящих сообщений будет добавлена следующим шагом Build.
|
||||
"""
|
||||
|
||||
from src.market_data.acquisition.trade_stream_message_adapter_protocol import (
|
||||
TradeStreamMessageAdapterProtocol,
|
||||
)
|
||||
from src.market_data.acquisition.consistency.trade_stream_protocol import (
|
||||
TradeStreamConsistencyProtocol,
|
||||
)
|
||||
from src.market_data.acquisition.models.trade import Trade
|
||||
from src.market_data.acquisition.runtime.acquisition_runtime_service_protocol import (
|
||||
AcquisitionRuntimeServiceProtocol,
|
||||
)
|
||||
from src.market_data.acquisition.subscriptions.trades import (
|
||||
build_trade_subscribe_command,
|
||||
)
|
||||
from src.market_data.acquisition.trade_stream_acquisition_protocol import (
|
||||
TradeStreamAcquisitionServiceProtocol,
|
||||
)
|
||||
|
||||
|
||||
class TradeStreamAcquisitionService(
|
||||
TradeStreamAcquisitionServiceProtocol,
|
||||
):
|
||||
"""
|
||||
Координатор инфраструктуры получения Trade Stream.
|
||||
|
||||
Сервис объединяет:
|
||||
|
||||
- Acquisition Runtime;
|
||||
- Unified WebSocket Adapter;
|
||||
- Trade Stream Consistency.
|
||||
|
||||
При этом сам сервис не реализует транспорт,
|
||||
жизненный цикл WebSocket либо Recovery.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
runtime_service: AcquisitionRuntimeServiceProtocol,
|
||||
adapter: TradeStreamMessageAdapterProtocol,
|
||||
consistency_controller: TradeStreamConsistencyProtocol,
|
||||
) -> None:
|
||||
self._runtime_service = runtime_service
|
||||
self._adapter = adapter
|
||||
self._consistency_controller = consistency_controller
|
||||
|
||||
async def subscribe(
|
||||
self,
|
||||
symbols: tuple[str, ...],
|
||||
*,
|
||||
correlation_id: str | None = None,
|
||||
) -> None:
|
||||
"""
|
||||
Передать в Acquisition Runtime команду подписки Trade Stream.
|
||||
|
||||
Args:
|
||||
symbols:
|
||||
Символы торговых инструментов для подписки.
|
||||
|
||||
correlation_id:
|
||||
Необязательный идентификатор транспортного запроса.
|
||||
При отсутствии значение создаётся Subscription Builder.
|
||||
"""
|
||||
command = build_trade_subscribe_command(
|
||||
symbols,
|
||||
correlation_id=correlation_id,
|
||||
)
|
||||
|
||||
await self._runtime_service.dispatch(command)
|
||||
|
||||
def handle_message(
|
||||
self,
|
||||
document: object,
|
||||
) -> Trade | None:
|
||||
"""
|
||||
Обработать один входящий WebSocket-документ.
|
||||
|
||||
Документ преобразуется через Unified Adapter. Только канонический
|
||||
Trade передаётся в Trade Stream Consistency.
|
||||
|
||||
Args:
|
||||
document:
|
||||
Сырой WebSocket-документ.
|
||||
|
||||
Returns:
|
||||
Trade после проверки согласованности;
|
||||
None, если сообщение не относится к Trade либо является
|
||||
корректным дубликатом.
|
||||
"""
|
||||
result = self._adapter.map_message(document)
|
||||
|
||||
if not isinstance(result, Trade):
|
||||
return None
|
||||
|
||||
return self._consistency_controller.accept(result)
|
||||
@@ -0,0 +1,40 @@
|
||||
# app/src/market_data/acquisition/trade_stream_message_adapter_protocol.py
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
"""
|
||||
Контракт адаптера входящих сообщений Trade Stream.
|
||||
|
||||
Build 060.23 отделяет сервис координации Acquisition
|
||||
от конкретной реализации WebSocket-протокола биржи.
|
||||
"""
|
||||
|
||||
from typing import Protocol, runtime_checkable
|
||||
|
||||
from src.market_data.acquisition.models.candle_close import (
|
||||
CandleCloseEvent,
|
||||
)
|
||||
from src.market_data.acquisition.models.quote import Quote
|
||||
from src.market_data.acquisition.models.trade import Trade
|
||||
|
||||
|
||||
TradeStreamMappedMessage = Quote | CandleCloseEvent | Trade
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class TradeStreamMessageAdapterProtocol(Protocol):
|
||||
"""
|
||||
Контракт преобразования одного входящего WebSocket-документа.
|
||||
|
||||
Реализация может быть exchange-specific, но вызывающий сервис
|
||||
зависит только от результата преобразования.
|
||||
"""
|
||||
|
||||
def map_message(
|
||||
self,
|
||||
document: object,
|
||||
) -> TradeStreamMappedMessage:
|
||||
"""
|
||||
Преобразовать один WebSocket-документ в каноническую модель.
|
||||
"""
|
||||
...
|
||||
Reference in New Issue
Block a user