technical-patterns-lab/docs/triangle_api_reference.md
褚宏光 7bdcb474ba Add triangle detection API and documentation
- Introduced a new API for converging triangle detection, including the main function `detect_matrix()` for batch processing of stock data.
- Added detailed documentation for the API, covering usage examples, parameter configurations, and output structures.
- Created new markdown files for reference and usage instructions, enhancing the overall documentation quality.

New files:
- `src/triangle_detector_api.py`: Core API implementation.
- `docs/triangle_api_reference.md`: Comprehensive API reference documentation.
- `discuss/20260129-三角形强度.md`: Documentation for triangle strength detection functions.
- `docs/2026-01-29_三角形数据_server.md`: Detailed usage of the triangle detection functions.
2026-01-29 13:13:52 +08:00

12 KiB
Raw Permalink Blame History

收敛三角形检测 API 参考文档

概览

triangle_detector_api.py 提供收敛三角形形态检测的完整封装,核心设计:

  • 主函数 detect_matrix()全市场矩阵批量检测如万得全A所有A股
  • 一个 strength 搞定筛选:正值=向上,负值=向下,绝对值=强度
  • 4 个核心参数:都有合理默认值,大多数场景无需调整

快速开始

from triangle_detector_api import detect_matrix

# 输入OHLCV 矩阵 (n_stocks, n_days)
df = detect_matrix(
    high_mtx=high_mtx,       # shape: (n_stocks, n_days)
    low_mtx=low_mtx,
    close_mtx=close_mtx,
    volume_mtx=volume_mtx,
    dates=dates,             # shape: (n_days,)
    tkrs=tkrs,               # shape: (n_stocks,) 股票代码
    tkrs_name=tkrs_name,     # shape: (n_stocks,) 股票名称
)

# 筛选
df[df['strength'] > 0.5]       # 强向上突破
df[df['strength'] < -0.5]      # 强向下突破
df.sort_values('strength', ascending=False)  # 排序

核心函数

detect_matrix() 主函数

全市场矩阵批量检测每只股票每天都进行检测。适用于万得全A等全市场扫描场景。

def detect_matrix(
    high_mtx: np.ndarray,      # (n_stocks, n_days)
    low_mtx: np.ndarray,
    close_mtx: np.ndarray,
    volume_mtx: np.ndarray,
    dates: np.ndarray,         # (n_days,)
    tkrs: np.ndarray = None,   # (n_stocks,) 股票代码
    tkrs_name: np.ndarray = None,  # (n_stocks,) 股票名称
    params: DetectionParams = None,
    start_day: int = None,
    end_day: int = None,
    only_valid: bool = True,
    verbose: bool = False,
) -> pd.DataFrame

参数说明:

参数 类型 必填 说明
high_mtx ndarray 最高价矩阵 (n_stocks, n_days)
low_mtx ndarray 最低价矩阵
close_mtx ndarray 收盘价矩阵
volume_mtx ndarray 成交量矩阵
dates ndarray 日期数组 (n_days,)
tkrs ndarray 股票代码数组
tkrs_name ndarray 股票名称数组
params DetectionParams 检测参数
start_day int 起始日索引
end_day int 结束日索引
only_valid bool 只返回有效形态,默认 True
verbose bool 打印进度

返回值: DataFrame

列名 说明
stock_idx 股票索引
stock_code 股票代码
stock_name 股票名称
date_idx 日期索引
date 日期
strength 强度分(核心输出)
is_valid 是否有效形态
direction 突破方向
width_ratio 收敛比例

示例:

from triangle_detector_api import detect_matrix

# 批量检测
df = detect_matrix(high, low, close, volume, dates, tkrs, tkrs_name, verbose=True)

# 筛选
strong_up = df[df['strength'] > 0.5]
strong_down = df[df['strength'] < -0.5]

# 某日最强股票
latest_date = df['date'].max()
df[df['date'] == latest_date].sort_values('strength', ascending=False).head(10)

detect_triangle()

单股票检测(用于生成图表数据)。

def detect_triangle(
    ohlc_data: Dict,
    params: DetectionParams = None,
    include_pivots: bool = True,
    display_window: int = None,
) -> DetectionResult

ohlc_data 格式:

{'dates': [...], 'open': [...], 'high': [...], 'low': [...], 'close': [...], 'volume': [...]}

