MT4 RSI EA Trading Strategy That PRINTS Money

BurtonM

New member

MT4 RSI EA Trading Strategy That PRINTS Money​

This title comes from a video by Ali Casey at StatOasis on YouTube,

Thank you Ali for sharing all your data analysis, and backtesting.

RSI Trading Strategy That PRINTS Money đź’° (Tested & Proven)

It is important you watch the video link above to understand the 2 EAs I have coded.

IMPORTANT: These MT4 EAs are developed and backtested on the S&P500 Daily timeframe.

All files are attached below this post for easy downloading.

I have coded 4 versions: MT5 version is here. TradingView version is here. Python version is here.

Test the EAs on a Demo account to check that they are operating correctly.

Here is the 1st code, a simple RSI EA (The only difference is I added a StopLoss)
Entry condition: if RSI < RSIEntryLevel
Exit condition: if RSI > RSIExitLevel || barCount >= MaxBarsHold

//+------------------------------------------------------------------+
//| Basic RSI_EA.mq4 |
//| |
//| Copyright 2025, BurtonM |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, BurtonM"
#property link "https://advancequants.com/"
#property version "1.00"
#property strict

// Input Parameters
extern double LotSize = 0.01; // Trading lot size
extern double StopLoss = 50; // Stop Loss in points
extern int RSIPeriod = 2; // RSI Period
extern double RSIEntryLevel = 25; // RSI Entry Level
extern double RSIExitLevel = 65; // RSI Exit Level
extern int MaxBarsHold = 5; // Maximum bars to hold position

// Global Variables
int ticket = 0;
int barCount = 0;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Validate lot size
if(LotSize < MarketInfo(Symbol(), MODE_MINLOT) ||
LotSize > MarketInfo(Symbol(), MODE_MAXLOT))
{
Print("Invalid lot size. Please adjust to be between ",
MarketInfo(Symbol(), MODE_MINLOT), " and ",
MarketInfo(Symbol(), MODE_MAXLOT));
return INIT_PARAMETERS_INCORRECT;
}

return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}

//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Check if we have an open position
if(ticket > 0)
{
// Check exit conditions
if(ShouldExit())
{
ClosePosition();
ticket = 0;
barCount = 0;
}
else
{
barCount++;
}
}
else
{
// Check entry conditions
if(ShouldEnter())
{
ticket = OpenPosition();
barCount = 0;
}
}
}

//+------------------------------------------------------------------+
//| Check entry conditions |
//+------------------------------------------------------------------+
bool ShouldEnter()
{
double rsi = iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE, 0);
return (rsi < RSIEntryLevel);
}

//+------------------------------------------------------------------+
//| Check exit conditions |
//+------------------------------------------------------------------+
bool ShouldExit()
{
double rsi = iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE, 0);
return (rsi > RSIExitLevel || barCount >= MaxBarsHold);
}

//+------------------------------------------------------------------+
//| Open a new position |
//+------------------------------------------------------------------+
int OpenPosition()
{
double sl = Ask - StopLoss * Point;
int t = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, sl, 0, "RSI EA", 0, 0, clrGreen);

if(t < 0)
{
Print("Error opening position: ", GetLastError());
return 0;
}

return t;
}

//+------------------------------------------------------------------+
//| Close the current position |
//+------------------------------------------------------------------+
void ClosePosition()
{
if(!OrderSelect(ticket, SELECT_BY_TICKET))
{
Print("Error selecting order: ", GetLastError());
return;
}

if(!OrderClose(ticket, OrderLots(), Bid, 3, clrRed))
{
Print("Error closing position: ", GetLastError());
}
//+---------------------------End Of Code------------------------+

I do not recommend using this 1st EA as it does not use/access OrderReliable for MT4

OrderRelaible is code that has been around for many years to assist MT4 EAs in being more reliable


I have coded/created a NewOrderReliable library that provides several important advantages for an EA:​

Retry Mechanism:​

  • If an order fails to execute, the library automatically retries up to 10 times (defined by retry_attempts)
  • This helps handle temporary network issues or broker server delays
  • Each retry attempt includes a random sleep time between attempts to avoid overwhelming the server

Error Handling:​

  • Better error detection and reporting through OrderReliableErrTxt function
  • Detailed error messages are printed for debugging
  • Specific handling for common errors like invalid prices or stops
  • Helps identify why trades aren't executing as expected

Sleep Randomization:​

  • Uses OrderReliable_SleepRandomTime between retries
  • Sleep time varies between 4.0 and 25.0 seconds (defined by sleep_time and sleep_maximum)
  • Helps prevent request flooding and reduces server rejection probability
  • More broker-friendly than immediate retries

Order Selection Safety:​

  • OrderSelectReliable function provides safer order selection
  • Helps prevent issues with concurrent access to order selection
  • More reliable than standard OrderSelect when managing multiple orders

Trade Validation:​

  • Includes built-in validation for stop losses through OrderReliable_EnsureValidStop
  • Helps prevent invalid order parameters from being sent
  • Reduces errors due to incorrect price levels

Consistency:​

  • Provides consistent behavior across different brokers
  • Helps handle varying broker server response times
  • More reliable execution in different market conditions

Maintenance Benefits:​

  • Centralized order handling code
  • Easier to update and maintain trading logic
  • Consistent error handling across multiple EAs

Server Load Management:​

  • Intelligent retry timing helps reduce server load
  • Better compliance with broker API limitations
  • Reduces risk of being blocked for excessive requests
These features make an EA more robust and reliable, especially during high-volatility periods or when experiencing connection issues with your broker.

The 2nd code of the RSI EA incorporates the NewOrderReliable library.

The 3rd code of the RSI_StdDev_EA incorporates the NewOrderReliable library.

From Ali Casey's video I have coded 2 EAs, RSI_EA, and the RSI_StdDev_EA, both requiring the NewOrderReliable library

Put the NewOrderReliable file in the experts/include directory.

IMPORTANT: Test the EAs on a Demo account to check that they are Opening & Closing trades correctly.




 

Attachments

  • 2xRSI_EAs.zip
    29.8 KB · Views: 2
  • RSI_EA.mq4
    5.3 KB · Views: 3
  • RSI_StdDev_EA.mq4
    7 KB · Views: 5
  • NewOrderReliable.mqh
    8.2 KB · Views: 4
Last edited:
Back
Top