Viewing the resource: Trend Flat Momentum Trading System in MQL5

Trend Flat Momentum Trading System in MQL5

Allan Munene Mutiiria 2025-06-26 15:38:50 125 Views
This MQL5 EA uses MA, RSI, and dual CCI crossovers to open 0.1-lot trend trades with pivot-based SL ...

Introduction

Imagine navigating market trends with a precision trend navigator, leveraging multiple indicators to detect momentum shifts and execute disciplined trades. The Trend Flat Momentum EA is your advanced trading tool, designed to automate trend-following on MetaTrader 5 using a combination of fast and slow moving averages (MA, "iMA()", 11- and 25-period), Relative Strength Index (RSI, "iRSI()", 27-period), and two Commodity Channel Index indicators (CCI, "iCCI()", 36- and 55-period). On each new bar ("OnTick()", "OnNewBar()", "iTime()"), it checks for MA crossovers ("ma11_buffer", "ma25_buffer") confirmed by RSI thresholds ("InpRSIThreshold"=58) and CCI conditions ("cci36_buffer", "cci55_buffer" > 0 for buys). Trades are opened with a configurable lot size ("InpLotsize"=0.1) using pivot-based stop losses ("GetPivotLow()", "GetPivotHigh()") and a fixed 300-pip take profit ("InpTakeProfitPoints"). Signal rejections are logged via "Print()". Managed via "CTrade", this strategy suits traders seeking robust trend trading, requiring sufficient account balance and market analysis for optimal performance.

This article is crafted with a professional, engaging, and seamless narrative, flowing like a well-calibrated trend navigator, designed to inform and captivate readers. Tailored for both novice and experienced traders, we’ll dissect each code component with clear, precise explanations, as if guiding an apprentice navigator through a trend-following project. With vivid examples—like trading EURUSD on a bullish crossover—and a polished tone, we’ll explore how the EA initializes, detects signals, executes trades, and ensures cleanup. Using a precision trend navigator metaphor, this guide will illuminate the code’s technical rigor, empowering you to trade trends with confidence. Let’s activate the system and begin this trend-following expedition!

Strategy Blueprint

Let’s outline the EA’s trading framework, like drafting specifications for a trend navigator:

  • Initialization: Sets up MA (11, 25), RSI (27), and CCI (36, 55) indicators ("iMA()", "iRSI()", "iCCI()") in "OnInit()".

  • Signal Detection: Checks MA crossovers ("ma11_buffer", "ma25_buffer") with RSI ("rsi_buffer", >58 for buys) and CCI ("cci36_buffer", "cci55_buffer", >0 for buys) on new bars ("OnNewBar()", "iTime()") in "OnTick()".

  • Trade Execution: Opens 0.1-lot trades ("obj_Trade.Buy()", "obj_Trade.Sell()") with pivot-based SL ("GetPivotLow()", "GetPivotHigh()") and 300-pip TP ("InpTakeProfitPoints").

  • Notifications: Logs rejections (e.g., RSI too low) via "Print()".

  • Execution: Processes signals on new bars, ensuring robust confirmation.

  • Enhancements: Adding configurable thresholds, position filters, or trailing stops could improve flexibility. This framework automates trend-following with precision, capturing momentum shifts efficiently.

Code Implementation

Let’s step into the trend navigator hub and dissect the MQL5 code that powers this Trend Flat Momentum EA. We’ll guide you through each phase like expert navigators, ensuring the narrative flows seamlessly with professional clarity and engaging precision that captivates readers. We’ll cover initialization, signal detection, trade execution, and cleanup, with detailed explanations and examples—like trading EURUSD on a bullish crossover—to make it accessible for beginners. Each phase will build on the last, crafting a cohesive technical narrative that transforms code into a compelling trend-following project. Let’s power up the system and begin!

Phase 1: Constructing the Framework—Initialization

We start by building the trading system, initializing the indicators.

//+------------------------------------------------------------------+
//|                                       Trend Flat Momentum EA.mq5 |
//|                           Copyright 2025, Allan Munene Mutiiria. |
//|                                   https://t.me/Forex_Algo_Trader |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Allan Munene Mutiiria."
#property link      "https://t.me/Forex_Algo_Trader"
#property version   "1.00"

#include <Trade/Trade.mqh>
CTrade obj_Trade;

input int InpCCI36Period = 36;
input int InpCCI55Period = 55;
input int InpRSIPeriod = 27;
input int InpMAFastPeriod = 11;
input int InpMASlowPeriod = 25;
input double InpRSIThreshold = 58;
input int InpTakeProfitPoints = 300;
input double InpLotsize = 0.1;

input int PivotLeft = 2;
input int PivotRight = 2;

