BW_MFI+Volumes
Download scriptOverview of the BW Market Facilitation Index (MFI) with Volumes
This script is designed to provide traders with a visual representation of market activity by analyzing the relationship between price movement and trading volume. Instead of looking at just one metric, it evaluates how much "effort" (volume) is being expended to achieve a specific "result" (price change).
Core Logic and Calculations
The tool operates through a two-step logical process:
1. Calculating the Market Facilitation Index (MFI)
The primary calculation determines the MFI value for each period on the chart. It does this by taking the total price range (the difference between the highest and lowest price) and dividing it by the volume of trades occurring in that same timeframe.
In simple terms, this tells you how much price "ground" was covered per unit of volume.
- A high MFI suggests that the price is moving significantly with relatively low effort (volume).
- A low MFI suggests that it is taking a massive amount of volume to move the price only a small amount, often indicating high resistance or heavy competition.
2. Classifying Market Behavior
Once the MFI is calculated, the script compares the current value against previous values and looks at the volume trends to categorize the market into four distinct types of behavior. These are displayed as different colored histograms:
- Upward Momentum (Green): Occurs when the MFI is increasing while volume is also increasing. This suggests a strong, healthy trend where buyers are aggressively pushing the price upward with significant conviction.
- Downward Momentum (Red): Occurs when the MFI is decreasing while volume is also increasing. This typically indicates that selling pressure is overwhelming, and it is taking a lot of volume to push the price down.
- Accelerating Trend (Gold): This identifies scenarios where the price move is becoming more efficient. It highlights periods where the MFI is rising but the volume is decreasing—meaning the price is moving "easier" as the trend gains momentum.
- Decelerating Trend (Blue): This identifies signs of exhaustion or heavy resistance. It highlights periods where the MFI is falling while volume is decreasing, suggesting that the current move is losing steam and requires less effort to maintain.
Summary for the User
By combining these two data points—Price Efficiency and Volume—the script helps you identify whether a market move is supported by strong participation, if it is becoming exhausted, or if there is a significant imbalance between the amount of trading activity and the actual price movement. This allows for a clearer picture of market "health" than looking at price alone.
//+------------------------------------------------------------------+
//| BW Market Facilitation Index.mq4 |
//| îáúåäèíåííûé ñ Volumes |
//| Copyright © 2005, MetaQuotes Software Corp. |
//| http://www.metaquotes.net/ |
//| Äîðàáîòêà AlexSilver http://viac.ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net/"
//---- indicator settings
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_buffers 5
#property indicator_color1 Black
#property indicator_color2 Green // Çåëåíàÿ ñâå÷à
#property indicator_color3 Blue // Óãàñàþùàÿ
#property indicator_color4 Gold // Ôàëüøèâàÿ
#property indicator_color5 Red // ïðèñåäàþùàÿ
//---- indicator buffers
double dMFIBuffer[];
double dMFIUpVUpBuffer[]; // Çåëåíàÿ
double dMFIDownVDownBuffer[]; // Óãàñàþùàÿ
double dMFIUpVDownBuffer[]; // Ôàëüøèâàÿ
double dMFIDownVUpBuffer[]; // ïðèñåäàþùàÿ
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicator buffers mapping
SetIndexBuffer(0,dMFIBuffer);
SetIndexBuffer(1,dMFIUpVUpBuffer);
SetIndexBuffer(2,dMFIDownVDownBuffer);
SetIndexBuffer(3,dMFIUpVDownBuffer);
SetIndexBuffer(4,dMFIDownVUpBuffer);
//---- drawing settings
SetIndexStyle(0,DRAW_NONE);
SetIndexStyle(1,DRAW_HISTOGRAM);
SetIndexStyle(2,DRAW_HISTOGRAM);
SetIndexStyle(3,DRAW_HISTOGRAM);
SetIndexStyle(4,DRAW_HISTOGRAM);
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("BW MFI + Volumes");
SetIndexLabel(0,"BW MFI");
SetIndexLabel(1,"Çåë¸íûé");
SetIndexLabel(2,"Óãàñàþùèé");
SetIndexLabel(3,"Ôàëüøèâûé");
SetIndexLabel(4,"Ïðèñåäàþùèé");
//---- sets drawing line empty value
SetIndexEmptyValue(1, 0.0);
SetIndexEmptyValue(2, 0.0);
SetIndexEmptyValue(3, 0.0);
SetIndexEmptyValue(4, 0.0);
IndicatorDigits(0);
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| BW Market Facilitation Index |
//+------------------------------------------------------------------+
int start()
{
int i,nLimit,nCountedBars;
//---- bars count that does not changed after last indicator launch.
nCountedBars=IndicatorCounted();
//---- last counted bar will be recounted
if(nCountedBars>0) nCountedBars--;
nLimit=Bars-nCountedBars;
//---- Market Facilitation Index calculation
for(i=0; i<nLimit; i++)
if(i==0 && Volume[i]<Period()*1.5)
dMFIBuffer[i]=0.0;
else
dMFIBuffer[i]=(High[i]-Low[i])/(Volume[i]*Point);
//---- dispatch values between 4 buffers
for(i=nLimit-1; i>=0; i--)
{
if((i!=nLimit-1&&bCompareDouble(dMFIBuffer[i],dMFIBuffer[i+1])&&dMFIBuffer[i]>dMFIBuffer[i+2]&&Volume[i]>Volume[i+1])||
(i!=nLimit-1&&dMFIBuffer[i]>dMFIBuffer[i+1]&&Volume[i]==Volume[i+1]&&Volume[i]>Volume[i+2])||
(i<nLimit-2&&dMFIBuffer[i]>dMFIBuffer[i+1]&&Volume[i]==Volume[i+1]&&Volume[i]==Volume[i+2]&&Volume[i]>Volume[i+3])||
(i!=nLimit-1&&bCompareDouble(dMFIBuffer[i],dMFIBuffer[i+1])&&dMFIBuffer[i]>dMFIBuffer[i+2]&&Volume[i]==Volume[i+1]&&Volume[i]>Volume[i+2])||
(dMFIBuffer[i]>dMFIBuffer[i+1]&&Volume[i]>Volume[i+1]))
{
dMFIUpVUpBuffer[i]=Volume[i];
dMFIDownVDownBuffer[i]=0.0;
dMFIUpVDownBuffer[i]=0.0;
dMFIDownVUpBuffer[i]=0.0;
continue;
}
if((i!=nLimit-1&&bCompareDouble(dMFIBuffer[i],dMFIBuffer[i+1])&&dMFIBuffer[i]<dMFIBuffer[i+2]&&Volume[i]<Volume[i+1])||
(i!=nLimit-1&&dMFIBuffer[i]<dMFIBuffer[i+1]&&Volume[i]==Volume[i+1]&&Volume[i]<Volume[i+2])||
(i<nLimit-2&&dMFIBuffer[i]<dMFIBuffer[i+1]&&Volume[i]==Volume[i+1]&&Volume[i]==Volume[i+2]&&Volume[i]<Volume[i+3])||
(i!=nLimit-1&&bCompareDouble(dMFIBuffer[i],dMFIBuffer[i+1])&&dMFIBuffer[i]<dMFIBuffer[i+2]&&Volume[i]==Volume[i+1]&&Volume[i]<Volume[i+2])||
(dMFIBuffer[i]<dMFIBuffer[i+1]&&Volume[i]<Volume[i+1]))
{
dMFIUpVUpBuffer[i]=0.0;
dMFIDownVDownBuffer[i]=Volume[i];
dMFIUpVDownBuffer[i]=0.0;
dMFIDownVUpBuffer[i]=0.0;
continue;
}
if((i!=nLimit-1&&bCompareDouble(dMFIBuffer[i],dMFIBuffer[i+1])&&dMFIBuffer[i]>dMFIBuffer[i+2]&&Volume[i]<Volume[i+1])||
(i!=nLimit-1&&dMFIBuffer[i]>dMFIBuffer[i+1]&&Volume[i]==Volume[i+1]&&Volume[i]<Volume[i+2])||
(i<nLimit-2&&dMFIBuffer[i]>dMFIBuffer[i+1]&&Volume[i]==Volume[i+1]&&Volume[i]==Volume[i+2]&&Volume[i]<Volume[i+3])||
(i!=nLimit-1&&bCompareDouble(dMFIBuffer[i],dMFIBuffer[i+1])&&dMFIBuffer[i]>dMFIBuffer[i+2]&&Volume[i]==Volume[i+1]&&Volume[i]<Volume[i+2])||
(dMFIBuffer[i]>dMFIBuffer[i+1]&&Volume[i]<Volume[i+1]))
{
dMFIUpVUpBuffer[i]=0.0;
dMFIDownVDownBuffer[i]=0.0;
dMFIUpVDownBuffer[i]=Volume[i];
dMFIDownVUpBuffer[i]=0.0;
continue;
}
if((i!=nLimit-1&&bCompareDouble(dMFIBuffer[i],dMFIBuffer[i+1])&&dMFIBuffer[i]<dMFIBuffer[i+2]&&Volume[i]>Volume[i+1])||
(i!=nLimit-1&&dMFIBuffer[i]<dMFIBuffer[i+1]&&Volume[i]==Volume[i+1]&&Volume[i]>Volume[i+2])||
(i<nLimit-2&&dMFIBuffer[i]<dMFIBuffer[i+1]&&Volume[i]==Volume[i+1]&&Volume[i]==Volume[i+2]&&Volume[i]>Volume[i+3])||
(i!=nLimit-1&&bCompareDouble(dMFIBuffer[i],dMFIBuffer[i+1])&&dMFIBuffer[i]<dMFIBuffer[i+2]&&Volume[i]==Volume[i+1]&&Volume[i]>Volume[i+2])||
(dMFIBuffer[i]<dMFIBuffer[i+1]&&Volume[i]>Volume[i+1]))
{
dMFIUpVUpBuffer[i]=0.0;
dMFIDownVDownBuffer[i]=0.0;
dMFIUpVDownBuffer[i]=0.0;
dMFIDownVUpBuffer[i]=Volume[i];
continue;
}
}
//---- done
return(0);
}
//+------------------------------------------------------------------+
bool bCompareDouble (double dNumber1, double dNumber2)
{
bool bCompare=NormalizeDouble(dNumber1 - dNumber2,8) == 0;
return(bCompare);
}
Comments