Author: Copyright � 2004, MetaQuotes Software Corp.
BW_MFI

The Market Facilitation Index (MFI) is a technical analysis tool designed to help traders understand the relationship between price movement and trading volume. By analyzing how much "effort" (volume) is required to produce a specific "result" (price change), the script categorizes market activity into four distinct behavioral states.

Core Logic and Calculations

The script functions by measuring the range of price action—the distance between the highest and lowest points reached during a specific period—and dividing that figure by the total volume traded during that same timeframe. Essentially, it calculates how much price moved for every unit of volume exchanged.

Market Behavior Categories

To make this data actionable, the script evaluates two simultaneous factors: whether the MFI value is increasing/decreasing and whether the trading volume is increasing/decreasing. Based on these combinations, the indicator visualizes four specific market conditions:

  • Strong Momentum (Upward Move / Increasing Volume): This occurs when both the price movement and the volume are rising together. It suggests a healthy, high-conviction trend where buyers or sellers are aggressively pushing the market in a single direction.
  • Weak Momentum (Downward Move / Decreasing Volume): This identifies situations where price is falling but trading activity is drying up. It may indicate a lack of interest or exhaustion in the current move.
  • Price Expansion (Upward Move / Decreasing Volume): Here, the price continues to climb even though volume is dropping. This often suggests that the move is becoming "thin" and might be reaching a point of fatigue or a potential reversal, as it takes less effort to move the price.
  • Price Compression (Downward Move / Increasing Volume): This occurs when volume spikes while the price range remains small or moves downward. This signifies high "effort" but low "result," often interpreted as a sign of intense distribution or heavy resistance where the market is struggling to break out.

Visual Representation

Instead of showing raw numbers, the script organizes these four states into a multi-colored histogram. This allows traders to quickly identify shifts in market sentiment at a glance, distinguishing between high-conviction trends and periods of uncertainty or exhaustion.

Miscellaneous
Implements a curve of type %1
15 Views
0 Downloads
0 Favorites
BW_MFI
//+------------------------------------------------------------------+
//|                                 BW Market Facilitation Index.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#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  Lime
#property indicator_color3  SaddleBrown
#property indicator_color4  Blue
#property indicator_color5  Pink
#property indicator_width2  2
#property indicator_width3  2
#property indicator_width4  2
#property indicator_width5  2
//---- indicator buffers
double ExtMFIBuffer[];
double ExtMFIUpVUpBuffer[];
double ExtMFIDownVDownBuffer[];
double ExtMFIUpVDownBuffer[];
double ExtMFIDownVUpBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMFIBuffer);       
   SetIndexBuffer(1,ExtMFIUpVUpBuffer);
   SetIndexBuffer(2,ExtMFIDownVDownBuffer);
   SetIndexBuffer(3,ExtMFIUpVDownBuffer);
   SetIndexBuffer(4,ExtMFIDownVUpBuffer);
//---- 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");
   SetIndexLabel(0,"BW MFI");      
   SetIndexLabel(1,NULL);
   SetIndexLabel(2,NULL);
   SetIndexLabel(3,NULL);
   SetIndexLabel(4,NULL);
//---- sets drawing line empty value
   SetIndexEmptyValue(0, 0.0);
   SetIndexEmptyValue(1, 0.0);
   SetIndexEmptyValue(2, 0.0);       
   SetIndexEmptyValue(3, 0.0);
   SetIndexEmptyValue(4, 0.0);      
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//| BW Market Facilitation Index                                     |
//+------------------------------------------------------------------+
int start()
  {
   int  i,nLimit,nCountedBars;
   bool bMfiUp=true,bVolUp=true;
//---- 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(CompareDouble(Volume[i],0.0))
        {
         Print(Volume[i]);
         if(i==Bars-1) ExtMFIBuffer[i]=0.0;
         else ExtMFIBuffer[i]=ExtMFIBuffer[i+1];
        }
      else ExtMFIBuffer[i]=(High[i]-Low[i])/(Volume[i]*Point);
     }
//---- upanddown flags setting
   if(nCountedBars>1)
     {
      //---- analyze previous bar before recounted bar
      i=nLimit+1;
      if(ExtMFIUpVUpBuffer[i]!=0.0)
        {
         bMfiUp=true;
         bVolUp=true;
        }
      if(ExtMFIDownVDownBuffer[i]!=0.0)
        {
         bMfiUp=false;
         bVolUp=false;
        }
      if(ExtMFIUpVDownBuffer[i]!=0.0)
        {
         bMfiUp=true;
         bVolUp=false;
        }
      if(ExtMFIDownVUpBuffer[i]!=0.0)
        {
         bMfiUp=false;
         bVolUp=true;
        }
     }
//---- dispatch values between 4 buffers
   for(i=nLimit-1; i>=0; i--)
     {
      if(i<Bars-1)
        {
         if(ExtMFIBuffer[i]>ExtMFIBuffer[i+1]) bMfiUp=true;
         if(ExtMFIBuffer[i]<ExtMFIBuffer[i+1]) bMfiUp=false;
         if(Volume[i]>Volume[i+1])             bVolUp=true;
         if(Volume[i]<Volume[i+1])             bVolUp=false;
        }
     if(bMfiUp && bVolUp)
       {
        ExtMFIUpVUpBuffer[i]=ExtMFIBuffer[i];
        ExtMFIDownVDownBuffer[i]=0.0;
        ExtMFIUpVDownBuffer[i]=0.0;
        ExtMFIDownVUpBuffer[i]=0.0;
        continue;
       }
     if(!bMfiUp && !bVolUp)
       {
        ExtMFIUpVUpBuffer[i]=0.0;
        ExtMFIDownVDownBuffer[i]=ExtMFIBuffer[i];
        ExtMFIUpVDownBuffer[i]=0.0;
        ExtMFIDownVUpBuffer[i]=0.0;
        continue;         
       }
     if(bMfiUp && !bVolUp)
       {
        ExtMFIUpVUpBuffer[i]=0.0;
        ExtMFIDownVDownBuffer[i]=0.0;
        ExtMFIUpVDownBuffer[i]=ExtMFIBuffer[i];
        ExtMFIDownVUpBuffer[i]=0.0;
        continue;         
       }
     if(!bMfiUp && bVolUp)
       {
        ExtMFIUpVUpBuffer[i]=0.0;
        ExtMFIDownVDownBuffer[i]=0.0;
        ExtMFIUpVDownBuffer[i]=0.0;
        ExtMFIDownVUpBuffer[i]=ExtMFIBuffer[i];
        continue;         
       }        
    }                     
//---- done
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CompareDouble(double dNumber1, double dNumber2)
  {
   bool bCompare=NormalizeDouble(dNumber1-dNumber2,8) == 0;
   return(bCompare);
  }
//+------------------------------------------------------------------+

Comments