//
+------------------------------------------
------------------------+
//|
MovingAverageCrossoverBot.mq
5|
//| Copyright 2023,
Your Name or Organization |
//|
https://www.yoururl |
//
+------------------------------------------
------------------------+
#property copyright "Copyright
2023"
#property link
"https://www.yoururl"
#property version "1.00"
// Input parameters
input int ShortMAPeriod = 50;
// Short MA Period
input int LongMAPeriod =
200; // Long MA Period
input double LotSize = 0.1;
// Lot Size
input double StopLoss = 200;
// Stop Loss (points)
input double TakeProfit = 300;
// Take Profit (points)
// Global variables
int shortMAHandle,
longMAHandle;
datetime lastBarTime;
//
+------------------------------------------
------------------------+
//| Expert initialization function
|
//
+------------------------------------------
------------------------+
int OnInit()
{
// Initialize moving averages
shortMAHandle =
iMA(_Symbol, _Period,
ShortMAPeriod, 0, MODE_SMA,
PRICE_CLOSE);
longMAHandle = iMA(_Symbol,
_Period, LongMAPeriod, 0,
MODE_SMA, PRICE_CLOSE);
if (shortMAHandle ==
INVALID_HANDLE ||
longMAHandle ==
INVALID_HANDLE)
{
Print("Error initializing
indicators!");
return(INIT_FAILED);
}
// Wait until indicators have
sufficient data
if
(BarsCalculated(shortMAHandle)
< ShortMAPeriod ||
BarsCalculated(longMAHandle)
< LongMAPeriod)
{
Print("Not enough historical
data");
return INIT_FAILED;
}
lastBarTime = 0;
return(INIT_SUCCEEDED);
}
//
+------------------------------------------
------------------------+
//| Expert tick function
|
//
+------------------------------------------
------------------------+
void OnTick()
{
// Check for new bar
datetime currentBarTime =
iTime(_Symbol, _Period, 0);
if (currentBarTime ==
lastBarTime)
return;
lastBarTime = currentBarTime;
// Get MA values for current
and previous bar
double shortMA[2], longMA[2];
if (CopyBuffer(shortMAHandle,
0, 0, 2, shortMA) != 2 ||
CopyBuffer(longMAHandle,
0, 0, 2, longMA) != 2)
{
Print("Error copying indicator
buffers");
return;
}
ArraySetAsSeries(shortMA,
true);
ArraySetAsSeries(longMA,
true);
// Check crossover conditions
bool buySignal = shortMA[1] >
longMA[1]
&& shortMA[0] <= longMA[0]; //
Current crossover up
bool sellSignal = shortMA[1] <
longMA[1] && shortMA[0] >=
longMA[0]; // Current crossover
down
// Close existing positions on
new signal
if (buySignal || sellSignal)
CloseAllPositions();
// Execute new trade
if (buySignal)
ExecuteTrade(ORDER_TYPE_B
UY);
else if (sellSignal)
ExecuteTrade(ORDER_TYPE_S
ELL);
}
//
+------------------------------------------
------------------------+
//| Execute trade order
|
//
+------------------------------------------
------------------------+
void
ExecuteTrade(ENUM_ORDER_
TYPE orderType)
{
MqlTradeRequest request = {};
MqlTradeResult result = {};
double price = (orderType ==
ORDER_TYPE_BUY) ?
SymbolInfoDouble(_Symbol,
SYMBOL_ASK)
:
SymbolInfoDouble(_Symbol,
SYMBOL_BID);
request.action =
TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = LotSize;
request.type = orderType;
request.price = price;
request.deviation = 50;
request.type_filling =
ORDER_FILLING_FOK;
// Calculate stop levels
if (orderType ==
ORDER_TYPE_BUY)
{
request.sl = price - StopLoss
* _Point;
request.tp = price +
TakeProfit * _Point;
}
else
{
request.sl = price + StopLoss
* _Point;
request.tp = price - TakeProfit
* _Point;
}
if (!OrderSend(request, result))
Print("Order failed. Error: ",
GetLastError());
else
Print("Order executed. Ticket:
",
result.deal);
}
//
+------------------------------------------
------------------------+
//| Close all positions
|
//
+------------------------------------------
------------------------+
void CloseAllPositions()
{
for (int i = PositionsTotal()-1; i
>= 0; i--)
{
ulong ticket =
PositionGetTicket(i);
if (!
PositionSelectByTicket(ticket))
continue;
ENUM_POSITION_TYPE
posType =
(ENUM_POSITION_TYPE)Positi
onGetIntege
r(POSITION_TYPE);
double volume =
PositionGetDouble(POSITION_V
OLUME);
MqlTradeRequest request =
{};
request.action =
TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = volume;
request.type = (posType
== POSITION_TYPE_BUY) ?
ORDER_TYPE_SELL :
ORDER_TYPE_BUY;
request.price =
SymbolInfoDouble(_Symbol,
(request.type ==
ORDER_TYPE_BUY) ?
SYMBOL_ASK : SYMBOL_BID);
request.deviation = 50;
request.type_filling =
ORDER_FILLING_FOK;
MqlTradeResult result;
if (!OrderSend(request,
result))
Print("Close position failed.
Error: ", GetLastError());
}
}
//
+------------------------------------------
------------------------+