QA GATE · GOOD 18/18 automated ai-check.js · 18 readability, YMYL and image gates · mechanics verified against vike-indicators · live real-data chart embedded
Burstiness (sentence-length SD)10.4
Lexical diversity (MATTR-50)0.83
Consecutive similar sentences2
Repeated paragraph starts (≥3)0
AI-marker phrases0
Demonstrated experience3
Avg sentence length (words)17.1
Repeated 5-grams0
H2 section balance (50–500w)0 off
YMYL risk disclaimeryes
Mechanics verified vs codeyes
Primary keyword coverageyes
Internal links + CTA6
Content visuals9
Every figure has a caption9/9
Alt / caption text coverage100%
Distributed (≥1 per section)6/7 (86%)
Filenames sluggedn/a (inline)
Live interactive chart6 real
Rust/Python port parity0.000e+00
Learn · Trading Indicators · Volume

Money Flow Index: The MFI Rule, Read From the Source

The money flow index is usually introduced as a volume-weighted RSI, and that shorthand is close enough to be useful and loose enough to hide the two decisions that actually matter. Vike computes it as batch_mfi, part of the volume family in our engine.

Both hidden decisions are ties. One decides what happens when a bar's typical price matches the bar before it, and the other decides what the indicator returns when a whole window has nothing falling in it. This page reads both off the crate source, measures how often each fires across 356,886 daily bars, and then scores the textbook 80/20 trade honestly.

What the money flow index measures

ETH/USDT daily — a real MFI crossing detected 2026-06-08, MFI 20.4 crossed up through 20 → rose 9.4% in 7 days.

Take a bar's high, low and close, average them, and multiply by volume. That product is the bar's raw money flow — an approximation of the money that changed hands, using a price the bar actually spent time near rather than the single instant it happened to end on.

Now classify. If the typical price rose against the previous bar's, the whole product joins the buying pile; if it fell, the selling pile. Sum each pile over fourteen bars, take the ratio, and squash it onto a zero-to-a-hundred scale.

Where RSI compares the size of gains against losses, this compares the money behind them. A tiny move on enormous turnover outweighs a large move on nothing, which is exactly the property people want from a volume indicator and exactly the property OBV refuses to give them, since OBV counts a bar's volume in full regardless of how far price travelled.

The exact MFI formula our engine runs

high + low + close÷ 3 = typical× volumeraw money flowtypical roseadd to postypical unchangedadded to neithertypical felladd to neg100 − 100÷ (1 + pos/neg)when neg is zero the division never happens — the result is a flat 100
The arithmetic batch_mfi runs. The middle branch is the tie nobody documents: an unchanged typical price sends the bar’s entire money flow to neither sum.
TAO/USDT daily — a real MFI crossing detected 2026-04-23, MFI 25.0 crossed up through 20 → rose 8.9% in 8 days.

Most descriptions stop at "volume-weighted RSI". Here is the arithmetic underneath.

How Vike computes it. batch_mfi builds tp[i] = (high + low + close) / 3 and rmf[i] = tp[i] * volume[i] for every bar. From bar period onward it walks the window backwards, adding rmf[j] to pos where tp[j] > tp[j-1] and to neg where tp[j] < tp[j-1], then returns 100 - 100/(1 + pos/neg) — or a flat 100.0 when neg came out at zero. Default period is fourteen.

I ported that from the crate source and checked it against the Python original the crate was ported from, over 292 symbols and 356,886 daily bars. Largest absolute difference across every position: zero. No position was defined in one series and missing in the other.

Notice the loop bound. It starts at i = period, not period - 1, because each bar in the window is compared with its predecessor — so a fourteen-period reading needs fifteen bars, and the first value lands on bar fourteen. One more than the parameter suggests, and enough to shift a chart if you assumed otherwise.

The two ties the formula throws away

How often each family member throws a bar away0.251%MFI: typical price tied0.786%OBV: close tied0.000%A/D: high equals low356,886 daily bars, 292 Binance pairs, 2017 to 2026
Three detectors, three ways to be undecided about a bar. The A/D column is not a rounding artefact — on daily candles its guard never fired at all.

A tie is where implementations diverge, and this one has two of them.

First tie, per bar. When tp[j] exactly equals tp[j-1], neither branch matches, so that bar's raw money flow — which can be an enormous number — is dropped from both sums rather than added to both. Across the tape this fires on 895 of 356,886 bars, or 0.251%. Notably rarer than the tied close that OBV discards, at 0.786%, and for a plain reason: an average of three prices reproduces itself far less often than one price does.

Second tie, per window. When nothing in fourteen bars had a falling typical price, neg is zero and the formula would divide by it, so the source short-circuits and returns exactly 100.0. That branch also catches the case where pos is zero too — a window of perfectly flat prices would read maximum, which is a strange thing for a dead market to say about itself.

