AlphaFeed Blog

如何用 Python 计算 VR 成交量变异率指标?(用量能判断多空强弱)

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

如何用 Python 计算 VR 成交量变异率指标?

一句话回答: VR(Volume Ratio,成交量变异率)把过去 N 日「上涨日的成交量」和「下跌日的成交量」相比,衡量多方与空方的量能对比:VR 高说明上涨日放量、买盘积极,VR 低说明下跌日放量、抛压重。用 AlphaFeed 取回前复权日线后,几行 pandas 就能算出 VR,不需要 TA-Lib。

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

只看价格看不出「量能站在哪一边」。同样横盘,若上涨日总是放量、下跌日缩量,说明资金在吸筹(VR 偏高);反之则是派发。VR 用成交量的多空分配量化这种能量对比。坑在于:一是要用前复权价判断涨跌方向,避免除权跳空误判;二是平盘日的成交量要按惯例折半计入分子分母,别漏掉。

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

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

判断涨跌用前复权收盘价(adjust="forward"),避免除权日把正常交易误判成涨/跌。

第 2 步:计算 VR(含平盘日折半)

def vr(df: pd.DataFrame, n: int = 26) -> pd.Series:
    chg = df["close"].diff()
    up_vol = df["volume"].where(chg > 0, 0.0)      # 上涨日成交量
    down_vol = df["volume"].where(chg < 0, 0.0)    # 下跌日成交量
    flat_vol = df["volume"].where(chg == 0, 0.0)   # 平盘日成交量
    up = up_vol.rolling(n).sum() + 0.5 * flat_vol.rolling(n).sum()
    down = down_vol.rolling(n).sum() + 0.5 * flat_vol.rolling(n).sum()
    return up / down * 100

df["VR"] = vr(df, n=26)
print(df[["trade_date", "close", "VR"]].tail(5).to_string(index=False))

参数与含义:

参数/字段含义常用值/解读
n统计周期26
VR上涨日量能 ÷ 下跌日量能 ×100越高多方量能越强
平盘日收盘=昨收成交量折半计入分子和分母

第 3 步:阈值参考(相对,不是绝对买卖点)

cur = df["VR"].iloc[-1]
if cur >= 350:
    state = "高位(量能过热,警惕)"
elif cur <= 40:
    state = "低位(缩量/超卖,可能筑底)"
elif cur < 80:
    state = "偏低(活跃度不足)"
else:
    state = "正常(80~350)"
print(f"当前 VR={cur:.1f} → {state}")

VR 常用区间(经验参考,因品种而异):

VR 区间含义参考
< 40低价区(超卖/地量)可能筑底,但也可能阴跌
40 ~ 80安全/偏低区活跃度一般
80 ~ 160正常区多空均衡
160 ~ 350获利/活跃区上涨放量
> 350警戒区量能过热,注意风险

第 4 步:全市场批量筛「低位 VR」候选

codes = ["600519.SH", "000001.SZ", "601318.SH", "000858.SZ", "300750.SZ"]
data = af.klines.batch(codes, period="1d", count=60,
                       adjust="forward", to_dataframe=True)  # dict{symbol: DataFrame}

low_vr = []
for sym, k in data.items():
    k = k.sort_values("trade_date")
    v = vr(k)
    if pd.notna(v.iloc[-1]) and v.iloc[-1] <= 60:
        low_vr.append((sym, round(float(v.iloc[-1]), 1)))
print("低位 VR 候选:", low_vr)

关键坑与注意事项

常见问题(FAQ)

Q:VR 和 OBV、量比有什么区别? A:OBV 累加带方向的成交量看趋势;量比看当日量对近期均量的放大;VR 则看一段时间内涨跌日的量能占比,三者角度不同、可互补。

Q:VR 的默认周期用多少? A:常用 26。周期越短越灵敏、噪音越大。可搭配一条 VR 的移动平均(如 6 日)作辅助。

Q:VR 高就一定要卖吗? A:不一定。高 VR 说明上涨放量、人气旺,可能继续,也可能过热见顶,要结合价格结构判断,别单指标决策。

Q:需要付费吗? A:单只历史日线有免费额度;全市场批量算 VR(klines.batch + universes)需 Starter 及以上。详见定价页。

小结

VR 成交量变异率的本质是「上涨日量能 ÷ 下跌日量能」,用成交量在多空之间的分配衡量能量对比。实现只需 pandas,不依赖 TA-Lib。关键是用前复权价判涨跌、平盘日折半、把阈值当相对参考而非绝对信号。用 AlphaFeed 取回前复权日线,几行就能算 VR 并做全市场筛选。

相关链接:


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