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

339 lines
8.5 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.

# 枢轴点边界问题分析
## 问题描述
当前算法存在**边界盲区**问题:
### 枢轴点检测的范围限制
```python
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)
```
**问题**:最近 `k`k=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
### 枢轴点可检测范围
```python
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右边界放宽推荐
修改枢轴点检测,允许使用"不完整右窗口"
```python
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
```python
DETECTION_PARAMS = ConvergingTriangleParams(
pivot_k=8, # 从15降到8减少盲区
...
)
```
**优点**:
- 盲区从30天减少到16天
- 更灵敏,适合短期形态
**缺点**:
- 可能捕获更多噪音
- 三角形质量下降
---
### 方案3使用"确认滞后"模式(当前方案)
保持现状,但明确告知用户:
- 检测结果有15天的"确认滞后"
- 适合历史复盘,不适合实时交易
**优点**:
- 枢轴点质量高(充分确认)
- 结果稳定可靠
**缺点**:
- 有滞后性
- 错过实时突破
---
### 方案4混合策略最佳
分两类枢轴点:
```python
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` 参数选项
---
## 验证脚本
创建测试用例,验证边界问题:
```python
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混合策略
**建议**
- 短期:在文档中说明这个限制
- 长期:如果要做实时选股,需要实现灵活枢轴点检测