---
name: converging-triangle-algorithm
overview: 基于现有对称三角形算法,创建一个新的"收敛三角形"算法,支持二维矩阵批量输入,历史滚动计算,返回包含突破强度分数的完整 DataFrame。
todos:
- id: create-params
content: 创建 ConvergingTriangleParams 参数对象
status: completed
- id: create-result
content: 创建 ConvergingTriangleResult 返回对象
status: completed
- id: impl-strength
content: 实现突破强度计算函数 calc_breakout_strength
status: completed
- id: impl-single
content: 实现单点检测函数 detect_converging_triangle
status: completed
- id: impl-batch
content: 实现批量滚动检测函数 detect_converging_triangle_batch
status: completed
- id: create-script
content: 创建运行脚本 run_converging_triangle.py
status: completed
- id: test-run
content: 测试运行并验证输出
status: in_progress
- id: todo-1768985498252-e4ly4s7r9
content: 只计算最近2年,可以变成一个默认的参数,方便后续修改
status: pending
---
# 收敛三角形算法设计
## 1. 核心设计
### 函数名
- `detect_converging_triangle` (单点检测)
- `detect_converging_triangle_batch` (批量滚动计算)
### 数据流
```mermaid
flowchart LR
subgraph input [Input]
OHLCV["OHLCV Matrices
(n_stocks, n_days)"]
Params[ConvergingTriangleParams]
end
subgraph process [Processing]
Rolling["Rolling Window
每天往过去看 window 天"]
Detect["收敛三角形检测"]
Score["突破强度计算"]
end
subgraph output [Output]
DF["DataFrame
(stock_idx, date_idx, 各指标...)"]
end
OHLCV --> Rolling
Params --> Rolling
Rolling --> Detect
Detect --> Score
Score --> DF
```
---
## 2. 参数对象设计
新建文件: [src/converging_triangle.py](src/converging_triangle.py)
```python
@dataclass
class ConvergingTriangleParams:
# 窗口设置
window: int = 400
# 枢轴点检测
pivot_k: int = 20
# 边界线拟合
boundary_n_segments: int = 2
boundary_source: str = "full" # "full" | "pivots"
# 斜率约束
upper_slope_max: float = 0.10
lower_slope_min: float = -0.10
# 触碰判定
touch_tol: float = 0.10
touch_loss_max: float = 0.10
# 收敛要求
shrink_ratio: float = 0.8
# 突破判定
break_tol: float = 0.001
vol_window: int = 20
vol_k: float = 1.3
false_break_m: int = 5
```
---
## 3. 返回对象设计
```python
@dataclass
class ConvergingTriangleResult:
# 基础标识
stock_idx: int
date_idx: int
is_valid: bool # 是否识别到有效三角形
# 突破强度 (0~1 连续分数)
breakout_strength_up: float # 向上突破强度
breakout_strength_down: float # 向下突破强度
# 几何属性
upper_slope: float
lower_slope: float
width_ratio: float
touches_upper: int
touches_lower: int
apex_x: float
# 突破状态
breakout_dir: str # "up" | "down" | "none"
volume_confirmed: Optional[bool]
false_breakout: Optional[bool]
# 窗口范围
window_start: int
window_end: int
```
---
## 4. 突破强度计算公式
```python
def calc_breakout_strength(
close: float,
upper_line: float,
lower_line: float,
volume_ratio: float,
width_ratio: float,
) -> tuple[float, float]:
"""
计算向上/向下突破强度 (0~1)
综合考虑:
- 价格突破幅度 (close 相对于上/下沿的距离)
- 成交量放大倍数
- 收敛程度 (width_ratio 越小越强)
"""
# 价格突破分数
price_up = max(0, (close - upper_line) / upper_line)
price_down = max(0, (lower_line - close) / lower_line)
# 收敛加成 (越收敛,突破越有效)
convergence_bonus = 1 - width_ratio
# 成交量加成
vol_bonus = min(1, volume_ratio / 2) # 放量2倍=满分
# 加权合成
strength_up = min(1, price_up * 5 * (1 + convergence_bonus) * (1 + vol_bonus))
strength_down = min(1, price_down * 5 * (1 + convergence_bonus) * (1 + vol_bonus))
return strength_up, strength_down
```
---
## 5. 核心函数签名
```python
def detect_converging_triangle_batch(
open_mtx: np.ndarray, # (n_stocks, n_days)
high_mtx: np.ndarray,
low_mtx: np.ndarray,
close_mtx: np.ndarray,
volume_mtx: np.ndarray,
params: ConvergingTriangleParams,
start_day: int = None, # 从哪一天开始计算 (默认: window)
end_day: int = None, # 到哪一天结束 (默认: 最后一天)
) -> pd.DataFrame:
"""
批量滚动检测收敛三角形
Returns:
DataFrame with columns:
- stock_idx, date_idx
- is_valid
- breakout_strength_up, breakout_strength_down
- upper_slope, lower_slope, width_ratio
- touches_upper, touches_lower, apex_x
- breakout_dir, volume_confirmed, false_breakout
- window_start, window_end
"""
```
---
## 6. 滚动计算逻辑
```mermaid
flowchart TD
Start[开始] --> Loop1["遍历 stock_idx: 0..107"]
Loop1 --> Loop2["遍历 date_idx: start_day..end_day"]
Loop2 --> Extract["提取窗口数据
ohlcv[:, date_idx-window+1 : date_idx+1]"]
Extract --> Check{"数据足够?
date_idx >= window"}
Check -->|No| Skip[跳过, is_valid=False]
Check -->|Yes| Detect["调用 detect_converging_triangle()"]
Detect --> CalcStrength["计算突破强度"]
CalcStrength --> Append["添加到结果列表"]
Skip --> Append
Append --> Loop2
Loop2 -->|done| Loop1
Loop1 -->|done| ToDF["转换为 DataFrame"]
ToDF --> End[返回]
```
---
## 7. 文件结构
```
technical-patterns-lab/
├── src/
│ ├── sym_triangle.py # 现有算法 (保留)
│ └── converging_triangle.py # 新算法 (新建)
├── scripts/
│ ├── run_sym_triangle_pkl.py # 现有脚本 (保留)
│ └── run_converging_triangle.py # 新脚本 (新建)
```
---
## 8. 性能考虑
- 108 只股票 × 5113 天 = 55 万次检测
- 预估耗时: 约 2-5 分钟 (可优化)
- 可选优化:
- 只计算最近 N 天
- 并行处理多只股票
- 向量化 pivot 检测