//+------------------------------------------------------------------+
//| ModularMultiStrategy.mq5 |
//| Copyright 2026, Financial Algo |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026"
#property version "1.00"
#property strict
//--- Include Trade Library
#include <Trade\Trade.mqh>
CTrade trade;
//--- Strategy Enumeration
enum ENUM_STRATEGY
{
STRATEGY_TREND_MA = 0, // 1. Trend Following (Moving Average Cross)
STRATEGY_MEAN_REV_RSI = 1, // 2. Mean Reversion (RSI Overbought/Oversold)
STRATEGY_BREAKOUT_CH = 2 // 3. Price Breakout (Highest/Lowest Channel)
};
//--- Input Parameters
input group "=== CORE STRATEGY CONTROLLER ==="
input ENUM_STRATEGY InpStrategy = STRATEGY_TREND_MA; // Active Execution Strategy
input group "=== RISK & POSITION MANAGEMENT ==="
input double InpLotSize = 0.1; // Trade Volume (Lots)
input int InpStopLoss = 200; // Stop Loss in Points (0 = Disabled)
input int InpTakeProfit = 400; // Take Profit in Points (0 = Disabled)
input ulong InpMagicNumber = 888111; // Unique Magic Identification Number
input group "=== PARAMETERS: STRATEGY 1 (MA CROSS) ==="
input int InpFastMAPeriod = 10; // Fast Moving Average Period
input int InpSlowMAPeriod = 20; // Slow Moving Average Period
input group "=== PARAMETERS: STRATEGY 2 (RSI REVERSION) ==="
input int InpRSIPeriod = 14; // RSI Period
input double InpRSIOverbought = 70.0; // RSI Upper Bound (Sell Zone)
input double InpRSIOversold = 30.0; // RSI Lower Bound (Buy Zone)
input group "=== PARAMETERS: STRATEGY 3 (CHANNEL BREAKOUT) ==="
input int InpChannelPeriod = 20; // Number of Bars for Price Range
//--- Global Variables for Indicator Handles
int fastMAHandle, slowMAHandle, rsiHandle;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Set the identity footprint for orders executed by this engine instances
trade.SetExpertMagicNumber(InpMagicNumber);
// Initialize structural indicator pipelines based on user strategy selection
if(InpStrategy == STRATEGY_TREND_MA)
{
fastMAHandle = iMA(_Symbol, _Period, InpFastMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
slowMAHandle = iMA(_Symbol, _Period, InpSlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
if(fastMAHandle == INVALID_HANDLE || slowMAHandle == INVALID_HANDLE) return(INIT_FAILED);
}
else if(InpStrategy == STRATEGY_MEAN_REV_RSI)
{
rsiHandle = iRSI(_Symbol, _Period, InpRSIPeriod, PRICE_CLOSE);
if(rsiHandle == INVALID_HANDLE) return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Free system performance memory allocations
IndicatorRelease(fastMAHandle);
IndicatorRelease(slowMAHandle);
IndicatorRelease(rsiHandle);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Restrict logic evaluation to the formation of a fresh candlestick
static datetime lastBarTime;
datetime currentBarTime = iTime(_Symbol, _Period, 0);
if(currentBarTime == lastBarTime) return;
lastBarTime = currentBarTime;
// Enforce clean execution setup by processing signals only when no trades are open
if(PositionsTotal() > 0) return;
// Structural Execution Routers
switch(InpStrategy)
{
case STRATEGY_TREND_MA: EvaluateMACross(); break;
case STRATEGY_MEAN_REV_RSI: EvaluateRSIReversion(); break;
case STRATEGY_BREAKOUT_CH: EvaluateBreakout(); break;
}
}
//+------------------------------------------------------------------+
//| Core Strategy Engine 1: Moving Average Intersection Module |
//+------------------------------------------------------------------+
void EvaluateMACross()
{
double fastMA[], slowMA[];
ArraySetAsSeries(fastMA, true);
ArraySetAsSeries(slowMA, true);
if(CopyBuffer(fastMAHandle, 0, 1, 2, fastMA) < 2 || CopyBuffer(slowMAHandle, 0, 1, 2, slowMA) < 2) return;
// Bullish crossover detected (Fast cross over Slow)
if(fastMA[0] > slowMA[0] && fastMA[1] <= slowMA[1])
{
ExecuteOrder(ORDER_TYPE_BUY);
}
// Bearish crossover detected (Fast cross under Slow)
else if(fastMA[0] < slowMA[0] && fastMA[1] >= slowMA[1])
{
ExecuteOrder(ORDER_TYPE_SELL);
}
}
//+------------------------------------------------------------------+
//| Core Strategy Engine 2: RSI Exhaustion Bounds Module |
//+------------------------------------------------------------------+
void EvaluateRSIReversion()
{
double rsiValues[];
ArraySetAsSeries(rsiValues, true);
if(CopyBuffer(rsiHandle, 0, 1, 2, rsiValues) < 2) return;
// Price recovering out of oversold territory
if(rsiValues[0] > InpRSIOversold && rsiValues[1] <= InpRSIOversold)
{
ExecuteOrder(ORDER_TYPE_BUY);
}
// Price correcting out of overbought territory
else if(rsiValues[0] < InpRSIOverbought && rsiValues[1] >= InpRSIOverbought)
{
ExecuteOrder(ORDER_TYPE_SELL);
}
}
//+------------------------------------------------------------------+
//| Core Strategy Engine 3: Multi-Bar Structural Range Breakout |
//+------------------------------------------------------------------+
void EvaluateBreakout()
{
// Identify high and low boundaries across the historical lookback range
int highestBar = iHighest(_Symbol, _Period, MODE_HIGH, InpChannelPeriod, 1);
int lowestBar = iLowest(_Symbol, _Period, MODE_LOW, InpChannelPeriod, 1);
double channelHigh = iHigh(_Symbol, _Period, highestBar);
double channelLow = iLow(_Symbol, _Period, lowestBar);
double closeCurrent = iClose(_Symbol, _Period, 1);
// Close price broke cleanly out above the historical channel ceiling
if(closeCurrent > channelHigh)
{
ExecuteOrder(ORDER_TYPE_BUY);
}
// Close price broke cleanly out below the historical channel floor
else if(closeCurrent < channelLow)
{
ExecuteOrder(ORDER_TYPE_SELL);
}
}
//+------------------------------------------------------------------+
//| Secure Order Execution Module |
//+------------------------------------------------------------------+
void ExecuteOrder(ENUM_ORDER_TYPE type)
{
double price = (type == ORDER_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID);
double sl = 0;
double tp = 0;
if(type == ORDER_TYPE_BUY)
{
sl = (InpStopLoss > 0) ? price - (InpStopLoss * _Point) : 0;
tp = (InpTakeProfit > 0) ? price + (InpTakeProfit * _Point) : 0;
trade.Buy(InpLotSize, _Symbol, price, sl, tp, "Modular Multi-Strategy Engine [BUY]");
}
else if(type == ORDER_TYPE_SELL)
{
sl = (InpStopLoss > 0) ? price + (InpStopLoss * _Point) : 0;
tp = (InpTakeProfit > 0) ? price - (InpTakeProfit * _Point) : 0;
trade.Sell(InpLotSize, _Symbol, price, sl, tp, "Modular Multi-Strategy Engine [SELL]");
}
}
//+------------------------------------------------------------------+