//+------------------------------------------------------------------+ //| SMA_CCI_Crossover_EA.mq4 | //| | //| SMA 100 (Shift 10) vs CCI 55 Crossover | //+------------------------------------------------------------------+ #property copyright "Custom EA" #property link "" #property version "1.00" #property strict // Input Parameters input double LotSize = 0.1; // Lot Size input int StopLoss = 50; // Stop Loss in pips (0 = disabled) input int TakeProfit = 100; // Take Profit in pips (0 = disabled) input int BreakevenPips = 30; // Move to Breakeven after X pips (0 = disabled) input int TrailingStop = 20; // Trailing Stop in pips (0 = disabled) input int TrailingStep = 5; // Trailing Step in pips input int MagicNumber = 12345; // Magic Number for this EA // Indicator Parameters input int SMA_Period = 100; // SMA Period input int SMA_Shift = 10; // SMA Shift input int CCI_Period = 55; // CCI Period input double CCI_Min = -500.0; // CCI Minimum Level input double CCI_Max = 500.0; // CCI Maximum Level // Global Variables int LastBarTraded = -1; double point_multiplier; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Determine point multiplier for 4/5 digit brokers if(Digits == 3 || Digits == 5) point_multiplier = 10.0; else point_multiplier = 1.0; Print("EA Initialized Successfully"); Print("Symbol: ", Symbol(), " | Timeframe: ", Period()); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Print("EA Deinitialized"); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Only trade on new candle if(Bars <= 100) return; // Need enough bars for indicators // Check for new bar if(LastBarTraded == Bars) return; // Calculate indicators for the closed candle (index 1) double sma_current = iMA(Symbol(), 0, SMA_Period, SMA_Shift, MODE_SMA, PRICE_CLOSE, 1); double cci_current = iCCI(Symbol(), 0, CCI_Period, PRICE_CLOSE, 1); // Previous candle values for crossover detection double sma_previous = iMA(Symbol(), 0, SMA_Period, SMA_Shift, MODE_SMA, PRICE_CLOSE, 2); double cci_previous = iCCI(Symbol(), 0, CCI_Period, PRICE_CLOSE, 2); // Clamp CCI values to min/max range cci_current = MathMax(CCI_Min, MathMin(CCI_Max, cci_current)); cci_previous = MathMax(CCI_Min, MathMin(CCI_Max, cci_previous)); // Check for crossover signals bool buySignal = (cci_previous <= sma_previous && cci_current > sma_current); bool sellSignal = (cci_previous >= sma_previous && cci_current < sma_current); // Manage existing positions ManageOpenPositions(); // Check current position int currentPosition = GetCurrentPosition(); // Trading Logic if(buySignal && currentPosition != 1) { if(currentPosition == -1) CloseAllOrders(); OpenBuyOrder(); LastBarTraded = Bars; } else if(sellSignal && currentPosition != -1) { if(currentPosition == 1) CloseAllOrders(); OpenSellOrder(); LastBarTraded = Bars; } } //+------------------------------------------------------------------+ //| Get Current Position | //| Returns: 1 for Buy, -1 for Sell, 0 for No Position | //+------------------------------------------------------------------+ int GetCurrentPosition() { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { if(OrderType() == OP_BUY) return 1; if(OrderType() == OP_SELL) return -1; } } } return 0; } //+------------------------------------------------------------------+ //| Open Buy Order | //+------------------------------------------------------------------+ void OpenBuyOrder() { double sl = 0, tp = 0; if(StopLoss > 0) sl = NormalizeDouble(Ask - StopLoss * Point * point_multiplier, Digits); if(TakeProfit > 0) tp = NormalizeDouble(Ask + TakeProfit * Point * point_multiplier, Digits); int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, sl, tp, "SMA-CCI Buy", MagicNumber, 0, clrGreen); if(ticket > 0) Print("BUY order opened: ", ticket); else Print("Error opening BUY order: ", GetLastError()); } //+------------------------------------------------------------------+ //| Open Sell Order | //+------------------------------------------------------------------+ void OpenSellOrder() { double sl = 0, tp = 0; if(StopLoss > 0) sl = NormalizeDouble(Bid + StopLoss * Point * point_multiplier, Digits); if(TakeProfit > 0) tp = NormalizeDouble(Bid - TakeProfit * Point * point_multiplier, Digits); int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, sl, tp, "SMA-CCI Sell", MagicNumber, 0, clrRed); if(ticket > 0) Print("SELL order opened: ", ticket); else Print("Error opening SELL order: ", GetLastError()); } //+------------------------------------------------------------------+ //| Close All Orders | //+------------------------------------------------------------------+ void CloseAllOrders() { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { if(OrderType() == OP_BUY) OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrWhite); else if(OrderType() == OP_SELL) OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrWhite); } } } } //+------------------------------------------------------------------+ //| Manage Open Positions (Breakeven & Trailing Stop) | //+------------------------------------------------------------------+ void ManageOpenPositions() { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { if(OrderType() == OP_BUY) { double profit_pips = (Bid - OrderOpenPrice()) / (Point * point_multiplier); // Move to Breakeven if(BreakevenPips > 0 && profit_pips >= BreakevenPips) { if(OrderStopLoss() < OrderOpenPrice()) { double new_sl = NormalizeDouble(OrderOpenPrice() + 1 * Point * point_multiplier, Digits); OrderModify(OrderTicket(), OrderOpenPrice(), new_sl, OrderTakeProfit(), 0, clrBlue); Print("Moved to Breakeven for BUY order: ", OrderTicket()); } } // Trailing Stop if(TrailingStop > 0 && profit_pips >= TrailingStop) { double new_sl = NormalizeDouble(Bid - TrailingStop * Point * point_multiplier, Digits); if(new_sl > OrderStopLoss() && (new_sl - OrderStopLoss()) >= TrailingStep * Point * point_multiplier) { OrderModify(OrderTicket(), OrderOpenPrice(), new_sl, OrderTakeProfit(), 0, clrBlue); Print("Trailing Stop updated for BUY order: ", OrderTicket()); } } } else if(OrderType() == OP_SELL) { double profit_pips = (OrderOpenPrice() - Ask) / (Point * point_multiplier); // Move to Breakeven if(BreakevenPips > 0 && profit_pips >= BreakevenPips) { if(OrderStopLoss() > OrderOpenPrice() || OrderStopLoss() == 0) { double new_sl = NormalizeDouble(OrderOpenPrice() - 1 * Point * point_multiplier, Digits); OrderModify(OrderTicket(), OrderOpenPrice(), new_sl, OrderTakeProfit(), 0, clrBlue); Print("Moved to Breakeven for SELL order: ", OrderTicket()); } } // Trailing Stop if(TrailingStop > 0 && profit_pips >= TrailingStop) { double new_sl = NormalizeDouble(Ask + TrailingStop * Point * point_multiplier, Digits); if((new_sl < OrderStopLoss() || OrderStopLoss() == 0) && (OrderStopLoss() - new_sl) >= TrailingStep * Point * point_multiplier) { OrderModify(OrderTicket(), OrderOpenPrice(), new_sl, OrderTakeProfit(), 0, clrBlue); Print("Trailing Stop updated for SELL order: ", OrderTicket()); } } } } } } } //+------------------------------------------------------------------+