首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >如何用 Python 计算 DPO 去趋势价格振荡器?

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

原创
作者头像
用户7083614
发布于 2026-10-15 15:00:57
发布于 2026-10-15 15:00:57
1280
举报

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

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

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

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

第 1 步:取前复权日线

代码语言:python
复制
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

代码语言:python
复制
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 估计周期长度

代码语言:python
复制
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 步:相对超买超卖阈值(用历史分位)

代码语言:python
复制
# 用 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})")

关键坑与注意事项

  • 必须用前复权价:除权跳空会让均线与 DPO 失真。
  • DPO 有意“平移、不追最新”:因为均线前移了 n//2+1 期,DPO 末端并不对齐当前趋势,它是研究周期的工具,不是实时择时信号。
  • 周期估计是统计近似:用零轴穿越间隔估周期只是粗略参考,需多段验证,市场周期本身不稳定。
  • 阈值用相对分位:DPO 无固定超买超卖线,用自身历史分位(如 80/20)判断相对高低更稳。
  • n 决定看多长的周期:n 越大过滤越多短波、突出更长周期;按你研究的节奏调。
  • 头部为 NaN:均线与前移需要预热,count 建议 ≥ 2n,忽略序列最前面若干根。

常见问题(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 并估计周期节奏。

参考

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 为什么会有这个问题 / 传统做法的痛点
  • 分步骤解决(每步配可运行代码)
    • 第 1 步:取前复权日线
    • 第 2 步:计算 DPO
    • 第 3 步:用 DPO 估计周期长度
    • 第 4 步:相对超买超卖阈值(用历史分位)
  • 关键坑与注意事项
  • 常见问题(FAQ)
  • 小结
  • 参考
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档