build 045: register canonical candles feed in acquisition registry

This commit is contained in:
2026-07-15 13:25:04 +03:00
parent 47c75d68b1
commit 0e86cca19d
4 changed files with 1022 additions and 1 deletions

View File

@@ -90,4 +90,9 @@ class CandleValueError(MarketDataAcquisitionError):
# Ошибка преобразования raw-модели источника во внутреннюю модель Candle.
class CandleMappingError(MarketDataAcquisitionError):
pass
pass
# Ошибка регистрации или получения Candles Feed.
class CandleFeedRegistryError(MarketDataAcquisitionError):
pass

View File

@@ -3,10 +3,12 @@
from __future__ import annotations
from src.market_data.acquisition.exceptions import (
CandleFeedRegistryError,
InstrumentFeedRegistryError,
QuoteFeedRegistryError,
)
from src.market_data.acquisition.protocol import (
CandlesFeedProtocol,
InstrumentFeedProtocol,
QuoteFeedProtocol,
)
@@ -140,3 +142,68 @@ class QuoteFeedRegistry:
)
return normalized_source_name
# Реестр доступных потоков рыночных свечей.
class CandlesFeedRegistry:
def __init__(self) -> None:
self._feeds: dict[str, CandlesFeedProtocol] = {}
def register(
self,
source_name: str,
feed: CandlesFeedProtocol,
) -> None:
"""
Зарегистрировать Candles Feed для указанного источника.
Повторная регистрация того же имени запрещена, чтобы исключить
неявную замену production-зависимости.
"""
normalized_source_name = self._normalize_source_name(source_name)
if not isinstance(feed, CandlesFeedProtocol):
raise CandleFeedRegistryError(
f"Объект для источника '{normalized_source_name}' "
"не соответствует CandlesFeedProtocol."
)
if normalized_source_name in self._feeds:
raise CandleFeedRegistryError(
f"Candles Feed для источника "
f"'{normalized_source_name}' уже зарегистрирован."
)
self._feeds[normalized_source_name] = feed
def get(
self,
source_name: str,
) -> CandlesFeedProtocol:
"""Вернуть зарегистрированный Candles Feed по имени источника."""
normalized_source_name = self._normalize_source_name(source_name)
feed = self._feeds.get(normalized_source_name)
if feed is None:
raise CandleFeedRegistryError(
f"Candles Feed для источника "
f"'{normalized_source_name}' не зарегистрирован."
)
return feed
def _normalize_source_name(
self,
source_name: str,
) -> str:
normalized_source_name = source_name.strip()
if not normalized_source_name:
raise CandleFeedRegistryError(
"Имя источника Candles Feed не должно быть пустым."
)
return normalized_source_name