- 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.
8.5 KiB
8.5 KiB
枢轴点边界问题分析
问题描述
当前算法存在边界盲区问题:
枢轴点检测的范围限制
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
枢轴点可检测范围
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(当前模式)+ 文档说明
理由:
- 历史回测不需要实时性
- 高质量枢轴点保证检测准确性
- 滞后15天对回测影响不大
改进措施:
- 在文档中明确说明15天的"确认窗口"
- 建议用户查看 "T-15天" 的检测结果,作为当前参考
对于未来扩展
如果要支持实时交易场景,建议:
- 实现方案4(混合策略)
- 添加"置信度"字段区分确认枢轴和候选枢轴
- 提供
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!
总结
您的观察完全正确:
- ✅ 问题确实存在: 最近k天(k=15)的数据无法被识别为枢轴点
- ✅ 影响场景: 当前点附近的重要转折点可能被遗漏
- ✅ 盲区大小: 30天(前15+后15),占窗口的25%
- ⚠️ 当前项目: 保持现状可接受(历史回测场景)
- 🔧 未来改进: 实时交易场景需要方案4(混合策略)
建议:
- 短期:在文档中说明这个限制
- 长期:如果要做实时选股,需要实现灵活枢轴点检测