- 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.
295 lines
7.0 KiB
Markdown
295 lines
7.0 KiB
Markdown
# 常见问题:为什么某些视觉上的低点不是枢轴点?
|
||
|
||
**日期**: 2026-01-26
|
||
**类型**: FAQ / 问题分析
|
||
|
||
---
|
||
|
||
## 📋 问题描述
|
||
|
||
用户在查看图表时经常会发现:某些视觉上很明显的低点(或高点),却没有被标记为枢轴点。
|
||
|
||
**典型案例**:SZ300892 在 20251110 之后有一个接近 30 元的明显低点,但它没有被识别为枢轴点,反而更高的 34 元的点被识别了。
|
||
|
||
---
|
||
|
||
## 🔍 原因分析
|
||
|
||
### 核心概念:枢轴点的严格定义
|
||
|
||
枢轴点不是"看起来低/高"就可以,必须满足严格的数学定义:
|
||
|
||
```
|
||
枢轴高点:在前后 k 天范围内(共 2k+1 天)是最高点
|
||
枢轴低点:在前后 k 天范围内(共 2k+1 天)是最低点
|
||
```
|
||
|
||
**默认参数**:`k = 15`,意味着必须是 **31 天范围内的绝对极值**。
|
||
|
||
---
|
||
|
||
## 🎯 四种常见情况
|
||
|
||
### 情况1: 前后范围内有更极端的点 ⭐
|
||
|
||
**最常见的原因**
|
||
|
||
```
|
||
价格
|
||
^
|
||
| *
|
||
| / \
|
||
| / \← 30元低点
|
||
| / \
|
||
|* *← 28元低点 ← 29元低点
|
||
└────────────────> 时间
|
||
前15天 中间 后15天
|
||
```
|
||
|
||
虽然 30 元看起来很低,但如果:
|
||
- 前 15 天有 28 元的点
|
||
- 或后 15 天有 29 元的点
|
||
|
||
那么 30 元不满足"31 天范围内最低"的条件。
|
||
|
||
### 情况2: 震荡区域,没有单一极值点
|
||
|
||
```
|
||
价格
|
||
^
|
||
|
|
||
| * * * ← 多个接近的低点(30-32元)
|
||
| \/\/
|
||
└────────────> 时间
|
||
```
|
||
|
||
视觉上看起来像一个低点区域,但实际是多个接近的点:
|
||
- 没有一个点在 31 天窗口内是绝对最低
|
||
- 算法会选择更具代表性的点(如震荡区边界)
|
||
|
||
### 情况3: 被相邻枢轴点遮蔽
|
||
|
||
```
|
||
价格
|
||
^
|
||
| 34元枢轴点 ← 被选中
|
||
| O
|
||
| 30元点
|
||
| *
|
||
└──────────────> 时间
|
||
<15天>
|
||
```
|
||
|
||
如果 30 元的点距离 34 元枢轴点 < 15 天:
|
||
- 算法倾向于选择更靠后的点(更具代表性)
|
||
- 34 元虽然高,但它在自己的 31 天窗口内是最低点
|
||
- 30 元在自己的 31 天窗口内可能不是最低点
|
||
|
||
### 情况4: 时间位置的影响
|
||
|
||
```
|
||
三角形检测窗口:
|
||
├────────────────────────────┤
|
||
│ 34元点 │ ← 接近检测窗口终点
|
||
│ 30元点 O │ 更能代表当前支撑
|
||
│ * │
|
||
└────────────────────────────┘
|
||
```
|
||
|
||
- 30 元点:时间较早,可能已经被后续走势"失效"
|
||
- 34 元点:时间较晚,更能代表当前的支撑位
|
||
- 算法选择更接近检测终点的枢轴点
|
||
|
||
---
|
||
|
||
## 💡 为什么 34 元反而被识别?
|
||
|
||
虽然 34 元比 30 元高,但它满足枢轴点的定义:
|
||
|
||
```
|
||
检查 34 元点的前后 15 天:
|
||
- 前 15 天的最低:可能是 35 元
|
||
- 后 15 天的最低:可能是 36 元
|
||
- 34 元 = 31 天范围内的最低点 ✓
|
||
```
|
||
|
||
同时,34 元点:
|
||
- ✅ 时间位置更靠后(更具代表性)
|
||
- ✅ 更好地定义三角形的终点支撑
|
||
- ✅ 在拟合下沿线时贡献更大
|
||
|
||
---
|
||
|
||
## 🧮 类比理解
|
||
|
||
### 山峰与山谷
|
||
|
||
```
|
||
高度
|
||
^
|
||
| 山峰 (枢轴高点)
|
||
| ^
|
||
| / \
|
||
| / \
|
||
| 凹陷 / \
|
||
| ↓ / \
|
||
| * / \
|
||
| /___________\
|
||
└──────────────────> 位置
|
||
```
|
||
|
||
- **山峰** = 枢轴高点(周围都比它低)
|
||
- **山谷** = 枢轴低点(周围都比它高)
|
||
- **山坡上的凹陷** ≠ 山谷(局部低但不是极值)
|
||
|
||
30 元那个点可能只是"山坡上的一个凹陷",而不是真正的"山谷"。
|
||
|
||
---
|
||
|
||
## 📊 实际案例:SZ300892
|
||
|
||
### 检测信息
|
||
|
||
```
|
||
窗口大小: 240 天
|
||
下沿触碰: 4 个
|
||
检测模式: 实时模式
|
||
枢轴点定义: k=15(前后各15天,共31天)
|
||
```
|
||
|
||
### 为什么 30 元不是枢轴点?
|
||
|
||
**可能原因1**: 前后 15 天内有更低的点
|
||
```
|
||
例如:
|
||
- 30 元点在 20251110
|
||
- 可能 20251025 有 29.5 元
|
||
- 或 20251125 有 29.8 元
|
||
→ 不满足"31天内最低"
|
||
```
|
||
|
||
**可能原因2**: 30 元点是震荡区域
|
||
```
|
||
20251105-20251115 区间:
|
||
- 20251105: 31 元
|
||
- 20251108: 30 元
|
||
- 20251112: 30.5 元
|
||
→ 没有单一的极值点
|
||
```
|
||
|
||
**可能原因3**: 34 元点更具代表性
|
||
```
|
||
- 30 元点:2025年11月
|
||
- 34 元点:2025年12月(更接近检测日期)
|
||
- 算法选择更新的、更能代表当前支撑的点
|
||
```
|
||
|
||
---
|
||
|
||
## 🔧 如何验证?
|
||
|
||
### 方法1: 查看原始数据
|
||
|
||
```python
|
||
# 获取30元点前后15天的所有数据
|
||
point_index = 210 # 假设索引
|
||
window_data = low[point_index-15:point_index+16]
|
||
min_value = np.min(window_data)
|
||
|
||
if window_data[15] == min_value:
|
||
print("✓ 是枢轴点")
|
||
else:
|
||
print("✗ 不是枢轴点")
|
||
print(f"最低值: {min_value} 在索引 {np.argmin(window_data)}")
|
||
```
|
||
|
||
### 方法2: 使用详细模式图表
|
||
|
||
```bash
|
||
python scripts/plot_converging_triangles.py --show-details
|
||
```
|
||
|
||
查看图表上:
|
||
- 浅色小圆:所有识别出的枢轴点
|
||
- 如果 30 元点没有小圆标记 → 不是枢轴点
|
||
- 如果有小圆但没有大空心圆 → 是枢轴点但未被选中拟合
|
||
|
||
---
|
||
|
||
## 📐 枢轴点 vs 低点的区别
|
||
|
||
| 特性 | 枢轴点 | 普通低点 |
|
||
|------|--------|---------|
|
||
| **定义** | 数学上的局部极值 | 视觉上的低位 |
|
||
| **要求** | 前后 k 天范围内最低 | 看起来低 |
|
||
| **窗口** | 固定 2k+1 天 | 无限制 |
|
||
| **唯一性** | 窗口内唯一 | 可以有多个 |
|
||
| **用途** | 定义趋势线 | 参考观察 |
|
||
|
||
---
|
||
|
||
## 💭 常见疑问
|
||
|
||
### Q1: 为什么不直接用所有低点?
|
||
|
||
**A**:
|
||
- 噪声太多,拟合线不稳定
|
||
- 需要有代表性的关键点
|
||
- 枢轴点是经过数学筛选的关键点
|
||
|
||
### Q2: k=15 是不是太严格了?
|
||
|
||
**A**:
|
||
- k=15 是经过调试的经验值
|
||
- 太小(如 k=5):太多点,噪声大
|
||
- 太大(如 k=30):太少点,漏检关键转折
|
||
- 如需调整,修改 `triangle_config.py` 中的 `pivot_k`
|
||
|
||
### Q3: 能否降低标准识别 30 元点?
|
||
|
||
**A**:
|
||
- 不建议:会引入大量噪声点
|
||
- 如果确实需要,可以:
|
||
1. 降低 `pivot_k`(如改为 10)
|
||
2. 使用实时模式(最近 5 天降低标准)
|
||
- 但这会影响整体检测质量
|
||
|
||
---
|
||
|
||
## ✅ 总结
|
||
|
||
### 核心要点
|
||
|
||
1. **枢轴点是数学定义**,不是视觉判断
|
||
2. **k=15 的窗口很严格**,需要 31 天的"统治力"
|
||
3. **视觉低点 ≠ 枢轴点**,后者更严格
|
||
4. **算法优先选择更具代表性的点**
|
||
|
||
### 正确的理解方式
|
||
|
||
```
|
||
视觉观察 → 初步判断
|
||
↓
|
||
枢轴点检测 → 数学验证
|
||
↓
|
||
分段选择 → 提取代表点
|
||
↓
|
||
线性回归 → 拟合趋势线
|
||
```
|
||
|
||
每一步都有其逻辑和意义,不能跳过。
|
||
|
||
---
|
||
|
||
## 📚 相关文档
|
||
|
||
- [枢轴点检测原理.md](./枢轴点检测原理.md) - 枢轴点的完整定义
|
||
- [枢轴点分段选择算法详解.md](./枢轴点分段选择算法详解.md) - 如何选择代表点
|
||
- [图表详细模式功能.md](./2026-01-26_图表详细模式功能.md) - 如何可视化验证
|
||
|
||
---
|
||
|
||
**版本**: v1.0
|
||
**更新**: 2026-01-26
|
||
|