一句话回答: ROC(Rate of Change,变动率)就是「当前价相对 N 日前价的涨跌幅百分比」,公式 ROC = (close / close.shift(N) - 1) × 100。用 AlphaFeed 取回前复权日线后,一行 pandas 就能算出 ROC,用来衡量动量强弱、识别零轴穿越与顶底背离,还能对全市场做动量排名——完全不需要 TA-Lib。
ROC 是最直观的动量指标:它直接回答「这只票 N 天涨了多少」。但两个坑常被忽略:一是用未复权价,遇到除权日 ROC 会出现虚假暴涨暴跌;二是把 ROC 当成孤立信号,忽略了它天生适合做横截面动量排名和背离判断。用一个稳定的数据源取回前复权价,这两点都能干净解决。
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)
def roc(close: pd.Series, n: int = 12) -> pd.Series:
return (close / close.shift(n) - 1.0) * 100.0
df["ROC12"] = roc(df["close"], 12)
df["ROC25"] = roc(df["close"], 25)
print(df[["trade_date", "close", "ROC12", "ROC25"]].tail(5).to_string(index=False))用
adjust="forward"(前复权)算 ROC,避免除权日的价格断层污染动量值。
参数/信号 | 含义 | 常用取值/解读 |
|---|---|---|
| 与几日前比较 | 短线 6/12,中线 25/125 |
| 价格高于 N 日前 | 上行动量 |
| 价格低于 N 日前 | 下行动量 |
零轴上穿 | ROC 由负转正 | 动量转强信号 |
零轴下穿 | ROC 由正转负 | 动量转弱信号 |
ROC 绝对值走高 | 动量加速 | 趋势强化 |
prev, cur = df["ROC12"].iloc[-2], df["ROC12"].iloc[-1]
if prev <= 0 < cur:
print("ROC 上穿零轴:动量转强")
elif prev >= 0 > cur:
print("ROC 下穿零轴:动量转弱")
# 平滑 ROC 减少噪音(对 ROC 再做移动平均)
df["ROC12_ma"] = df["ROC12"].rolling(6).mean()ROC 天生适合横截面比较——同一 N 下,ROC 越高动量越强。批量取多只股票日线,算 N 日 ROC 后排名:
codes = ["600519.SH", "000001.SZ", "300750.SZ", "601318.SH", "000858.SZ"]
data = af.klines.batch(codes, period="1d", count=60,
adjust="forward", to_dataframe=True) # 返回 dict{symbol: DataFrame}
rows = []
for sym, k in data.items():
k = k.sort_values("trade_date")
r = (k["close"].iloc[-1] / k["close"].iloc[-21] - 1) * 100 # 20 日 ROC
rows.append({"symbol": sym, "ROC20": round(float(r), 2)})
rank = pd.DataFrame(rows).sort_values("ROC20", ascending=False)
print(rank.to_string(index=False))想扫全市场?把
codes换成af.quotes.get(universes="CN_Stock")拿到的symbol列表,再分批klines.batch(注意请求量,建议本地缓存)。
# 价格创新高但 ROC 未创新高 → 顶背离(动量衰减)
window = 20
price_high = df["close"].iloc[-1] >= df["close"].tail(window).max()
roc_high = df["ROC12"].iloc[-1] >= df["ROC12"].tail(window).max()
if price_high and not roc_high:
print("疑似顶背离:价格新高但动量未同步")count 至少要大于 N,否则 shift(N) 前 N 行为 NaN。Q:ROC 和动量指标 MTM 有什么区别?
A:MTM(动量)用差值 close - close.shift(N),ROC 用比值百分比 (close/close.shift(N)-1)×100。ROC 做跨股票比较更合适,因为它是无量纲的百分比。
Q:ROC 和 RSI 都算动量,用哪个?
A:RSI 有 0~100 的有界区间、适合看超买超卖;ROC 无界、更适合看动量方向与横截面强弱排名。两者可互补。
Q:为什么我算出来前面几行是 NaN?
A:ROC 需要 N 日前的价格,前 N 行没有可比基准,正常为 NaN;取数时把 count 设得比 N 大即可。
Q:需要付费吗?
A:单只历史日线有免费额度;klines.batch 全市场动量排名(配合 universes)需 Starter 及以上。详见定价页。
ROC 变动率的本质是「N 日区间收益率」,计算只需一行 pandas,不必依赖 TA-Lib。关键是用前复权价保证动量真实、按需要选好 N,并善用它无量纲的特性做全市场动量排名与背离判断。用 AlphaFeed 取回前复权日线,从单股信号到全市场动量梯队都能几行搞定。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。