返回值: DetectionResult 对象,包含 chart_data 可生成 ECharts 配置


入参配置

DetectionParams

检测参数类,所有参数都有合理默认值。

from triangle_detector_api import DetectionParams

# 使用默认参数(推荐)
params = DetectionParams()

# 自定义参数
params = DetectionParams(
    window=120,
    min_convergence=0.6,
)

可调参数:

参数 类型 默认值 说明
window int 240 检测窗口大小(交易日)
min_convergence float 0.45 收敛比例阈值(末端宽度/起始宽度)
breakout_threshold float 0.005 突破阈值0.5%
volume_multiplier float 1.5 放量确认倍数

参数调整建议:

参数 较小值效果 较大值效果
window 检测短期形态,信号及时 检测中长期形态,信号可靠
min_convergence 要求更强收敛,形态标准 放宽收敛,更多候选
breakout_threshold 更敏感,可能假突破 减少假突破,可能漏信号
volume_multiplier 允许轻度放量 要求更强放量确认

输出结构

DetectionResult

检测结果类。

@dataclass
class DetectionResult:
    # 核心输出
    strength: float           # 综合强度分 (-1 ~ +1)
    is_valid: bool            # 是否检测到有效形态
    direction: BreakoutDirection  # 突破方向
    
    # 辅助输出
    strength_up: float        # 向上强度原始值 (0~1)
    strength_down: float      # 向下强度原始值 (0~1)
    strength_components: StrengthComponents  # 强度分分量
    
    # 形态几何属性
    width_ratio: float        # 收敛比例
    touches_upper: int        # 触碰上沿次数
    touches_lower: int        # 触碰下沿次数
    volume_confirmed: bool    # 成交量确认
    
    # 前端数据
    chart_data: ChartData     # 图表数据

核心字段:strength

范围:-1 ~ +1

范围 含义 建议操作
+0.7 ~ +1.0 强向上突破 ⬆️⬆️⬆️ 重点关注
+0.4 ~ +0.7 中等向上 ⬆️⬆️ 关注
+0.2 ~ +0.4 向上潜力 ⬆️ 观察
0 无效形态 忽略
-0.2 ~ -0.4 向下潜力 ⬇️ 观察
-0.4 ~ -0.7 中等向下 ⬇️⬇️ 关注
-0.7 ~ -1.0 强向下突破 ⬇️⬇️⬇️ 重点关注

StrengthComponents

强度分各分量,便于理解分数构成。

分量 权重 说明
price_score 50% 价格突破幅度
convergence_score 15% 收敛程度
volume_score 10% 放量程度
fitting_score 10% 拟合贴合度
utilization_score 15% 边界利用率

筛选示例

基础筛选

from triangle_detector_api import detect_matrix

# 批量检测
df = detect_matrix(high, low, close, volume, dates, tkrs, tkrs_name)

# 强向上突破
df[df['strength'] > 0.5]

# 强向下突破
df[df['strength'] < -0.5]

# 任意强信号
df[abs(df['strength']) > 0.3]

# 按强度排序
df.sort_values('strength', ascending=False)

按日期筛选

# 某日的检测结果
target_date = 20260120
df_day = df[df['date'] == target_date]

# 某日最强的10只股票
df_day.sort_values('strength', ascending=False).head(10)

按股票筛选

# 某只股票的历史检测结果
df_stock = df[df['stock_code'] == '000001.SZ']

# 查看该股票的强度分变化
df_stock[['date', 'strength', 'direction']].tail(20)

统计分析

# 每日有效形态数量
df.groupby('date')['is_valid'].sum()

# 每日强向上突破数量
df[df['strength'] > 0.5].groupby('date').size()

# 强度分分布
df['strength'].describe()

前端集成

Vue3 + ECharts

1. 安装依赖

npm install echarts vue-echarts

2. 获取 ECharts 配置

result = detect_triangle(ohlc_data)

if result.chart_data:
    echarts_option = result.chart_data.to_echarts_option("股票名称")
    # echarts_option 可直接用于前端

3. Vue3 组件使用

<script setup>
import { ref } from 'vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { CandlestickChart, BarChart, LineChart, ScatterChart } from 'echarts/charts'
import { GridComponent, TooltipComponent, LegendComponent, MarkLineComponent } from 'echarts/components'
import VChart from 'vue-echarts'

