technical-patterns-lab/discuss/20260727-讨论.md
褚宏光 24652b5790 Enhance converging triangle analysis with boundary utilization scoring and detailed chart mode
- Introduced a new boundary utilization score to measure price proximity to triangle boundaries, improving the accuracy of strength assessments.
- Updated scoring weights to incorporate boundary utilization, adjusting the contributions of convergence, volume, and fitting scores.
- Added detailed chart mode in the stock viewer, allowing users to toggle between standard and detailed views with additional metrics displayed.
- Enhanced documentation to reflect new features, including usage instructions for the boundary utilization score and detailed chart mode.
- Improved error handling in the stock viewer for better user experience.
2026-01-27 18:54:56 +08:00

167 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

![](images/2026-01-27-11-32-39.png)
拟合线不好,需要使用 "凸优化经典算法"。
最终是希望 上沿线或下沿线,包含大部分的 枢轴点。
---
## 已实现凸优化拟合方法2026-01-27
### 新增参数
```python
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线在点下方)
```
### 使用方法
```python
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()`
# 拟合度分数低,强度分却整体偏高
![](images/2026-01-27-16-26-02.png)
---
## 已实现边界利用率分数2026-01-27
### 问题分析
观察图中 SZ002748 世龙实业:
- 宽度比0.12(非常收敛)
- 强度分0.177(排名第三)
- 但肉眼观察:价格走势与三角形边界之间有**大量空白**
**原因**
- 原权重:收敛分 20%、拟合贴合度 15%
- 当宽度比 0.12 时,收敛分 = 1 - 0.12 = 0.88
- 收敛分贡献 = 0.20 × 0.88 = 0.176 ≈ 全部强度分
- **收敛分只衡量"形状收窄",不衡量"价格是否贴近边界"**
### 解决方案
新增**边界利用率**分数,衡量价格走势对三角形通道空间的利用程度。
### 新增函数
```python
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%** | 新增 |
### 空白惩罚(新增)
为避免“通道很宽但价格很空”的误判,加入空白惩罚:
![](images/2026-01-27-18-49-33.png)
![](images/2026-01-27-18-49-17.png)
```
UTILIZATION_FLOOR = 0.20
惩罚系数 = min(1, boundary_utilization / UTILIZATION_FLOOR)
最终强度分 = 原强度分 × 惩罚系数
```
当边界利用率明显偏低时,总分会被进一步压制。
### 结果字段
`ConvergingTriangleResult` 新增字段:
```python
boundary_utilization: float = 0.0 # 边界利用率分数
```
### 效果
- 价格贴近边界(空白少)→ 利用率高 → 强度分高
- 价格远离边界(空白多)→ 利用率低 → 强度分被惩罚
- 当边界利用率 < 0.20 强度分按比例衰减空白惩罚
- 解决"形状收敛但空白多"的误判问题
# 上/下沿线,有些点没有碰到线的边缘
![](images/2026-01-27-17-56-30.png)
![](images/2026-01-27-17-56-41.png)