Triple Moving Average Crossover Expert Advisor (EA) for the MetaTrader 4 platform, written in the MQL4 language.

Triple Moving Average Crossover Expert Advisor
The short URL of the present article is: https://netbizint.com.au/triple-crossover-ma

Triple cross forex trading strategy

This EA incorporates the complete strategy we’ve discussed, including the triple moving average crossover for the primary signal, confirmation filters using RSI, MACD, and ADX, and dynamic risk management using the Average True Range (ATR) for stop-loss placement.

How to Use the Code

  1. Open MetaEditor: In your MT4 platform, press the F4 key or go to Tools > MetaQuotes Language Editor.
  2. Create a New File: In MetaEditor, click File > New. In the wizard that appears, select Expert Advisor (template) and click Next.
  3. Name the EA: Give it a name, like TripleCrossoverEA, and click Finish.
  4. Paste the Code: A new file will open with some template code. Delete all of it and paste the complete code provided below into this window.
  5. Compile: Click the Compile button at the top of the MetaEditor window (it looks like a stack of books). If there are no errors, you can close the editor.
  6. Attach to Chart: Go back to your MT4 platform. In the “Navigator” window on the left, find your new EA under the “Expert Advisors” section. Drag and drop it onto the chart you want to trade (e.g., EURUSD, H4).
  7. Configure Settings: The “Inputs” tab will appear, allowing you to customize all the parameters of the strategy, such as the moving average periods, risk settings, and indicator levels.
  8. Enable AutoTrading: Make sure the “AutoTrading” button at the top of your MT4 platform is enabled (green).

MQL4 Code for Triple Crossover Expert Advisor

Code snippet

//+------------------------------------------------------------------+
//| TripleCrossoverEA.mq4 |
//| Copyright 2025, Award-Winning Writer |
//| Implements the Triple Moving Average Crossover |
//| Strategy with RSI, MACD, and ADX filters. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Award-Winning Writer"
#property link      "https://example.com"
#property version   "1.00"
#property strict

//--- EA Inputs (User-Configurable Settings)
//--- Moving Average Settings
input int ShortMAPeriod   = 9;      // Period for the short-term MA
input int MediumMAPeriod  = 21;     // Period for the medium-term MA
input int LongMAPeriod    = 55;     // Period for the long-term MA
input ENUM_MA_METHOD MAMethod = MODE_EMA; // MA Method (EMA, SMA, etc.)

//--- Confirmation Indicator Settings
input int RSIPeriod       = 14;     // Period for RSI
input int ADXPeriod       = 14;     // Period for ADX
input int MACDFast        = 12;     // Fast EMA for MACD
input int MACDSlow        = 26;     // Slow EMA for MACD
input int MACDSignal      = 9;      // Signal line for MACD

//--- Filter Levels
input double RSI_Filter_Level = 50.0; // RSI must be above/below this level
input double ADX_Filter_Level = 25.0; // ADX must be above this level for a trend

//--- Risk Management Settings
input double Lots            = 0.01;   // Fixed lot size for trades
input int    ATRPeriod       = 14;     // Period for ATR calculation
input double ATRMultiplier   = 2.0;    // Stop Loss = ATR * Multiplier
input double RiskRewardRatio = 2.0;    // Take Profit = Risk * Ratio

