Files
sanguo_vnpy_v2/tests/trader/test_data_source.py
T
claude_dev c6b19f4244 feat(data): 恢复双源(task#79)—撮合raw+策略qfq, 分红除权准确
用户要模拟=回测准确: raw除权缺口致MA假信号, 必须双源。
- data_source: qfq→qfq_dir(干净qfq), raw→raw_dir; _check_adjust_cfg(cfg提供才校验)
- engine 双bar流: step(raw_bars,qfq_bars)撮合/盯市raw+策略on_bar qfq; run zip(raw,qfq)
- live_orchestrator: warmup用qfq(信号am); 去adjust参数(双源固定)
- raw_redownload --adjust(''raw/'qfq'); config qfq_dir
- 113/113通过
2026-07-08 07:21:33 +08:00

94 lines
3.5 KiB
Python
Raw 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.
"""data_source 测试(mock _read_fn,不依赖 vnpy 链,spec §5/§3.3)。
read_parquet 的真测试依赖 vnpy BarData + NAS parquet,本机无完整依赖,
在容器内冒烟(spec §17);本文件测 iter_bars 调度逻辑(adjust → dir_key 路由)。
"""
import logging
from datetime import datetime
from types import SimpleNamespace
import pytest
from sanguo_trader.data_source import iter_bars, fetch_day
def _mock_bar(sym: str, date_str: str, close: float):
return SimpleNamespace(
symbol=sym,
datetime=datetime.strptime(date_str, "%Y-%m-%d"),
close_price=close,
)
def _cfg(paths):
return SimpleNamespace(data_paths=paths)
def test_iter_bars_cross_section_multi_symbol(monkeypatch):
seen = []
def mock_read(sym, start, end, cfg, dir_key):
seen.append(dir_key)
return [_mock_bar(sym, "2024-01-02", 10.5 if sym == "600000" else 15.5)]
monkeypatch.setattr("sanguo_trader.data_source._read_fn", lambda iv: mock_read)
sections = list(iter_bars(["600000", "000001"], "2024-01-01", "2024-01-31", "d"))
assert len(sections) == 1
_date, d = sections[0]
assert d["600000"].close_price == 10.5
assert all(k == "qfq_dir" for k in seen) # 默认 qfq → qfq_dir(双源)
def test_iter_bars_raw_uses_raw_dir(monkeypatch, caplog):
"""raw 模式路由到 raw_dir,不再 fallback qfqtask #79)。"""
seen = []
def mock_read(sym, start, end, cfg, dir_key):
seen.append(dir_key)
return [_mock_bar(sym, "2024-01-02", 10.01)]
monkeypatch.setattr("sanguo_trader.data_source._read_fn", lambda iv: mock_read)
with caplog.at_level(logging.WARNING):
sections = list(iter_bars(
["600000"], "2024-01-01", "2024-01-31", "d",
adjust="raw", cfg=_cfg({"raw_dir": "/x/raw"}),
))
assert seen == ["raw_dir"] # raw → raw_dir
assert "fallback" not in caplog.text.lower()
assert sections[0][1]["600000"].close_price == 10.01
def test_iter_bars_raw_missing_dir_raises(monkeypatch):
"""raw 缺 raw_dir 配置 → 明确报错(不静默 fallback,防混源)。"""
monkeypatch.setattr(
"sanguo_trader.data_source._read_fn",
lambda iv: lambda s, st, e, c, dir_key: [],
)
with pytest.raises(ValueError, match="raw_dir"):
list(iter_bars(["600000"], "2024-01-01", "2024-01-31", "d",
adjust="raw", cfg=_cfg({})))
def test_iter_bars_raw_15min_unsupported(monkeypatch):
"""raw 仅日线;15min+raw 报错(raw 15min 待分期项)。"""
monkeypatch.setattr(
"sanguo_trader.data_source._read_fn",
lambda iv: lambda s, st, e, c, dir_key: [],
)
with pytest.raises(ValueError, match="日线"):
list(iter_bars(["600000"], "2024-01-01", "2024-01-31", "15m",
adjust="raw", cfg=_cfg({"raw_dir": "/x"})))
def test_unsupported_interval_rejected():
with pytest.raises(ValueError):
# _read_fn 在生成器首次 next 时才执行,用 list 触发
list(iter_bars(["600000"], "2024-01-01", "2024-01-31", "5m"))
def test_fetch_day_returns_last_bar(monkeypatch):
seen = []
def mock_read(sym, start, end, cfg, dir_key):
seen.append(dir_key)
return [_mock_bar(sym, "2024-01-02", 10.0), _mock_bar(sym, "2024-01-02", 10.5)]
monkeypatch.setattr("sanguo_trader.data_source._read_fn", lambda iv: mock_read)
bar = fetch_day("600000", "2024-01-02", "d")
assert bar.close_price == 10.5 # 取最后一个
assert seen == ["qfq_dir"] # 默认 qfq → qfq_dir(双源)