OPEN-SOURCE SCRIPT

MFI Volume Profile [Kodexius]

156
The MFI Volume Profile indicator blends a classic volume profile with the Money Flow Index so you can see not only where volume traded, but also how strong the buying or selling pressure was at those prices. Instead of showing a simple horizontal histogram of volume, this tool adds a money flow dimension and turns the profile into a price volume momentum heat map.

The script scans a user controlled lookback window and builds a set of price levels between the lowest and highest price in that period. For every bar inside that window, its volume is distributed across the price levels that the bar actually touched, and that volume is combined with the bar’s MFI value. This creates a volume weighted average MFI for each price level, so every row of the profile knows both how much volume traded there and what the typical money flow condition was when that volume appeared.

On the chart, the indicator plots a stack of horizontal boxes to the right of current price. The length of each box represents the relative amount of volume at that price, while the color represents the average MFI there. Levels with stronger positive money flow will lean toward warmer shades, and levels with weaker or negative money flow will lean toward cooler or more neutral shades inside the configured MFI band. Each row is also labeled in the format Volume [MFI], so you can instantly read the exact volume and money flow value at that level instead of guessing.

This gives you a detailed map of where the market really cared about price, and whether that interest came with strong inflow or outflow. It can help you spot areas of accumulation, distribution, absorption, or exhaustion, and it does so in a compact visual that sits next to price without cluttering the candles themselves.

imagen

Features

Combined volume profile and MFI weighting

The indicator builds a volume profile over a user selected lookback and enriches each price row with a volume weighted average MFI. This lets you study both participation and money flow at the same price level.

Volume distributed across the bar price range

For every bar in the window, volume is not assigned to a single price. Instead, it is proportionally distributed across all price rows between the bar low and bar high. This creates a smoother and more realistic profile of where trading actually happened.

MFI based color gradient between 30 and 70

Each price row is colored according to its average MFI. The gradient is anchored between MFI values of 30 and 70, which covers typical oversold, neutral and overbought zones. This makes strong demand or distribution areas easier to spot visually.

Configurable structure resolution and depth

Main user inputs are the lookback length, the number of rows, the width of the profile in bars, and the label text size. You can quickly switch between coarse profiles for a big picture and higher resolution profiles for detailed structure.

Numeric labels with volume and MFI per row

Every box is labeled with the total volume at that level and the average MFI for that level, in the format Volume [MFI]. This gives you exact values while still keeping the visual profile clean and compact.

imagen

Calculations

Money Flow Index calculation

currentMfi is calculated once using ta.mfi(hlc3, mfiLen) as usual,

Creation of the profileBins array

The script creates an array named profileBins that will hold one VPBin element per price row.
Each VPBin contains

volume which is the total volume accumulated at that price row

mfiProduct which is the sum of volume multiplied by MFI for that row

The loop;

Pine Script®
for i = 0 to rowCount - 1 by 1 array.push(profileBins, VPBin.new(0.0, 0.0))


pre allocates a clean structure with zero values for all rows.

Finding highest and lowest price across the lookback

The script starts from the current bar high and low, then walks backward through the lookback window

Pine Script®
for i = 0 to lookback - 1 by 1 highestPrice := math.max(highestPrice, high) lowestPrice := math.min(lowestPrice, low)


After this loop, highestPrice and lowestPrice define the full price range covered by the chosen lookback.

Price range and step size for rows

The code computes

Pine Script®
float rangePrice = highestPrice - lowestPrice rangePrice := rangePrice == 0 ? syminfo.mintick : rangePrice float step = rangePrice / rowCount


rangePrice is the total height of the profile in price terms. If the range is zero, the script replaces it with the minimum tick size for the symbol. Then step is the price height of each row. This step size is used to map any price into a row index.

Processing each bar in the lookback

For every bar index i inside the lookback, the script checks that currentMfi is not missing. If it is valid, it reads the bar high, low, volume and MFI

Pine Script®
float barTop = high float barBottom = low float barVol = volume float barMfi = currentMfi


Mapping bar prices to bin indices
The bar high and low are converted into row indices using the known lowestPrice and step

Pine Script®
int indexTop = math.floor((barTop - lowestPrice) / step) int indexBottom = math.floor((barBottom - lowestPrice) / step)

Then the indices are clamped into valid bounds so they stay between zero and rowCount - 1. This ensures that every bar contributes only inside the profile range

Splitting bar volume across all covered bins

Once the top and bottom indices are known, the script calculates how many rows the bar spans
Pine Script®
int coveredBins = indexTop - indexBottom + 1 float volPerBin = barVol / coveredBins float mfiPerBin = volPerBin * barMfi

Here the total bar volume is divided equally across all rows that the bar touches. For each of those rows, the same fraction of volume and volume times MFI is used.

Accumulating into each VPBin

Finally, a nested loop iterates from indexBottom to indexTop and updates the corresponding VPBin
Pine Script®
for k = indexBottom to indexTop by 1 VPBin binData = array.get(profileBins, k) binData.volume := binData.volume + volPerBin binData.mfiProduct := binData.mfiProduct + mfiPerBin

Over all bars in the lookback window, each row builds up

total volume at that price range

total volume times MFI at that price range

Later, during the drawing stage, the script computes
Pine Script®
avgMfi = bin.mfiProduct / bin.volume

for each row. This is the volume weighted average MFI used both for coloring the box and for the numeric MFI value shown in the label Volume [MFI].

Exención de responsabilidad

La información y las publicaciones no constituyen, ni deben considerarse como asesoramiento o recomendaciones financieras, de inversión, de trading o de otro tipo proporcionadas o respaldadas por TradingView. Más información en Condiciones de uso.