Indicator TutorialPine Script v6

How to Code the Money Flow Index (MFI) in Pine Script

Money flow, positive/negative periods, and overbought/oversold context

MFI classifies price-times-volume amounts by whether the selected source rose or fell from the previous bar. It does not identify buyer-initiated trades, institutional orders or actual net cash entering an asset. This guide provides a Pine v6 example with explicit missing-data rules, 80/20 reference levels and confirmed alerts.

What Is the Money Flow Index?

MFI scales positive directional flow relative to positive plus negative directional flow into a 0–100 oscillator when prices and volume meet the calculation assumptions. Raw flow is selected source × bar volume. Rising-source bars contribute to the positive sum, falling-source bars to the negative sum, and unchanged-source bars to neither.

TradingView documents the typical-price formula. Calling the output buying or selling pressure is an interpretation of aggregated bars, not a measurement of trade aggressors. A high reading does not prove accumulation or predict a reversal.

Why Traders Use This Indicator

  • Compare the amounts assigned to rising-source and falling-source bars.
  • Define reference-level events using the same classification on each window.
  • Compare MFI with a separately calculated price-only RSI.
ParameterDefaultDescription
Length14Number of directional-flow observations in the window. The example requires a complete valid window plus the preceding source observation.
Overbought / oversold80 / 20Illustrative reference levels, not a buy/sell recommendation. Lower must be below upper, and both must lie from 0 to 100.
Volume sourcevolumeThe chart feed supplies volume. Tick counts and traded units are different measures; missing volume is not zero.
Typical pricehlc3The example uses hlc3 and requires positive source values throughout its window. Changing source changes the classification.

How MFI Is Calculated

Typical price TP = (high + low + close) / 3. Raw flow = TP × volume. Let P be the n-bar sum of raw flow when TP rises, and N the sum when TP falls. Unchanged TP adds nothing to either sum.

For P + N > 0, MFI = 100 × P / (P + N). This equals 100 − 100 / (1 + P/N) when N is positive, and makes the one-sided limits explicit: positive-only flow gives 100 and negative-only flow gives 0. With both sums zero there is no directional-flow ratio.

Hypothetical P = 300 and N = 100 gives MFI 75; reversing the amounts gives 25. These are arithmetic examples, not reported market observations. Multiplying all volumes by the same positive factor leaves the ratio unchanged.

The script calls ta.mfi but displays no value until every observation in the window has positive current/previous source and nonnegative, available volume, and the classified-flow total is positive. It does not fill missing data with a neutral 50 or zero. This conservative display gate can differ from an ungated built-in indicator during gaps or warm-up.

Signal Interpretation

Above 80 and below 20 are reference states. The markers show a new confirmed crossing, not every bar that stays beyond a level. A rising MFI is not proof of buyer-initiated volume, and a reading below 40 does not establish institutional distribution.

Regular bullish divergence means price makes a lower low while MFI makes a higher low; the bearish counterpart uses a higher price high and lower MFI high. Neither is a reversal guarantee. No divergence detector is implemented here.

Lines and table values can update during an open bar. Markers, backgrounds and alert conditions wait for bar close. Create an alert in TradingView and recreate it after input or code changes. A historical marker does not prove live alert delivery.

Combining with Other Indicators

The Data Window includes RSI of the same selected source and length. MFI and RSI still use different weighting and aggregation, so their difference is not an isolated measure of volume’s causal effect. Adding VWAP, OBV or a price filter creates another rule to evaluate; it does not guarantee fewer false signals.

Writing Pine Script Manually

Challenges of Manual Coding

Specify unchanged-source bars and zero-flow windows.

Keep missing volume distinct from a valid zero-volume bar.

Use a consistent 0–100 scale for the line and columns.

Make plot controls, table missing states and confirmed alert rules agree.

Pine Script v6
//@version=6
indicator("MFI with explicit data and event boundaries", shorttitle="MFI rules", overlay=false)
length = input.int(14, "MFI length", minval=1)
src = input.source(hlc3, "Source")
ob = input.float(80, "Upper reference", minval=0, maxval=100)
os = input.float(20, "Lower reference", minval=0, maxval=100)
showHist = input.bool(true, "Show columns from 50")
showMid = input.bool(true, "Show 50 midline")
if os >= ob
    runtime.error("Lower reference must be below upper reference.")
