technical-patterns-lab/docs/强度分_增加角度参数_深度分析.md
褚宏光 0f8b9d836b Refactor strength scoring system with new parameters and renaming
- 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.
2026-01-29 15:55:50 +08:00

14 KiB
Raw Permalink Blame History

强度分中增加"角度"参数的深度分析

一、问题背景

根据讨论记录(discuss/20260129-讨论.md),需要在"强度分"中新增"角度"参数,即斜率、三角形的旋转角度。

二、当前"强度分"的组成结构

2.1 现有五大维度

根据 docs/强度分组成梳理.md,当前强度分由以下5个组成部分加权求和总权重100%

序号 组成部分 权重 英文字段名 说明
1 突破幅度分 50% price_score 价格突破上/下沿的幅度tanh归一化
2 收敛度分 15% convergence_score 三角形收敛程度1 - width_ratio
3 成交量分 10% volume_score 突破时的放量程度
4 形态规则度 10% geometry_score 枢轴点到拟合线的贴合程度
5 价格活跃度 15% activity_score 价格对通道空间的利用程度

计算公式

strength = (
    0.50 × 突破幅度分 +
    0.15 × 收敛度分 +
    0.10 × 成交量分 +
    0.10 × 形态规则度 +
    0.15 × 价格活跃度
)

2.2 现有的斜率数据

实际上,代码中已经计算并存储了斜率信息

# converging_triangle.py: line 86-87
upper_slope: float = 0.0   # 上沿斜率
lower_slope: float = 0.0   # 下沿斜率

但这些斜率未被纳入强度分计算,仅用于:

  1. 形态识别约束:确保三角形相向收敛(上沿向下,下沿向上)
  2. 可视化展示:绘制三角形边界线

三、"角度"参数的含义与作用

3.1 "角度"的数学定义

收敛三角形有两条边界线,因此涉及到多个角度

方案A上沿/下沿的倾斜角度(独立角度)

  • 上沿角度θ_upper = arctan(upper_slope)
  • 下沿角度θ_lower = arctan(lower_slope)

示例:

  • 上沿斜率 = -0.05 → 角度 ≈ -2.86°(向下倾斜)
  • 下沿斜率 = +0.03 → 角度 ≈ +1.72°(向上倾斜)

方案B三角形的整体倾斜方向合成角度

  • 三角形中轴角度θ_mid = arctan((upper_slope + lower_slope) / 2)
    • 中轴向上倾斜 → 上升三角形
    • 中轴向下倾斜 → 下降三角形
    • 中轴接近水平 → 对称三角形

方案C三角形的收敛角度张角

  • 收敛角度θ_apex = arctan(upper_slope - lower_slope)
    • 反映三角形收敛的"尖锐程度"
    • 张角越小 → 形态越尖锐,预示突破可能更强

3.2 "角度"参数的技术分析意义

角度类型 技术分析含义 对突破的影响
上沿倾斜度 压力线的陡峭程度 过于陡峭可能表示抛压过大
下沿倾斜度 支撑线的强度 陡峭向上表示买盘强劲
中轴倾斜方向 市场整体趋势偏向 向上偏=多头趋势,向下偏=空头趋势
收敛张角 多空力量博弈的紧张度 张角越小=能量积蓄越充分

3.3 用户需求推测

根据"用户可调整强度分中的每个参数"的需求,增加"角度"参数的目的可能是:

  1. 筛选特定形态:只要对称三角形(中轴接近水平)或只要上升/下降三角形
  2. 控制倾斜度:排除过于陡峭或过于平缓的形态
  3. 评估突破质量:角度影响突破的有效性(如陡峭向上的支撑线更可能向上突破)

四、增加"角度"参数的具体实现方案

4.1 推荐方案:增加"中轴倾斜度分"

核心思路:将三角形的整体倾斜方向纳入强度分,反映市场趋势的偏向性。

4.1.1 计算方法

