technical-patterns-lab/discuss/20260127-讨论.md
褚宏光 09ac66caa1 Enhance converging triangle detection with new features and performance improvements
- Added support for daily best stocks reporting, including a new CSV output for daily best triangles based on strength.
- Introduced a logging mechanism to capture detailed execution logs, improving traceability and debugging.
- Implemented a v2 optimization for batch detection, significantly reducing detection time from 92 seconds to under 2 seconds.
- Updated the .gitignore file to include new log files and outputs for better management.
- Enhanced the pipeline script to allow for flexible configuration of detection parameters and improved user experience.

Files modified:
- scripts/run_converging_triangle.py: Added logging and v2 optimization.
- scripts/pipeline_converging_triangle.py: Updated for new features and logging.
- scripts/plot_converging_triangles.py: Adjusted for new plotting options.
- New files: discuss/20260127-拟合线.md, discuss/20260128-拟合线.md, and several images for visual documentation.
2026-01-28 18:43:46 +08:00

5.0 KiB
Raw Blame History

拟合线不好,需要使用 "凸优化经典算法"。 最终是希望 上沿线或下沿线,包含大部分的 枢轴点。


已实现凸优化拟合方法2026-01-27

新增参数

fitting_method: str = "iterative"  # "iterative" | "lp" | "quantile" | "anchor"

拟合方法对比

方法 说明 优点 缺点
iterative 迭代离群点移除 + 最小二乘法 稳定保守,已有调参经验 线"穿过"数据而非"包住"
lp 线性规划凸优化 数学严谨,保证边界包络 对极端值敏感
quantile 分位数回归 (上95%/下5%) 统计稳健,抗异常值 计算稍慢
anchor 绝对极值锚点 + 斜率优化 锚点明确,线更贴近主趋势 对枢轴点数量较敏感

LP 方法数学原理

上沿问题 (找"天花板",最紧的包络):

minimize    Σ(a*x_i + b - y_i)    线与点的总距离
subject to  y_i ≤ a * x_i + b     所有点在线下方
            -0.5 ≤ a ≤ 0.5        斜率限制

下沿问题 (找"地板",最紧的包络):

minimize    Σ(y_i - a*x_i - b)    线与点的总距离
subject to  y_i ≥ a * x_i + b     所有点在线上方
            -0.5 ≤ a ≤ 0.5        斜率限制

这确保拟合线严格"包住"所有枢轴点,且尽量贴近数据,符合技术分析中"压力线/支撑线"的语义。

Anchor 方法思路

核心目标:固定锚点,优化斜率,使大部分枢轴点在边界线正确一侧。

  • 锚点:检测窗口内的绝对最高/最低点排除最后1天用于突破判断
  • 上沿:找最“平缓”的下倾线,使 >=95% 枢轴高点在上沿线下方
  • 下沿:找最“平缓”的上倾线,使 >=95% 枢轴低点在下沿线上方
  • 实现:对斜率做二分搜索,满足覆盖率约束后取最贴近的一条线

测试验证

上沿 LP: slope=-0.006667, intercept=10.5333
  验证(线-点): [0.033, 0.000, 0.067, 0.033, 0.000]  (全>=0线在点上方)
下沿 LP: slope=0.005000, intercept=8.0000
  验证(点-线): [0.00, 0.05, 0.00, 0.05, 0.00]  (全>=0线在点下方)

使用方法

from src.converging_triangle import ConvergingTriangleParams, detect_converging_triangle

# 使用凸优化/统计方法
params = ConvergingTriangleParams(
    fitting_method="lp",  # 或 "quantile" / "anchor"
    # ... 其他参数
)

result = detect_converging_triangle(high, low, close, volume, params)

实现位置

  • 参数类: ConvergingTriangleParams.fitting_method
  • LP拟合: fit_boundary_lp()
  • 分位数回归: fit_boundary_quantile()
  • 锚点拟合: fit_boundary_anchor()
  • 分发函数: fit_pivot_line_dispatch()

拟合度分数低,强度分却整体偏高


已实现边界利用率分数2026-01-27

问题分析

观察图中 SZ002748 世龙实业:

  • 宽度比0.12(非常收敛)
  • 强度分0.177(排名第三)
  • 但肉眼观察:价格走势与三角形边界之间有大量空白

原因

  • 原权重:收敛分 20%、拟合贴合度 15%
  • 当宽度比 0.12 时,收敛分 = 1 - 0.12 = 0.88
  • 收敛分贡献 = 0.20 × 0.88 = 0.176 ≈ 全部强度分
  • 收敛分只衡量"形状收窄",不衡量"价格是否贴近边界"

解决方案

新增边界利用率分数,衡量价格走势对三角形通道空间的利用程度。

新增函数

def calc_boundary_utilization(
    high, low,
    upper_slope, upper_intercept,
    lower_slope, lower_intercept,
    start, end,
) -> float:
    """
    计算边界利用率 (0~1)
    
    对窗口内每一天:
    1. 计算价格到上下边界的距离
    2. 空白比例 = (到上沿距离 + 到下沿距离) / 通道宽度
    3. 当日利用率 = 1 - 空白比例
    
    返回平均利用率
    """

新权重配置

分量 原权重 新权重 说明
突破幅度 50% 50% 不变
收敛分 20% 15% 降低
成交量分 15% 10% 降低
拟合贴合度 15% 10% 降低
边界利用率 - 15% 新增

空白惩罚(新增)

为避免“通道很宽但价格很空”的误判,加入空白惩罚:

UTILIZATION_FLOOR = 0.20
惩罚系数 = min(1, boundary_utilization / UTILIZATION_FLOOR)
最终强度分 = 原强度分 × 惩罚系数

当边界利用率明显偏低时,总分会被进一步压制。

结果字段

ConvergingTriangleResult 新增字段:

boundary_utilization: float = 0.0  # 边界利用率分数

效果

  • 价格贴近边界(空白少)→ 利用率高 → 强度分高
  • 价格远离边界(空白多)→ 利用率低 → 强度分被惩罚
  • 当边界利用率 < 0.20 时,强度分按比例衰减(空白惩罚)
  • 解决"形状收敛但空白多"的误判问题