Problem Description
Solution
Here is a complete, fully functional Expert Advisor (EA) for MetaTrader 4.
This strategy utilizes Bill Williams' Market Facilitation Index (MFI) combined with Volume to identify "Green" bars. A Green Bar occurs when both MFI and Volume increase, indicating that the market is moving directionally and new players are entering the market.
Strategy Logic
- Green Bar Condition: Current MFI > Previous MFI AND Current Volume > Previous Volume.
- Trend Filter: A Simple Moving Average (SMA) is used to determine the overall trend direction.
- Buy Signal: Green Bar formed + Close Price > Moving Average + Bullish Candle.
- Sell Signal: Green Bar formed + Close Price < Moving Average + Bearish Candle.
MQL4 Code
//+------------------------------------------------------------------+
//| MFI_Volume_EA.mq4 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative AI"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//--- Input Parameters
input double InpLots = 0.1; // Lot Size
input int InpStopLoss = 50; // Stop Loss in points
input int InpTakeProfit = 100; // Take Profit in points
input int InpMagicNumber = 123456; // Magic Number ID
input int InpMAPeriod = 50; // Moving Average Period (Trend Filter)
input int InpSlippage = 3; // Max Slippage in points
//--- Global Variables
double m_point;
int m_digits;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Adjust point values for 3/5 digit brokers
if(Digits == 3 || Digits == 5)
{
m_point = Point * 10;
m_digits = Digits;
}
else
{
m_point = Point;
m_digits = Digits;
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Clean up if necessary
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Check if we have enough bars to calculate
if(Bars < InpMAPeriod + 2) return;
// Define shift (1 = closed bar, 0 = current forming bar)
// We use 1 and 2 to ensure we trade on confirmed signals
int shiftCurr = 1;
int shiftPrev = 2;
// --- 1. Get MFI Values ---
double mfiCurr = iBWMFI(NULL, 0, shiftCurr);
double mfiPrev = iBWMFI(NULL, 0, shiftPrev);
// --- 2. Get Volume Values ---
long volCurr = iVolume(NULL, 0, shiftCurr);
long volPrev = iVolume(NULL, 0, shiftPrev);
// --- 3. Get Trend Filter (MA) ---
double maValue = iMA(NULL, 0, InpMAPeriod, 0, MODE_SMA, PRICE_CLOSE, shiftCurr);
double closePrice = iClose(NULL, 0, shiftCurr);
double openPrice = iOpen(NULL, 0, shiftCurr);
// --- 4. Determine "Green Bar" State ---
// Green Bar: MFI is UP and Volume is UP
bool isGreenBar = (mfiCurr > mfiPrev) && (volCurr > volPrev);
// --- 5. Check for Open Positions ---
if(CountOrders() == 0)
{
// --- Buy Logic ---
// Green Bar + Price above MA + Bullish Candle
if(isGreenBar && closePrice > maValue && closePrice > openPrice)
{
OpenTrade(OP_BUY);
}
// --- Sell Logic ---
// Green Bar + Price below MA + Bearish Candle
else if(isGreenBar && closePrice < maValue && closePrice < openPrice)
{
OpenTrade(OP_SELL);
}
}
}
//+------------------------------------------------------------------+
//| Helper: Count Open Orders for this EA |
//+------------------------------------------------------------------+
int CountOrders()
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == InpMagicNumber)
{
count++;
}
}
}
return(count);
}
//+------------------------------------------------------------------+
//| Helper: Open Trade Execution |
//+------------------------------------------------------------------+
void OpenTrade(int type)
{
double price, sl, tp;
color clr;
if(type == OP_BUY)
{
price = Ask;
sl = (InpStopLoss > 0) ? price - InpStopLoss * m_point : 0;
tp = (InpTakeProfit > 0) ? price + InpTakeProfit * m_point : 0;
clr = clrBlue;
}
else
{
price = Bid;
sl = (InpStopLoss > 0) ? price + InpStopLoss * m_point : 0;
tp = (InpTakeProfit > 0) ? price - InpTakeProfit * m_point : 0;
clr = clrRed;
}
// Normalize prices
price = NormalizeDouble(price, m_digits);
sl = NormalizeDouble(sl, m_digits);
tp = NormalizeDouble(tp, m_digits);
// Send Order
int ticket = OrderSend(Symbol(), type, InpLots, price, InpSlippage, sl, tp, "MFI_Vol_EA", InpMagicNumber, 0, clr);
if(ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
}
//+------------------------------------------------------------------+
Key Components Explained
iBWMFIFunction: This is the native MQL4 function to retrieve the Market Facilitation Index. We compare index1(the last closed bar) with index2(the bar before that) to determine if MFI is rising.iVolumeFunction: Retrieves the tick volume. We compare index1and2to determine if Volume is rising.- Green Bar Logic: The boolean variable
isGreenBarbecomes true only if both MFI and Volume are higher than the previous bar. This indicates strong market participation facilitating price movement. - Trend Filter: To avoid entering during choppy "Squat" bars or counter-trend corrections, we use a Simple Moving Average (
iMA). We only buy if the price is above the MA and sell if it is below. - Point Adjustment: The
OnInitfunction calculatesm_pointto ensure Stop Loss and Take Profit work correctly on both 4-digit and 5-digit brokers (e.g., JPY pairs).
How to Test
- Save the code as
MFI_Volume_EA.mq4in yourMQL4/Expertsfolder. - Compile it in MetaEditor.
- Open the Strategy Tester in MT4 (Ctrl+R).
- Select the EA, choose a symbol (e.g., EURUSD), and a timeframe (H1 or H4 is recommended for Bill Williams' strategies).
- Start the test.
Q&A
Q: What is the significance of a "Green" bar in this strategy?
A: A Green bar (MFI Up, Volume Up) signifies that the market is moving freely and new volume is entering the market to support that move. It is generally considered a trend continuation signal.
Q: Why is a Moving Average included in the code?
A: MFI and Volume are volatility and momentum indicators, not directional indicators. Without the Moving Average, the EA might buy a Green bar that occurs during a bearish retracement. The MA ensures we trade in the direction of the broader trend.
Q: Can I use this on any timeframe?
A: Yes, the code is timeframe independent. However, Volume/MFI strategies tend to generate fewer false signals on H1, H4, and Daily charts compared to M1 or M5 due to market noise.
Q: How does the EA handle 5-digit brokers?
A: The code includes a logic block in OnInit that detects if Digits is 3 or 5. It adjusts the m_point multiplier by 10, so a 50-point Stop Loss entered in the inputs remains 50 pips (500 points) or 5 pips (50 points) depending on your intent, ensuring consistency.