feat(data): B1-2 指数成分同步(Provider + CLI sync index_weight)
- 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 通过
This commit is contained in:
@@ -91,3 +91,36 @@ class TestFailover:
|
||||
with pytest.raises(DataSourceError, match="无备用源"):
|
||||
f.get_daily("600519.SH", date(2024, 1, 1), date(2024, 1, 5))
|
||||
assert len(collected) == 1
|
||||
|
||||
|
||||
class TestIndexFailover:
|
||||
def test_primary_only_index(self) -> None:
|
||||
"""指数成分:主源成功即用(新浪不支持会自动尝试并审计失败 → 结果仍来自主源)。"""
|
||||
from datetime import date
|
||||
from decimal import Decimal
|
||||
|
||||
from app.domain.entities.index import IndexWeight
|
||||
from app.infrastructure.data_sources.failover import FailoverProvider
|
||||
from app.infrastructure.data_sources.sina import SinaProvider
|
||||
from app.infrastructure.data_sources.tushare import TushareProvider
|
||||
|
||||
class _P(TushareProvider):
|
||||
name = "tushare"
|
||||
|
||||
def __init__(self): # 不触网
|
||||
pass
|
||||
|
||||
def get_index_weight(self, index_code):
|
||||
return [IndexWeight(index_code=index_code, index_name="沪深300",
|
||||
trade_date=date(2024, 6, 28), symbol="600519.SH",
|
||||
weight=Decimal("1"))]
|
||||
|
||||
logs: list[SyncLog] = []
|
||||
|
||||
def audit(log: SyncLog):
|
||||
logs.append(log)
|
||||
|
||||
f = FailoverProvider(_P(), SinaProvider(), audit=audit)
|
||||
rows = f.get_index_weight("000300.SH")
|
||||
assert len(rows) == 1 and rows[0].symbol == "600519.SH"
|
||||
assert len(logs) >= 1 # 每次尝试已审计
|
||||
|
||||
Reference in New Issue
Block a user