""" 信号层测试 测试SignalGenerator抽象接口 """ import pandas as pd import numpy as np import pytest from framework.signals import SignalGenerator from strategies.shared.signals.selectors import TopNSelector, TrendFollower, ReversalTrader class TestTopNSelector: """测试TopNSelector""" def test_top_n_selector_init(self): """测试初始化""" selector = TopNSelector(select_num=3) assert selector.select_num == 3 assert selector.mode == "top_n" def test_top_n_selection(self): """测试Top N选股""" dates = pd.date_range('2020-01-01', periods=50) # 生成因子数据 data = pd.DataFrame({ 'factor_A': np.random.randn(50), 'factor_B': np.random.randn(50), 'factor_C': np.random.randn(50), }, index=dates) selector = TopNSelector(select_num=2) result = selector.generate(data) # 检查结果列 assert 'signal' in result.columns assert 'signal_raw' in result.columns # 检查T+1移位(signal比signal_raw滞后1天) assert result['signal'].iloc[0] == '' or pd.isna(result['signal'].iloc[0]) def test_min_score_filter(self): """测试最小得分过滤""" dates = pd.date_range('2020-01-01', periods=50) # 生成因子数据,部分为负值 data = pd.DataFrame({ 'factor_A': [0.1] * 50, 'factor_B': [-0.1] * 50, # 负分 'factor_C': [0.2] * 50, }, index=dates) selector = TopNSelector(select_num=2, min_score=0.0) result = selector.generate(data) # 负分因子应该被过滤 signals = result['signal_raw'].dropna().unique() for sig in signals: if sig: codes = sig.split(',') assert 'factor_B' not in codes def test_grouped_selection(self): """测试分组选股""" dates = pd.date_range('2020-01-01', periods=50) # 生成因子数据和分组信息 data = pd.DataFrame({ 'factor_A': [0.1] * 50, 'factor_B': [0.2] * 50, 'factor_C': [0.15] * 50, }, index=dates) # 分组信息(模拟) # 注:实际使用需要在数据中包含group_info列 selector = TopNSelector(select_num=2, group_by='market') result = selector.generate(data) assert 'signal' in result.columns class TestTrendFollower: """测试趋势跟随器""" def test_trend_follower_init(self): """测试初始化""" follower = TrendFollower(entry_threshold=0.02, exit_threshold=-0.02) assert follower.entry_threshold == 0.02 assert follower.exit_threshold == -0.02 assert follower.mode == "trend" def test_trend_signal_generation(self): """测试趋势信号生成""" dates = pd.date_range('2020-01-01', periods=50) # 生成趋势因子数据 data = pd.DataFrame({ 'trend_A': [0.05] * 50, # 强趋势 'trend_B': [-0.05] * 50, # 弱趋势 }, index=dates) follower = TrendFollower(entry_threshold=0.02) result = follower.generate(data) # 检查信号列 assert 'signal' in result.columns class TestReversalTrader: """测试反转交易器""" def test_reversal_trader_init(self): """测试初始化""" trader = ReversalTrader(overbought=70, oversold=30) assert trader.overbought == 70 assert trader.oversold == 30 assert trader.mode == "reversal" def test_reversal_signal_generation(self): """测试反转信号生成""" dates = pd.date_range('2020-01-01', periods=50) # 生成反转因子数据 data = pd.DataFrame({ 'reversal_A': [0.15] * 50, # 超卖反转 'reversal_B': [-0.15] * 50, # 超买反转 }, index=dates) trader = ReversalTrader(reversal_threshold=0.1) result = trader.generate(data) # 检查信号列 assert 'signal' in result.columns class TestSignalGeneratorBase: """测试SignalGenerator抽象基类""" def test_validate_factor_data(self): """测试数据验证""" selector = TopNSelector(select_num=3) # 空数据应该返回False empty_data = pd.DataFrame() assert selector.validate_factor_data(empty_data) == False # 有效数据应该返回True valid_data = pd.DataFrame({'factor_A': [1, 2, 3]}) assert selector.validate_factor_data(valid_data) == True def test_repr(self): """测试字符串表示""" selector = TopNSelector(select_num=3, min_score=0.5) repr_str = repr(selector) assert "TopNSelector" in repr_str if __name__ == '__main__': pytest.main([__file__, '-v'])