Files
myquant/finance/tests/test_fundamental_lookahead.py
T
Simon 73d191b43a feat: 量化引擎加固 — 新增测试 + 数据/因子/回测层优化
- 新增 finance/tests/ 6 个测试套件(agents/backtest/dao_upsert/factors/features/fundamental_lookahead)
- 数据层: data_manager / dao 优化,新增 upsert 逻辑
- 因子层: 基本面因子抽象定位 _mapping、ROE/PE/PB 重构
- 回测层: vectorbt/engine 大改动(251 行),report 增强
- ML 层: features/backtest_integration 特征工程与回测优化
- CLI: agent_cli 重构
- config/settings 扩充配置项
2026-08-31 14:01:06 +08:00

71 lines
2.6 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.
"""
基本面因子前视回归测试:财报不得在披露日之前被回测看到。
"""
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import numpy as np
import pandas as pd
import pytest
from factors.fundamental.pe_pb import PEFactor
from factors.fundamental.roe import ROEFactor, ROETTMDeltaFactor
from factors.fundamental._mapping import map_fundamental_to_daily, effective_available_dates
INDICES = pd.date_range('2024-01-01', '2024-09-30', freq='B').strftime('%Y%m%d')
def _daily():
return pd.DataFrame({'close': np.full(len(INDICES), 10.0)}, index=INDICES)
def _fin_ann():
# 提供 ann_date(实际披露日):年报 4/25, 一季报 4/28, 中报 8/30
return pd.DataFrame({
'end_date': ['20231231', '20240331', '20240630'],
'ann_date': ['20240425', '20240428', '20240830'],
'eps': [1.0, 1.2, 1.5],
'roe': [0.10, 0.12, 0.15],
})
def test_lookahead_absent_before_disclosure():
daily = _daily()
mapped = map_fundamental_to_daily(daily, _fin_ann(), 'eps')
# 披露日(4/25)之前绝不可见任何财务值 → 消除前视
pre = mapped[mapped.index <= '20240424'].dropna()
assert pre.empty, "披露日前出现财务值 → 前视泄漏!"
# 4/25 起可见年报 eps=1.0
post = mapped[mapped.index >= '20240425'].dropna()
assert abs(float(post.iloc[0]) - 1.0) < 1e-6
def test_ann_date_refines_overlap():
daily = _daily()
mapped = map_fundamental_to_daily(daily, _fin_ann(), 'eps')
# 4/25-4/27 是年报(1.0),4/28 起切换为一季报(1.2)
band = mapped[(mapped.index >= '20240425') & (mapped.index <= '20240427')]
assert (band.dropna() == 1.0).all()
post = mapped[mapped.index >= '20240428'].dropna()
assert abs(float(post.iloc[0]) - 1.2) < 1e-6
def test_pe_roe_no_lookahead():
daily = _daily()
fin = _fin_ann()
for f in [PEFactor(fin), ROEFactor(fin), ROETTMDeltaFactor(fin)]:
s = f.calculate(daily)
pre = s[s.index <= '20240424'].dropna()
assert pre.empty, f"{f.name} 在披露日前出现值 → 前视泄漏"
def test_default_disclosure_lag_without_ann_date():
"""无 ann_date 时用法定滞后:年报(1231)→次年4/30。"""
daily = _daily()
fin = pd.DataFrame({'end_date': ['20231231'], 'eps': [1.0]})
mapped = map_fundamental_to_daily(daily, fin, 'eps')
pre = mapped[mapped.index <= '20240429'].dropna()
assert pre.empty, "无 ann_date 时财报不应在披露日前可见"
post = mapped[mapped.index >= '20240430'].dropna()
assert not post.empty