- 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.
450 lines
12 KiB
Markdown
450 lines
12 KiB
Markdown
# 方案4:混合策略(推荐的实时方案)
|
||
|
||
## 核心思想
|
||
|
||
将枢轴点分为两类,兼顾**质量**和**实时性**:
|
||
|
||
1. **确认枢轴点(Confirmed Pivots)**:有完整左右k天数据,高置信度
|
||
2. **候选枢轴点(Candidate Pivots)**:右边数据不完整,低置信度(待确认)
|
||
|
||
---
|
||
|
||
## 算法设计
|
||
|
||
### 1. 检测逻辑
|
||
|
||
```python
|
||
def pivots_fractal_hybrid(
|
||
high: np.ndarray,
|
||
low: np.ndarray,
|
||
k: int = 15, # 标准窗口大小
|
||
flexible_zone: int = 5 # 灵活区域(最近几天使用降低标准)
|
||
) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
|
||
"""
|
||
混合枢轴点检测:区分确认点和候选点
|
||
|
||
Returns:
|
||
(confirmed_ph, confirmed_pl, candidate_ph, candidate_pl)
|
||
- confirmed: 完整窗口确认的高质量枢轴点
|
||
- candidate: 右边窗口不完整的待确认枢轴点
|
||
"""
|
||
n = len(high)
|
||
|
||
# ========================================
|
||
# 第1步:确认枢轴点(完整窗口,高质量)
|
||
# ========================================
|
||
confirmed_ph = []
|
||
confirmed_pl = []
|
||
|
||
# 中间部分:严格要求左右各k天
|
||
for i in range(k, n - k):
|
||
# 高点枢轴:左右各k天的最高点
|
||
if high[i] == np.max(high[i - k : i + k + 1]):
|
||
confirmed_ph.append(i)
|
||
|
||
# 低点枢轴:左右各k天的最低点
|
||
if low[i] == np.min(low[i - k : i + k + 1]):
|
||
confirmed_pl.append(i)
|
||
|
||
# ========================================
|
||
# 第2步:候选枢轴点(灵活窗口,低置信度)
|
||
# ========================================
|
||
candidate_ph = []
|
||
candidate_pl = []
|
||
|
||
# 最近 flexible_zone 天:降低右边窗口要求
|
||
for i in range(n - flexible_zone, n):
|
||
# 右边可用天数(可能不足k天)
|
||
right_avail = n - 1 - i
|
||
|
||
# 高点候选:左k天 + 右边所有可用天数
|
||
if high[i] == np.max(high[i - k : i + right_avail + 1]):
|
||
candidate_ph.append(i)
|
||
|
||
# 低点候选:左k天 + 右边所有可用天数
|
||
if low[i] == np.min(low[i - k : i + right_avail + 1]):
|
||
candidate_pl.append(i)
|
||
|
||
return (
|
||
np.array(confirmed_ph, dtype=int),
|
||
np.array(confirmed_pl, dtype=int),
|
||
np.array(candidate_ph, dtype=int),
|
||
np.array(candidate_pl, dtype=int)
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 工作原理图解
|
||
|
||
### 检测窗口划分(window=120, k=15, flexible_zone=5)
|
||
|
||
```
|
||
索引: 0 ... 14 15 ... 104 105 ... 114 115 ... 119
|
||
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
|
||
|--------|---|---------|---|--------|---|--------|
|
||
无法检测 确认枢轴点 候选枢轴点 (当前点)
|
||
(前15天) (90天) (灵活区5天)
|
||
|
||
确认枢轴点: [15, 104] ← 完整窗口,高质量
|
||
候选枢轴点: [115, 119] ← 右边窗口不完整,待确认
|
||
灵活区外: [105, 114] ← 既不是确认,也不是候选(过渡区)
|
||
```
|
||
|
||
### 检测标准对比
|
||
|
||
#### 确认枢轴点(索引 i ∈ [15, 104])
|
||
|
||
```
|
||
检查窗口: [i-15, i+15] ← 完整的31天窗口
|
||
|
||
示例(i=50):
|
||
窗口范围: [35, 65]
|
||
判断条件: high[50] == max(high[35:66])
|
||
置信度: 高 ★★★★★
|
||
```
|
||
|
||
#### 候选枢轴点(索引 i ∈ [115, 119])
|
||
|
||
```
|
||
检查窗口: [i-15, i+实际可用] ← 右边窗口缩短
|
||
|
||
示例(i=118):
|
||
左边窗口: [103, 118] ← 完整的15天
|
||
右边窗口: [118, 119] ← 只有1天!
|
||
判断条件: high[118] == max(high[103:120])
|
||
置信度: 低 ★★☆☆☆ (待确认)
|
||
```
|
||
|
||
---
|
||
|
||
## 置信度管理
|
||
|
||
### 增加置信度字段
|
||
|
||
修改返回结果,为每个枢轴点添加置信度标记:
|
||
|
||
```python
|
||
@dataclass
|
||
class PivotPoint:
|
||
"""枢轴点数据结构"""
|
||
index: int # 索引位置
|
||
value: float # 价格值
|
||
confidence: str # 置信度:"confirmed" 或 "candidate"
|
||
right_window: int # 右边实际窗口大小(用于评估质量)
|
||
|
||
|
||
def pivots_fractal_hybrid_v2(
|
||
high: np.ndarray,
|
||
low: np.ndarray,
|
||
k: int = 15,
|
||
flexible_zone: int = 5
|
||
) -> Tuple[List[PivotPoint], List[PivotPoint]]:
|
||
"""
|
||
返回带置信度的枢轴点列表
|
||
|
||
Returns:
|
||
(pivot_highs, pivot_lows)
|
||
每个点包含:索引、价格、置信度、右窗口大小
|
||
"""
|
||
n = len(high)
|
||
pivot_highs = []
|
||
pivot_lows = []
|
||
|
||
# 确认枢轴点(完整窗口)
|
||
for i in range(k, n - k):
|
||
if high[i] == np.max(high[i - k : i + k + 1]):
|
||
pivot_highs.append(PivotPoint(
|
||
index=i,
|
||
value=high[i],
|
||
confidence="confirmed",
|
||
right_window=k # 完整的右窗口
|
||
))
|
||
|
||
if low[i] == np.min(low[i - k : i + k + 1]):
|
||
pivot_lows.append(PivotPoint(
|
||
index=i,
|
||
value=low[i],
|
||
confidence="confirmed",
|
||
right_window=k
|
||
))
|
||
|
||
# 候选枢轴点(灵活窗口)
|
||
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]):
|
||
pivot_highs.append(PivotPoint(
|
||
index=i,
|
||
value=high[i],
|
||
confidence="candidate",
|
||
right_window=right_avail # 不完整的右窗口
|
||
))
|
||
|
||
if low[i] == np.min(low[i - k : i + right_avail + 1]):
|
||
pivot_lows.append(PivotPoint(
|
||
index=i,
|
||
value=low[i],
|
||
confidence="candidate",
|
||
right_window=right_avail
|
||
))
|
||
|
||
return pivot_highs, pivot_lows
|
||
```
|
||
|
||
---
|
||
|
||
## 在三角形检测中的应用
|
||
|
||
### 1. 修改检测函数
|
||
|
||
```python
|
||
def detect_converging_triangle_realtime(
|
||
high: np.ndarray,
|
||
low: np.ndarray,
|
||
close: np.ndarray,
|
||
volume: Optional[np.ndarray],
|
||
params: ConvergingTriangleParams,
|
||
real_time_mode: bool = False, # 新增:实时模式开关
|
||
flexible_zone: int = 5, # 新增:灵活区域大小
|
||
) -> ConvergingTriangleResult:
|
||
"""
|
||
支持实时模式的三角形检测
|
||
|
||
Args:
|
||
real_time_mode: 是否启用实时模式
|
||
- False: 使用原始方法(仅确认枢轴点)
|
||
- True: 使用混合策略(确认+候选枢轴点)
|
||
"""
|
||
|
||
if real_time_mode:
|
||
# 使用混合策略检测枢轴点
|
||
ph_confirmed, pl_confirmed, ph_candidate, pl_candidate = \
|
||
pivots_fractal_hybrid(high, low, k=params.pivot_k,
|
||
flexible_zone=flexible_zone)
|
||
|
||
# 合并确认和候选枢轴点
|
||
ph_idx = np.concatenate([ph_confirmed, ph_candidate])
|
||
pl_idx = np.concatenate([pl_confirmed, pl_candidate])
|
||
|
||
else:
|
||
# 原始方法:仅使用确认枢轴点
|
||
ph_idx, pl_idx = pivots_fractal(high, low, k=params.pivot_k)
|
||
|
||
# 后续检测逻辑保持不变...
|
||
# (筛选窗口内枢轴点、拟合边界线等)
|
||
```
|
||
|
||
### 2. 结果标注
|
||
|
||
在检测结果中添加置信度信息:
|
||
|
||
```python
|
||
@dataclass
|
||
class ConvergingTriangleResult:
|
||
"""收敛三角形检测结果"""
|
||
|
||
# ... 原有字段 ...
|
||
|
||
# 新增字段
|
||
detection_mode: str = "standard" # "standard" 或 "realtime"
|
||
pivot_confidence: str = "high" # 枢轴点置信度
|
||
has_candidate_pivots: bool = False # 是否包含候选枢轴点
|
||
candidate_count: int = 0 # 候选枢轴点数量
|
||
```
|
||
|
||
---
|
||
|
||
## 参数配置建议
|
||
|
||
### flexible_zone 的选择
|
||
|
||
```python
|
||
# 保守配置(推荐)
|
||
flexible_zone = 5 # 最近5天使用灵活标准
|
||
# - 捕获最近的突破点
|
||
# - 置信度相对较高(右边至少有0-4天数据)
|
||
|
||
# 平衡配置
|
||
flexible_zone = 10 # 最近10天
|
||
# - 更早发现形态
|
||
# - 置信度中等
|
||
|
||
# 激进配置(不推荐)
|
||
flexible_zone = 15 # 完全覆盖盲区
|
||
# - 最大实时性
|
||
# - 置信度低,噪音多
|
||
```
|
||
|
||
### 配置示例
|
||
|
||
```python
|
||
# 在 triangle_config.py 中添加
|
||
|
||
# 实时模式参数
|
||
REALTIME_PARAMS = ConvergingTriangleParams(
|
||
window=120,
|
||
pivot_k=15,
|
||
# ... 其他参数与严格模式相同 ...
|
||
)
|
||
|
||
FLEXIBLE_ZONE = 5 # 灵活区域大小
|
||
REALTIME_MODE = False # 默认关闭实时模式
|
||
```
|
||
|
||
---
|
||
|
||
## 使用场景对比
|
||
|
||
### 场景1:历史回测(使用标准模式)
|
||
|
||
```python
|
||
result = detect_converging_triangle(
|
||
high=high_win,
|
||
low=low_win,
|
||
close=close_win,
|
||
volume=volume_win,
|
||
params=params,
|
||
real_time_mode=False # 标准模式
|
||
)
|
||
|
||
# 优点:高质量,无误报
|
||
# 缺点:有15天滞后
|
||
```
|
||
|
||
### 场景2:实时选股(使用实时模式)
|
||
|
||
```python
|
||
result = detect_converging_triangle_realtime(
|
||
high=high_win,
|
||
low=low_win,
|
||
close=close_win,
|
||
volume=volume_win,
|
||
params=params,
|
||
real_time_mode=True, # 实时模式
|
||
flexible_zone=5
|
||
)
|
||
|
||
# 优点:无滞后,捕获当前突破
|
||
# 缺点:可能有误报,需要后续确认
|
||
```
|
||
|
||
---
|
||
|
||
## 优势与限制
|
||
|
||
### 优势
|
||
|
||
1. **兼顾质量和实时性**
|
||
- 确认枢轴点保证准确性
|
||
- 候选枢轴点提供实时信号
|
||
|
||
2. **可控的风险**
|
||
- 通过 `flexible_zone` 调整激进程度
|
||
- 通过置信度字段区分信号强度
|
||
|
||
3. **向后兼容**
|
||
- 标准模式保持原有逻辑
|
||
- 实时模式作为可选增强
|
||
|
||
4. **灵活应用**
|
||
- 回测:使用标准模式
|
||
- 实盘:使用实时模式 + 人工确认
|
||
|
||
### 限制
|
||
|
||
1. **候选枢轴点不稳定**
|
||
- 右边数据不完整,可能随后续数据变化
|
||
- 需要后续确认机制
|
||
|
||
2. **逻辑复杂度增加**
|
||
- 需要管理两类枢轴点
|
||
- 需要处理置信度逻辑
|
||
|
||
3. **参数敏感**
|
||
- `flexible_zone` 需要根据市场调优
|
||
- 不同股票可能需要不同配置
|
||
|
||
---
|
||
|
||
## 实施步骤
|
||
|
||
### 第1步:实现混合检测函数
|
||
|
||
在 `src/converging_triangle.py` 中添加 `pivots_fractal_hybrid()`
|
||
|
||
### 第2步:修改检测函数
|
||
|
||
在 `detect_converging_triangle()` 中添加 `real_time_mode` 参数
|
||
|
||
### 第3步:更新配置文件
|
||
|
||
在 `triangle_config.py` 中添加实时模式配置
|
||
|
||
### 第4步:修改调用脚本
|
||
|
||
在 `run_converging_triangle.py` 中支持实时模式参数
|
||
|
||
### 第5步:测试验证
|
||
|
||
创建测试用例,对比标准模式和实时模式的结果
|
||
|
||
---
|
||
|
||
## 测试示例
|
||
|
||
```python
|
||
def test_realtime_vs_standard():
|
||
"""对比实时模式和标准模式"""
|
||
|
||
# 模拟一个当前正在突破的场景
|
||
high = create_triangle_with_breakout()
|
||
low = create_triangle_with_breakout()
|
||
|
||
# 标准模式
|
||
result_std = detect_converging_triangle(
|
||
high, low, close, volume, params,
|
||
real_time_mode=False
|
||
)
|
||
|
||
# 实时模式
|
||
result_rt = detect_converging_triangle(
|
||
high, low, close, volume, params,
|
||
real_time_mode=True,
|
||
flexible_zone=5
|
||
)
|
||
|
||
print("标准模式:")
|
||
print(f" 检测到三角形: {result_std.is_valid}")
|
||
print(f" 突破强度: {result_std.breakout_strength_up:.3f}")
|
||
|
||
print("实时模式:")
|
||
print(f" 检测到三角形: {result_rt.is_valid}")
|
||
print(f" 突破强度: {result_rt.breakout_strength_up:.3f}")
|
||
print(f" 候选枢轴点数: {result_rt.candidate_count}")
|
||
```
|
||
|
||
---
|
||
|
||
## 总结
|
||
|
||
方案4(混合策略)是**最佳平衡方案**,适合需要实时性的场景:
|
||
|
||
| 特性 | 标准模式 | 混合策略(方案4) |
|
||
|------|---------|-----------------|
|
||
| 枢轴点质量 | 高 ★★★★★ | 高(确认)+ 中(候选) ★★★★☆ |
|
||
| 实时性 | 低(15天滞后) | 高(无滞后) ★★★★★ |
|
||
| 适用场景 | 历史回测 | 实时选股 |
|
||
| 误报风险 | 低 | 中(候选点需确认) |
|
||
| 实施复杂度 | 简单 | 中等 |
|
||
|
||
**推荐应用**:
|
||
- 当前项目(回测):保持标准模式
|
||
- 未来扩展(实盘):实施方案4
|
||
|
||
**关键参数**:
|
||
- `k=15`:标准窗口大小
|
||
- `flexible_zone=5`:灵活区域(建议3-7天)
|
||
- `real_time_mode=True/False`:模式开关
|
||
|