Pine Script Money Flow Index (MFI)

Master this unique volume-weighted momentum oscillator in TradingView's Pine Script for identifying shifts in money flow, overbought/oversold conditions, and divergence.

Last Updated on: Expertise: Intermediate

What is the Money Flow Index (MFI)?

The Money Flow Index (MFI) is a technical oscillator that measures the strength of money flowing into and out of an asset. It is similar to the Relative Strength Index (RSI) but incorporates volume data, making it a "volume-weighted RSI." MFI oscillates between 0 and 100. It's often used to identify overbought and oversold conditions, signal potential trend reversals, and confirm trend strength by showing the conviction behind price movements.

In Pine Script, MFI is a valuable tool for traders seeking to understand whether purchasing or selling pressure is dominant, providing insights into buying and selling enthusiasm validated by volume.

Components and Calculation

The calculation of MFI involves several steps, integrating both price and volume:

  1. Typical Price (TP): `(High + Low + Close) / 3`
  2. Raw Money Flow (RMF): `Typical Price * Volume`
  3. Positive Money Flow (PMF): Sum of all `Raw Money Flow` values where the `Typical Price` is greater than the previous bar's `Typical Price` over the `length` period.
  4. Negative Money Flow (NMF): Sum of all `Raw Money Flow` values where the `Typical Price` is less than the previous bar's `Typical Price` over the `length` period.
  5. Money Ratio (MR): `PMF / NMF`
  6. Money Flow Index (MFI) Formula: `MFI = 100 - (100 / (1 + Money Ratio))`

If `NMF` is zero, `MR` will be infinite, and `MFI` will be 100. If `PMF` is zero, `MR` will be zero, and `MFI` will be 0.

Basic Money Flow Index (MFI) Implementation in Pine Script

Pine Script v5 provides a straightforward built-in function `ta.mfi()` for calculating the Money Flow Index.

//@version=5
indicator("My MFI Indicator", overlay=false) // overlay=false to plot in a separate pane

// Input for MFI length
length = input.int(14, title="MFI Length", minval=1)

// Calculate MFI value using the built-in function
// ta.mfi takes the source (usually close), high, low, and volume
mfiValue = ta.mfi(close, high, low, volume, length)

// Plot the MFI line
plot(mfiValue, title="MFI", color=color.blue, linewidth=2)

// Plot horizontal lines for overbought and oversold levels
h_overbought = hline(80, "Overbought (80)", color.red, linestyle=hline.style_dashed)
h_oversold = hline(20, "Oversold (20)", color.green, linestyle=hline.style_dashed)
hline(50, "Centerline", color.gray, linestyle=hline.style_dotted)

// Fill background between MFI and levels for visual clarity
fill(h_overbought, h_oversold, color.new(color.gray, 90))
Standard Levels: The conventional overbought level is 80 and the oversold level is 20.

Practical MFI Trading Strategies

1. Overbought and Oversold Conditions

When MFI moves above 80, the asset is considered overbought, suggesting an excessive inflow of money that might lead to a price correction. When MFI moves below 20, it's considered oversold, indicating an excessive outflow of money that might lead to a bounce.

//@version=5
strategy("MFI Overbought/Oversold Strategy", overlay=true)

// Inputs for MFI
length = input.int(14, title="MFI Length", minval=1)
overboughtLevel = input.int(80, title="Overbought Level")
oversoldLevel = input.int(20, title="Oversold Level")

// Calculate MFI
mfiValue = ta.mfi(close, high, low, volume, length)

// Define conditions for entries and exits
// Buy when MFI goes oversold and then crosses back above the oversold level
longCondition = ta.crossunder(mfiValue, oversoldLevel)
longExitCondition = ta.crossover(mfiValue, oversoldLevel)

// Sell when MFI goes overbought and then crosses back below the overbought level
shortCondition = ta.crossover(mfiValue, overboughtLevel)
shortExitCondition = ta.crossunder(mfiValue, overboughtLevel)

// Strategy entries/exits (entry upon exiting extreme zones)
if (longExitCondition)
    strategy.entry("Long", strategy.long)

