Generate code in 3 minutes
Enter your idea and AI generates runnable code.
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.
//+------------------------------------------------------------------+
//| 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());
}
}
//+------------------------------------------------------------------+
iBWMFI Function: This is the native MQL4 function to retrieve the Market Facilitation Index. We compare index 1 (the last closed bar) with index 2 (the bar before that) to determine if MFI is rising.iVolume Function: Retrieves the tick volume. We compare index 1 and 2 to determine if Volume is rising.isGreenBar becomes true only if both MFI and Volume are higher than the previous bar. This indicates strong market participation facilitating price movement.iMA). We only buy if the price is above the MA and sell if it is below.OnInit function calculates m_point to ensure Stop Loss and Take Profit work correctly on both 4-digit and 5-digit brokers (e.g., JPY pairs).MFI_Volume_EA.mq4 in your MQL4/Experts folder.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.