# 强度分:形态规则度和价格活跃度的归一化详解 本文档详细说明**形态规则度** (`geometry_score`) 和**价格活跃度** (`activity_score`) 这两个强度分量的归一化实现方式。 --- ## 4. 形态规则度 (`geometry_score`) 的归一化 **目的**:测量枢轴点(4-8个关键点)到拟合线的贴合程度,形态越规则得分越高。 ### 计算步骤 ```python # 1. 计算相对误差:遍历所有枢轴点 for i in range(n): fitted_value = slope * pivot_indices[i] + intercept rel_error = abs(pivot_values[i] - fitted_value) / max(abs(fitted_value), 1e-9) sum_rel_error += rel_error # 2. 计算平均相对误差 mean_rel_error = sum_rel_error / n # 3. 指数衰减归一化 SCALE_FACTOR = 20.0 geometry_score = np.exp(-mean_rel_error * SCALE_FACTOR) # 4. 显式 clamp 到 [0, 1] geometry_score = min(1.0, max(0.0, geometry_score)) ``` ### 归一化原理 - **输入**:`mean_rel_error` ∈ [0, +∞)(平均相对误差,0 = 完美拟合) - **指数衰减**:`exp(-mean_rel_error * 20)` 将误差映射到 (0, 1] 区间 - 误差 = 0 → 得分 = 1.0(完美拟合) - 误差 = 0.05 → 得分 ≈ 0.37(中等拟合) - 误差 = 0.10 → 得分 ≈ 0.14(较差拟合) - 误差 → ∞ → 得分 → 0(完全不拟合) - **缩放因子 20**:决定衰减速度,值越大对误差越敏感 ### 范围保证 - 指数函数 `exp(-x)` 对于 x ≥ 0,输出自然在 (0, 1] 区间 - 最后显式 clamp 确保异常情况下也在 [0, 1] ### 实现位置 - 函数名:`calc_geometry_score_numba()` - 文件:`src/converging_triangle_optimized.py`(第350-374行) --- ## 5. 价格活跃度 (`activity_score`) 的归一化 **目的**:测量价格在通道内的振荡充分性,识别真实博弈 vs 僵尸形态。 ### 计算步骤 ```python # 1. 逐日计算活跃度(遍历 240 天完整数据) total_activity = 0.0 valid_days = 0 for i in range(start, end + 1): # 1.1 计算当日通道宽度 upper_line = upper_slope * i + upper_intercept lower_line = lower_slope * i + lower_intercept channel_width = upper_line - lower_line if channel_width <= 0: continue # 1.2 计算空白距离 dist_to_upper = max(0.0, upper_line - high[i]) # 高点未触及上沿的距离 dist_to_lower = max(0.0, low[i] - lower_line) # 低点未触及下沿的距离 # 1.3 计算空白比例 blank_ratio = (dist_to_upper + dist_to_lower) / channel_width # 1.4 单日活跃度 = 1 - 空白比例,并 clamp 到 [0, 1] day_activity = max(0.0, min(1.0, 1.0 - blank_ratio)) total_activity += day_activity valid_days += 1 # 2. 计算平均活跃度(已自动在 [0, 1] 区间) activity_score = total_activity / valid_days ``` ### 归一化原理 - **输入**:每日的 `blank_ratio`(空白比例)∈ [0, +∞) - 0 = 价格完全填满通道(高点触上沿且低点触下沿) - 1 = 价格只占通道一半空间 - \> 1 = 价格严重偏离通道(理论上不应出现) - **反转**:`1 - blank_ratio` 将"空白"转为"活跃" - blank_ratio = 0 → activity = 1(最活跃) - blank_ratio = 0.5 → activity = 0.5(中等活跃) - blank_ratio = 1 → activity = 0(不活跃) - **双重 clamp**: 1. **每日 clamp**:`max(0.0, min(1.0, ...))` 确保单日得分在 [0, 1] 2. **最终平均**:因为每日都在 [0, 1],平均值自然在 [0, 1] ### 范围保证 - 每日活跃度通过双边 clamp 严格限制在 [0, 1] - 最终得分是所有有效日的平均值,数学上保证在 [0, 1] ### 实际意义 - **0.8-1.0**:价格充分振荡,真实博弈形态 - **0.5-0.8**:价格较活跃,形态有效 - **0.2-0.5**:价格偏弱,形态存疑 - **< 0.2**:僵尸形态,触发空白惩罚机制 ### 实现位置 - 函数名:`calc_activity_score_numba()` - 文件:`src/converging_triangle_optimized.py`(第378-412行) --- ## 总结 这两个分量的归一化方式各有特点: 1. **形态规则度**:使用指数衰减映射,对误差敏感度高,适合质量评估 2. **价格活跃度**:使用线性反转+双重clamp,逐日计算后取平均,适合统计性指标 两者都严格保证输出在 [0, 1] 区间,满足强度分系统的设计要求。 --- **文档创建日期**:2026-01-29 **相关文档**: - `docs/强度分组成梳理.md`:6个强度分量的完整说明 - `discuss/20260129-讨论.md`:强度分参数讨论