如何用 Python 计算 CMO 钱德动量摆动指标?不用 TA-Lib(含与 RSI 的区别)
如何用 Python 计算 CMO 钱德动量摆动指标?
一句话回答: CMO(Chande Momentum Oscillator,钱德动量摆动指标)由 Tushar Chande 提出,公式是 100 × (N 日涨幅之和 − N 日跌幅之和) / (涨幅之和 + 跌幅之和),取值 −100 ~ +100:接近 +100 说明近期几乎全是上涨(强多头动量)、接近 −100 全是下跌。它和 RSI 用同样的涨跌幅材料,但分子保留了正负号、分母不做平滑,因此比 RSI 更灵敏、摆幅更大。用 AlphaFeed 取前复权日线几行就能算,不需要 TA-Lib。
为什么会有这个问题 / 传统做法的痛点
RSI 把动量压进 0~100 且常用 Wilder 平滑,灵敏度被削弱、顶背离/底背离有时反应慢。Chande 的设计让 CMO 直接用涨跌幅的净差除以总波动,既保留方向(正负)又不额外平滑,于是对动量的变化更敏感、更早触及极值区。痛点是 TA-Lib 虽有 CMO,但很多人不清楚它和 RSI 的关系与阈值差异(CMO 用 ±50 而非 70/30),容易误用。
分步骤解决(每步配可运行代码)
第 1 步:取前复权日线
from alphafeed import AlphaFeed
import numpy as np, pandas as pd
af = AlphaFeed(api_key="your-api-key") # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()
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)
第 2 步:实现 CMO
def cmo(close, n=14):
d = close.diff()
su = d.clip(lower=0).rolling(n).sum() # N 日涨幅之和
sd = (-d.clip(upper=0)).rolling(n).sum() # N 日跌幅绝对值之和
return 100 * (su - sd) / (su + sd).replace(0, np.nan)
df["cmo"] = cmo(df["close"], 14)
print(df[["trade_date", "cmo"]].tail())
实测(
tools/verify_new_2026-10-16.py,SDK 0.1.4):贵州茅台近 250 日 CMO 尾值 ≈ 29.31(中性),区间 −94.48 ~ 61.35——曾深跌到 −94(极弱)、也曾升到 61(偏强),取值始终在 ±100 内。
第 3 步:超买超卖与零轴判读
def judge(v):
if v > 50: return "超买(强多头动量)"
if v < -50: return "超卖(强空头动量)"
return "多头区" if v > 0 else "空头区"
print("CMO 判读:", judge(df["cmo"].iloc[-1]))
常用规则:CMO > +50 超买、< −50 超卖;穿越零轴代表动量多空切换;也可对 CMO 再取均线做信号线。
参数与字段说明
| 参数/概念 | 含义 | 备注 |
|---|---|---|
adjust="forward" | 前复权 | 必须,除权缺口会制造假涨跌幅 |
su | N 日涨幅之和 | 分子正项 |
sd | N 日跌幅绝对值之和 | 分子负项 |
n=14 | 回看周期 | 常用 14/9 |
| CMO | −100 ~ +100 | 带方向的动量 |
| ±50 | 超买/超卖阈值 | 不同于 RSI 的 70/30 |
关键坑与注意事项
- 阈值不是 70/30:CMO 跨 −100~+100,超买超卖常用 ±50(有人用 ±60),别套 RSI 的 70/30。
- 更灵敏=更易骗线:CMO 不做 Wilder 平滑,摆幅大、信号多,震荡市假信号比 RSI 还多,常需叠加信号线或趋势过滤。
- 前复权必须:除权缺口会让涨跌幅失真。
- 分母为零:极端平盘(N 日无波动)时分母可能为 0,需
replace(0, nan)防除零。 - 是动量不是价格目标:CMO 只描述动量强弱与方向,不预测涨跌幅度。
常见问题(FAQ)
Q:CMO 和 RSI 到底差在哪?
A:材料相同(涨跌幅),但 RSI = 100 − 100/(1+RS),RS 用平滑后的均值、范围 0100;CMO = (涨−跌)/(涨+跌)×100,范围 −100+100、不额外平滑。CMO 更灵敏、带正负号,RSI 更平滑、常用。
Q:CMO 可以配合什么用? A:常对 CMO 取一条移动平均当信号线(金叉死叉),或用零轴判多空切换,并结合趋势/成交量过滤震荡市假信号。
Q:需要付费吗?
A:单只股票日线在免费额度内即可;若要对全市场批量扫 CMO 超卖反弹的票,需要 klines.batch + universes(Starter 及以上),详见官网定价页。
小结
CMO 用「涨跌幅净差 ÷ 总波动」把动量映射到 −100~+100,比 RSI 更灵敏、自带方向。用 AlphaFeed 的前复权日线几行即可实现——记住阈值用 ±50 而非 70/30、它更灵敏也更易骗线、前复权必须、防分母为零。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。