Tortoise/tests/test_real_sources.py
2026-06-24 16:50:59 +08:00

124 lines
4.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""真实数据源集成测试。"""
import os
import random
from pathlib import Path
import pytest
from sidecar.config import SidecarConfig
from sidecar.service import UnifiedDataService
from sidecar.sources.mootdx_source import MootdxSource
from sidecar.sources.tencent import TencentFinanceSource
from sidecar.storage import DuckDBStore
pytestmark = pytest.mark.skipif(
os.getenv("RUN_REAL_MARKET_TESTS") != "1",
reason="真实网络测试需设置 RUN_REAL_MARKET_TESTS=1",
)
def test_3_1_real_tencent_snapshot() -> None:
"""
功能说明:验证腾讯财经真实快照接口可用。
参数说明:无。
返回值说明:无返回值。
注意事项:用例编号 3-1需要可访问 qt.gtimg.cn。
"""
snapshot = TencentFinanceSource(timeout_seconds=10).fetch_snapshot("600000")
assert snapshot.symbol == "sh600000"
assert snapshot.name
assert snapshot.price is not None
assert snapshot.source == "tencent"
def test_3_2_real_mootdx_kline() -> None:
"""
功能说明:验证 mootdx 真实 K 线接口可用。
参数说明:无。
返回值说明:无返回值。
注意事项:用例编号 3-2需要可连接通达信行情服务器。
"""
bars = MootdxSource().fetch_kline("600000", "day", 5)
assert len(bars) > 0
assert bars[-1].symbol == "sh600000"
assert bars[-1].close is not None
assert bars[-1].source == "mootdx"
def test_3_3_real_unified_service_cache(tmp_path: Path) -> None:
"""
功能说明:验证统一服务可使用真实数据源写入 DuckDB 缓存。
参数说明tmp_path 为 pytest 临时目录。
返回值说明:无返回值。
注意事项:用例编号 3-3同时覆盖腾讯快照、mootdx K 线和 DuckDB 往返。
"""
config = SidecarConfig(db_path=str(tmp_path / "real.duckdb"), snapshot_ttl_seconds=60)
store = DuckDBStore(config.db_path)
mootdx = MootdxSource()
service = UnifiedDataService(store, config, mootdx, [TencentFinanceSource(10), mootdx])
bars = service.get_kline("600000", limit=5, refresh=True)
snapshot = service.get_snapshot("600000", refresh=True)
assert len(bars) > 0
assert store.load_kline("sh600000", "day", 5)
assert snapshot.price is not None
assert store.load_snapshot("sh600000") is not None
def assert_random_kline_prices_match(symbols, sample_size: int, seed: int) -> None:
"""
功能说明:随机抽取多个代码的 K 线价格并比较 mootdx 与腾讯财经是否基本一致。
参数说明symbols 为待比较代码列表sample_size 为抽样值数量seed 为固定随机种子。
返回值说明:无返回值。
注意事项:仅比较 OHLC 价格,成交量和成交额因接口口径差异不参与比较。
"""
fields = ["open", "high", "low", "close"]
mootdx = MootdxSource()
tencent = TencentFinanceSource(timeout_seconds=10)
candidates = []
for symbol in symbols:
mootdx_bars = {bar.trade_date: bar for bar in mootdx.fetch_kline(symbol, "day", 60)}
tencent_bars = {bar.trade_date: bar for bar in tencent.fetch_kline(symbol, "day", 60)}
for trade_date in sorted(set(mootdx_bars) & set(tencent_bars)):
for field in fields:
mootdx_value = getattr(mootdx_bars[trade_date], field)
tencent_value = getattr(tencent_bars[trade_date], field)
if mootdx_value is not None and tencent_value is not None:
candidates.append((symbol, trade_date, field, mootdx_value, tencent_value))
assert len(candidates) >= sample_size
samples = random.Random(seed).sample(candidates, sample_size)
mismatches = [
(symbol, trade_date, field, mootdx_value, tencent_value)
for symbol, trade_date, field, mootdx_value, tencent_value in samples
if abs(mootdx_value - tencent_value) > 0.05
]
assert mismatches == []
def test_3_4_real_mootdx_index_kline_matches_tencent() -> None:
"""
功能说明:验证 mootdx 指数 K 线与腾讯财经 K 线价格基本一致。
参数说明:无。
返回值说明:无返回值。
注意事项:用例编号 3-4随机抽取上证指数、深证成指、创业板指共 100 个 OHLC 值对比。
"""
assert_random_kline_prices_match(["sh000001", "sz399001", "sz399006"], 100, 20260623)
def test_3_5_real_mootdx_component_kline_matches_tencent() -> None:
"""
功能说明:验证三大指数代表成分股的 mootdx K 线与腾讯财经 K 线价格基本一致。
参数说明:无。
返回值说明:无返回值。
注意事项:用例编号 3-5分别选取贵州茅台、平安银行、宁德时代并随机抽取 100 个 OHLC 值对比。
"""
assert_random_kline_prices_match(["sh600519", "sz000001", "sz300750"], 100, 20260624)