//+------------------------------------------------------------------+ //| Trend + Pullback EA (Default Version) | //| Works on NASDAQ100 & GOLD | //+------------------------------------------------------------------+ #property strict input int EMA_Fast = 20; input int EMA_Trend = 200; input double RiskPercent = 1.0; input double RR = 2.0; //--- Handles int fastEMA, trendEMA; //+------------------------------------------------------------------+ int OnInit() { fastEMA = iMA(_Symbol, _Period, EMA_Fast, 0, MODE_EMA, PRICE_CLOSE); trendEMA = iMA(_Symbol, _Period, EMA_Trend, 0, MODE_EMA, PRICE_CLOSE); if (fastEMA == INVALID_HANDLE || trendEMA == INVALID_HANDLE) { Print("Error creating indicators."); return INIT_FAILED; } return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ void OnTick() { if(!IsNewCandle()) return; double fastEMA_val = CopyBufferVal(fastEMA, 0); double trendEMA_val = CopyBufferVal(trendEMA, 0); double prevHigh = iHigh(_Symbol, _Period, 1); double prevLow = iLow(_Symbol, _Period, 1); double close1 = iClose(_Symbol, _Period, 1); // previous candle close double open1 = iOpen (_Symbol, _Period, 1); // previous candle open double low1 = iLow (_Symbol, _Period, 1); double high1 = iHigh (_Symbol, _Period, 1); // Trend Filters bool upTrend = (close1 > trendEMA_val); bool downTrend = (close1 < trendEMA_val); // Pullback Check = price touches EMA20 bool touchedFastEMA = (low1 <= fastEMA_val && high1 >= fastEMA_val); // Engulfing Conditions bool bullishEngulf = (close1 > open1) && (close1 > iOpen(_Symbol, _Period, 2)) && (open1 < iClose(_Symbol, _Period, 2)); bool bearishEngulf = (close1 < open1) && (close1 < iOpen(_Symbol, _Period, 2)) && (open1 > iClose(_Symbol, _Period, 2)); // BUY CONDITIONS if (upTrend && touchedFastEMA && bullishEngulf) { double sl = prevLow; // swing low double entry = close1; double tp = entry + (entry - sl) * RR; // RR = 2 OpenTrade(ORDER_TYPE_BUY, entry, sl, tp); } // SELL CONDITIONS if (downTrend && touchedFastEMA && bearishEngulf) { double sl = prevHigh; // swing high double entry = close1; double tp = entry - (sl - entry) * RR; OpenTrade(ORDER_TYPE_SELL, entry, sl, tp); } } //+------------------------------------------------------------------+ // Risk-based Lot Calculation //+------------------------------------------------------------------+ double LotByRisk(double slPrice, ENUM_ORDER_TYPE type) { double riskMoney = AccountBalance() * (RiskPercent / 100.0); double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE); double slDistance = MathAbs(slPrice - SymbolInfoDouble(_Symbol, SYMBOL_BID)); double costPerLot = slDistance / tickSize * tickValue; if (costPerLot <= 0) return 0.1; return NormalizeDouble(riskMoney / costPerLot, 2); } //+------------------------------------------------------------------+ void OpenTrade(ENUM_ORDER_TYPE type, double price, double sl, double tp) { if (PositionsTotal() > 0) return; // one trade at a time double lots = LotByRisk(sl, type); MqlTradeRequest req; MqlTradeResult res; ZeroMemory(req); req.action = TRADE_ACTION_DEAL; req.symbol = _Symbol; req.volume = lots; req.type = type; req.price = (type == ORDER_TYPE_BUY ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID)); req.sl = sl; req.tp = tp; req.magic = 12345; OrderSend(req, res); } //+------------------------------------------------------------------+ bool IsNewCandle() { static datetime lastTime = 0; datetime current = iTime(_Symbol, _Period, 0); if (current != lastTime) { lastTime = current; return true; } return false; } //+------------------------------------------------------------------+ double CopyBufferVal(int handle, int index) { double val[]; if(CopyBuffer(handle, 0, index, 1, val) < 1) return EMPTY_VALUE; return val[0]; } //+------------------------------------------------------------------+