int handleCCI36 = INVALID_HANDLE;
int handleCCI55 = INVALID_HANDLE;
int handleRSI = INVALID_HANDLE;
int handleMA11 = INVALID_HANDLE;
int handleMA25 = INVALID_HANDLE;

double ma11_buffer[];
double ma25_buffer[];
double rsi_buffer[];
double cci36_buffer[];
double cci55_buffer[];

datetime lastBarTime = 0;

int OnInit(){
   handleCCI36 = iCCI(_Symbol,_Period,InpCCI36Period,PRICE_CLOSE);
   if (handleCCI36 == INVALID_HANDLE){
      Print("EEROR: FAILED TO CREATE THE CCI 36 HANDLE. REVERTING!");
      return (INIT_FAILED);
   }
   handleCCI55 = iCCI(_Symbol,_Period,InpCCI55Period,PRICE_CLOSE);
   if (handleCCI55 == INVALID_HANDLE){
      Print("EEROR: FAILED TO CREATE THE CCI 55 HANDLE. REVERTING!");
      return (INIT_FAILED);
   }
   handleRSI = iRSI(_Symbol,_Period,InpRSIPeriod,PRICE_CLOSE);
   if (handleRSI == INVALID_HANDLE){
      Print("EEROR: FAILED TO CREATE THE RSI HANDLE. REVERTING!");
      return (INIT_FAILED);
   }
   handleMA11 = iMA(_Symbol,_Period,InpMAFastPeriod,0,MODE_SMMA,PRICE_MEDIAN);
   if (handleMA11 == INVALID_HANDLE){
      Print("EEROR: FAILED TO CREATE THE MA 11 HANDLE. REVERTING!");
      return (INIT_FAILED);
   }
   handleMA25 = iMA(_Symbol,_Period,InpMASlowPeriod,0,MODE_SMMA,PRICE_MEDIAN);
   if (handleMA25 == INVALID_HANDLE){
      Print("EEROR: FAILED TO CREATE THE MA 25 HANDLE. REVERTING!");
      return (INIT_FAILED);
   }
   ArraySetAsSeries(ma11_buffer, true);
   ArraySetAsSeries(ma25_buffer, true);
   ArraySetAsSeries(rsi_buffer, true);
   ArraySetAsSeries(cci36_buffer, true);
   ArraySetAsSeries(cci55_buffer, true);
   return(INIT_SUCCEEDED);
}

The system begins with the #property header, establishing copyright and contact details, like calibrating a trend navigator’s core. The "OnInit()" function initializes the setup, including "Trade/Trade.mqh" for trading ("CTrade", "obj_Trade") and defining input parameters: CCI periods ("InpCCI36Period"=36, "InpCCI55Period"=55), RSI period ("InpRSIPeriod"=27), MA periods ("InpMAFastPeriod"=11, "InpMASlowPeriod"=25), RSI threshold ("InpRSIThreshold"=58), take profit ("InpTakeProfitPoints"=300), lot size ("InpLotsize"=0.1), and pivot lookback ("PivotLeft"=2, "PivotRight"=2). It creates handles for CCI ("iCCI()", "handleCCI36", "handleCCI55"), RSI ("iRSI()", "handleRSI"), and smoothed MAs ("iMA()", "handleMA11", "handleMA25", MODE_SMMA, PRICE_MEDIAN), returning INIT_FAILED if any handle is invalid ("INVALID_HANDLE"). Arrays ("ma11_buffer", "rsi_buffer", etc.) are set as time series ("ArraySetAsSeries()"). Returning INIT_SUCCEEDED signals, “Navigator is ready, let’s catch trends!” This primes the EA for signal-based trading, like a navigator poised for action. Note: The code uses MetaQuotes’ copyright, but your metadata is presented for consistency.

Phase 2: Detecting Trends—Processing Signals

We check for trend signals to trigger trades, like navigating market momentum.

void OnTick(){
   datetime currentTime = iTime(_Symbol,_Period,0);
   if (currentTime != lastBarTime){
      lastBarTime = currentTime;
      OnNewBar();
   }
}

