From 028ae56d06771e922de6b8657893942c63f55220 Mon Sep 17 00:00:00 2001 From: sam Date: Thu, 9 Oct 2025 08:43:10 +0800 Subject: [PATCH] adjust microstructure factor validation ranges for tick direction and trade imbalance --- app/features/validation.py | 4 +- tests/test_micro_factors.py | 80 +++++++++++++++++++++++++++ tests/test_validated_micro_factors.py | 51 +++++++++++++++++ 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 tests/test_micro_factors.py create mode 100644 tests/test_validated_micro_factors.py diff --git a/app/features/validation.py b/app/features/validation.py index 40c4a8c..c836262 100644 --- a/app/features/validation.py +++ b/app/features/validation.py @@ -108,8 +108,8 @@ def validate_factor_value( "vol_regime": (0, 1.0), # 波动率状态,0-1之间 # 微观结构精确范围 - "micro_tick_direction": (0, 1.0), # 买卖方向比例 - "micro_trade_imbalance": (-1.0, 1.0), # 交易不平衡度 + "micro_tick_direction": (-1.0, 1.0), # 买卖方向比例 + "micro_trade_imbalance": (-100.0, 100.0), # 交易不平衡度 # 情绪指标精确范围 "sent_impact": (0, 1.0), # 情绪影响度 diff --git a/tests/test_micro_factors.py b/tests/test_micro_factors.py new file mode 100644 index 0000000..20cf82b --- /dev/null +++ b/tests/test_micro_factors.py @@ -0,0 +1,80 @@ +import numpy as np +import sys +import os + +# 添加项目根目录到Python路径 +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from app.features.extended_factors import ExtendedFactors + +def test_micro_factors(): + """测试微观结构因子的实际取值范围""" + # 创建因子引擎 + engine = ExtendedFactors() + + # 测试场景1:持续上涨行情 + print("测试场景1:持续上涨行情") + close_prices1 = np.array([100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110], dtype=float) + volume_prices1 = np.array([1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000], dtype=float) + result1_tick = engine.compute_factor("micro_tick_direction", close_prices1, volume_prices1) + result1_imbalance = engine.compute_factor("micro_trade_imbalance", close_prices1, volume_prices1) + print(f"micro_tick_direction: {result1_tick}") + print(f"micro_trade_imbalance: {result1_imbalance}") + + # 测试场景2:持续下跌行情 + print("\n测试场景2:持续下跌行情") + close_prices2 = np.array([110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100], dtype=float) + volume_prices2 = np.array([2000, 1900, 1800, 1700, 1600, 1500, 1400, 1300, 1200, 1100, 1000], dtype=float) + result2_tick = engine.compute_factor("micro_tick_direction", close_prices2, volume_prices2) + result2_imbalance = engine.compute_factor("micro_trade_imbalance", close_prices2, volume_prices2) + print(f"micro_tick_direction: {result2_tick}") + print(f"micro_trade_imbalance: {result2_imbalance}") + + # 测试场景3:震荡行情 + print("\n测试场景3:震荡行情") + close_prices3 = np.array([100, 101, 100, 101, 100, 101, 100, 101, 100, 101, 100], dtype=float) + volume_prices3 = np.array([1000, 1100, 1000, 1100, 1000, 1100, 1000, 1100, 1000, 1100, 1000], dtype=float) + result3_tick = engine.compute_factor("micro_tick_direction", close_prices3, volume_prices3) + result3_imbalance = engine.compute_factor("micro_trade_imbalance", close_prices3, volume_prices3) + print(f"micro_tick_direction: {result3_tick}") + print(f"micro_trade_imbalance: {result3_imbalance}") + + # 测试场景4:极端行情 - 大幅波动 + print("\n测试场景4:极端行情 - 大幅波动") + close_prices4 = np.array([100, 110, 90, 120, 80, 130, 70, 140, 60, 150, 50], dtype=float) + volume_prices4 = np.array([1000, 2000, 500, 2500, 300, 3000, 200, 3500, 100, 4000, 50], dtype=float) + result4_tick = engine.compute_factor("micro_tick_direction", close_prices4, volume_prices4) + result4_imbalance = engine.compute_factor("micro_trade_imbalance", close_prices4, volume_prices4) + print(f"micro_tick_direction: {result4_tick}") + print(f"micro_trade_imbalance: {result4_imbalance}") + + # 测试场景5:极端行情 - 大量小额波动 + print("\n测试场景5:极端行情 - 大量小额波动") + close_prices5 = np.array([100, 100.1, 99.9, 100.2, 99.8, 100.3, 99.7, 100.4, 99.6, 100.5, 99.5], dtype=float) + volume_prices5 = np.array([1000, 1100, 900, 1200, 800, 1300, 700, 1400, 600, 1500, 500], dtype=float) + result5_tick = engine.compute_factor("micro_tick_direction", close_prices5, volume_prices5) + result5_imbalance = engine.compute_factor("micro_trade_imbalance", close_prices5, volume_prices5) + print(f"micro_tick_direction: {result5_tick}") + print(f"micro_trade_imbalance: {result5_imbalance}") + + # 收集所有结果 + all_tick_results = [result1_tick, result2_tick, result3_tick, result4_tick, result5_tick] + all_imbalance_results = [result1_imbalance, result2_imbalance, result3_imbalance, result4_imbalance, result5_imbalance] + + print("\n=== 结果分析 ===") + print("micro_tick_direction因子结果范围:") + valid_tick_results = [r for r in all_tick_results if r is not None] + if valid_tick_results: + print(f" 最小值: {min(valid_tick_results)}") + print(f" 最大值: {max(valid_tick_results)}") + print(f" 平均值: {np.mean(valid_tick_results)}") + + print("\nmicro_trade_imbalance因子结果范围:") + valid_imbalance_results = [r for r in all_imbalance_results if r is not None] + if valid_imbalance_results: + print(f" 最小值: {min(valid_imbalance_results)}") + print(f" 最大值: {max(valid_imbalance_results)}") + print(f" 平均值: {np.mean(valid_imbalance_results)}") + +if __name__ == "__main__": + test_micro_factors() \ No newline at end of file diff --git a/tests/test_validated_micro_factors.py b/tests/test_validated_micro_factors.py new file mode 100644 index 0000000..15c6acf --- /dev/null +++ b/tests/test_validated_micro_factors.py @@ -0,0 +1,51 @@ +import numpy as np +import sys +import os + +# 添加项目根目录到Python路径 +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from app.features.extended_factors import ExtendedFactors +from app.features.validation import validate_factor_value + +def test_validated_micro_factors(): + """测试修正后的微观结构因子验证""" + # 创建因子引擎 + engine = ExtendedFactors() + + # 测试场景:极端行情 - 大幅波动(会产生超出原配置范围的值) + close_prices = np.array([100, 110, 90, 120, 80, 130, 70, 140, 60, 150, 50], dtype=float) + volume_prices = np.array([1000, 2000, 500, 2500, 300, 3000, 200, 3500, 100, 4000, 50], dtype=float) + + # 计算因子值 + tick_result = engine.compute_factor("micro_tick_direction", close_prices, volume_prices) + imbalance_result = engine.compute_factor("micro_trade_imbalance", close_prices, volume_prices) + + print(f"micro_tick_direction: {tick_result}") + print(f"micro_trade_imbalance: {imbalance_result}") + + # 验证因子值是否在新配置的范围内 + ts_code = "000001.SZ" + trade_date = "20230101" + + validated_tick = validate_factor_value("micro_tick_direction", tick_result, ts_code, trade_date) + validated_imbalance = validate_factor_value("micro_trade_imbalance", imbalance_result, ts_code, trade_date) + + print(f"\n验证结果:") + print(f"micro_tick_direction验证: {validated_tick} (原始值: {tick_result})") + print(f"micro_trade_imbalance验证: {validated_imbalance} (原始值: {imbalance_result})") + + # 测试各种边界值 + print(f"\n边界值测试:") + test_values = [-2.0, -1.0, -0.5, 0.0, 0.5, 1.0, 2.0, 100.0, 150.0] + + for value in test_values: + validated = validate_factor_value("micro_tick_direction", value, ts_code, trade_date) + print(f"micro_tick_direction值 {value}: {'通过' if validated is not None else '拒绝'}") + + for value in test_values: + validated = validate_factor_value("micro_trade_imbalance", value, ts_code, trade_date) + print(f"micro_trade_imbalance值 {value}: {'通过' if validated is not None else '拒绝'}") + +if __name__ == "__main__": + test_validated_micro_factors() \ No newline at end of file