use([
  CanvasRenderer, 
  CandlestickChart, 
  BarChart, 
  LineChart, 
  ScatterChart,
  GridComponent, 
  TooltipComponent, 
  LegendComponent,
  MarkLineComponent
])

// 从 API 获取的配置
const chartOption = ref({})

async function loadChart(stockCode) {
  const response = await fetch(`/api/triangle/${stockCode}`)
  const data = await response.json()
  chartOption.value = data.echarts_option
}
</script>

<template>
  <v-chart :option="chartOption" style="height: 500px" autoresize />
</template>

ChartData 结构

@dataclass
class ChartData:
    candlestick: List[List[float]]  # K线数据 [[open, close, low, high], ...]
    dates: List[str]                 # 日期数组
    volumes: List[float]             # 成交量
    upper_line: Optional[TrendLine]  # 上沿趋势线
    lower_line: Optional[TrendLine]  # 下沿趋势线
    pivots: List[PivotPoint]         # 枢轴点列表
    detection_window: Tuple[int, int]  # 检测窗口范围

注意: ECharts K线格式为 [open, close, low, high],与标准 OHLC 顺序不同。


完整示例

from triangle_detector_api import detect_triangle, DetectionParams, quick_detect

# ============ 示例1基础使用 ============
ohlc_data = {
    'dates': dates_list,
    'open': open_list,
    'high': high_list,
    'low': low_list,
    'close': close_list,
    'volume': volume_list,
}

result = detect_triangle(ohlc_data)

print(f"是否有效形态: {result.is_valid}")
print(f"强度分: {result.strength}")
print(f"突破方向: {result.direction.value}")

if result.is_valid:
    print(f"收敛比例: {result.width_ratio:.2f}")
    print(f"触碰次数: 上沿 {result.touches_upper}, 下沿 {result.touches_lower}")

# ============ 示例2自定义参数 ============
params = DetectionParams(
    window=120,              # 短窗口,检测短期形态
    min_convergence=0.6,     # 放宽收敛要求
    breakout_threshold=0.01, # 更严格的突破阈值
)
result = detect_triangle(ohlc_data, params)

# ============ 示例3快速筛选 ============
strength = quick_detect(
    dates=dates_list,
    open_=open_list,
    high=high_list,
    low=low_list,
    close=close_list,
    volume=volume_list,
)

if strength > 0.5:
    print("发现强向上突破信号!")
elif strength < -0.5:
    print("发现强向下突破信号!")

# ============ 示例4获取前端数据 ============
if result.chart_data:
    # 获取 ECharts 配置
    echarts_option = result.chart_data.to_echarts_option("000001.SZ 平安银行")
    
    # 转为 JSON用于 API 响应)
    import json
    json_data = json.dumps(echarts_option, ensure_ascii=False)

常见问题

Q: 为什么强度分为 0

可能原因:

  1. 数据长度不足(需要至少 window 天的数据)
  2. 未形成有效的收敛三角形形态
  3. 斜率不满足收敛要求(上沿应向下,下沿应向上)

Q: 如何调整检测敏感度?

# 更严格(高质量形态)
params = DetectionParams(
    min_convergence=0.4,      # 要求更强收敛
    breakout_threshold=0.01,  # 要求更明显突破
    volume_multiplier=1.8,    # 要求更强放量
)

# 更宽松(更多候选)
params = DetectionParams(
    min_convergence=0.7,      # 放宽收敛要求
    breakout_threshold=0.002, # 允许轻微突破
    volume_multiplier=1.2,    # 允许轻度放量
)

Q: 图表数据格式与其他库不兼容?

ECharts K线格式为 [open, close, low, high]

如需标准 OHLC 格式 [open, high, low, close],可自行转换:

# ECharts -> 标准 OHLC
def to_standard_ohlc(echarts_data):
    return [[row[0], row[3], row[2], row[1]] for row in echarts_data]

版本信息

  • 模块: triangle_detector_api.py
  • 核心依赖: converging_triangle.py(自动使用 Numba 优化版本)
  • Python: 3.8+
  • NumPy: 1.20+
  • Numba: 0.55+(可选,安装后自动启用加速)

性能优化说明converging_triangle.py 会自动检测并加载 converging_triangle_optimized.pyNumba 加速版)。启动时会打印:

  • [性能优化] 已启用Numba加速 - 优化版本生效
  • [性能优化] 未启用Numba加速 - 回退到原版numba 未安装)