//+------------------------------------------------------------------+ //| EA1.mq5 | //| SMA 12/26 Crossover Strategy | //| Timeframe: M15 | //| TP: 1000 pips | SL: 500 pips | //+------------------------------------------------------------------+ #property copyright "EA1" #property version "1.00" #property strict #include //--- Input Parameters input int FastPeriod = 12; // Fast SMA Period input int SlowPeriod = 26; // Slow SMA Period input double LotSize = 0.1; // Trade Lot Size input int TakeProfitPips = 1000; // Take Profit in Pips input int StopLossPips = 500; // Stop Loss in Pips input double PipSize = 0.0001; // Pip Size (0.0001 for FX, 0.01 for JPY pairs) input int MagicNumber = 112600; // Magic Number //--- Global Variables CTrade trade; int fastHandle; int slowHandle; datetime lastBarTime = 0; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Validate inputs if(FastPeriod >= SlowPeriod) { Print("ERROR: FastPeriod must be less than SlowPeriod."); return INIT_PARAMETERS_INCORRECT; } // Create SMA indicator handles on M15 timeframe fastHandle = iMA(_Symbol, PERIOD_M15, FastPeriod, 0, MODE_SMA, PRICE_CLOSE); slowHandle = iMA(_Symbol, PERIOD_M15, SlowPeriod, 0, MODE_SMA, PRICE_CLOSE); if(fastHandle == INVALID_HANDLE || slowHandle == INVALID_HANDLE) { Print("ERROR: Failed to create MA indicator handles."); return INIT_FAILED; } trade.SetExpertMagicNumber(MagicNumber); trade.SetDeviationInPoints(10); Print("EA1 initialized | Symbol: ", _Symbol, " | FastSMA: ", FastPeriod, " | SlowSMA: ", SlowPeriod, " | TP: ", TakeProfitPips, " pips", " | SL: ", StopLossPips, " pips"); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if(fastHandle != INVALID_HANDLE) IndicatorRelease(fastHandle); if(slowHandle != INVALID_HANDLE) IndicatorRelease(slowHandle); Print("EA1 deinitialized."); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Only process logic on a new M15 bar datetime currentBarTime = iTime(_Symbol, PERIOD_M15, 0); if(currentBarTime == lastBarTime) return; lastBarTime = currentBarTime; // Get crossover signal from closed bars [1] and [2] int signal = CheckCrossover(); if(signal == 0) return; // Close any opposite open position before opening a new trade CloseOppositePosition(signal); // Avoid opening a duplicate position in the same direction if(HasOpenPosition(signal)) return; // Calculate SL and TP in price double tpDistance = TakeProfitPips * PipSize; double slDistance = StopLossPips * PipSize; double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); if(signal == 1) // BUY signal — SMA12 crossed above SMA26 { double sl = NormalizeDouble(ask - slDistance, _Digits); double tp = NormalizeDouble(ask + tpDistance, _Digits); if(trade.Buy(LotSize, _Symbol, ask, sl, tp, "SMA CrossUp")) Print("BUY opened | Ask: ", ask, " | SL: ", sl, " | TP: ", tp); else Print("BUY failed | Error: ", GetLastError()); } else if(signal == -1) // SELL signal — SMA12 crossed below SMA26 { double sl = NormalizeDouble(bid + slDistance, _Digits); double tp = NormalizeDouble(bid - tpDistance, _Digits); if(trade.Sell(LotSize, _Symbol, bid, sl, tp, "SMA CrossDown")) Print("SELL opened | Bid: ", bid, " | SL: ", sl, " | TP: ", tp); else Print("SELL failed | Error: ", GetLastError()); } } //+------------------------------------------------------------------+ //| Check for SMA crossover on the last two closed bars | //| Returns: 1 = Bullish cross (SMA12 crosses ABOVE SMA26) | //| -1 = Bearish cross (SMA12 crosses BELOW SMA26) | //| 0 = No crossover | //+------------------------------------------------------------------+ int CheckCrossover() { double fastCurrent[1], fastPrev[1]; double slowCurrent[1], slowPrev[1]; // Copy values for bar [1] (last closed bar) and bar [2] (bar before that) if(CopyBuffer(fastHandle, 0, 1, 1, fastCurrent) < 1) return 0; if(CopyBuffer(fastHandle, 0, 2, 1, fastPrev) < 1) return 0; if(CopyBuffer(slowHandle, 0, 1, 1, slowCurrent) < 1) return 0; if(CopyBuffer(slowHandle, 0, 2, 1, slowPrev) < 1) return 0; bool bullishCross = (fastPrev[0] <= slowPrev[0]) && (fastCurrent[0] > slowCurrent[0]); bool bearishCross = (fastPrev[0] >= slowPrev[0]) && (fastCurrent[0] < slowCurrent[0]); if(bullishCross) return 1; if(bearishCross) return -1; return 0; } //+------------------------------------------------------------------+ //| Close any open position opposite to the new signal | //+------------------------------------------------------------------+ void CloseOppositePosition(int signal) { for(int i = PositionsTotal() - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket == 0) continue; if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue; if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue; long posType = PositionGetInteger(POSITION_TYPE); // Close BUY position on a SELL signal, or SELL position on a BUY signal if((signal == -1 && posType == POSITION_TYPE_BUY) || (signal == 1 && posType == POSITION_TYPE_SELL)) { if(trade.PositionClose(ticket)) Print("Position closed | Ticket: ", ticket); else Print("Close failed | Ticket: ", ticket, " | Error: ", GetLastError()); } } } //+------------------------------------------------------------------+ //| Check if there is already an open position in the signal direction| //+------------------------------------------------------------------+ bool HasOpenPosition(int signal) { for(int i = 0; i < PositionsTotal(); i++) { ulong ticket = PositionGetTicket(i); if(ticket == 0) continue; if(PositionGetString(POSITION_SYMBOL) != _Symbol) continue; if(PositionGetInteger(POSITION_MAGIC) != MagicNumber) continue; long posType = PositionGetInteger(POSITION_TYPE); if(signal == 1 && posType == POSITION_TYPE_BUY) return true; if(signal == -1 && posType == POSITION_TYPE_SELL) return true; } return false; } //+------------------------------------------------------------------+