//+------------------------------------------------------------------+ //| SecUnit B2 Free Premium GBPUSD Multi-TF 1H | //+------------------------------------------------------------------+ #property copyright "Copyright © 2025 Jawad Ait Ali Ouichou " #property link "https://www.mql5.com/en/users/jawadexpo/seller" #property version "1.02" #property description "SecUnit B2 Free Premium - 4 Independent Strategies 1H" #include #include //+------------------------------------------------------------------+ //| STRATEGY 1: Smart Money BOS (Current Timeframe) | //+------------------------------------------------------------------+ input group "════════════Strategy 1: BOS Current TF═══════" input group " Core Parameters" input bool UseBOSStrategy = true; // Enable BOS Strategy? input int BOS_SwingSize = 34; // BOS: Market Structure Time-Horizon input string BOS_ConfirmationType = "Candle Close"; // BOS: Confirmation Type input group " Risk Management" input double BOS_SL_Points = 200; // BOS: Stop Loss input double BOS_TP_Points = 300; // BOS: Take Profit //+------------------------------------------------------------------+ //| STRATEGY 2: Smart Money Structure (Current Timeframe) | //+------------------------------------------------------------------+ input group "════════════Strategy 2: Structure Current TF═" input group " Core Parameters" input bool UseStructureStrategy = true; // Enable Structure Strategy? input int Structure_SwingSize = 22; // Structure: Pivot Period input bool Structure_UseWicks = true; // Structure: Use Wicks? input group " Risk Management" input double Structure_SL_Points = 500; // Structure: Stop Loss input double Structure_TP_Points = 200; // Structure: Take Profit //+------------------------------------------------------------------+ //| STRATEGY 3: Smart Money BOS (4H Only) | //+------------------------------------------------------------------+ input group "════════════Strategy 3: BOS 4H Only══════════" input group " Core Parameters" input bool UseBOS_4H_Strategy = true; // Enable BOS 4H Strategy? input int BOS_4H_SwingSize = 10; // BOS 4H: Market Structure Time-Horizon input string BOS_4H_ConfirmationType = "Candle Close"; // BOS 4H: Confirmation Type input group " Risk Management" input double BOS_4H_SL_Points = 200; // BOS 4H: Stop Loss input double BOS_4H_TP_Points = 110; // BOS 4H: Take Profit //+------------------------------------------------------------------+ //| STRATEGY 4: Smart Money Structure (4H Only) | //+------------------------------------------------------------------+ input group "════════════Strategy 4: Structure 4H Only════" input group " Core Parameters" input bool UseStructure_4H_Strategy = true; // Enable Structure 4H Strategy? input int Structure_4H_SwingSize = 5; // Structure 4H: Pivot Period input bool Structure_4H_UseWicks = true; // Structure 4H: Use Wicks? input group " Risk Management" input double Structure_4H_SL_Points = 200; // Structure 4H: Stop Loss input double Structure_4H_TP_Points = 200; // Structure 4H: Take Profit //+------------------------------------------------------------------+ //| GENERAL SETTINGS | //+------------------------------------------------------------------+ input group "═══════════ Lot Size ═══════════" input double Lots = 0.01; // Fixed Lot Size input group "Magic Numbers" input int MagicNumber_BOS = 2022220; // Magic: BOS (Current TF) input int MagicNumber_Structure = 3033330; // Magic: Structure (Current TF) input int MagicNumber_BOS_4H = 2022224; // Magic: BOS 4H input int MagicNumber_Structure_4H = 3033334; // Magic: Structure 4H //+------------------------------------------------------------------+ //| GLOBAL VARIABLES | //+------------------------------------------------------------------+ CTrade *Trade_BOS; CTrade *Trade_Structure; CTrade *Trade_BOS_4H; CTrade *Trade_Structure_4H; CPositionInfo PositionInfo; bool HaveLongPosition; bool HaveShortPosition; datetime LastTradeBarTime = 0; datetime LastTradeBarTime_4H = 0; int CurrentBOSDirection = 0; int CurrentStructureDirection = 0; int CurrentBOSDirection_4H = 0; int CurrentStructureDirection_4H = 0; struct BOSData { double prevHigh; double prevLow; int prevHighIndex; int prevLowIndex; bool highActive; bool lowActive; int prevBreakoutDir; }; BOSData BOS; BOSData BOS_4H; struct StructureData { double lastHigh; double lastLow; int lastHighIndex; int lastLowIndex; bool highActive; bool lowActive; int prevBreakoutDir; datetime lastTradeTime; }; StructureData Structure; StructureData Structure_4H; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ void OnInit() { Trade_BOS = new CTrade; Trade_BOS.SetExpertMagicNumber(MagicNumber_BOS); Trade_Structure = new CTrade; Trade_Structure.SetExpertMagicNumber(MagicNumber_Structure); Trade_BOS_4H = new CTrade; Trade_BOS_4H.SetExpertMagicNumber(MagicNumber_BOS_4H); Trade_Structure_4H = new CTrade; Trade_Structure_4H.SetExpertMagicNumber(MagicNumber_Structure_4H); LastTradeBarTime = 0; LastTradeBarTime_4H = 0; CurrentBOSDirection = 0; CurrentStructureDirection = 0; CurrentBOSDirection_4H = 0; CurrentStructureDirection_4H = 0; InitBOSData(BOS); InitBOSData(BOS_4H); InitStructureData(Structure); InitStructureData(Structure_4H); } void InitBOSData(BOSData &data) { data.prevHigh = 0; data.prevLow = 0; data.prevHighIndex = 0; data.prevLowIndex = 0; data.highActive = false; data.lowActive = false; data.prevBreakoutDir = 0; } void InitStructureData(StructureData &data) { data.lastHigh = 0; data.lastLow = 0; data.lastHighIndex = 0; data.lastLowIndex = 0; data.highActive = false; data.lowActive = false; data.prevBreakoutDir = 0; data.lastTradeTime = 0; } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { delete Trade_BOS; delete Trade_Structure; delete Trade_BOS_4H; delete Trade_Structure_4H; } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if ((!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) || (!TerminalInfoInteger(TERMINAL_CONNECTED)) || (SymbolInfoInteger(_Symbol, SYMBOL_TRADE_MODE) != SYMBOL_TRADE_MODE_FULL)) return; datetime currentBarTime = iTime(_Symbol, _Period, 0); bool isNewBar = (currentBarTime != LastTradeBarTime); datetime currentBarTime_4H = iTime(_Symbol, PERIOD_H4, 0); bool isNewBar_4H = (currentBarTime_4H != LastTradeBarTime_4H); GetPositionStates(); // STRATEGY 1: BOS (Current Timeframe) if (UseBOSStrategy && isNewBar) { int bosSignal = DetectBOSSignal(_Period, BOS, BOS_SwingSize, BOS_ConfirmationType); if (bosSignal == 1) { if (CurrentBOSDirection == -1 && HasOpenPosition(MagicNumber_BOS)) ClosePositionsByMagic(MagicNumber_BOS); if (!HasOpenPosition(MagicNumber_BOS)) { ExecuteBOSEntry(true, Trade_BOS, BOS_SL_Points, BOS_TP_Points); CurrentBOSDirection = 1; LastTradeBarTime = currentBarTime; } } else if (bosSignal == -1) { if (CurrentBOSDirection == 1 && HasOpenPosition(MagicNumber_BOS)) ClosePositionsByMagic(MagicNumber_BOS); if (!HasOpenPosition(MagicNumber_BOS)) { ExecuteBOSEntry(false, Trade_BOS, BOS_SL_Points, BOS_TP_Points); CurrentBOSDirection = -1; LastTradeBarTime = currentBarTime; } } } // STRATEGY 2: Structure (Current Timeframe) if (UseStructureStrategy && isNewBar) { UpdateMarketStructure(_Period, Structure, Structure_SwingSize); int structureSignal = CheckStructureSignals(_Period, Structure, Structure_UseWicks); if (structureSignal == 1) { if (CurrentStructureDirection == -1 && HasOpenPosition(MagicNumber_Structure)) ClosePositionsByMagic(MagicNumber_Structure); if (!HasOpenPosition(MagicNumber_Structure)) { OpenStructureBuy(Trade_Structure, Structure_SL_Points, Structure_TP_Points); CurrentStructureDirection = 1; } } else if (structureSignal == -1) { if (CurrentStructureDirection == 1 && HasOpenPosition(MagicNumber_Structure)) ClosePositionsByMagic(MagicNumber_Structure); if (!HasOpenPosition(MagicNumber_Structure)) { OpenStructureSell(Trade_Structure, Structure_SL_Points, Structure_TP_Points); CurrentStructureDirection = -1; } } } // STRATEGY 3: BOS (4H Only) if (UseBOS_4H_Strategy && isNewBar_4H) { int bosSignal_4H = DetectBOSSignal(PERIOD_H4, BOS_4H, BOS_4H_SwingSize, BOS_4H_ConfirmationType); if (bosSignal_4H == 1) { if (CurrentBOSDirection_4H == -1 && HasOpenPosition(MagicNumber_BOS_4H)) ClosePositionsByMagic(MagicNumber_BOS_4H); if (!HasOpenPosition(MagicNumber_BOS_4H)) { ExecuteBOSEntry(true, Trade_BOS_4H, BOS_4H_SL_Points, BOS_4H_TP_Points); CurrentBOSDirection_4H = 1; LastTradeBarTime_4H = currentBarTime_4H; } } else if (bosSignal_4H == -1) { if (CurrentBOSDirection_4H == 1 && HasOpenPosition(MagicNumber_BOS_4H)) ClosePositionsByMagic(MagicNumber_BOS_4H); if (!HasOpenPosition(MagicNumber_BOS_4H)) { ExecuteBOSEntry(false, Trade_BOS_4H, BOS_4H_SL_Points, BOS_4H_TP_Points); CurrentBOSDirection_4H = -1; LastTradeBarTime_4H = currentBarTime_4H; } } } // STRATEGY 4: Structure (4H Only) if (UseStructure_4H_Strategy && isNewBar_4H) { UpdateMarketStructure(PERIOD_H4, Structure_4H, Structure_4H_SwingSize); int structureSignal_4H = CheckStructureSignals(PERIOD_H4, Structure_4H, Structure_4H_UseWicks); if (structureSignal_4H == 1) { if (CurrentStructureDirection_4H == -1 && HasOpenPosition(MagicNumber_Structure_4H)) ClosePositionsByMagic(MagicNumber_Structure_4H); if (!HasOpenPosition(MagicNumber_Structure_4H)) { OpenStructureBuy(Trade_Structure_4H, Structure_4H_SL_Points, Structure_4H_TP_Points); CurrentStructureDirection_4H = 1; } } else if (structureSignal_4H == -1) { if (CurrentStructureDirection_4H == 1 && HasOpenPosition(MagicNumber_Structure_4H)) ClosePositionsByMagic(MagicNumber_Structure_4H); if (!HasOpenPosition(MagicNumber_Structure_4H)) { OpenStructureSell(Trade_Structure_4H, Structure_4H_SL_Points, Structure_4H_TP_Points); CurrentStructureDirection_4H = -1; } } } } //+------------------------------------------------------------------+ //| STRATEGY: BOS Functions (Multi-Timeframe) | //+------------------------------------------------------------------+ int DetectBOSSignal(ENUM_TIMEFRAMES timeframe, BOSData &data, int swingSize, string confirmType) { MqlRates rates[]; ArraySetAsSeries(rates, true); int lookback = swingSize * 2 + 10; if (CopyRates(_Symbol, timeframe, 0, lookback, rates) <= 0) return 0; for (int i = swingSize; i < ArraySize(rates) - swingSize; i++) { bool isPivotHigh = true; for (int j = 1; j <= swingSize; j++) { if (rates[i].high <= rates[i - j].high || rates[i].high <= rates[i + j].high) { isPivotHigh = false; break; } } if (isPivotHigh) { data.prevHigh = rates[i].high; data.prevHighIndex = i; data.highActive = true; break; } } for (int i = swingSize; i < ArraySize(rates) - swingSize; i++) { bool isPivotLow = true; for (int j = 1; j <= swingSize; j++) { if (rates[i].low >= rates[i - j].low || rates[i].low >= rates[i + j].low) { isPivotLow = false; break; } } if (isPivotLow) { data.prevLow = rates[i].low; data.prevLowIndex = i; data.lowActive = true; break; } } double checkPrice; if (data.highActive) { checkPrice = (confirmType == "Candle Close") ? rates[0].close : rates[0].high; if (checkPrice > data.prevHigh) { data.highActive = false; data.prevBreakoutDir = 1; return 1; } } if (data.lowActive) { checkPrice = (confirmType == "Candle Close") ? rates[0].close : rates[0].low; if (checkPrice < data.prevLow) { data.lowActive = false; data.prevBreakoutDir = -1; return -1; } } return 0; } void ExecuteBOSEntry(bool isBuy, CTrade *trade, double slPoints, double tpPoints) { double entryPrice = isBuy ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID); double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS); double sl = isBuy ? entryPrice - (slPoints * point) : entryPrice + (slPoints * point); double tp = isBuy ? entryPrice + (tpPoints * point) : entryPrice - (tpPoints * point); ENUM_ORDER_TYPE type = isBuy ? ORDER_TYPE_BUY : ORDER_TYPE_SELL; trade.PositionOpen(_Symbol, type, Lots, entryPrice, NormalizeDouble(sl, digits), NormalizeDouble(tp, digits), ""); } //+------------------------------------------------------------------+ //| STRATEGY: Market Structure Functions (Multi-Timeframe) | //+------------------------------------------------------------------+ void UpdateMarketStructure(ENUM_TIMEFRAMES timeframe, StructureData &data, int swingSize) { double pivotHigh = FindPivotHigh(timeframe, swingSize); if(pivotHigh > 0) { data.lastHigh = pivotHigh; data.lastHighIndex = swingSize; data.highActive = true; } double pivotLow = FindPivotLow(timeframe, swingSize); if(pivotLow > 0) { data.lastLow = pivotLow; data.lastLowIndex = swingSize; data.lowActive = true; } } double FindPivotHigh(ENUM_TIMEFRAMES timeframe, int period) { if(iBars(_Symbol, timeframe) < period * 2 + 1) return 0; double centerHigh = iHigh(_Symbol, timeframe, period); for(int i = 1; i <= period; i++) { if(iHigh(_Symbol, timeframe, period - i) >= centerHigh) return 0; if(iHigh(_Symbol, timeframe, period + i) >= centerHigh) return 0; } return centerHigh; } double FindPivotLow(ENUM_TIMEFRAMES timeframe, int period) { if(iBars(_Symbol, timeframe) < period * 2 + 1) return 0; double centerLow = iLow(_Symbol, timeframe, period); for(int i = 1; i <= period; i++) { if(iLow(_Symbol, timeframe, period - i) <= centerLow) return 0; if(iLow(_Symbol, timeframe, period + i) <= centerLow) return 0; } return centerLow; } int CheckStructureSignals(ENUM_TIMEFRAMES timeframe, StructureData &data, bool useWicks) { if(!data.highActive && !data.lowActive) return 0; datetime currentBarTime = iTime(_Symbol, timeframe, 0); if(currentBarTime == data.lastTradeTime) return 0; double currentPrice; if(useWicks) { currentPrice = iHigh(_Symbol, timeframe, 0); if(data.highActive && currentPrice > data.lastHigh) { data.highActive = false; data.prevBreakoutDir = 1; data.lastTradeTime = currentBarTime; return 1; } currentPrice = iLow(_Symbol, timeframe, 0); if(data.lowActive && currentPrice < data.lastLow) { data.lowActive = false; data.prevBreakoutDir = -1; data.lastTradeTime = currentBarTime; return -1; } } else { currentPrice = iClose(_Symbol, timeframe, 0); if(data.highActive && currentPrice > data.lastHigh) { data.highActive = false; data.prevBreakoutDir = 1; data.lastTradeTime = currentBarTime; return 1; } if(data.lowActive && currentPrice < data.lastLow) { data.lowActive = false; data.prevBreakoutDir = -1; data.lastTradeTime = currentBarTime; return -1; } } return 0; } void OpenStructureBuy(CTrade *trade, double slPoints, double tpPoints) { double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS); double sl = NormalizeDouble(ask - (slPoints * point), digits); double tp = NormalizeDouble(ask + (tpPoints * point), digits); trade.PositionOpen(_Symbol, ORDER_TYPE_BUY, Lots, ask, sl, tp, ""); } void OpenStructureSell(CTrade *trade, double slPoints, double tpPoints) { double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double point = SymbolInfoDouble(_Symbol, SYMBOL_POINT); int digits = (int)SymbolInfoInteger(_Symbol, SYMBOL_DIGITS); double sl = NormalizeDouble(bid + (slPoints * point), digits); double tp = NormalizeDouble(bid - (tpPoints * point), digits); trade.PositionOpen(_Symbol, ORDER_TYPE_SELL, Lots, bid, sl, tp, ""); } //+------------------------------------------------------------------+ //| SHARED FUNCTIONS | //+------------------------------------------------------------------+ void GetPositionStates() { HaveLongPosition = false; HaveShortPosition = false; for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionInfo.SelectByIndex(i) && PositionInfo.Symbol() == _Symbol) { if (PositionInfo.PositionType() == POSITION_TYPE_BUY) HaveLongPosition = true; else HaveShortPosition = true; } } } bool HasOpenPosition(int magicNumber) { for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionInfo.SelectByIndex(i) && PositionInfo.Symbol() == _Symbol && PositionInfo.Magic() == magicNumber) return true; } return false; } void ClosePositionsByMagic(int magicNumber) { CTrade closeTrade; for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionInfo.SelectByIndex(i) && PositionInfo.Symbol() == _Symbol && PositionInfo.Magic() == magicNumber) { closeTrade.PositionClose(PositionInfo.Ticket()); } } }