AI-Trading-Bot-MT4/AITradingBot.mq4

361 lines
9.5 KiB
MQL4
Raw Permalink Normal View History

2026-08-26 04:59:38 +00:00
//+------------------------------------------------------------------+
//| AITradingBot.mq4 |
//| MT4 Automated Trading Bot - Starter Version |
//| Strategy: EMA Crossover + RSI + Risk Management |
//+------------------------------------------------------------------+
#property strict
//---------------------- INPUT SETTINGS -----------------------------//
input double RiskPercent = 1.0;
input double FixedLot = 0.01;
input bool UseFixedLot = true;
input int FastEMA = 9;
input int SlowEMA = 21;
input int RSIPeriod = 14;
input double BuyRSIMin = 55.0;
input double SellRSIMax = 45.0;
input int StopLossPips = 30;
input int TakeProfitPips = 60;
input int TrailingStopPips = 20;
input int MaxSpreadPips = 3;
input int Slippage = 5;
input int MagicNumber = 20260826;
input bool EnableBuy = true;
input bool EnableSell = true;
input bool EnableTrailing = true;
//---------------------- GLOBAL VARIABLES ---------------------------//
datetime LastBarTime = 0;
//+------------------------------------------------------------------+
//| Expert initialization |
//+------------------------------------------------------------------+
int OnInit()
{
Print("AITradingBot MT4 started successfully.");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Print("AITradingBot MT4 stopped.");
}
//+------------------------------------------------------------------+
//| Main Tick Function |
//+------------------------------------------------------------------+
void OnTick()
{
ManageTrailingStop();
if(!IsNewBar())
return;
if(!TradingAllowed())
return;
if(CountOpenTrades() > 0)
return;
double fastEMA1 = iMA(Symbol(), PERIOD_CURRENT, FastEMA, 0, MODE_EMA, PRICE_CLOSE, 1);
double fastEMA2 = iMA(Symbol(), PERIOD_CURRENT, FastEMA, 0, MODE_EMA, PRICE_CLOSE, 2);
double slowEMA1 = iMA(Symbol(), PERIOD_CURRENT, SlowEMA, 0, MODE_EMA, PRICE_CLOSE, 1);
double slowEMA2 = iMA(Symbol(), PERIOD_CURRENT, SlowEMA, 0, MODE_EMA, PRICE_CLOSE, 2);
double rsi = iRSI(Symbol(), PERIOD_CURRENT, RSIPeriod, PRICE_CLOSE, 1);
// BUY SIGNAL
bool buySignal =
EnableBuy &&
fastEMA2 <= slowEMA2 &&
fastEMA1 > slowEMA1 &&
rsi >= BuyRSIMin;
// SELL SIGNAL
bool sellSignal =
EnableSell &&
fastEMA2 >= slowEMA2 &&
fastEMA1 < slowEMA1 &&
rsi <= SellRSIMax;
if(buySignal)
{
OpenBuy();
return;
}
if(sellSignal)
{
OpenSell();
return;
}
}
//+------------------------------------------------------------------+
//| Check for new candle |
//+------------------------------------------------------------------+
bool IsNewBar()
{
datetime currentBar = iTime(Symbol(), PERIOD_CURRENT, 0);
if(currentBar != LastBarTime)
{
LastBarTime = currentBar;
return(true);
}
return(false);
}
//+------------------------------------------------------------------+
//| Check trading conditions |
//+------------------------------------------------------------------+
bool TradingAllowed()
{
if(!IsTradeAllowed())
{
Print("Trading is not allowed.");
return(false);
}
double spreadPips = (Ask - Bid) / PipSize();
if(spreadPips > MaxSpreadPips)
{
Print("Spread too high: ", DoubleToString(spreadPips, 1), " pips");
return(false);
}
return(true);
}
//+------------------------------------------------------------------+
//| Open Buy |
//+------------------------------------------------------------------+
void OpenBuy()
{
RefreshRates();
double pip = PipSize();
double lots = CalculateLotSize();
double price = Ask;
double sl = NormalizeDouble(price - StopLossPips * pip, Digits);
double tp = NormalizeDouble(price + TakeProfitPips * pip, Digits);
int ticket = OrderSend(
Symbol(),
OP_BUY,
lots,
price,
Slippage,
sl,
tp,
"AITradingBot BUY",
MagicNumber,
0,
clrBlue
);
if(ticket < 0)
Print("BUY failed. Error: ", GetLastError());
else
Print("BUY opened successfully. Ticket: ", ticket);
}
//+------------------------------------------------------------------+
//| Open Sell |
//+------------------------------------------------------------------+
void OpenSell()
{
RefreshRates();
double pip = PipSize();
double lots = CalculateLotSize();
double price = Bid;
double sl = NormalizeDouble(price + StopLossPips * pip, Digits);
double tp = NormalizeDouble(price - TakeProfitPips * pip, Digits);
int ticket = OrderSend(
Symbol(),
OP_SELL,
lots,
price,
Slippage,
sl,
tp,
"AITradingBot SELL",
MagicNumber,
0,
clrRed
);
if(ticket < 0)
Print("SELL failed. Error: ", GetLastError());
else
Print("SELL opened successfully. Ticket: ", ticket);
}
//+------------------------------------------------------------------+
//| Calculate lot size |
//+------------------------------------------------------------------+
double CalculateLotSize()
{
if(UseFixedLot)
return(NormalizeLot(FixedLot));
double riskMoney = AccountBalance() * RiskPercent / 100.0;
double pipValuePerLot =
MarketInfo(Symbol(), MODE_TICKVALUE) /
MarketInfo(Symbol(), MODE_TICKSIZE) *
PipSize();
if(pipValuePerLot <= 0)
return(NormalizeLot(FixedLot));
double lots = riskMoney / (StopLossPips * pipValuePerLot);
return(NormalizeLot(lots));
}
//+------------------------------------------------------------------+
//| Normalize lot size |
//+------------------------------------------------------------------+
double NormalizeLot(double lots)
{
double minLot = MarketInfo(Symbol(), MODE_MINLOT);
double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
if(lots < minLot)
lots = minLot;
if(lots > maxLot)
lots = maxLot;
lots = MathFloor(lots / lotStep) * lotStep;
return(NormalizeDouble(lots, 2));
}
//+------------------------------------------------------------------+
//| Pip size |
//+------------------------------------------------------------------+
double PipSize()
{
if(Digits == 3 || Digits == 5)
return(Point * 10);
return(Point);
}
//+------------------------------------------------------------------+
//| Count current bot trades |
//+------------------------------------------------------------------+
int CountOpenTrades()
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() &&
OrderMagicNumber() == MagicNumber)
{
count++;
}
}
}
return(count);
}
//+------------------------------------------------------------------+
//| Trailing Stop |
//+------------------------------------------------------------------+
void ManageTrailingStop()
{
if(!EnableTrailing)
return;
double pip = PipSize();
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
continue;
if(OrderSymbol() != Symbol())
continue;
if(OrderMagicNumber() != MagicNumber)
continue;
// BUY TRAILING
if(OrderType() == OP_BUY)
{
double newSL = NormalizeDouble(
Bid - TrailingStopPips * pip,
Digits
);
if(Bid - OrderOpenPrice() >= TrailingStopPips * pip)
{
if(OrderStopLoss() < newSL)
{
bool modified = OrderModify(
OrderTicket(),
OrderOpenPrice(),
newSL,
OrderTakeProfit(),
0,
clrBlue
);
if(!modified)
Print("BUY trailing error: ", GetLastError());
}
}
}
// SELL TRAILING
if(OrderType() == OP_SELL)
{
double newSL = NormalizeDouble(
Ask + TrailingStopPips * pip,
Digits
);
if(OrderOpenPrice() - Ask >= TrailingStopPips * pip)
{
if(OrderStopLoss() == 0 || OrderStopLoss() > newSL)
{
bool modified = OrderModify(
OrderTicket(),
OrderOpenPrice(),
newSL,
OrderTakeProfit(),
0,
clrRed
);
if(!modified)
Print("SELL trailing error: ", GetLastError());
}
}
}
}
}
//+------------------------------------------------------------------+