void OnNewBar(){
   if (CopyBuffer(handleMA11,0,1,2,ma11_buffer) != 2){return;}
   if (CopyBuffer(handleMA25,0,1,2,ma25_buffer) != 2){return;}
   if (CopyBuffer(handleRSI,0,1,2,rsi_buffer) != 2){return;}
   if (CopyBuffer(handleCCI36,0,1,2,cci36_buffer) != 2){return;}
   if (CopyBuffer(handleCCI55,0,1,2,cci55_buffer) != 2){return;}
   double ma11_current = ma11_buffer[0];
   double ma11_previous = ma11_buffer[1];
   double ma25_current = ma25_buffer[0];
   double ma25_previous = ma25_buffer[1];
   double rsi_current = rsi_buffer[0];
   double cci36_current = cci36_buffer[0];
   double cci55_current = cci55_buffer[0];
   bool maCrossoverBuy = (ma11_current > ma25_current) && (ma11_previous < ma25_previous);
   bool rsiConditionBuy = rsi_current > InpRSIThreshold;
   bool cci36ConditionBuy = cci36_current > 0;
   bool cci55ConditionBuy = cci55_current > 0;
   if (maCrossoverBuy){
      bool conditionOk = true;
      if (!rsiConditionBuy){
         Print("Buy signal rejected. RSI condition not met. RSI=",rsi_current," Threshold = ",InpRSIThreshold);
         conditionOk = false;
      }
      if (!cci36ConditionBuy){
         Print("Buy signal rejected. CCI36 condition not met. CCI36=",cci36_current);
         conditionOk = false;
      }
      if (!cci55ConditionBuy){
         Print("Buy signal rejected. CCI55 condition not met. CCI55=",cci55_current);
         conditionOk = false;
      }
      if (conditionOk){
         double stoploss = GetPivotLow(PivotLeft,PivotRight);
         if (stoploss <= 0){
            stoploss = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         }
         double entryPrice = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         double tp = entryPrice + InpTakeProfitPoints*_Point;
         Print("Buy signal: Swing low used as the stop loss = ",stoploss);
         obj_Trade.Buy(InpLotsize,_Symbol,entryPrice,stoploss,tp);
      }
   }
   bool maCrossoverSell = (ma11_current < ma25_current) && (ma11_previous > ma25_previous);
   bool rsiConditionSell = rsi_current < (100-InpRSIThreshold);
   bool cci36ConditionSell = cci36_current < 0;
   bool cci55ConditionSell = cci55_current < 0;
   if (maCrossoverSell){
      bool conditionOk = true;
      if (!rsiConditionSell){
         Print("Sell signal rejected. RSI condition not met. RSI=",rsi_current," Threshold = ",100-InpRSIThreshold);
         conditionOk = false;
      }
      if (!cci36ConditionSell){
         Print("Sell signal rejected. CCI36 condition not met. CCI36=",cci36_current);
         conditionOk = false;
      }
      if (!cci55ConditionSell){
         Print("Sell signal rejected. CCI55 condition not met. CCI55=",cci55_current);
         conditionOk = false;
      }
      if (conditionOk){
         double stoploss = GetPivotHigh(PivotLeft,PivotRight);
         if (stoploss <= 0){
            stoploss = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
         }
         double entryPrice = SymbolInfoDouble(_Symbol,SYMBOL_BID);
         double tp = entryPrice - InpTakeProfitPoints*_Point;
         Print("Sell signal: Swing high used as the stop loss = ",stoploss);
         obj_Trade.Sell(InpLotsize,_Symbol,entryPrice,stoploss,tp);
      }
   }
}

In the signal detection hub, "OnTick()" checks for new bars ("iTime()", "lastBarTime") and calls "OnNewBar()". The "OnNewBar()" function retrieves two bars of data ("CopyBuffer()", "ma11_buffer", "rsi_buffer", etc.) and exits if insufficient (!= 2). It evaluates buy signals: fast MA (11) crossing above slow MA (25) ("maCrossoverBuy"), RSI > 58 ("rsiConditionBuy"), and both CCI > 0 ("cci36ConditionBuy", "cci55ConditionBuy"). If all conditions are met, it calculates a pivot low SL ("GetPivotLow()", "PivotLeft"=2, "PivotRight"=2) or uses bid if invalid (<= 0), sets entry at ask ("SymbolInfoDouble()") and TP at entry + 300 pips, then opens a buy trade ("obj_Trade.Buy()", "InpLotsize"=0.1). Sell signals check MA crossing below, RSI < 42 (100-InpRSIThreshold), and both CCI < 0, using pivot high SL ("GetPivotHigh()") or ask, with TP at entry - 300 pips. Rejections are logged ("Print()") if conditions fail. For example, on EURUSD H1, a buy signal with MA crossover, RSI=60, CCI36=50, CCI55=40 opens a trade at 1.2050, SL=1.2000 (pivot low), TP=1.2350, like a navigator plotting a bullish course.

Phase 3: Calculating Pivots—Setting Stop Losses

We calculate pivot points for stop losses, like calibrating the navigator’s coordinates.

