Files
etf/framework/tests/test_integration.py
aszerW fc59836ec3 test: 更新测试以验证框架重构正确性
- 测试文件改用strategies.shared的具体实现
- 新增framework_comparison_test.py对比新旧实现结果
- 因子计算相关系数达到1.0000,差异为0.000000
- 79个单元测试全部通过
2026-05-11 23:10:02 +08:00

166 lines
5.2 KiB
Python

"""
集成测试
测试框架与定制组件的集成
"""
import pandas as pd
import numpy as np
import pytest
from framework.factors import FactorRegistry, FactorCombiner
from framework.signals import SignalGenerator
from framework.risk import CallbackHook, Position
from framework.strategy import StrategyBase
from framework.execution import Portfolio, BacktestExecutor
from strategies.shared.factors.momentum import MomentumFactor, VolatilityFactor
from strategies.shared.signals.selectors import TopNSelector
from strategies.shared.risk.controls import StopLossControl, premium_filter_callback
from strategies.rotation.strategy import RotationStrategy
class TestFactorIntegration:
"""测试因子集成"""
def setup_method(self):
"""每个测试前清空注册表"""
FactorRegistry.clear()
def test_register_and_use_custom_factor(self):
"""测试注册并使用定制因子"""
FactorRegistry.register(MomentumFactor)
factor = FactorRegistry.get('momentum', n_days=25, crash_filter=True)
dates = pd.date_range('2020-01-01', periods=100)
data = pd.DataFrame({
'close': np.random.randn(100).cumsum() + 100
}, index=dates)
values = factor.compute(data)
assert len(values) == len(data)
def test_combiner_with_custom_factors(self):
"""测试组合器使用定制因子"""
FactorRegistry.register(MomentumFactor)
FactorRegistry.register(VolatilityFactor)
momentum = FactorRegistry.get('momentum', n_days=25)
volatility = FactorRegistry.get('volatility', method='std', period=20)
dates = pd.date_range('2020-01-01', periods=100)
data = pd.DataFrame({
'close': np.random.randn(100).cumsum() + 100,
'high': np.random.randn(100).cumsum() + 105,
'low': np.random.randn(100).cumsum() + 95
}, index=dates)
combiner = FactorCombiner([momentum, volatility], weights=[0.7, 0.3])
result = combiner.compute(data)
assert 'momentum' in result.columns
assert 'volatility' in result.columns
assert 'combined' in result.columns
class TestSignalIntegration:
"""测试信号生成器集成"""
def test_custom_signal_generator_with_factors(self):
"""测试定制信号生成器与因子集成"""
dates = pd.date_range('2020-01-01', periods=50)
factor_data = pd.DataFrame({
'momentum_A': np.random.randn(50),
'momentum_B': np.random.randn(50),
'momentum_C': np.random.randn(50),
}, index=dates)
selector = TopNSelector(select_num=2, min_score=0.0)
result = selector.generate(factor_data)
assert 'signal' in result.columns
class TestRiskIntegration:
"""测试风控组件集成"""
def test_custom_risk_control(self):
"""测试定制风控组件"""
control = StopLossControl(threshold=-0.05, trailing=True)
position = Position(
code='AAPL',
entry_price=100.0,
current_price=105.0,
entry_time=pd.Timestamp.now()
)
# 首次检查,设置最高价
assert control.check(position) == True
# 价格下跌,触发跟踪止损
position.current_price = 100.0
assert control.check(position) == False
def test_callback_hook_with_custom_callback(self):
"""测试回调钩子与定制回调集成"""
hook = CallbackHook()
# 注册定制回调
callback = premium_filter_callback(threshold=0.10)
hook.register('before_entry', callback)
# 正常溢价通过
result = hook.trigger('before_entry', 'AAPL', 100.0, premium=0.05)
assert result == True
# 高溢价拒绝
result = hook.trigger('before_entry', 'AAPL', 100.0, premium=0.15)
assert result == False
class TestStrategyIntegration:
"""测试策略集成"""
def setup_method(self):
"""每个测试前清空注册表"""
FactorRegistry.clear()
def test_rotation_strategy_full_flow(self):
"""测试轮动策略完整流程"""
strategy = RotationStrategy()
# 生成测试数据
dates = pd.date_range('2020-01-01', periods=100)
data = pd.DataFrame({
'close': np.random.randn(100).cumsum() + 100
}, index=dates)
# 运行策略
result = strategy.run(data)
assert 'signal' in result.columns
def test_strategy_with_backtest_executor(self):
"""测试策略与回测执行器集成"""
FactorRegistry.clear()
strategy = RotationStrategy()
dates = pd.date_range('2020-01-01', periods=100)
data = pd.DataFrame({
'close': np.random.randn(100).cumsum() + 100
}, index=dates)
signals = strategy.run(data)
executor = BacktestExecutor(initial_capital=100000, trade_cost=0.001)
portfolio = executor.execute(signals, data)
assert isinstance(portfolio, Portfolio)
if __name__ == '__main__':
pytest.main([__file__, '-v'])