- Introduced a new "tilt" parameter to the strength scoring system, allowing for the assessment of triangle slope directionality. - Renamed existing parameters: "拟合贴合度" to "形态规则度" and "边界利用率" to "价格活跃度" for improved clarity. - Updated normalization methods for all strength components to ensure they remain within the [0, 1] range, facilitating LLM tuning. - Enhanced documentation to reflect changes in parameter names and scoring logic, including detailed explanations of the new tilt parameter. - Modified multiple source files and scripts to accommodate the new scoring structure and ensure backward compatibility. Files modified: - `src/converging_triangle.py`, `src/converging_triangle_optimized.py`, `src/triangle_detector_api.py`: Updated parameter names and scoring logic. - `scripts/plot_converging_triangles.py`, `scripts/generate_stock_viewer.py`: Adjusted for new scoring parameters in output. - New documentation files created to explain the renaming and new scoring system in detail.
4.4 KiB
4.4 KiB
强度分:形态规则度和价格活跃度的归一化详解
本文档详细说明形态规则度 (geometry_score) 和价格活跃度 (activity_score) 这两个强度分量的归一化实现方式。
4. 形态规则度 (geometry_score) 的归一化
目的:测量枢轴点(4-8个关键点)到拟合线的贴合程度,形态越规则得分越高。
计算步骤
# 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 僵尸形态。
计算步骤
# 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:
- 每日 clamp:
max(0.0, min(1.0, ...))确保单日得分在 [0, 1] - 最终平均:因为每日都在 [0, 1],平均值自然在 [0, 1]
- 每日 clamp:
范围保证
- 每日活跃度通过双边 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行)
总结
这两个分量的归一化方式各有特点:
- 形态规则度:使用指数衰减映射,对误差敏感度高,适合质量评估
- 价格活跃度:使用线性反转+双重clamp,逐日计算后取平均,适合统计性指标
两者都严格保证输出在 [0, 1] 区间,满足强度分系统的设计要求。
文档创建日期:2026-01-29
相关文档:
docs/强度分组成梳理.md:6个强度分量的完整说明discuss/20260129-讨论.md:强度分参数讨论