//--- Trade Management Settings
input int MagicNumber = 12345;  // Unique ID for trades from this EA
input int Slippage    = 3;      // Allowed slippage in points

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
   //--- Initialization successful
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert tick function (main trading logic) |
//+------------------------------------------------------------------+
void OnTick()
{
   //--- Check if a new bar has started to avoid multiple trades per bar
   static datetime lastBarTime = 0;
   if(lastBarTime == Time)
      return;
   lastBarTime = Time;

   //--- Check if a trade is already open for this symbol
   if(IsTradeOpen())
      return;

   //--- Get indicator values for the last closed bar (shift = 1)
   //--- We use shift=1 to ensure the signal is based on a completed candle
   
   // MA Crossover Check (requires values from bar 1 and bar 2)
   double short_ma_1 = iMA(NULL, 0, ShortMAPeriod, 0, MAMethod, PRICE_CLOSE, 1);
   double short_ma_2 = iMA(NULL, 0, ShortMAPeriod, 0, MAMethod, PRICE_CLOSE, 2);
   double medium_ma_1 = iMA(NULL, 0, MediumMAPeriod, 0, MAMethod, PRICE_CLOSE, 1);
   double medium_ma_2 = iMA(NULL, 0, MediumMAPeriod, 0, MAMethod, PRICE_CLOSE, 2);
   
   // Trend Filter MA
   double long_ma_1 = iMA(NULL, 0, LongMAPeriod, 0, MAMethod, PRICE_CLOSE, 1);

   // Confirmation Indicators
   double rsi_1 = iRSI(NULL, 0, RSIPeriod, PRICE_CLOSE, 1);
   double macd_main_1 = iMACD(NULL, 0, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE, MODE_MAIN, 1);
   double macd_signal_1 = iMACD(NULL, 0, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE, MODE_SIGNAL, 1);
   double adx_1 = iADX(NULL, 0, ADXPeriod, PRICE_CLOSE, MODE_MAIN, 1);
   
   //--- Define Entry Conditions ---
   
   // Bullish Conditions
   bool bullish_crossover = (short_ma_2 < medium_ma_2) && (short_ma_1 > medium_ma_1);
   bool bullish_filter = (short_ma_1 > long_ma_1) && (medium_ma_1 > long_ma_1);
   bool bullish_rsi_confirm = (rsi_1 > RSI_Filter_Level);
   bool bullish_macd_confirm = (macd_main_1 > macd_signal_1);
   bool trend_strong_confirm = (adx_1 > ADX_Filter_Level);

   // Bearish Conditions
   bool bearish_crossover = (short_ma_2 > medium_ma_2) && (short_ma_1 < medium_ma_1);
   bool bearish_filter = (short_ma_1 < long_ma_1) && (medium_ma_1 < long_ma_1);
   bool bearish_rsi_confirm = (rsi_1 < RSI_Filter_Level);
   bool bearish_macd_confirm = (macd_main_1 < macd_signal_1);
   // trend_strong_confirm is the same for both directions

   //--- Execute Trades ---
   
   // Check for BUY signal
   if(bullish_crossover && bullish_filter && bullish_rsi_confirm && bullish_macd_confirm && trend_strong_confirm)
   {
      double atr_val = iATR(NULL, 0, ATRPeriod, 1);
      double stop_loss_pips = atr_val * ATRMultiplier / _Point;
      double take_profit_pips = stop_loss_pips * RiskRewardRatio;
      
      double stop_loss_price = NormalizeDouble(Ask - (stop_loss_pips * _Point), _Digits);
      double take_profit_price = NormalizeDouble(Ask + (take_profit_pips * _Point), _Digits);
      
      OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, stop_loss_price, take_profit_price, "TripleCross_Buy", MagicNumber, 0, clrGreen);
   }
   // Check for SELL signal
   else if(bearish_crossover && bearish_filter && bearish_rsi_bearish && bearish_macd_confirm && trend_strong_confirm)
   {
      double atr_val = iATR(NULL, 0, ATRPeriod, 1);
      double stop_loss_pips = atr_val * ATRMultiplier / _Point;
      double take_profit_pips = stop_loss_pips * RiskRewardRatio;

      double stop_loss_price = NormalizeDouble(Bid + (stop_loss_pips * _Point), _Digits);
      double take_profit_price = NormalizeDouble(Bid - (take_profit_pips * _Point), _Digits);
      
      OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage, stop_loss_price, take_profit_price, "TripleCross_Sell", MagicNumber, 0, clrRed);
   }
}

//+------------------------------------------------------------------+
//| Helper function to check for open trades |
//+------------------------------------------------------------------+
bool IsTradeOpen()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
         {
            return(true); // Found an open trade for this EA on this symbol
         }
      }
   }
   return(false); // No open trades found
}

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

Explanation of the Code

  • #property directives: These set basic properties for the EA, such as copyright information and version. #property strict enables a stricter mode of MQL4 programming, which helps catch potential errors.
  • input variables: These are the parameters you can change in the EA’s settings window on your MT4 chart. This allows you to easily test different settings for various currency pairs and timeframes (e.g., swing trading settings like 20/50/100 MAs on the H4 chart, or day trading settings like 9/21/55 on the M15 chart) without modifying the code.  
  • OnTick(): This is the main function where all the action happens. It runs every time a new price tick is received from your broker.
  • New Bar Logic: The static datetime lastBarTime check ensures that the trading logic only runs once at the beginning of each new candle. This is crucial to prevent the EA from opening hundreds of trades on a single signal.
  • Indicator Calculations: The code uses built-in MQL4 functions like iMA(), iRSI(), iMACD(), iADX(), and iATR() to get the values from the indicators. The shift = 1 parameter tells the function to get the value from the most recently closed candle, ensuring signals are based on confirmed price action.  
  • Signal Logic: The boolean variables (bullish_crossover, bullish_filter, etc.) make the code clean and easy to read. A trade is only considered if the primary crossover signal occurs and all the confirmation filters (RSI, MACD, ADX) align with the trade direction.  
  • Risk Management:
    • The Stop Loss is dynamically calculated using the Average True Range (ATR). This is superior to a fixed pip value because it adapts to the market’s current volatility.  
    • The initial Take Profit is set based on a simple risk-to-reward ratio, a common and effective technique.  
  • OrderSend(): This is the function that executes the buy or sell trade. It includes the symbol, trade type, lot size, price, slippage, stop loss, take profit, a comment, and the unique MagicNumber.
  • IsTradeOpen(): This is a helper function that prevents the EA from opening more than one trade at a time on the same chart. It loops through all open orders and checks if any match the EA’s MagicNumber and the current currency pair.

Disclaimer: This code is provided for educational purposes to demonstrate the implementation of the triple crossover trading strategy. Trading forex and other financial markets involves substantial risk, and past performance is not indicative of future results. Always conduct thorough backtesting and forward-testing on a demo account before using any automated trading strategy with real funds. Sources and related content

How To Use Moving Averages – Moving Average Trading 101 – Tradeciety

Source icon

tradeciety.com/how-to-use-moving-averages

Moving Average Strategies for Forex Trading – Investopedia

Source icon

investopedia.com/ask/answers/122314/how-do-i-use-moving-average-ma-create-forex-trading-strategy.asp

Moving Averages Trading Strategies – How to Install & Use | AvaTrade

Tags:

No responses yet

Leave a Reply

Latest Comments

No comments to show.