Does it happen? The value 100.0 appeared on 39 readings out of 352,798. On every single one, pos was large: BTC hit it on 2017-12-07 and again the next day, mid-parabola, on roughly 920 million dollars of buying. The dead-market branch fired zero times in nine years of bars. Reachable in theory, unobserved in practice, and now you know which.

Where 80 and 20 sit in the real distribution

10080502006.30% of all readingsp95 = 81.5median 54.1p5 = 24.52.50% of all readings
The two lines are not mirror images. Overbought printed two and a half times as often as oversold across 352,798 readings, so a symmetric rule produces an asymmetric trade log.

Everyone quotes 80 and 20 as symmetric extremes. I've repeated that pairing from memory for years, so I measured where the lines really sit.

Across 352,798 readings, the fifth percentile landed at 24.5 and the ninety-fifth at 81.5, with the median at 54.1. So the upper line is roughly where the top twentieth begins, but the lower one is well inside the bottom twentieth rather than at its edge.

Count the crossings and the asymmetry sharpens. Readings at or above 80 occurred 22,219 times; readings at or below 20 occurred 8,809 times. Overbought prints two and a half times as often as oversold on this sample, which is what a market with a long upward drift and periodic vertical melt-ups looks like through a bounded oscillator. Treating those two lines as mirror images will hand you far more sell signals than buy signals and let you believe that is the market talking.

How to trade the MFI crossings

DODO/USDT daily — a real MFI crossing detected 2026-07-02, MFI 77.0 crossed down through 80 → fell 8.4% in 2 days.

Here is the rule I tested, tightly enough to be proven wrong: buy when the reading crosses back up through 20, sell when it crosses back down through 80.

Outcomes resolve first-touch over the next ten bars inside a symmetric eight percent bracket, so break-even sits at 50% before fees, and any bar tagging both levels is scored a loss. That identical bracket then runs on every bar in the sample. Without the base rate it produces, a win rate is just a number with nothing to lean on.

Crossings up through 20 fired 2,751 times and resolved 49.4% winners. An arbitrary long entry on those same bars: 49.4%. Identical to the decimal place, which is a cleaner nothing than I expected to find.

Crossings down through 80 fired more than twice as often, 5,611 times, and resolved 48.1% against a random short's 48.9%. Slightly worse than nothing.

Where the money flow index fails

ETHFI/USDT daily — a real MFI crossing detected 2026-04-05, MFI 25.7 crossed up through 20 → went the other way 10.6% first.
EPIC/USDT daily — a real MFI crossing detected 2026-04-26, MFI 76.9 crossed down through 80 → went the other way 9.2% first.
KAITO/USDT daily — a real MFI crossing detected 2026-04-25, MFI 77.7 crossed down through 80 → went the other way 9.5% first.
Three real failures. ETHFI crossed up out of oversold and fell another 10.6%; EPIC and KAITO both crossed down through 80 and kept climbing — the shape a bounded oscillator takes when a trend pins it against the ceiling.

Publishing a zero is the point of running the test, so here is what those numbers mean rather than an excuse for them.

The oversold signal carries no edge whatsoever under this bracket, and the overbought signal is mildly negative. My reading is that the bounded scale is doing the damage: a strong trend pins the indicator against its ceiling for weeks, and every crossing back below 80 during that stretch is a sell into strength. When I see a reading camped above 80 for a fortnight, I skip its next crossing without looking further. The failures below are exactly that shape — EPIC and KAITO both crossed down and kept rising.

Volume quality is the other problem, and it is specific to crypto. Every figure here rests on exchange-reported volume, which is a number a venue publishes about itself. Spot volume on a major pair is credible enough; the same field on a thin listing is not, and the indicator has no way to tell the difference because it never sees anything except that column and three prices.

Frequently asked questions

Is the money flow index just RSI with volume? Not quite. Both squash a ratio onto the same scale, but this one compares typical prices rather than closes, and weights each bar by turnover. Read the RSI breakdown and the difference in inputs becomes obvious.

What is the best MFI period? Fourteen is the default, and every measurement here uses it. Shortening it produces more crossings, and since the crossings tested at no edge, more of them is not an improvement.

Why does my chart show no MFI value for the first fortnight? Because there is none. Fifteen bars are needed before the first reading exists, and returning nothing beats returning a partial number dressed up as a real one.

Can the MFI actually reach 100? Yes, and it did 39 times in this sample — always because every bar in the window rose or held, never because the window was flat.

Which volume indicator should I pair it with? Something that splits the column differently. The accumulation distribution line weights by position inside the bar's own range, so it disagrees with this one in ways worth examining, much as the SMI disagrees with RSI on momentum.

This is educational material, not financial advice. Every number here comes from bars that have already closed, past behavior generalizes poorly, and trading carries real risk of loss — size any position so that being wrong stays affordable.

Read the on balance volume breakdown