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 written in MQL4.
This strategy implements a classic Mean Reversion logic:
//+------------------------------------------------------------------+
//| SimpleRSI_EA.mq4 |
//| Copyright 2023, Quantitative Trading AI |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative Trading AI"
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//--- Input Parameters
input double Lots = 0.1; // Fixed Lot Size
input int RSIPeriod = 14; // Period for RSI Indicator
input double Overbought = 70.0; // Level to trigger Sell
input double Oversold = 30.0; // Level to trigger Buy
input int StopLoss = 50; // Stop Loss in pips (0 = no SL)
input int TakeProfit = 100; // Take Profit in pips (0 = no TP)
input int MagicNumber = 123456; // Unique ID for this EA
input int Slippage = 3; // Max slippage allowed in pips
//--- Global Variables
double pipValue;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Adjust pip value for 3 or 5 digit brokers (Jpy pairs vs others)
if(Digits == 3 || Digits == 5)
pipValue = Point * 10;
else
pipValue = Point;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Clean up if necessary
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// 1. Check if we already have an open position for this symbol
if(CountOpenTrades() > 0) return;
// 2. Calculate RSI Value
// We use shift 1 (previous candle) to ensure the candle has closed and the signal is confirmed.
// Using shift 0 (current candle) can cause "repainting" where the signal disappears.
double rsiValue = iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE, 1);
// 3. Check Buy Condition (Oversold)
if(rsiValue < Oversold)
{
OpenTrade(OP_BUY);
}
// 4. Check Sell Condition (Overbought)
else if(rsiValue > Overbought)
{
OpenTrade(OP_SELL);
}
}
//+------------------------------------------------------------------+
//| Helper: Count Open Trades for this EA |
//+------------------------------------------------------------------+
int CountOpenTrades()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
// Check if the order belongs to this Symbol and this EA (MagicNumber)
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
count++;
}
}
}
return count;
}
//+------------------------------------------------------------------+
//| Helper: Open Order Execution |
//+------------------------------------------------------------------+
void OpenTrade(int type)
{
double price, sl, tp;
color arrowColor;
if(type == OP_BUY)
{
price = Ask;
sl = (StopLoss > 0) ? price - StopLoss * pipValue : 0;
tp = (TakeProfit > 0) ? price + TakeProfit * pipValue : 0;
arrowColor = clrBlue;
}
else // OP_SELL
{
price = Bid;
sl = (StopLoss > 0) ? price + StopLoss * pipValue : 0;
tp = (TakeProfit > 0) ? price - TakeProfit * pipValue : 0;
arrowColor = clrRed;
}
// Send the order
int ticket = OrderSend(Symbol(), type, Lots, price, Slippage, sl, tp, "RSI Strategy", MagicNumber, 0, arrowColor);
// Error handling
if(ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
}
//+------------------------------------------------------------------+
SimpleRSI.SimpleRSI in the Navigator panel under Expert Advisors.iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE, 1).
NULL: Uses the current symbol.0: Uses the current timeframe.1: This is the Shift. It looks at the previous candle (index 1) rather than the currently forming candle (index 0). This is crucial to prevent "repainting," where a trade opens but the RSI moves back to neutral before the candle closes.CountOpenTrades() function ensures the EA only opens one trade at a time. It will not open a new trade until the existing one hits Stop Loss or Take Profit.OnInit function automatically detects if your broker uses 4-digit or 5-digit pricing (e.g., 1.1234 vs 1.12345) to ensure the Stop Loss distance is calculated correctly.Q: Why does the strategy check CountOpenTrades() > 0?
A: Without this check, the EA would open a new order on every single tick (price change) as long as the RSI remains above 70 or below 30. This would flood your account with hundreds of orders in a few minutes. This logic restricts it to one active position per symbol.
Q: Can this strategy work on ECN brokers?
A: The code provided uses standard OrderSend with SL and TP attached immediately. Some strict ECN brokers require you to open the trade with 0 SL/TP first, and then use OrderModify to add them. However, most modern MT4 bridges handle the standard code automatically.
Q: What are the risks of this specific RSI strategy?
A: This is a Mean Reversion strategy. It assumes price will return to the average.
Q: How do I optimize the parameters?
A: In MT4, go to View -> Strategy Tester. Select this EA, choose a symbol and timeframe. Click "Expert properties" and go to the "Inputs" tab. You can check the boxes next to RSIPeriod, StopLoss, or TakeProfit to let MT4 run thousands of simulations to find the most profitable settings for historical data.