- MarketDataProvider.get_index_weight(协议);Tushare 实现 normalize_index_weight + get_index_weight(ts_code=... 全历史成分权重);Sina 抛 DataSourceNotSupported; FailoverProvider 代理并审计每次尝试 - CLI:sync index_weight --code 000300.SH(拉取→幂等落库 index_weight→打印最新快照; 失败走 sync_log 审计并返回非零) - tests:Tushare 映射与调用(FakePro)、Failover 主源单源语义(新浪不支持被审计); 全量 pytest 通过
59 lines
1.9 KiB
Python
59 lines
1.9 KiB
Python
"""MarketDataProvider(数据源抽象)。
|
||
|
||
业务层只依赖本 Protocol(AGENT.md §6),禁止在业务代码中 import
|
||
tushare / 新浪实现。数据源一律返回 domain.entities 中的归一化实体。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from datetime import date
|
||
from typing import Protocol
|
||
|
||
from app.domain.entities.index import IndexWeight
|
||
from app.domain.entities.market import (
|
||
AdjustFactor,
|
||
DailyBar,
|
||
FinancialIndicator,
|
||
Stock,
|
||
TradingCalendar,
|
||
)
|
||
|
||
|
||
class MarketDataProvider(Protocol):
|
||
"""统一市场数据源接口。
|
||
|
||
实现约定:
|
||
- get_daily 返回**不复权**行情(复权经 AdjustFactor 显式计算,禁止静默改口径)
|
||
- get_financial 返回带 announce_date 的指标,供上层按 as_of 过滤
|
||
- 实现不得抛出裸连接异常以外的噪音;业务错误应转为 DataSourceError
|
||
"""
|
||
|
||
name: str
|
||
|
||
def get_stock_basic(self) -> list[Stock]: ...
|
||
|
||
def get_trade_cal(self, start: date, end: date) -> list[TradingCalendar]: ...
|
||
|
||
def get_daily(self, symbol: str, start: date, end: date) -> list[DailyBar]: ...
|
||
|
||
def get_adjust_factor(self, symbol: str, start: date, end: date) -> list[AdjustFactor]: ...
|
||
|
||
def get_financial(
|
||
self,
|
||
symbol: str,
|
||
start: date | None = None,
|
||
end: date | None = None,
|
||
) -> list[FinancialIndicator]:
|
||
"""财务指标快照。
|
||
|
||
start/end 为**报告期**窗口(对应 Tushare fina_indicator 的
|
||
start_date/end_date 参数,按报告期过滤);不传表示全量历史。
|
||
新浪接口不支持按窗口拉取,提供方会忽略窗口后由调用方自行过滤。
|
||
"""
|
||
|
||
def get_index_weight(self, index_code: str) -> list[IndexWeight]:
|
||
"""指数历史成分(含权重):每期成分快照 → IndexWeight(index_code, trade_date, symbol)。
|
||
|
||
供 index_weight 同步与历史成分 Universe(v3 §9)。"""
|
||
|