Files
sanguo_vnpy_v2/tests/portfolio/test_shadow_price_getter.py
T

58 lines
2.4 KiB
Python

# -*- coding: utf-8 -*-
"""影子撮合定价(2026-08-28 价差对齐,用户拍板「费率一致后只留撮合方法差」)。
08-27 双轨 19/60 实锤:影子按「昨收 fq=pre」记账 vs 实盘盘中真实成交,每笔
天然偏差(600988:47.12 vs 46.00,低开日 -237bps;除权日另跳一个分红因子)。
对齐后契约:实时 tick 优先(与实盘同源同刻的裸价),失败回退**不复权**昨收。
"""
from __future__ import annotations
from types import SimpleNamespace
from sanguo_trader.shadow.runner import build_price_getter
class _StubProvider:
"""provider 替身:实时价/日线收盘可控,记录 get_price 的 fq 实参。"""
def __init__(self, realtime=None, close=10.0):
self._realtime = realtime
self._close = close
self.fq_seen = []
def get_realtime_price(self, security):
if isinstance(self._realtime, Exception):
raise self._realtime
return self._realtime
def get_price(self, security=None, start_date=None, end_date=None,
frequency=None, fields=None, fq=None, **_):
self.fq_seen.append(fq)
import pandas as pd
return pd.DataFrame({"close": [self._close]})
class TestBuildPriceGetter:
def test_realtime_tick_preferred(self):
"""有实时价 → 直接用(与实盘同源同刻),不碰日线。"""
p = _StubProvider(realtime=12.34, close=10.0)
assert build_price_getter(p)("600519.XSHG") == 12.34
assert p.fq_seen == []
def test_fallback_to_raw_close_when_realtime_none(self):
"""实时不可得 → 回退最新收盘,且 fq=raw(不复权,实盘成交价为裸价)。"""
p = _StubProvider(realtime=None, close=46.85)
assert build_price_getter(p)("600988.XSHG") == 46.85
assert p.fq_seen == ["raw"]
def test_fallback_when_realtime_raises(self):
"""实时抛异常 → 静默回退收盘(撮合不因实时源故障停摆)。"""
p = _StubProvider(realtime=RuntimeError("断连"), close=9.9)
assert build_price_getter(p)("000001.XSHE") == 9.9
def test_provider_without_realtime_method_uses_raw_close(self):
"""旧/回测 provider 无实时方法 → 原路径可用,fq 仍为 raw。"""
p = SimpleNamespace(get_price=_StubProvider(close=22.35).get_price)
getter = build_price_getter(p)
assert getter("001234.XSHE") == 22.35