technical-patterns-lab/docs/枢轴点边界问题分析.md
褚宏光 6d545eb231 Enhance converging triangle detection with new features and documentation updates
- Added support for a detailed chart mode in plot_converging_triangles.py, allowing users to visualize all pivot points and fitting lines.
- Improved pivot fitting logic to utilize multiple representative points, enhancing detection accuracy and reducing false positives.
- Introduced a new real-time detection mode with flexible zone parameters for better responsiveness in stock analysis.
- Updated README.md and USAGE.md to reflect new features and usage instructions.
- Added multiple documentation files detailing recent improvements, including pivot point fitting and visualization enhancements.
- Cleaned up and archived outdated scripts to streamline the project structure.
2026-01-26 16:21:36 +08:00

8.5 KiB
Raw Permalink Blame History

枢轴点边界问题分析

问题描述

当前算法存在边界盲区问题:

枢轴点检测的范围限制

for i in range(k, n - k):  # k=15时从索引15到n-16
    if high[i] == np.max(high[i - k : i + k + 1]):
        ph.append(i)

问题:最近 kk=15即最近15天的数据无法被识别为枢轴点


图解说明

检测窗口假设window=120, k=15

索引:  0   ...  14  15  ...  104 105 ...  119 (窗口末端=当前点)
       ↓        ↓   ↓        ↓   ↓        ↓
       |--------|---|---------|---|--------|
       无法检测  可以检测枢轴点    无法检测
       (前15天) (中间90天)         (后15天)
       
枢轴点检测范围: [15, 104]  ← 只有这90天可以被识别
边界盲区: [0, 14] 和 [105, 119]  ← 这30天无法识别

实际影响

场景1当前点就是最高点突破中

价格
 │              ○ (枢轴高点)
50│           /   \
 │         /       \
45│       /           \
 │     /               \            ★ (当前点=最高点)
40│   /                   \      /
 │  ○                       \  /   ← 无法识别为枢轴!
35│                           ○
 │                            ← 这是枢轴低点
 └──────────────────────────────────→ 时间
    ←─── 120天窗口 ───→   ↑
                         当前点
                         (索引119)
                         
枢轴点检测:
- ○ 可识别: 索引 < 105 的点
- ★ 不可识别: 索引 > 104 的点最近15天

问题: 当前上升突破的最高点无法被确认为枢轴点!

场景2三角形顶点在最近15天

价格
 │    ○ (枢轴高点1)
45│   /  \                    ★ (近期高点,但无法识别)
 │  /    \              /\  /
40│ /      \          /    ★
 │/        \      /
35│          \  /           ○ (枢轴低点)
 │           ○           /
30│                    /
 └────────────────────────────→ 时间
     ←── 120天 ───→  ↑
                   当前点
                   
问题: 三角形的后半部分高点/低点可能被忽略!

数值示例k=15

假设检测窗口

  • 窗口大小: 120天
  • 索引范围: [0, 119]
  • 当前点: 索引119

枢轴点可检测范围

for i in range(15, 120 - 15):  # range(15, 105)
    # 可检测范围: 索引 15~104
    # 共90个位置

边界盲区

  • 前15天: 索引 0~14需要左边的15天数据不存在
  • 后15天: 索引 105~119需要右边的15天数据不存在
  • 盲区大小: 30天占窗口的25%

实际案例分析

您的问题场景

当前是 2026-01-20
检测窗口: 2025-08-21 ~ 2026-01-20 (120天)

假设股票走势:
- 2025-12-20 (索引90): 高点 50元  ✓ 可识别为枢轴
- 2026-01-05 (索引105): 高点 48元  ✗ 无法识别!
- 2026-01-20 (索引119): 当前 52元  ✗ 无法识别!

结果: 算法可能遗漏最近的重要转折点

潜在影响

1. 遗漏近期突破点

如果当前点附近最近15天内有重要的高点/低点,无法被识别为枢轴点, 导致三角形边界线拟合不准确。

2. 检测滞后

三角形形态可能已经完整形成并突破,但因为最近的关键点无法确认, 检测结果会滞后15天左右。

3. 突破判断不准

当前点的突破判断依赖三角形边界线,如果边界线因遗漏近期枢轴点 而不准确,突破强度计算会有偏差。


解决方案选项

方案1右边界放宽推荐

修改枢轴点检测,允许使用"不完整右窗口"

