347 lines
No EOL
13 KiB
MQL5
347 lines
No EOL
13 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| 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 <Trade\Trade.mqh>
|
|
|
|
// 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);
|
|
}
|
|
} |