def calc_tilt_score(
    upper_slope: float,
    lower_slope: float,
    breakout_dir: str,
) -> float:
    """
    计算三角形倾斜度分 (0~1)
    
    衡量三角形中轴的倾斜方向与突破方向的一致性。
    趋势偏向与突破方向一致时,得分越高。
    
    计算方法:
    1. 计算中轴斜率mid_slope = (upper_slope + lower_slope) / 2
    2. 计算倾斜度tilt = arctan(mid_slope) / (π/4),归一化到 [-1, +1]
       - 向上倾斜上升三角形tilt > 0
       - 向下倾斜下降三角形tilt < 0
       - 对称三角形tilt ≈ 0
    3. 根据突破方向计算得分:
       - 向上突破score = (1 + tilt) / 2  # 倾斜向上时得分高
       - 向下突破score = (1 - tilt) / 2  # 倾斜向下时得分高
    
    归一化映射(以向上突破为例):
    - 上升三角形中轴向上15°+ 向上突破 → 得分 0.85
    - 对称三角形(中轴水平) + 向上突破 → 得分 0.50
    - 下降三角形中轴向下15°+ 向上突破 → 得分 0.15(逆势突破)
    
    Args:
        upper_slope: 上沿斜率
        lower_slope: 下沿斜率
        breakout_dir: 突破方向 "up" | "down" | "none"
    
    Returns:
        tilt_score: 0~1越大表示倾斜方向与突破方向越一致
    """
    import math
    
    # 1. 计算中轴斜率
    mid_slope = (upper_slope + lower_slope) / 2.0
    
    # 2. 计算倾斜角度(弧度),并归一化到 [-1, +1]
    # 使用 arctan(slope) / (π/4) 映射:
    # - 45° 向上 → +1
    # - 0° 水平 → 0
    # - 45° 向下 → -1
    angle_rad = math.atan(mid_slope)
    tilt = angle_rad / (math.pi / 4)  # 归一化到 [-1, +1]
    tilt = max(-1.0, min(1.0, tilt))  # 限制在 [-1, 1]
    
    # 3. 根据突破方向计算得分
    if breakout_dir == "up":
        # 向上突破:倾斜向上时得分高
        score = (1.0 + tilt) / 2.0
    elif breakout_dir == "down":
        # 向下突破:倾斜向下时得分高
        score = (1.0 - tilt) / 2.0
    else:
        # 未突破使用中性分数0.5
        score = 0.5
    
    return max(0.0, min(1.0, score))

4.1.2 权重分配调整

新增"倾斜度分"后需要调整权重保持总和100%

方案1从"突破幅度分"中分配

W_PRICE = 0.45          # 突破幅度权重从50%降至45%
W_CONVERGENCE = 0.15    # 收敛度权重
W_VOLUME = 0.10         # 成交量权重
W_GEOMETRY = 0.10       # 形态规则度权重
W_ACTIVITY = 0.15       # 价格活跃度权重
W_TILT = 0.05           # 倾斜度权重新增占5%

方案2均匀分配

W_PRICE = 0.47          # 突破幅度权重50% → 47%
W_CONVERGENCE = 0.13    # 收敛度权重15% → 13%
W_VOLUME = 0.08         # 成交量权重10% → 8%
W_GEOMETRY = 0.10       # 形态规则度权重
W_ACTIVITY = 0.15       # 价格活跃度权重
W_TILT = 0.07           # 倾斜度权重新增占7%

4.1.3 修改位置

需要修改以下文件:

  1. src/converging_triangle.py

    • ConvergingTriangleResult 中新增字段:
      tilt_score: float = 0.0  # 倾斜度分数
      
    • 新增函数 calc_tilt_score()
    • 修改 calc_breakout_strength() 函数,纳入倾斜度分
  2. src/converging_triangle_optimized.py

    • 新增 Numba 优化版本的 calc_tilt_score_numba()
    • 修改 calc_breakout_strength_numba()
  3. src/triangle_detector_api.py

    • StrengthComponents 中新增:
      tilt_score: float  # 倾斜度分数
      
  4. docs/强度分组成梳理.md

    • 更新为6个组成部分添加倾斜度的说明

4.2 备选方案:增加"收敛角度分"

核心思路:将三角形的收敛尖锐程度纳入强度分。

def calc_apex_angle_score(
    upper_slope: float,
    lower_slope: float,
) -> float:
    """
    计算收敛角度分 (0~1)
    
    衡量三角形的收敛尖锐程度(张角大小)。
    张角越小(形态越尖锐),得分越高。
    
    计算方法:
    1. 张角 = arctan(upper_slope - lower_slope)
    2. 归一化到 [0, 1]
       - 张角 < 5° → 得分 1.0 (极度尖锐)
       - 张角 ≈ 15° → 得分 0.7
       - 张角 ≈ 30° → 得分 0.4
       - 张角 > 45° → 得分 0.1 (过于开阔)
    
    Args:
        upper_slope: 上沿斜率
        lower_slope: 下沿斜率
    
    Returns:
        angle_score: 0~1越大表示形态越尖锐
    """
    import math
    
    # 计算张角(绝对值)
    slope_diff = abs(upper_slope - lower_slope)
    angle_rad = math.atan(slope_diff)
    angle_deg = math.degrees(angle_rad)
    
    # 指数衰减归一化(张角越大分数越低)
    # 使用 exp(-angle_deg / 20) 映射:
    # - 0° → 1.00
    # - 10° → 0.61
    # - 20° → 0.37
    # - 30° → 0.22
    # - 45° → 0.11
    score = math.exp(-angle_deg / 20.0)
    
    return max(0.0, min(1.0, score))

五、对"LLM 调参"友好性的考虑

5.1 要求所有参数在 0-1 区间

根据讨论记录第3点"强度分内所有参数需保持在 0-1 区间,便于 LLM 调参;要求均匀/正态分布,默认值为 0.5。"

当前"角度"的原始值范围

  • 斜率范围:约 -0.1 ~ +0.1(受代码约束)
  • 角度范围:约 -5.7° ~ +5.7°arctan(±0.1)

归一化到 [0, 1] 的方法

方法1线性归一化

