一句话回答: DPO(Detrended Price Oscillator,去趋势价格振荡器)用「当前价 − 前移了 N/2+1 期的 N 日均线」剥离长期趋势,把价格围绕均值的周期性波动单独显示出来,方便估计高低点节奏、判断相对超买超卖。用 AlphaFeed 取回前复权日线后,几行 pandas 就能算出 DPO,不需要 TA-Lib。
趋势会掩盖周期:一只票一路上涨时,普通振荡指标也一直高位,看不清「相对自己的贵/便宜」。DPO 的巧思是把均线向前平移再与价格相减,等于把趋势成分抽掉,只留下价格绕均线的周期起伏。坑在于:一是要用前复权价避免除权跳空;二是 DPO 不是用来追最新价的(它有意平移、不预测当前),主要用于研究历史周期长度。
from alphafeed import AlphaFeed
import pandas as pd
af = AlphaFeed() # 读取 ALPHAFEED_API_KEY
df = af.klines.get("600519.SH", period="1d", count=250,
adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)DPO 基于均线,务必用
adjust="forward"(前复权),避免除权断层污染。
def dpo(close: pd.Series, n: int = 20) -> pd.Series:
shift = n // 2 + 1
ma = close.rolling(n).mean()
return close - ma.shift(shift) # 当前价 − 前移后的均线
df["DPO"] = dpo(df["close"], n=20)
print(df[["trade_date", "close", "DPO"]].tail(6).to_string(index=False))参数与含义:
参数/字段 | 含义 | 常用值 |
|---|---|---|
| 均线周期(≈你关注的周期长度) | 20 |
| 均线前移期数 | 11(n=20 时) |
| 价格高于该周期均值 | 相对偏高 |
| 价格低于该周期均值 | 相对偏低 |
import numpy as np
# 统计 DPO 相邻“由负转正”的间隔,粗估周期天数
sign = np.sign(df["DPO"].fillna(0))
cross_up = df.index[(sign.shift() < 0) & (sign > 0)].tolist()
if len(cross_up) >= 2:
gaps = np.diff(cross_up)
print("DPO 上穿零轴的平均间隔(≈周期):", round(gaps.mean(), 1), "天")# 用 DPO 的历史分位判断当前相对高低
q80 = df["DPO"].quantile(0.8)
q20 = df["DPO"].quantile(0.2)
cur = df["DPO"].iloc[-1]
state = "相对高位" if cur >= q80 else ("相对低位" if cur <= q20 else "中性")
print(f"当前 DPO={cur:.2f} 状态={state}(80/20 分位: {q80:.2f}/{q20:.2f})")count 建议 ≥ 2n,忽略序列最前面若干根。Q:DPO 和普通均线偏离(价格−均线)有什么不同?
A:关键在均线前移了 n/2+1 期,这样能更好地对齐并剥离趋势、突出周期成分,而不是简单的乖离。
Q:DPO 能预测拐点吗?
A:不能直接预测。它主要用于回顾性地研究周期长度与相对高低,因平移设计而不对齐最新价,别拿它做实时买卖信号。
Q:n 取多少?
A:常用 20(约一个月)。想看更长周期就加大 n。先用 20 观察零轴穿越间隔再调。
Q:需要付费吗?
A:单只历史日线有免费额度;全市场批量算 DPO(klines.batch + universes)需 Starter 及以上。详见定价页。
DPO 去趋势价格振荡器的本质是「当前价 − 前移后的均线」,用平移相减剥离趋势、突出价格周期。实现只需 pandas 的 rolling + shift,不依赖 TA-Lib。关键是用前复权价、理解它「平移不追最新、用于研究周期」的定位、用历史分位定相对高低。用 AlphaFeed 取回前复权日线,几行就能算 DPO 并估计周期节奏。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。