validBar = not na(src) and not na(src[1]) and src > 0 and src[1] > 0 and not na(volume) and volume >= 0
invalidCount = math.sum(validBar ? 0.0 : 1.0, length)
directionalFlow = validBar and src != src[1] ? src * volume : 0.0
flowTotal = math.sum(directionalFlow, length)
rawMfi = ta.mfi(src, length)
// Require a complete usable window and some classified flow.
mfi = invalidCount == 0 and flowTotal > 0 ? rawMfi : na
stateOb = not na(mfi) and mfi > ob
stateOs = not na(mfi) and mfi < os
rawOb = ta.crossover(mfi, ob)
rawOs = ta.crossunder(mfi, os)
rawMidUp = ta.crossover(mfi, 50)
rawMidDown = ta.crossunder(mfi, 50)
crossOb = barstate.isconfirmed and rawOb
crossOs = barstate.isconfirmed and rawOs
crossMid = barstate.isconfirmed and (rawMidUp or rawMidDown)
plot(mfi, "MFI", color=stateOb ? color.red : stateOs ? color.green : color.teal, linewidth=2)
hline(ob, "Upper reference", color=color.new(color.red, 40))
hline(os, "Lower reference", color=color.new(color.green, 40))
hline(50, "Mid", color=color.gray, linestyle=hline.style_dotted, display=showMid ? display.all : display.none)
plot(showHist ? mfi : na, "MFI columns from 50", style=plot.style_columns, histbase=50, color=mfi >= 50 ? color.new(color.teal, 70) : color.new(color.orange, 70))
plotshape(crossOb, "Upper cross", shape.triangledown, location.top, color.red, size=size.tiny)
plotshape(crossOs, "Lower cross", shape.triangleup, location.bottom, color.green, size=size.tiny)
bgcolor(crossMid ? color.new(color.blue, 92) : na)
rsi = ta.rsi(src, length)
plot(rsi, "RSI of same source - Data Window", display=display.data_window)
alertcondition(crossOb, "MFI upper reference cross", "MFI crossed above the selected upper reference at bar close.")
alertcondition(crossOs, "MFI lower reference cross", "MFI crossed below the selected lower reference at bar close.")
alertcondition(crossMid, "MFI midpoint cross", "MFI crossed 50 at bar close.")
var table summary = table.new(position.top_right, 1, 3)
if barstate.islast
    table.cell(summary, 0, 0, na(mfi) ? "MFI: unavailable" : "MFI: " + str.tostring(mfi, "#.##"))
    table.cell(summary, 0, 1, na(rsi) ? "RSI: unavailable" : "RSI: " + str.tostring(rsi, "#.##"))
    table.cell(summary, 0, 2, na(mfi) ? "Check history, positive source and volume" : stateOb ? "Above upper reference" : stateOs ? "Below lower reference" : "Between references (inclusive)")

Maintenance Note: The example uses chart volume and positive source prices, with a strict full-window data gate. Missing, negative-volume, nonpositive-price or zero-directional-flow windows display unavailable. Columns start at 50 on the same scale as the MFI line; RSI uses the same source in the Data Window. No trades, session filter or divergence detection are implemented.

Build with Pineify Visual Editor

Pineify lets you configure supported indicators and export Pine Script. Available settings and plan requirements vary by indicator. Compare the generated rules with the example before using its signals.

FeatureManual Pine ScriptPineify Visual Editor
MFI inputSet source and length in ta.mfi.The MFI module exposes Source and Length with hlc3 and 14 defaults.
Custom data rulesWrite validity gates and missing-value presentation.Ask AI Coding Agent for explicit data and alert rules, then review the source.
ValidationCompare matching windows, inputs and feed volume.Perform the same checks on generated output.

Configure the existing MFI module and inspect its output.

Use supported conditions for explicit threshold rules.

Request custom missing-data or display behavior from AI Coding Agent.

Step-by-Step Tutorial

1

Add the MFI module

Choose the source and length; the visual module defaults to hlc3 and 14.

2

Review the generated indicator

Inspect its line and band settings. This page’s strict data gate and table are custom code, not assumed module features.

3

Specify custom requirements

Ask AI Coding Agent for the intended data gate, closing confirmation and display behavior.

4

Compare before creating alerts

Match chart source, timeframe and volume feed, then inspect available and unavailable windows.

Trading Strategies & Pro Tips

Threshold event study

Hold source, length and dates fixed. Compare event counts for predeclared reference levels without treating fewer events as improved returns.

Data-quality comparison

Compare windows with valid zero volume, missing volume and unchanged prices. The strict gate deliberately suppresses unusable ratios.

Separate strategy test

If studying entries from MFI, define exits, costs, sizing and a later evaluation sample. This indicator supplies no performance result.

Common Mistakes to Avoid

  • Interpreting price-times-volume classification as actual buyer/seller aggressor data.
  • Reporting missing MFI as a neutral reading.
  • Treating unchanged source bars as both positive and negative flow.
  • Comparing tick-volume and traded-volume feeds without naming the difference.
  • Treating threshold crosses or indicator agreement as a profit guarantee.

Frequently Asked Questions

No. MFI sums source-times-volume amounts classified by source direction. RSI uses smoothed price changes. The example shows RSI of the same source, but the formulas remain different.

No. Its positive and negative flows are classifications of aggregated price and volume. They do not identify trade aggressors, investor identity or net fund inflows.

The example needs a full valid window with positive source prices, available nonnegative volume and positive total classified flow. Missing data and a zero directional-flow denominator are not a neutral signal.

When the selected source equals its prior value, that bar adds neither positive nor negative directional flow. A window containing only unchanged sources has no directional-flow ratio in this example.

No. The midline and columns have independent controls. Both use the same MFI scale, and the columns extend from 50 to the current value.

No. They are reference levels. Values can remain beyond them, and filters may remove useful as well as losing observations. A trading claim requires a separately specified and evaluated strategy.

Build an MFI rule with explicit data assumptions

  • Set source and length in the MFI module.
  • Define missing-data and confirmation rules for custom code.
  • Review the output against matching chart observations.

Disclaimer: Trading involves significant risk. The indicators, code, and strategies provided are for educational purposes only and do not constitute financial advice. Past performance is not indicative of future results.