# 将 [-5.7°, +5.7°] 映射到 [0, 1]
normalized = (angle_deg + 5.7) / 11.4
# 默认值 0.5 对应 0° (水平)

方法2sigmoid 归一化

# 使用 sigmoid 函数0° 映射到 0.5
normalized = 1 / (1 + exp(-angle_deg / 3))
# 默认值 0.5 对应 0°

方法3绝对值归一化仅关心角度大小不关心方向

# 将 [0°, 5.7°] 映射到 [0, 1]
normalized = abs(angle_deg) / 5.7
# 默认值 0.5 对应 约 2.85°

5.2 为 LLM 设计的可调参数接口

triangle_detector_api.py 中新增参数:

@dataclass
class DetectionParams:
    """检测参数,都有合理默认值,大多数场景无需调整"""
    # ===== 用户可调参数 =====
    window: int = 240
    min_convergence: float = 0.45
    breakout_threshold: float = 0.005
    volume_multiplier: float = 1.5
    
    # 【新增】角度相关参数
    tilt_preference: float = 0.5        # 倾斜偏好 [0, 1]
                                        # 0=偏好下降三角形0.5=中性1=偏好上升三角形
    
    apex_angle_preference: float = 0.5  # 收敛角度偏好 [0, 1]
                                        # 0=偏好开阔形态0.5=中性1=偏好尖锐形态
    
    # 【新增】权重配置
    weight_price: float = 0.45          # 突破幅度权重
    weight_convergence: float = 0.15    # 收敛度权重
    weight_volume: float = 0.10         # 成交量权重
    weight_geometry: float = 0.10       # 形态规则度权重
    weight_activity: float = 0.15       # 价格活跃度权重
    weight_tilt: float = 0.05           # 倾斜度权重(新增)

六、实现步骤总结

6.1 短期方案(最小改动)

仅暴露斜率信息,不改变强度分计算

  1. 在 API 返回结果中添加斜率字段的解释说明
  2. 在可视化和导出中突出显示角度信息
  3. 用户可以在后处理时根据角度手动筛选

优点:零风险,不影响现有逻辑
缺点:未真正集成到强度分,用户需要自己处理

6.2 中期方案(推荐)

增加"倾斜度分"作为第6个维度

  1. 新增 calc_tilt_score() 函数
  2. 修改 calc_breakout_strength() 将倾斜度纳入加权
  3. 调整权重配置建议从突破幅度中分出5%
  4. 更新文档和测试

优点:有实际技术分析意义,易于理解
缺点:需要调整权重,可能影响现有结果的一致性

6.3 长期方案(完全可配置)

允许用户自定义强度分的权重

  1. 将所有权重作为参数暴露给 LLM
  2. 新增多种角度相关的分数(倾斜度、收敛角度、上下沿独立角度)
  3. 用户可以根据自己的策略调整权重组合

优点:最大灵活性,适应不同交易策略
缺点:复杂度高,需要大量测试和文档支持

七、潜在的技术挑战与注意事项

7.1 数值稳定性

  • 斜率接近0时角度变化敏感需要设置阈值
  • 极端情况(垂直线)需要特殊处理

7.2 多重共线性

  • 倾斜度与"收敛度"可能相关(如对称三角形收敛度通常更高)
  • 需要验证新参数是否引入冗余信息

7.3 历史数据回测

  • 增加新参数后,需要重新回测所有历史数据
  • 评估对现有高强度信号的影响

7.4 用户理解成本

  • "角度"参数的含义可能不如"突破幅度"直观
  • 需要提供清晰的文档和示例

八、推荐的实施路径

阶段1数据验证2小时

  1. 统计现有数据中斜率的分布情况
  2. 分析角度与突破强度的相关性
  3. 确认增加角度参数的必要性

阶段2方案确认1小时

  1. 与用户确认具体需求(是倾斜度、收敛角度还是其他?)
  2. 确定权重分配方案
  3. 确定参数归一化方式

阶段3代码实现4小时

  1. 修改 converging_triangle.py1.5小时)
  2. 修改 converging_triangle_optimized.py1.5小时)
  3. 修改 triangle_detector_api.py1小时

阶段4测试与验证3小时

  1. 单元测试1小时
  2. 历史数据回测1小时
  3. 可视化验证1小时

阶段5文档更新1小时

  1. 更新 docs/强度分组成梳理.md
  2. 更新 API 文档
  3. 添加使用示例

总计:约 11 小时

九、决策建议

根据以上分析,我的建议是:

  1. 采用中期方案(增加倾斜度分)

    • 有明确的技术分析意义
    • 实现成本适中
    • 对现有系统影响可控
  2. 参数设计

    • 新增 tilt_score 作为第6个维度
    • 权重从突破幅度中分配 5%
    • 归一化到 [0, 1],默认值 0.5
  3. 下一步行动

    • 与用户确认具体需求(是否就是"倾斜度"
    • 进行小规模数据验证
    • 如果验证通过,再进入实施阶段

文档创建时间2026-01-29
作者AI Assistant
状态:待用户确认