//+------------------------------------------------------------------+
//| XAUUSD Optimized EA - MA/RSI/News/Trailing |
//| Author: ChatGPT | MetaTrader 4 |
//+------------------------------------------------------------------+
#property strict
// === Input Parameters ===
extern string StrategySettings = "==== Strategy ====";
extern int FastMAPeriod = 9;
extern int SlowMAPeriod = 21;
extern int MAType = MODE_EMA;
extern int RSI_Period = 14;
extern double RSI_Low = 30.0;
extern double RSI_High = 70.0;
extern string TradeSettings = "==== Risk & Trade ====";
extern double LotSize = 0.1;
extern bool UseMoneyManagement = true;
extern double RiskPercent = 2.0;
extern double StopLoss = 300; // in points
extern double TakeProfit = 600; // in points
extern double MaxDrawdownPercent = 15.0;
extern string TrailingSettings = "==== Trailing Stop ====";
extern bool EnableTrailingStop = true;
extern int TrailingStart = 300; // in points
extern int TrailingStep = 100;
extern string NewsSettings = "==== News Filter ====";
extern bool EnableNewsFilter = true;
extern int NewsHourStart = 12;
extern int NewsHourEnd = 15;
extern int Slippage = 3;
datetime lastTradeTime;
//+------------------------------------------------------------------+
int OnInit()
{
Print("XAUUSD Optimized EA initialized.");
return INIT_SUCCEEDED;
}
//+------------------------------------------------------------------+
void OnTick()
{
if (_Symbol != "XAUUSD" || _Period != PERIOD_M15) return;
ManageTrailingStop();
if (OrdersTotal() > 0) return; // Allow one position at a time
if (!CheckDrawdown()) return;
if (EnableNewsFilter && IsNewsTime()) return;
if (!RSIFilterPasses()) return;
double fastMA = iMA(NULL, 0, FastMAPeriod, 0, MAType, PRICE_CLOSE, 1);
double slowMA = iMA(NULL, 0, SlowMAPeriod, 0, MAType, PRICE_CLOSE, 1);
double prevFastMA = iMA(NULL, 0, FastMAPeriod, 0, MAType, PRICE_CLOSE, 2);
double prevSlowMA = iMA(NULL, 0, SlowMAPeriod, 0, MAType, PRICE_CLOSE, 2);
double sl = StopLoss * Point;
double tp = TakeProfit * Point;
double lots = UseMoneyManagement ? CalculateLotSize(RiskPercent) : LotSize;
// --- Buy Signal ---
if (prevFastMA < prevSlowMA && fastMA > slowMA)
{
if (OrderSend(_Symbol, OP_BUY, lots, Ask, Slippage, Ask - sl, Ask + tp, "Buy
Order", 0, 0, clrBlue) > 0)
lastTradeTime = TimeCurrent();
}
// --- Sell Signal ---
if (prevFastMA > prevSlowMA && fastMA < slowMA)
{
if (OrderSend(_Symbol, OP_SELL, lots, Bid, Slippage, Bid + sl, Bid - tp,
"Sell Order", 0, 0, clrRed) > 0)
lastTradeTime = TimeCurrent();
}
}
//+------------------------------------------------------------------+
//| RSI Filter |
//+------------------------------------------------------------------+
bool RSIFilterPasses()
{
double rsi = iRSI(NULL, 0, RSI_Period, PRICE_CLOSE, 1);
return (rsi > RSI_Low && rsi < RSI_High);
}
//+------------------------------------------------------------------+
//| Drawdown Checker |
//+------------------------------------------------------------------+
bool CheckDrawdown()
{
double balance = AccountBalance();
double equity = AccountEquity();
double drawdown = 100.0 * (balance - equity) / balance;
if (drawdown >= MaxDrawdownPercent)
{
Print("Drawdown exceeded: ", drawdown, "%");
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| News Filter (Basic Time-Based) |
//+------------------------------------------------------------------+
bool IsNewsTime()
{
int currentHour = TimeHour(TimeCurrent());
if (currentHour >= NewsHourStart && currentHour <= NewsHourEnd)
{
Print("Skipping trade due to news hour: ", currentHour);
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| Risk-based Money Management |
//+------------------------------------------------------------------+
double CalculateLotSize(double riskPercent)
{
double riskAmount = AccountBalance() * riskPercent / 100;
double tickValue = MarketInfo(_Symbol, MODE_TICKVALUE);
double slInMoney = StopLoss * tickValue;
if (slInMoney <= 0.0) slInMoney = 1.0;
double lots = NormalizeDouble(riskAmount / slInMoney, 2);
return MathMax(lots, 0.01); // Minimum allowed lot
}
//+------------------------------------------------------------------+
//| Trailing Stop Logic |
//+------------------------------------------------------------------+
void ManageTrailingStop()
{
if (!EnableTrailingStop) return;
for (int i = 0; i < OrdersTotal(); i++)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if (OrderSymbol() != _Symbol) continue;
double trailStart = TrailingStart * Point;
double trailStep = TrailingStep * Point;
if (OrderType() == OP_BUY)
{
double profit = Bid - OrderOpenPrice();
double newSL = Bid - trailStep;
if (profit > trailStart && newSL > OrderStopLoss())
OrderModify(OrderTicket(), OrderOpenPrice(), newSL,
OrderTakeProfit(), 0, clrGreen);
}
if (OrderType() == OP_SELL)
{
double profit = OrderOpenPrice() - Ask;
double newSL = Ask + trailStep;
if (profit > trailStart && (OrderStopLoss() == 0 || newSL <
OrderStopLoss()))
OrderModify(OrderTicket(), OrderOpenPrice(), newSL,
OrderTakeProfit(), 0, clrGreen);
}
}
}
}