//+------------------------------------------------------------------+ //| Expert Advisor for Gold on M5 Chart | //| Strategy: Based on last 5 bars' high-low range | //+------------------------------------------------------------------+ #include //--- Input parameters input double LotSize = 1.0; input int TakeProfit = 200; input int StopLoss = 500; input int Slippage = 3; // Allowable slippage in points input bool AvoidNews = true; input string NewsStartTime = "00:00"; // Manual news start time (HH:MM) input string NewsEndTime = "00:00"; // Manual news end time (HH:MM) //--- Global variables const int MAGIC_NUMBER = 123456; // Unique identifier for EA orders double lastBuyPrice = 0; double lastSellPrice = 0; datetime lastSLTime = 0; // Track last stop loss hit time const int SL_WAIT_TIME = 20 * 60; // 20 minutes in seconds double InitialAccountBalance = 0; double MaxAccountBalance = 0; double MinAccountBalance = 0; //+------------------------------------------------------------------+ //| Check for High-Impact News (Manual Time) | //+------------------------------------------------------------------+ bool IsHighImpactNews() { if (!AvoidNews) return false; datetime now = TimeCurrent(); string timeParts[]; int startHour = 0, startMinute = 0, endHour = 0, endMinute = 0; if (StringSplit(NewsStartTime, ':', timeParts) == 2) { startHour = StringToInteger(timeParts[0]); startMinute = StringToInteger(timeParts[1]); } if (StringSplit(NewsEndTime, ':', timeParts) == 2) { endHour = StringToInteger(timeParts[0]); endMinute = StringToInteger(timeParts[1]); } datetime today = iTime(Symbol(), PERIOD_D1, 0); datetime startTime = today + startHour * 3600 + startMinute * 60; datetime endTime = today + endHour * 3600 + endMinute * 60; if (now >= startTime && now <= endTime) return true; return false; } int CountOpenOrders(int type) { int count = 0; for (int i = 0; i < OrdersTotal(); i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderMagicNumber() == MAGIC_NUMBER && OrderType() == type) { count++; } } } return count; } //+------------------------------------------------------------------+ //| Calculate Entry Conditions | //+------------------------------------------------------------------+ void CheckTradeConditions() { if (TimeCurrent() - lastSLTime < SL_WAIT_TIME) return; // Wait 20 minutes after SL hit double high4 = -DBL_MAX, low4 = DBL_MAX; double openCloseSum = 0; // Sum of absolute differences of open and close prices for (int i = 0; i < 4; i++) { double openPrice = iOpen(Symbol(), PERIOD_M5, i); double closePrice = iClose(Symbol(), PERIOD_M5, i); openCloseSum += MathAbs(openPrice - closePrice); high4 = MathMax(high4, openPrice); low4 = MathMin(low4, closePrice); } double high5 = -DBL_MAX, low5 = DBL_MAX; for (int j = 3; j >= 0; j--) { high5 = MathMax(high5, iHigh(Symbol(), PERIOD_M5, j)); low5 = MathMin(low5, iLow(Symbol(), PERIOD_M5, j)); } double range = openCloseSum; if (range < 50 * Point) return; // 500 pips (MT4 uses fractional pip representation) double lastClose = iClose(Symbol(), PERIOD_M5, 0); if (lastClose <= low5 && lastBuyPrice != low5 && CountOpenOrders(OP_BUY) == 0) { OpenOrder(OP_BUY, low5); lastBuyPrice = low5; } else if (lastClose >= high5 && lastSellPrice != high5 && CountOpenOrders(OP_SELL) == 0) { OpenOrder(OP_SELL, high5); lastSellPrice = high5; } } //+------------------------------------------------------------------+ //| Open Trade Order with Requote Handling | //+------------------------------------------------------------------+ bool OpenOrder(int type, double price) { if (IsHighImpactNews()) return false; // Avoid trading during news double sl = (type == OP_BUY) ? price - StopLoss * Point : price + StopLoss * Point; double tp = (type == OP_BUY) ? price + TakeProfit * Point : price - TakeProfit * Point; int retryCount = 3; // Retry up to 3 times on requote int ticket; for (int i = 0; i < retryCount; i++) { ticket = OrderSend(Symbol(), type, LotSize, price, Slippage, sl, tp, "Gold M5 EA", MAGIC_NUMBER, 0, clrNONE); if (ticket > 0) return true; if (GetLastError() == 138) // Requote error { RefreshRates(); price = (type == OP_BUY) ? Ask : Bid; // Update price } else { break; // Exit loop if another error occurs } } return false; } //+------------------------------------------------------------------+ //| Track Stop Loss Hit and Wait Time | //+------------------------------------------------------------------+ void CheckStopLossHit() { for (int i = 0; i < OrdersTotal(); i++) { if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { if (OrderMagicNumber() == MAGIC_NUMBER && OrderType() <= OP_SELL) { if (OrderClosePrice() == OrderStopLoss() && OrderType() <= OP_SELL) { lastSLTime = TimeCurrent(); // Record last stop loss hit time } } } } } //+------------------------------------------------------------------+ //| Main Function - OnTick | //+------------------------------------------------------------------+ void OnTick() { CheckStopLossHit(); CheckTradeConditions(); double CurrentAccountBalance = AccountBalance(); if (MaxAccountBalance < AccountBalance()) MaxAccountBalance = AccountBalance(); if (MinAccountBalance > AccountBalance()) MinAccountBalance = AccountBalance(); Comment ("Initial Account Balance was ", InitialAccountBalance, ", Minimum Balance was ", MinAccountBalance, ", Max Balance was ", MaxAccountBalance, ", Current Balance is ", CurrentAccountBalance, " and Current Equity is ", AccountEquity(), ""); }