def pivots_fractal_flexible(
    high: np.ndarray, low: np.ndarray, k: int = 3
) -> Tuple[np.ndarray, np.ndarray]:
    """
    灵活枢轴点检测:
    - 中间部分严格左右各k天
    - 右边界:放宽要求,只需要"已有的"右边数据
    """
    n = len(high)
    ph: List[int] = []
    pl: List[int] = []
    
    # 标准检测中间部分左右各k天
    for i in range(k, n - k):
        if high[i] == np.max(high[i - k : i + k + 1]):
            ph.append(i)
        if low[i] == np.min(low[i - k : i + k + 1]):
            pl.append(i)
    
    # 右边界扩展最后k天使用"已有的"右边数据
    for i in range(n - k, n):
        # 右边窗口缩短到可用范围
        right_window = min(k, n - 1 - i)
        if high[i] == np.max(high[i - k : i + right_window + 1]):
            ph.append(i)
        if low[i] == np.min(low[i - k : i + right_window + 1]):
            pl.append(i)
    
    return np.array(ph, dtype=int), np.array(pl, dtype=int)

优点:

  • 可以捕获最近的高低点
  • 适合实时检测场景

缺点:

  • 最近的枢轴点"确认度"较低(右边数据不完整)
  • 可能引入噪音

方案2减小k值

pivot_k 从15减小到5-8

DETECTION_PARAMS = ConvergingTriangleParams(
    pivot_k=8,  # 从15降到8减少盲区
    ...
)

优点:

  • 盲区从30天减少到16天
  • 更灵敏,适合短期形态

缺点:

  • 可能捕获更多噪音
  • 三角形质量下降

方案3使用"确认滞后"模式(当前方案)

保持现状,但明确告知用户:

  • 检测结果有15天的"确认滞后"
  • 适合历史复盘,不适合实时交易

优点:

  • 枢轴点质量高(充分确认)
  • 结果稳定可靠

缺点:

  • 有滞后性
  • 错过实时突破

方案4混合策略最佳

分两类枢轴点:

def pivots_fractal_hybrid(high, low, k=15, flexible_zone=5):
    """
    混合枢轴点检测:
    - 确认枢轴点有完整左右k天数据高质量
    - 候选枢轴点:右边数据不完整(低置信度)
    """
    n = len(high)
    
    # 确认枢轴点(完整窗口)
    confirmed_ph = []
    confirmed_pl = []
    for i in range(k, n - k):
        if high[i] == np.max(high[i - k : i + k + 1]):
            confirmed_ph.append(i)
        if low[i] == np.min(low[i - k : i + k + 1]):
            confirmed_pl.append(i)
    
    # 候选枢轴点最近flexible_zone天降低要求
    candidate_ph = []
    candidate_pl = []
    for i in range(n - flexible_zone, n):
        right_avail = n - 1 - i
        if high[i] == np.max(high[i - k : i + right_avail + 1]):
            candidate_ph.append(i)
        if low[i] == np.min(low[i - k : i + right_avail + 1]):
            candidate_pl.append(i)
    
    return (
        np.array(confirmed_ph + candidate_ph),
        np.array(confirmed_pl + candidate_pl)
    )

优点:

  • 兼顾质量和实时性
  • 可以标记"待确认"的点

缺点:

  • 逻辑较复杂
  • 需要额外的置信度管理

建议

对于当前项目

场景: "当前点往过去看",用于历史回测和复盘

推荐: 保持方案3当前模式+ 文档说明

理由:

  1. 历史回测不需要实时性
  2. 高质量枢轴点保证检测准确性
  3. 滞后15天对回测影响不大

改进措施:

  • 在文档中明确说明15天的"确认窗口"
  • 建议用户查看 "T-15天" 的检测结果,作为当前参考

对于未来扩展

如果要支持实时交易场景,建议:

  1. 实现方案4混合策略
  2. 添加"置信度"字段区分确认枢轴和候选枢轴
  3. 提供 real_time_mode=True 参数选项

验证脚本

创建测试用例,验证边界问题:

def test_boundary_pivots():
    # 模拟一个在窗口末端有高点的情况
    high = np.zeros(120)
    high[50] = 45  # 中间高点(可识别)
    high[110] = 50  # 末端高点k=15时无法识别
    
    low = np.ones(120) * 30
    
    ph_idx, pl_idx = pivots_fractal(high, low, k=15)
    
    print(f"检测到的高点枢轴: {ph_idx}")
    print(f"是否检测到索引110的高点: {110 in ph_idx}")  # False!

总结

您的观察完全正确

  1. 问题确实存在: 最近k天k=15的数据无法被识别为枢轴点
  2. 影响场景: 当前点附近的重要转折点可能被遗漏
  3. 盲区大小: 30天前15+后15占窗口的25%
  4. ⚠️ 当前项目: 保持现状可接受(历史回测场景)
  5. 🔧 未来改进: 实时交易场景需要方案4混合策略

建议

  • 短期:在文档中说明这个限制
  • 长期:如果要做实时选股,需要实现灵活枢轴点检测