如何用 Python 计算蔡金资金流 CMF 指标?(带量的资金流向,不用 TA-Lib)
如何用 Python 计算蔡金资金流 CMF 指标?
一句话回答: CMF(Chaikin Money Flow,蔡金资金流)先用「收盘价在当日最高-最低区间里的相对位置」算出一个 资金流乘数(±1 之间),乘以成交量得到「资金流量」,再把 N 日的资金流量之和除以 N 日成交量之和——结果在 −1 到 +1 之间,大于 0 代表这段时间资金净流入、小于 0 代表净流出。用 AlphaFeed 取回前复权日线(含 high/low/close/volume),十几行 pandas 即可,无需 TA-Lib。
为什么会有这个问题 / 传统做法的痛点
很多人想知道「最近是主力在吸筹还是在出货」,但单看成交量只有大小、没有方向。CMF 的巧思是:同样的放量,收盘收在当天高位(接近最高价)记为资金流入,收在低位记为流出,再用成交量加权累加。它和两个常被混淆的指标不同:
- OBV:只看收盘价涨跌决定整笔成交量加减,是「全有全无」;CMF 用区间位置做连续加权,更细腻。
- MFI:是「带量的 RSI」,用典型价(HLC 均值)× 量算成 0
100 的超买超卖摆动指标;CMF 直接给出 −1+1 的资金净流入强度,口径不同。
TA-Lib 安装常年劝退(编译 C 库),其实 CMF 用 pandas 就能精确复现,还能顺手处理 A 股常见的一字板(最高=最低)除零问题。
分步骤解决(每步配可运行代码)
第 1 步:取前复权日线
from alphafeed import AlphaFeed
af = AlphaFeed(api_key="your-api-key") # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()
df = af.klines.get("600519.SH", period="1d", count=120,
adjust="forward", to_dataframe=True)
df = df.sort_values("trade_date").reset_index(drop=True)
必须用前复权(adjust="forward"):除权缺口会制造假的「高低位置」,污染资金流乘数。
第 2 步:计算资金流乘数与 CMF
import numpy as np
import pandas as pd
def cmf(df: pd.DataFrame, n: int = 20) -> pd.Series:
high, low, close, vol = df["high"], df["low"], df["close"], df["volume"]
rng = (high - low).replace(0, np.nan) # high==low(一字板)时无方向
mfm = ((close - low) - (high - close)) / rng # 资金流乘数 ∈ [-1, 1]
mfm = mfm.fillna(0.0) # 一字板当作中性 0,避免除零
mfv = mfm * vol # 资金流量
return mfv.rolling(n).sum() / vol.rolling(n).sum() # N 日累加比值
df["cmf20"] = cmf(df, 20)
print(df[["trade_date", "close", "cmf20"]].tail())
资金流乘数 MFM = ((C−L) − (H−C)) / (H−L):收盘贴着最高价 → 接近 +1;贴着最低价 → 接近 −1;收在正中 → 0。
用真实数据实测(
tools/verify_new_2026-10-04b.py,SDK 0.1.4):贵州茅台(600519.SH)近 120 日 CMF(20) = −0.1981,落在 [−1, 1] 内、尾部无 NaN,说明近一个月资金温和净流出。
第 3 步:解读信号
last = df["cmf20"].iloc[-1]
if last > 0.10:
state = "资金明显流入(偏多)"
elif last < -0.10:
state = "资金明显流出(偏空)"
else:
state = "多空均衡"
print(round(last, 4), state)
常见用法:CMF 持续 > 0 且股价上行 = 量价配合;股价新高但 CMF 掉头向下 = 顶背离,提示上涨动能衰竭。
参数与字段说明
| 参数/字段 | 含义 | 备注 |
|---|---|---|
period="1d" | 日线 | CMF 也可用于周线/分钟线 |
adjust="forward" | 前复权 | 必须,否则除权缺口污染高低位置 |
n(窗口) | 累加天数 | 常用 20;越大越平滑、越滞后 |
high/low/close/volume | OHLC + 量 | CMF 四者缺一不可 |
| CMF 取值 | −1 ~ +1 | >0 净流入,<0 净流出 |
关键坑与注意事项
- 一字板除零:A 股涨跌停常出现
high == low,(H−L)=0会得到 inf/NaN。本文把该乘数置 0(中性),实测构造一字板序列不会产生 inf/NaN。 - 前复权:务必用
adjust="forward",否则高低位置被除权缺口扭曲。 - 不是择时圣杯:CMF 是量价辅助,背离信号会失败;需结合趋势与风控,别单指标梭哈。
- 成交量口径:CMF 对成交量单位不敏感(分子分母同量纲抵消),但停牌后首日放量会放大当日权重,解读需留意。
常见问题(FAQ)
Q:CMF 和 MFI、OBV 到底选哪个? A:想要 −1~+1 的「资金净流入强度」用 CMF;想要 0~100 的超买超卖摆动用 MFI;想要最简单的累计量能方向用 OBV。三者可互为印证。
Q:窗口 N 选多少? A:原始定义常用 20。短线可用 10 更灵敏,但假信号更多;长线可用 40~60 更稳。
Q:需要付费吗?
A:单只股票的日线在免费额度内即可拉取;若要对全市场批量算 CMF 做选股扫描,需要 universes(标的池)能力,属 Starter 及以上,详见官网定价页。
小结
CMF 的本质是「用收盘在日内区间的位置给成交量定方向,再做 N 日加权累加」。有了 AlphaFeed 的前复权 OHLCV,十几行 pandas 就能精确复现,还顺手解决了 A 股一字板的除零坑——比折腾 TA-Lib 省心得多。
相关链接:
- AlphaFeed 官网:https://alphafeed.org/
- Python SDK 快速开始:https://docs.alphafeed.org/zh-Hans/sdk/python-quickstart
免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。