AlphaFeed Blog

如何用 Python 计算 DPO 去趋势价格振荡器?(剔除趋势看价格周期)

分析与指标 · 代码验证于 2026-09-27

如何用 Python 计算 DPO 去趋势价格振荡器?

一句话回答: DPO(Detrended Price Oscillator,去趋势价格振荡器)用「当前价 − 前移了 N/2+1 期的 N 日均线」剥离长期趋势,把价格围绕均值的周期性波动单独显示出来,方便估计高低点节奏、判断相对超买超卖。用 AlphaFeed 取回前复权日线后,几行 pandas 就能算出 DPO,不需要 TA-Lib。

为什么会有这个问题 / 传统做法的痛点

趋势会掩盖周期:一只票一路上涨时,普通振荡指标也一直高位,看不清「相对自己的贵/便宜」。DPO 的巧思是把均线向前平移再与价格相减,等于把趋势成分抽掉,只留下价格绕均线的周期起伏。坑在于:一是要用前复权价避免除权跳空;二是 DPO 不是用来追最新价的(它有意平移、不预测当前),主要用于研究历史周期长度。

分步骤解决(每步配可运行代码)

第 1 步:取前复权日线

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"(前复权),避免除权断层污染。

第 2 步:计算 DPO

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))

参数与含义:

参数/字段含义常用值
n均线周期(≈你关注的周期长度)20
shift = n//2+1均线前移期数11(n=20 时)
DPO > 0价格高于该周期均值相对偏高
DPO < 0价格低于该周期均值相对偏低

第 3 步:用 DPO 估计周期长度

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), "天")

第 4 步:相对超买超卖阈值(用历史分位)

# 用 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})")

关键坑与注意事项

常见问题(FAQ)

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 并估计周期节奏。

相关链接:


免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。