本文介绍如何使用 pandas 的滚动窗口与条件选择,仅标记每个局部极值首次出现的枢轴点(1 表示局部低点,2 表示局部高点),避免重复触发,适用于技术分析中的有效突破信号识别。
在量化交易与技术分析中,枢轴点(Pivot Points)常用于识别价格趋势转折的关键位置。但原始的局部极值检测(如 rolling(5, center=True).max() == high)容易在平台或窄幅震荡区间内连续多日触发相同信号(例如连续3天都是局部高点),导致“信号漂移”——即同一波段内多次标记,丧失交易意义。
核心目标:对每个已识别的枢轴类型(高点=2 / 低点=1),仅保留该极值序列中首个出现且未被后续更强极值覆盖的独立信号。换言之:一旦某日被标记为 pivot=2(局部高点),则在其后直到下一个更高 pivot=2 出现前,中间所有“伪高点”均应忽略;pivot=1 同理。
首先,使用中心对称的 5 窗口(含自身及上下各 2 行)检测局部极值:
import pandas as pd
import numpy as np
# 示例数据构建
data = {
'date': ['01.01.2025', '02.01.2025', '03.01.2025', '04.01.2025', '05.01.2025',
'06.01.2025', '07.01.2025', '08.01.2025', '09.01.2025', '10.01.2025',
'11.01.2025', '12.01.2025', '13.01.2025', '14.01.2025', '15.01.2025',
'16.01.2025', '17.01.2025'],
'high': [207, 208, 209, 207, 206, 205, 204, 206, 207, 208, 210, 212, 214,
207, 203, 201, 199],
'low': [204, 205, 205, 203, 202, 200, 199, 201, 202, 205, 207, 209, 210,
204, 202, 198, 196]
}
df = pd.DataFrame(data)
# 构建基础 pivot 列:2=局部高点,1=局部低点,0=非枢轴
cond_high = df['high'].rolling(5, center=True).max().eq(df['high'])
cond_low = df['low'].rolling(5, center=True).min().eq(df['low'])
df['pivot'] = np.select([cond_high, cond_low], [2, 1], default=0)⚠️ 注意:rolling(..., center=True) 要求窗口大小为奇数(此处为 5),且首尾两行因无法满足中心对称而返回 NaN —— 需填充或截断。推荐用 min_periods=3 或直接 dropna() 处理边界。
上述代码生成的是所有局部极值点,但题目要求“only once”——即每个方向(高/低)只取第一个有效突破,后续同向信号需抑制,直至反向或更强信号重置。
实现逻辑如下:
# 初始化状态变量
last_high = -np.inf
last_low = np.inf
takes_pivot = np.zeros(len(df), dtype=int)
for i in range(len(df)):
h, l = df.iloc[i]['high'], df.iloc[i]['low']
if h > last_high and df.iloc[i]['pivot'] == 2:
takes_pivot[i] = 2
last_high = h
elif l < last_low and df.iloc[i]['pivot'] == 1:
takes_pivot[i] = 1
last_low = l
df['takes_pivot'] = takes_pivot运行后,takes_pivot 列将严格满足题意:
通过此方法,你不仅能准确识别枢轴点,更能将其转化为稳健、去噪、可直接对接交易系统的信号列。