//+------------------------------------------------------------------+ //| GBP_USD_Trading_EA.mq5 | //| Copyright 2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include // Input parameters input double LotSize = 0.1; // Lot size for trading input int MagicNumber = 123456; // Magic number for orders input int MACD_Fast = 12; // MACD Fast EMA period input int MACD_Slow = 26; // MACD Slow EMA period input int MACD_Signal = 9; // MACD Signal period input double MaxSpread = 3.0; // Maximum allowed spread in points input bool EnableBuyScenario1 = true; // Enable Buy Scenario 1 input bool EnableBuyScenario2 = true; // Enable Buy Scenario 2 input bool EnableSellScenario1 = true; // Enable Sell Scenario 1 input bool EnableSellScenario2 = true; // Enable Sell Scenario 2 // Key price levels const double ENTRY_BUY_LEVEL = 1.3600; // Buy entry level (green line) const double TARGET_LEVEL = 1.3641; // Target level (thicker green line) const double SUPPORT_LEVEL = 1.3566; // Support/resistance level const double SELL_TARGET = 1.3521; // Sell target level // Global variables CTrade trade; int macdHandle; double macdMain[], macdSignal[]; int testCount1_3566 = 0; // Counter for 1.3566 tests int testCount1_3600 = 0; // Counter for 1.3600 tests datetime lastTestTime1_3566 = 0; datetime lastTestTime1_3600 = 0; bool inLongPosition = false; bool inShortPosition = false; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Initialize MACD indicator macdHandle = iMACD(_Symbol, PERIOD_CURRENT, MACD_Fast, MACD_Slow, MACD_Signal, PRICE_CLOSE); if(macdHandle == INVALID_HANDLE) { Print("Error creating MACD indicator"); return INIT_FAILED; } // Set trade parameters trade.SetExpertMagicNumber(MagicNumber); trade.SetDeviationInPoints(10); // Initialize arrays ArraySetAsSeries(macdMain, true); ArraySetAsSeries(macdSignal, true); Print("GBP/USD Trading EA initialized successfully"); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { IndicatorRelease(macdHandle); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // Get current prices double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); // Check spread double spread = (ask - bid) / _Point; if(spread > MaxSpread) return; // Update MACD values if(!UpdateMACDValues()) return; // Update position status UpdatePositionStatus(); // Check for buy scenarios if(EnableBuyScenario1) CheckBuyScenario1(); if(EnableBuyScenario2) CheckBuyScenario2(); // Check for sell scenarios if(EnableSellScenario1) CheckSellScenario1(); if(EnableSellScenario2) CheckSellScenario2(); // Check for exit conditions CheckExitConditions(); } //+------------------------------------------------------------------+ //| Update MACD indicator values | //+------------------------------------------------------------------+ bool UpdateMACDValues() { if(CopyBuffer(macdHandle, 0, 0, 3, macdMain) < 0 || CopyBuffer(macdHandle, 1, 0, 3, macdSignal) < 0) { Print("Error copying MACD buffers"); return false; } return true; } //+------------------------------------------------------------------+ //| Update current position status | //+------------------------------------------------------------------+ void UpdatePositionStatus() { inLongPosition = false; inShortPosition = false; for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber) { if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) inLongPosition = true; else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) inShortPosition = true; } } } //+------------------------------------------------------------------+ //| Check Buy Scenario 1: Buy at 1.3600 with MACD above zero | //+------------------------------------------------------------------+ void CheckBuyScenario1() { if(inLongPosition) return; double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double currentPrice = ask; // Check if price is near entry level (within 5 pips) if(MathAbs(currentPrice - ENTRY_BUY_LEVEL) <= 5 * _Point) { // Check MACD conditions: above zero and rising if(macdMain[0] > 0 && macdMain[0] > macdMain[1]) { // Execute buy order if(trade.Buy(LotSize, _Symbol, ask, 0, TARGET_LEVEL, "Buy Scenario 1")) { Print("Buy Scenario 1 executed at ", ask); } } } } //+------------------------------------------------------------------+ //| Check Buy Scenario 2: Two tests of 1.3566 with MACD oversold | //+------------------------------------------------------------------+ void CheckBuyScenario2() { if(inLongPosition) return; double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double currentPrice = bid; // Check if price is testing 1.3566 level (within 3 pips) if(MathAbs(currentPrice - SUPPORT_LEVEL) <= 3 * _Point) { // Check if this is a new test (not within last 4 hours) if(TimeCurrent() - lastTestTime1_3566 > 4 * 3600) { testCount1_3566++; lastTestTime1_3566 = TimeCurrent(); Print("Test #", testCount1_3566, " of 1.3566 level detected"); // If second test and MACD is oversold (below -0.0005) if(testCount1_3566 >= 2 && macdMain[0] < -0.0005) { // Execute buy order if(trade.Buy(LotSize, _Symbol, ask, 0, TARGET_LEVEL, "Buy Scenario 2")) { Print("Buy Scenario 2 executed at ", ask); testCount1_3566 = 0; // Reset counter } } } } // Reset counter if price moves significantly away from level if(MathAbs(currentPrice - SUPPORT_LEVEL) > 20 * _Point) { testCount1_3566 = 0; } } //+------------------------------------------------------------------+ //| Check Sell Scenario 1: Sell below 1.3566 with MACD below zero | //+------------------------------------------------------------------+ void CheckSellScenario1() { if(inShortPosition) return; double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double currentPrice = bid; // Check if price breaks below 1.3566 if(currentPrice < SUPPORT_LEVEL - 2 * _Point) { // Check MACD conditions: below zero and declining if(macdMain[0] < 0 && macdMain[0] < macdMain[1]) { // Execute sell order if(trade.Sell(LotSize, _Symbol, bid, 0, SELL_TARGET, "Sell Scenario 1")) { Print("Sell Scenario 1 executed at ", bid); } } } } //+------------------------------------------------------------------+ //| Check Sell Scenario 2: Two tests of 1.3600 with MACD overbought| //+------------------------------------------------------------------+ void CheckSellScenario2() { if(inShortPosition) return; double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double currentPrice = ask; // Check if price is testing 1.3600 level (within 3 pips) if(MathAbs(currentPrice - ENTRY_BUY_LEVEL) <= 3 * _Point) { // Check if this is a new test (not within last 4 hours) if(TimeCurrent() - lastTestTime1_3600 > 4 * 3600) { testCount1_3600++; lastTestTime1_3600 = TimeCurrent(); Print("Test #", testCount1_3600, " of 1.3600 level detected"); // If second test and MACD is overbought (above 0.0005) if(testCount1_3600 >= 2 && macdMain[0] > 0.0005) { // Execute sell order if(trade.Sell(LotSize, _Symbol, bid, 0, SUPPORT_LEVEL, "Sell Scenario 2")) { Print("Sell Scenario 2 executed at ", bid); testCount1_3600 = 0; // Reset counter } } } } // Reset counter if price moves significantly away from level if(MathAbs(currentPrice - ENTRY_BUY_LEVEL) > 20 * _Point) { testCount1_3600 = 0; } } //+------------------------------------------------------------------+ //| Check exit conditions and reversal trades | //+------------------------------------------------------------------+ void CheckExitConditions() { double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber) { ulong ticket = PositionGetInteger(POSITION_TICKET); double openPrice = PositionGetDouble(POSITION_PRICE_OPEN); double currentPrice = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? bid : ask; // Check long position exit at target if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { if(currentPrice >= TARGET_LEVEL) { if(trade.PositionClose(ticket)) { Print("Long position closed at target: ", currentPrice); // Open reverse short position for pullback (30-35 pips) if(trade.Sell(LotSize, _Symbol, bid, 0, TARGET_LEVEL - 35 * _Point, "Reversal Short")) { Print("Reversal short position opened"); } } } } // Check short position exit at target else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { if(currentPrice <= SELL_TARGET) { if(trade.PositionClose(ticket)) { Print("Short position closed at target: ", currentPrice); // Open reverse long position for rebound (20-25 pips) if(trade.Buy(LotSize, _Symbol, ask, 0, SELL_TARGET + 25 * _Point, "Reversal Long")) { Print("Reversal long position opened"); } } } } } } } //+------------------------------------------------------------------+ //| Trade transaction function | //+------------------------------------------------------------------+ void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) { // Handle trade events if needed if(trans.type == TRADE_TRANSACTION_DEAL_ADD) { Print("Trade executed: ", trans.symbol, " Volume: ", trans.volume, " Price: ", trans.price); } }