# 突破方向计算逻辑详解 **日期**: 2026-01-26 **类型**: 算法说明 --- ## 📋 概述 图表中的"突破方向"(`breakout_dir`)显示了价格相对于三角形上下沿线的突破状态,取值为: - **`up`**: 向上突破(突破上沿线) - **`down`**: 向下突破(跌破下沿线) - **`none`**: 未突破(在三角形内部) --- ## 🎯 计算逻辑 ### 核心代码 ```597:607:src/converging_triangle.py # 突破判定 breakout_dir: Literal["up", "down", "none"] = "none" breakout_idx: Optional[int] = None if close[end] > upper_end * (1 + params.break_tol): breakout_dir = "up" breakout_idx = end elif close[end] < lower_end * (1 - params.break_tol): breakout_dir = "down" breakout_idx = end ``` ### 判定标准 #### 1. 向上突破 (`up`) **条件**: ``` 当前收盘价 > 上沿线终点价格 × (1 + break_tol) ``` **详细说明**: - `close[end]`: 检测窗口最后一天的收盘价(当前价格) - `upper_end`: 上沿线在窗口终点的拟合值 - `break_tol`: 突破容忍度(默认 `0.001` = 0.1%) **示例**: ```python # 假设 upper_end = 100.0 # 上沿线终点在 100 元 break_tol = 0.001 # 0.1% 容忍度 close[end] = 100.2 # 当前收盘价 100.2 元 # 判断 threshold = 100.0 * (1 + 0.001) = 100.1 100.2 > 100.1 # True → breakout_dir = "up" ``` #### 2. 向下突破 (`down`) **条件**: ``` 当前收盘价 < 下沿线终点价格 × (1 - break_tol) ``` **详细说明**: - `lower_end`: 下沿线在窗口终点的拟合值 - 需要跌破下沿线至少 `break_tol` 的幅度 **示例**: ```python # 假设 lower_end = 50.0 # 下沿线终点在 50 元 break_tol = 0.001 # 0.1% 容忍度 close[end] = 49.8 # 当前收盘价 49.8 元 # 判断 threshold = 50.0 * (1 - 0.001) = 49.95 49.8 < 49.95 # True → breakout_dir = "down" ``` #### 3. 未突破 (`none`) **条件**: ``` 当前收盘价在 [lower_end * (1 - break_tol), upper_end * (1 + break_tol)] 区间内 ``` **说明**: - 价格仍在三角形内部 - 或者突破幅度不足 `break_tol` --- ## ⚙️ 参数说明 ### `break_tol` (突破容忍度) **位置**: `triangle_config.py` ```python break_tol: float = 0.001 # 默认 0.1% ``` **作用**: - 过滤微小的价格波动 - 避免将正常波动误判为突破 - 确保突破的有效性 **取值建议**: | break_tol | 突破要求 | 适用场景 | |-----------|---------|---------| | 0.0005 | 0.05% | 非常敏感,捕获微小突破 | | 0.001 | 0.1% | **默认**,平衡敏感度和准确性 | | 0.002 | 0.2% | 宽松,只关注明显突破 | | 0.005 | 0.5% | 非常宽松,过滤大部分噪声 | **影响**: - **太小**(如 0.0001):过于敏感,噪声突破增多 - **太大**(如 0.01):不够敏感,错过早期突破信号 - **推荐**:0.001(0.1%)适合大多数场景 --- ## 📊 视觉示意 ### 突破判定区域 ``` 价格 ^ | 向上突破区域 | ─────────────────────── upper_end × (1 + 0.001) | ╱╲ ← 上沿线 (upper_end) | ╱ ╲ |╱ ╲ 未突破区域 (三角形内部) | ╲ | ╲╱ ← 下沿线 (lower_end) | ─────────────────────── lower_end × (1 - 0.001) | 向下突破区域 └────────────────────────> 时间 ↑ end (当前) ``` ### 实际案例分析 **案例 1: SZ002343 慈文传媒** ``` 上沿线终点: 约 8.9 元 下沿线终点: 约 7.7 元 当前收盘价: 约 7.6 元 判断: 7.6 < 7.7 × (1 - 0.001) = 7.69 # True → breakout_dir = "down" ``` **案例 2: 未突破** ``` 上沿线终点: 100.0 元 下沿线终点: 80.0 元 当前收盘价: 90.0 元 判断: 90.0 不大于 100.1 # 未向上突破 90.0 不小于 79.92 # 未向下突破 → breakout_dir = "none" ``` --- ## 🔍 相关计算 ### 1. 上下沿线终点值 **上沿线终点** (`upper_end`): ```python upper_end = a_u * end + b_u ``` - `a_u`: 上沿线斜率 - `b_u`: 上沿线截距 - `end`: 窗口终点索引 **下沿线终点** (`lower_end`): ```python lower_end = a_l * end + b_l ``` - `a_l`: 下沿线斜率 - `b_l`: 下沿线截距 ### 2. 突破强度计算 突破方向只是定性判断(up/down/none),突破强度是定量评分(0~1): ```python strength_up, strength_down = calc_breakout_strength( close=close[end], upper_line=upper_end, lower_line=lower_end, volume_ratio=volume_ratio, width_ratio=width_ratio, ) ``` **详见**: [突破强度计算方法.md](./突破强度计算方法.md) --- ## 🎨 图表显示 ### 标题栏信息 ``` SZ002343 慈文传媒 - 收敛三角形 (检测窗口: 20250123 ~ 20260120) 显示范围: 20231227 ~ 20260120 (500个交易日) 突破方向: down 宽度比: 0.30 极轴点: 高6/低4 触碰: 上5/下2 放量确认: 否 ``` **突破方向**显示: - `up` → 红色 - `down` → 绿色 - `none` → 灰色 --- ## 📐 计算流程 ### 完整流程 ```mermaid graph TD A[开始检测] --> B[拟合上下沿线] B --> C[计算终点线值] C --> D[获取当前收盘价] D --> E{close > upper × 1.001?} E -->|是| F[向上突破 up] E -->|否| G{close < lower × 0.999?} G -->|是| H[向下突破 down] G -->|否| I[未突破 none] F --> J[计算突破强度] H --> J I --> J J --> K[返回结果] ``` ### 代码执行顺序 1. **拟合趋势线** (第 520-540 行) ```python a_u, b_u, selected_ph = fit_pivot_line(ph_in, high[ph_in], mode="upper") a_l, b_l, selected_pl = fit_pivot_line(pl_in, low[pl_in], mode="lower") ``` 2. **计算终点值** (第 543-548 行) ```python upper_end = float(a_u * end + b_u) lower_end = float(a_l * end + b_l) ``` 3. **判定突破方向** (第 597-606 行) ```python if close[end] > upper_end * (1 + params.break_tol): breakout_dir = "up" elif close[end] < lower_end * (1 - params.break_tol): breakout_dir = "down" ``` 4. **计算突破强度** (第 624-631 行) ```python strength_up, strength_down = calc_breakout_strength(...) ``` --- ## 💡 常见问题 ### Q1: 为什么有 break_tol 容忍度? **A**: - 价格波动是连续的,完全精确的边界不现实 - 0.1% 的容忍度可以过滤微小噪声 - 确保只标记"真实的、有意义的"突破 ### Q2: 能否同时向上和向下突破? **A**: 不能。逻辑是互斥的: ```python if close > upper: # 先判断向上 dir = "up" elif close < lower: # 再判断向下 dir = "down" else: # 否则未突破 dir = "none" ``` ### Q3: 突破方向与突破强度的关系? **A**: - **突破方向**: 定性判断(是否突破、方向) - **突破强度**: 定量评分(突破的质量、程度) 示例: ``` breakout_dir = "down" # 向下突破 breakout_strength_down = 0.65 # 强度 65%(中等强度) ``` ### Q4: 为什么图表显示 "down" 但收盘价看起来在下沿线上? **A**: 可能原因: 1. **视觉误差**: 图表是近似显示 2. **容忍度**: 实际判断用了 0.1% 的容忍度 3. **拟合线**: 下沿线是拟合值,不一定正好穿过所有点 验证方法: ```python # 查看详细数值 print(f"收盘价: {close[end]:.2f}") print(f"下沿线: {lower_end:.2f}") print(f"阈值: {lower_end * 0.999:.2f}") ``` ### Q5: 如何修改突破敏感度? **A**: 修改 `triangle_config.py`: ```python # 更敏感(捕获更多突破) break_tol = 0.0005 # 0.05% # 默认 break_tol = 0.001 # 0.1% # 更宽松(只捕获明显突破) break_tol = 0.005 # 0.5% ``` --- ## 🔗 相关文档 - [突破强度计算方法.md](./突破强度计算方法.md) - 突破强度的详细说明 - [枢轴点分段选择算法详解.md](./枢轴点分段选择算法详解.md) - 趋势线拟合 - [系统架构.md](./系统架构.md) - 整体架构 --- ## 📝 总结 ### 核心要点 1. **简单比较**: 当前价格 vs 上下沿线终点值 2. **容忍度**: ±0.1% 过滤噪声 3. **互斥判断**: 先判断向上,再判断向下 4. **实时计算**: 基于窗口终点的实时价格 ### 计算公式 ``` 向上突破: close > upper_end × 1.001 向下突破: close < lower_end × 0.999 未突破: 其他情况 ``` ### 可调参数 ```python # triangle_config.py break_tol = 0.001 # 突破容忍度,推荐 0.0005 ~ 0.005 ``` --- **版本**: v1.0 **更新**: 2026-01-26