//+------------------------------------------------------------------+ //| EURUSD H1 EMA Bot – 2025 FINAL 100% CLEAN | //+------------------------------------------------------------------+ #property copyright "2025" #property version "1.00 #property strict #include CTrade trade; //--- Inputs input double RiskPercent = 0.75; input int Slippage = 3; input int MaxPositions = 2; input double MaxSpreadPoints = 18; input bool TradeFridayClose = true; input double RewardRR = 2.7; input double TrailingStartR = 1.0; input double BreakEvenR = 1.0; //--- Indicator handles (created once in OnInit) int handle_ema8, handle_ema9, handle_ema21, handle_ema55, handle_ema200, handle_rsi; //+------------------------------------------------------------------+ int OnInit() { if(_Symbol!="EURUSD" || _Period!=PERIOD_H1) { Alert("This EA works ONLY on EURUSD H1"); return(INIT_FAILED); } handle_ema8 = iMA(_Symbol,PERIOD_H1,8, 0,MODE_EMA,PRICE_CLOSE); handle_ema9 = iMA(_Symbol,PERIOD_H1,9, 0,MODE_EMA,PRICE_CLOSE); handle_ema21 = iMA(_Symbol,PERIOD_H1,21, 0,MODE_EMA,PRICE_CLOSE); handle_ema55 = iMA(_Symbol,PERIOD_H1,55, 0,MODE_EMA,PRICE_CLOSE); handle_ema200 = iMA(_Symbol,PERIOD_H1,200,0,MODE_EMA,PRICE_CLOSE); handle_rsi = iRSI(_Symbol,PERIOD_H1,14,PRICE_CLOSE); if(handle_ema8==INVALID_HANDLE || handle_ema9==INVALID_HANDLE || handle_ema21==INVALID_HANDLE || handle_ema55==INVALID_HANDLE || handle_ema200==INVALID_HANDLE || handle_rsi==INVALID_HANDLE) { Print("Failed to create indicator handles"); return(INIT_FAILED); } Print("EURUSD H1 2025 Bot – 100% CLEAN & READY"); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ void OnTick() { if(PositionsTotal()>0) ManageOpenPositions(); if(!IsNewBar()) return; if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) return; if(!IsLondonNYSession()) return; if(TradeFridayClose && TimeDayOfWeek(TimeCurrent())==5 && TimeHour(TimeCurrent())>=15) return; double spread = (SymbolInfoDouble(_Symbol,SYMBOL_ASK)-SymbolInfoDouble(_Symbol,SYMBOL_BID))/_Point; if(spread>MaxSpreadPoints) return; if(PositionsTotal()>=MaxPositions) return; //--- Get indicator values (shift 1 = previous closed bar) double ema8[], ema9[], ema21[], ema55[], ema200[], rsi[]; if(CopyBuffer(handle_ema8, 0,1,1,ema8) <=0) return; if(CopyBuffer(handle_ema9, 0,1,1,ema9) <=0) return; if(CopyBuffer(handle_ema21, 0,1,1,ema21) <=0) return; if(CopyBuffer(handle_ema55, 0,1,1,ema55) <=0) return; if(CopyBuffer(handle_ema200,0,1,1,ema200) <=0) return; if(CopyBuffer(handle_rsi, 0,1,1,rsi) <=0) return; double o1 = iOpen(_Symbol,PERIOD_H1,1); double c1 = iClose(_Symbol,PERIOD_H1,1); double h1 = iHigh(_Symbol,PERIOD_H1,1); double l1 = iLow(_Symbol,PERIOD_H1,1); double o2 = iOpen(_Symbol,PERIOD_H1,2); double c2 = iClose(_Symbol,PERIOD_H1,2); bool upTrend = ema21[0]>ema55[0] && ema55[0]>ema200[0]; bool downTrend = ema21[0]o1 && rsi[0]>40 && rsi[0]<65) if(BullishEngulfing(o1,c1,o2,c2) || BullishPinbar(o1,c1,h1,l1)) EnterLong(); // SHORT if(downTrend && (h1>=ema8[0] || h1>=ema9[0]) && c135 && rsi[0]<60) if(BearishEngulfing(o1,c1,o2,c2) || BearishPinbar(o1,c1,h1,l1)) EnterShort(); } //+------------------------------------------------------------------+ void EnterLong() { int idx = iLowest(_Symbol,PERIOD_H1,MODE_LOW,20,1); double sl = iLow(_Symbol,PERIOD_H1,idx) - 8*_Point; double tp = SymbolInfoDouble(_Symbol,SYMBOL_ASK) + RewardRR*(SymbolInfoDouble(_Symbol,SYMBOL_ASK)-sl); double lot = OptimalLot((SymbolInfoDouble(_Symbol,SYMBOL_ASK)-sl)/_Point); trade.SetDeviationInPoints(Slippage); trade.Buy(lot,_Symbol,0,sl,tp,"2025 Long"); } void EnterShort() { int idx = iHighest(_Symbol,PERIOD_H1,MODE_HIGH,20,1); double sl = iHigh(_Symbol,PERIOD_H1,idx) + 8*_Point; double tp = SymbolInfoDouble(_Symbol,SYMBOL_BID) - RewardRR*(sl-SymbolInfoDouble(_Symbol,SYMBOL_BID)); double lot = OptimalLot((sl-SymbolInfoDouble(_Symbol,SYMBOL_BID))/_Point); trade.SetDeviationInPoints(Slippage); trade.Sell(lot,_Symbol,0,sl,tp,"2025 Short"); } //+------------------------------------------------------------------+ double OptimalLot(double riskPips) { if(riskPips<=0) return(0.01); double money = AccountInfoDouble(ACCOUNT_BALANCE)*RiskPercent/100.0; double tick = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE); if(tick<=0) return(0.01); double lot = money/(riskPips*tick); return(NormalizeDouble(MathMax(lot,0.01),2)); } //+------------------------------------------------------------------+ void ManageOpenPositions() { for(int i=PositionsTotal()-1; i>=0; i--) { if(!PositionSelectByIndex(i)) continue; if(PositionGetString(POSITION_SYMBOL)!=_Symbol) continue; ulong ticket = PositionGetInteger(POSITION_TICKET); int type = (int)PositionGetInteger(POSITION_TYPE); double sl = PositionGetDouble(POSITION_SL); double tp = PositionGetDouble(POSITION_TP); double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); double riskR = MathAbs(openPrice-sl)/_Point; if(type==POSITION_TYPE_BUY) { if(Bid >= openPrice + BreakEvenR*riskR*_Point && sl < openPrice) trade.PositionModify(ticket,openPrice,tp); if(Bid > openPrice + TrailingStartR*riskR*_Point) { double newSL = Bid - riskR*_Point; if(newSL>sl) trade.PositionModify(ticket,newSL,tp); } } else { if(Ask <= openPrice - BreakEvenR*riskR*_Point && (sl>openPrice || sl==0)) trade.PositionModify(ticket,openPrice,tp); if(Ask < openPrice - TrailingStartR*riskR*_Point) { double newSL = Ask + riskR*_Point; if(newSL=7 && TimeHour(TimeCurrent())<17); } //+------------------------------------------------------------------+ // Clean pattern functions bool BullishEngulfing(double o1,double c1,double o2,double c2) { return(o2>c2 && c1>o1 && c1>o2 && o1c2); } bool BullishPinbar(double o1,double c1,double h1,double l1) { double b=MathAbs(o1-c1); return((MathMin(o1,c1)-l1)>2*b && c1>o1); } bool BearishPinbar(double o1,double c1,double h1,double l1) { double b=MathAbs(o1-c1); return((h1-MathMax(o1,c1))>2*b && c1