Chaikin Money Flow is three clean steps in pandas — a multiplier, a volume weight, and a normalized rolling sum, as the explainer covered. Here it is, with the flat-bar guard that most implementations forget.
What you’ll need
- Python 3.9+,
pandas/numpy high,low,close,volumeseries.
From scratch
import numpy as np
import pandas as pd
def cmf(high, low, close, volume, period: int = 20):
rng = (high - low).replace(0, np.nan) # guard flat bars
mfm = ((close - low) - (high - close)) / rng # money flow multiplier
mfm = mfm.fillna(0.0) # flat bar -> neutral
mfv = mfm * volume # money flow volume
return (mfv.rolling(period).sum()
/ volume.rolling(period).sum()).rename("cmf")
mfm is the close-location value (+1 at the high, −1 at the low), mfv weights it
by volume, and dividing the rolling sums normalizes CMF into its bounded, zero-
centered range — the oscillator from the output chart.
A confirmation filter
CMF earns its keep confirming price:
c = cmf(df["high"], df["low"], df["close"], df["volume"])
df["accum"] = c > 0.05 # meaningful buying pressure
df["distrib"] = c < -0.05 # meaningful selling pressure
# e.g. only take long entries while accumulation is present:
df["long_ok"] = df["accum"]
Use long_ok to gate another entry signal and test whether it helps in
AlgoGen.
Gotchas
- Flat-bar guard. When
high == low, the multiplier divides by zero.replace(0, np.nan)thenfillna(0.0)sets those bars neutral — the standard fix. - Sum, then divide. CMF divides the sum of money flow volume by the sum of volume over the window — not the average of per-bar ratios. Order matters.
- Gap blindness. The multiplier only sees inside each bar’s range, so overnight gaps don’t register. Know this limitation; don’t expect CMF to catch gap moves.
The lazy one-liner
import pandas_ta as ta
df["cmf20"] = ta.cmf(df["high"], df["low"], df["close"], df["volume"], length=20)
Same indicator elsewhere: MQL5, Pine Script, EasyLanguage, NinjaScript.
This post is educational, not financial advice. Indicators describe the past; they don’t predict the future. Backtest anything before you risk real money on it.
Sources and further reading
- Windowing operations (pandas documentation)
