Files
sanguo_vnpy_v2/tests/data/test_datareader.py
T
claude_dev 1ed7b72aca feat(data): raw真实价数据源(task#79)—raw_dir+dir_key路由+新浪源重下
根因: daily_dir mixed-adjust(hfq bulk+akshare raw tail)致3-30 -94%假跌。
方案(Linus三问简化单raw, 除权留分期项#3):
- datareader read_parquet_daily/15min 加 dir_key 参数
- data_source iter_bars/fetch_day: adjust=raw→raw_dir(缺配置报错防混源), qfq→daily_dir
- engine PaperEngine 默认 adjust=raw
- config 加 raw_dir; scripts/raw_redownload.py 新浪源adjust='' 直连+单线程限速
- 验证: 浦发606行close 6.5/14.6 mean10.08 0跳变, 撮合成交价9.71-10.25真实
- 测试9/9+trader全量108/108通过
2026-07-07 22:19:11 +08:00

74 lines
2.8 KiB
Python

import pandas as pd
from unittest.mock import patch, MagicMock
from vnpy.trader.constant import Exchange, Interval
from vnpy.trader.setting import SETTINGS
from sanguo_data.config import DataConfig
from sanguo_data.datareader import read_parquet_daily, guess_exchange, read_db_daily
def test_read_parquet_daily_returns_bardata(tmp_path):
year_dir = tmp_path / "2026"
year_dir.mkdir()
df = pd.DataFrame({
"date": ["2026-01-05", "2026-01-06"],
"open": [10.0, 11.0], "high": [10.5, 11.5],
"low": [9.8, 10.8], "close": [10.2, 11.2],
"volume": [10000, 12000],
})
df.to_parquet(year_dir / "600000.parquet")
cfg = DataConfig(
data_paths={"daily_dir": str(tmp_path)},
data_sources={}, validation={}, performance={},
)
bars = read_parquet_daily("600000", "2026-01-01", "2026-12-31", cfg)
assert len(bars) == 2
assert bars[0].symbol == "600000"
assert bars[0].open_price == 10.0
def test_read_parquet_daily_dir_key_raw(tmp_path):
"""dir_key='raw_dir':切换到 raw 目录读真实价(task #79 双源)。"""
raw_year = tmp_path / "2026"
raw_year.mkdir()
df = pd.DataFrame({
"date": ["2026-03-30"],
"open": [9.97], "high": [10.05], "low": [9.95],
"close": [10.01], "volume": [800000],
})
df.to_parquet(raw_year / "sh600000_daily.parquet") # 真实文件名:sh 前缀 + _daily
cfg = DataConfig(
data_paths={"raw_dir": str(tmp_path)},
data_sources={}, validation={}, performance={},
)
bars = read_parquet_daily("600000", "2026-01-01", "2026-12-31", cfg, dir_key="raw_dir")
assert len(bars) == 1
assert bars[0].close_price == 10.01
def test_guess_exchange_sh():
assert guess_exchange("600000").value == "SSE"
def test_guess_exchange_sz():
assert guess_exchange("000001").value == "SZSE"
def test_read_db_daily_configures_vnpy_settings():
"""Test that read_db_daily configures vnpy SETTINGS with correct database path."""
cfg = DataConfig(
data_paths={"vnpy_db": "/volume1/stock/sanguo_vnpy/data/quant_trading.db"},
data_sources={}, validation={}, performance={},
)
# Mock get_database to avoid actual database connection
mock_db = MagicMock()
mock_db.load_bar_data.return_value = [] # Return empty list to avoid data processing
with patch('sanguo_data.datareader.get_database', return_value=mock_db):
# Call read_db_daily
read_db_daily("600000", "2024-01-01", "2024-12-31", cfg)
# Assert that SETTINGS was configured correctly
assert SETTINGS["database.name"] == "sqlite", f"Expected database.name to be 'sqlite', got {SETTINGS.get('database.name')}"
assert SETTINGS["database.database"] == cfg.data_paths["vnpy_db"], f"Expected database.database to be {cfg.data_paths['vnpy_db']}, got {SETTINGS.get('database.database')}"