🚀 AI One-Click Generation of mql4 Strategy Code

How to Build a Confirmation Strategy EA in Mql4 (RSI + MA)

mql4 | Published on: 2025/12/10
The following content is generated by EasyQuant .

Problem Description

Write a trading strategy that enters a buy trade only when the RSI is above 50 AND a fast moving average crosses above a slow one.

Solution

Here is the complete MQL4 code for an Expert Advisor (EA) based on your specific requirements.

Strategy Logic

  1. RSI Filter: The Relative Strength Index (RSI) on the previous closed candle must be greater than 50.
  2. MA Crossover: The Fast Moving Average must cross above the Slow Moving Average. This is detected by checking if the Fast MA was below or equal to the Slow MA two candles ago, and is above it on the most recently closed candle.
  3. Execution: If both conditions are met and there are no currently open buy positions, a Buy order is placed with Stop Loss and Take Profit.

MQL4 Code

//+------------------------------------------------------------------+
//|                                            RSI_MA_Crossover_Buy.mq4 |
//|                        Copyright 2023, Quantitative Trading Assistant |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Quantitative Trading Assistant"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//--- Input Parameters
input double LotSize         = 0.1;      // Trade Volume
input int    FastMAPeriod    = 12;       // Fast Moving Average Period
input int    SlowMAPeriod    = 26;       // Slow Moving Average Period
input int    MAMethod        = 0;        // MA Method (0=SMA, 1=EMA, 2=SMMA, 3=LWMA)
input int    RSIPeriod       = 14;       // RSI Period
input double RSI_Level       = 50.0;     // RSI Threshold Level
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 Identifier for this EA
input int    Slippage        = 3;        // Max Slippage in points

//--- Global Variables
double pipMultiplier;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Adjust pip multiplier for 3 or 5 digit brokers (Jpy vs others)
   if(Digits == 3 || Digits == 5)
      pipMultiplier = 10;
   else
      pipMultiplier = 1;
      
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   // 1. Check if we already have an open Buy position for this symbol
   if(CountOpenBuyPositions() > 0) return;

   // 2. Define Shift Indices
   // We use shift 1 (previous closed bar) and shift 2 (bar before that)
   // to confirm a crossover has completed.
   int shift_curr = 1;
   int shift_prev = 2;

   // 3. Calculate Indicator Values
   
   // Fast MA
   double fastMA_curr = iMA(NULL, 0, FastMAPeriod, 0, MAMethod, PRICE_CLOSE, shift_curr);
   double fastMA_prev = iMA(NULL, 0, FastMAPeriod, 0, MAMethod, PRICE_CLOSE, shift_prev);
   
   // Slow MA
   double slowMA_curr = iMA(NULL, 0, SlowMAPeriod, 0, MAMethod, PRICE_CLOSE, shift_curr);
   double slowMA_prev = iMA(NULL, 0, SlowMAPeriod, 0, MAMethod, PRICE_CLOSE, shift_prev);
   
   // RSI
   double rsiValue = iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE, shift_curr);

   // 4. Check Strategy Conditions
   
   // Condition A: RSI > 50
   bool isRSIValid = (rsiValue > RSI_Level);
   
   // Condition B: Fast MA Crosses Above Slow MA
   // (Fast was below/equal to Slow previously, and is now above)
   bool isCrossoverUp = (fastMA_prev <= slowMA_prev) && (fastMA_curr > slowMA_curr);

   // 5. Execute Trade
   if(isRSIValid && isCrossoverUp)
   {
      OpenBuyOrder();
   }
}

//+------------------------------------------------------------------+
//| Helper: Count Open Buy Positions                                 |
//+------------------------------------------------------------------+
int CountOpenBuyPositions()
{
   int count = 0;
   for(int i = 0; i < OrdersTotal(); i++)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            if(OrderType() == OP_BUY) count++;
         }
      }
   }
   return count;
}

//+------------------------------------------------------------------+
//| Helper: Open Buy Order                                           |
//+------------------------------------------------------------------+
void OpenBuyOrder()
{
   double slPrice = 0;
   double tpPrice = 0;
   
   // Calculate Stop Loss and Take Profit prices
   if(StopLoss > 0)
      slPrice = Ask - (StopLoss * pipMultiplier * Point);
   
   if(TakeProfit > 0)
      tpPrice = Ask + (TakeProfit * pipMultiplier * Point);
      
   // Normalize prices to prevent errors
   slPrice = NormalizeDouble(slPrice, Digits);
   tpPrice = NormalizeDouble(tpPrice, Digits);
   
   // Send Order
   int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, slPrice, tpPrice, "RSI+MA Buy", MagicNumber, 0, clrGreen);
   
   if(ticket < 0)
   {
      Print("OrderSend failed with error #", GetLastError());
   }
   else
   {
      Print("Buy Order Opened Successfully. Ticket: ", ticket);
   }
}
//+------------------------------------------------------------------+

Q&A: Strategy Implementation Details

Q: Why does the code use shift_curr = 1 instead of 0?
A: In quantitative trading, using shift 0 (the current forming candle) can lead to "repainting." The MA crossover might appear and disappear multiple times as the price fluctuates within the current minute/hour. Using shift 1 ensures the candle is closed and the crossover is confirmed and permanent.

Q: How does the code handle 5-digit brokers?
A: The OnInit function calculates a pipMultiplier. If the broker uses 5 decimal places (e.g., EURUSD = 1.10505), a "pip" is technically 10 "points." The code automatically adjusts the Stop Loss and Take Profit calculations so that an input of "50 pips" behaves correctly on both 4-digit and 5-digit brokers.

Q: Can this EA handle multiple currency pairs simultaneously?
A: Yes. You can attach this EA to multiple charts (e.g., EURUSD and GBPUSD). The MagicNumber input allows the EA to distinguish its own trades. However, if you attach it to two charts of the same currency pair (e.g., two EURUSD charts), you must change the MagicNumber on the second chart to avoid conflicts.

Q: What happens if the RSI is exactly 50?
A: The logic rsiValue > RSI_Level is strict. If the RSI is exactly 50.0, the trade will not trigger. If you wish to include 50, you would change the logic to >=.

Q: Does this strategy close the trade automatically?
A: This specific code relies on the StopLoss and TakeProfit inputs to close the trade. It does not include logic to close the trade if the Moving Averages cross back down (Death Cross), though that functionality could be added if required.