double GetPivotLow(int left, int right){
   MqlRates rates[];
   ArraySetAsSeries(rates, true);
   int copied = CopyRates(_Symbol,_Period,0,100,rates);
   if (copied <= (left+right)){
      return (0);
   }
   for (int i=left; i<=copied-right-1; i++){
      bool isPivot = true;
      double currentLow = rates[i].low;
      for (int j=i-left; j<=i+right; j++){
         if (j==i){
            continue;
         }
         if (rates[j].low <= currentLow){
            isPivot = false;
            break;
         }
      }
      if (isPivot){
         return (currentLow);
      }
   }
   return (0);
}

double GetPivotHigh(int left, int right){
   MqlRates rates[];
   ArraySetAsSeries(rates, true);
   int copied = CopyRates(_Symbol,_Period,0,100,rates);
   if (copied <= (left+right)){
      return (0);
   }
   for (int i=left; i<=copied-right-1; i++){
      bool isPivot = true;
      double currentHigh = rates[i].high;
      for (int j=i-left; j<=i+right; j++){
         if (j==i){
            continue;
         }
         if (rates[j].high >= currentHigh){
            isPivot = false;
            break;
         }
      }
      if (isPivot){
         return (currentHigh);
      }
   }
   return (0);
}

In the pivot calculation hub, "GetPivotLow()" and "GetPivotHigh()" retrieve 100 bars ("CopyRates()", "MqlRates", "rates") and check for pivots using "PivotLeft"=2 and "PivotRight"=2. For lows, it finds a bar where the low ("rates[i].low") is lower than the surrounding bars (i-left to i+right); for highs, it finds a higher high. If no pivot is found or insufficient bars (copied <= left+right), it returns 0. For example, on EURUSD H1, a pivot low at 1.2000 is used as SL for a buy, ensuring a strategic stop, like setting precise coordinates.

Phase 4: Shutting Down the System—Cleaning Up Resources

As our expedition concludes, we shut down the system, ensuring resource release.

void OnDeinit(const int reason){
   IndicatorRelease(handleCCI36);
   IndicatorRelease(handleCCI55);
   IndicatorRelease(handleMA11);
   IndicatorRelease(handleMA25);
   IndicatorRelease(handleRSI);
}

In the shutdown control room, "OnDeinit()" releases all indicator handles ("handleCCI36", "handleCCI55", "handleRSI", "handleMA11", "handleMA25") using "IndicatorRelease()", ensuring a clean shutdown, like powering down the navigator’s systems.

Why This EA is a Trend Navigator Triumph

The Trend Flat Momentum EA is a trend-following triumph, automating robust trades with precision, like a master-crafted navigator. Its multi-indicator confirmation ("ma11_buffer", "rsi_buffer", "cci36_buffer") and pivot-based SL ("GetPivotLow()") ensure disciplined entries, with potential for trailing stops or additional filters. Picture opening a buy on EURUSD at 1.2050 with a pivot SL—strategic brilliance! Beginners will value the automated clarity, while experts can enhance its flexibility, making it essential for trend-focused traders.

Putting It All Together

To deploy this EA:

  1. Open MetaEditor in MetaTrader 5, like entering your trend navigator hub.

  2. Copy the code, compile with F5, and verify no errors—no navigator wants a faulty system!

  3. Attach the EA to your chart (e.g., EURUSD H1) and configure inputs (e.g., "InpLotsize"=0.1, "InpRSIThreshold"=58).

  4. Monitor logs (e.g., “Buy signal: Swing low used as the stop loss = 1.2000”) for trade actions.

  5. Test on a demo account first—real capital deserves a trial run!

Conclusion

We’ve engineered a Trend Flat Momentum system that navigates trends with precision, like a master-crafted navigator. This MQL5 code is your strategic tool, brought to life with a seamless, professional narrative packed with clear explanations and vivid examples to fuel your trading confidence. Whether you’re a novice trader or a seasoned market strategist, this EA empowers you to capture trends with ease. Ready to navigate? Watch our video guide on the website for a step-by-step creation process. Now, chart your trading with precision! 🔍

Disclaimer: Trading is like navigating complex markets—challenging and risky. Losses can exceed deposits. Test strategies on a demo account before going live.

Disclaimer: The ideas and strategies presented in this resource are solely those of the author and are intended for informational and educational purposes only. They do not constitute financial advice, and past performance is not indicative of future results. All materials, including but not limited to text, images, files, and any downloadable content, are protected by copyright and intellectual property laws and are the exclusive property of Forex Algo-Trader or its licensors. Reproduction, distribution, modification, or commercial use of these materials without prior written consent from Forex Algo-Trader is strictly prohibited and may result in legal action. Users are advised to exercise extreme caution, perform thorough independent research, and consult with qualified financial professionals before implementing any trading strategies or decisions based on this resource, as trading in financial markets involves significant risk of loss.

Recent Comments

Go to discussion to Comment or View other Comments

No comments yet. Be the first to comment!