if (shortExitCondition)
    strategy.entry("Short", strategy.short)

// Optional: Plot MFI in a separate pane for visualization
// plot(mfiValue, "MFI", color.blue)
// hline(overboughtLevel, "Overbought", color.red)
// hline(oversoldLevel, "Oversold", color.green)
// hline(50, "Centerline", color.gray)

2. MFI Divergence Strategy (Key Signal)

Divergence between price and MFI is considered a strong signal, as it incorporates volume to confirm the underlying momentum. It suggests that the current trend is weakening despite price action.

//@version=5
indicator("MFI Divergence Scanner", overlay=true)

// Inputs for MFI
length = input.int(14, title="MFI Length", minval=1)
overboughtLevel = input.int(80, title="Overbought Level")
oversoldLevel = input.int(20, title="Oversold Level")
centerLine = input.int(50, title="Centerline")

// Calculate MFI
mfiValue = ta.mfi(close, high, low, volume, length)

// Plot MFI in a separate pane
plot(mfiValue, "MFI", color.blue)
hline(overboughtLevel, "Overbought (80)", color.red)
hline(oversoldLevel, "Oversold (20)", color.green)
hline(centerLine, "Centerline (50)", color.gray)

// Simple divergence detection (conceptual, robust detection requires advanced pivot logic)
// This is a simplified example focusing on price vs MFI divergence.

// Bullish Divergence (Price lower low, MFI higher low)
bullishDivergence = close[2] > close[1] and close[1] > close and mfiValue[2] < mfiValue[1] and mfiValue[1] < mfiValue

// Bearish Divergence (Price higher high, MFI lower high)
bearishDivergence = close[2] < close[1] and close[1] < close and mfiValue[2] > mfiValue[1] and mfiValue[1] > mfiValue

plotshape(bullishDivergence, title="Bullish Divergence", location=location.belowbar, color=color.green, style=shape.triangleup, size=size.small)
plotshape(bearishDivergence, title="Bearish Divergence", location=location.abovebar, color=color.red, style=shape.triangledown, size=size.small)

alertcondition(bullishDivergence, "Bullish MFI Divergence", "Potential bullish reversal based on MFI divergence.")
alertcondition(bearishDivergence, "Bearish MFI Divergence", "Potential bearish reversal based on MFI divergence.")

3. MFI Zero Line (50) Crossover

While MFI is typically used with overbought/oversold levels, the 50-line can act as a momentum centerline. Crossing above 50 suggests a shift towards positive money flow and bullish momentum, while crossing below 50 suggests increasing negative money flow and bearish momentum.

//@version=5
strategy("MFI Zero Line Crossover Strategy", overlay=true)

// Inputs for MFI
length = input.int(14, title="MFI Length", minval=1)
centerLine = input.int(50, title="Centerline")

// Calculate MFI
mfiValue = ta.mfi(close, high, low, volume, length)

// Define conditions for entries
longSignal = ta.crossover(mfiValue, centerLine)
shortSignal = ta.crossunder(mfiValue, centerLine)

// Strategy entries/exits
if (longSignal)
    strategy.entry("Long", strategy.long)

if (shortSignal)
    strategy.entry("Short", strategy.short)

// Optional: Plot MFI in a separate pane
// plot(mfiValue, "MFI", color.blue)
// hline(centerLine, "Centerline", color.gray)

Optimizing MFI Performance

To get the most from the Money Flow Index in Pine Script:

Volume is Key: MFI's integration of volume provides a unique advantage over purely price-based momentum oscillators like RSI, offering greater conviction behind signals.

Common MFI Pitfalls

Conclusion

The Money Flow Index (MFI) is a robust and highly insightful momentum oscillator in Pine Script for TradingView. Its unique integration of volume data provides a clearer and more convicted view of money flowing into and out of an asset, making it invaluable for identifying overbought/oversold conditions, assessing trend strength, and spotting powerful reversals through divergence. By understanding its calculation, thoughtfully tuning its parameters, and integrating it strategically with other technical analysis tools, you can leverage the MFI to gain deeper insights into market dynamics and enhance your trading decisions.