The Simplest Way to Manage Your Expert Advisor Trades on MetaTrader
Learn how to use your Expert Advisor to manage all your open trades. Super simple, and super helpful.
Learn how to use your Expert Advisor to manage all your open trades. Super simple, and super helpful.
So, you’ve developed a fantastic trading algorithm.
You’ve invested time into building it into an Expert Advisor. You’re excited, pumped! It’s go time!
Then you realize something.
How can you make sure your trading bot only trades a certain number of trades?
For instance, if you’re trading the RSI, you might not want to enter every. single. candle. while the RSI stays below your RSI low value.
In this article, I’ll show you how you can get your EA to automanage your trades.
In this series, I cover everything you need to build your own advanced Expert Advisor from scratch. I cover:
All of the code that I use is available on my public GitHub repo, and each episode contains working code snippets you can immediately use in your own trading bot.
If you’d like some more general help, join our Discord server here, and if you prefer content in a video format, you can check out my YouTube channel here.
Get working code on my GitHub, linked below:
In this episode, I’ll show you a simple way to manage your Expert Advisor trades.
When you set your Expert Advisor to autotrade, you are handing over your trading decisions to your trading bot. While this can be a great thing, and many traders use it to eliminate things like emotions and downtime while sleeping, it also means that you need a way to manage your trades.
For instance, in previous episodes, I’ve been demonstrating how to build an autotrading EA that uses the RSI technical indicator. Without order management, I could end up with a situation where my trading bot keeps opening up trades every time the RSI goes above or below the RSIHigh
and RSILow
values I’ve set.
To demonstrate, have a look at this screenshot of all my trades:
While this is an extreme example where I was using the Current Close
value, it does a demonstrate a critical requirement for my trading bot EA:
What would it take for Crypto, AI, and Cyber to truly change the world?
No spam. Unsubscribe anytime.
I need a way to restrict how many trades my Expert Advisor enters simultaneously
Without it I am at risk of:
So let’s start adding in some order management
What would it take for Crypto, AI, and Cyber to truly change the world?
No spam. Unsubscribe anytime.
For the simplest of order management approaches, there are two items we must manage:
In the interests of keeping all our code nice and neat, we will be collecting all our order management into one function: TradeManagement()
. This function will be responsible for:
To manage the concurrent number of trades, we need to make sure that the sum of orders and positions is less than or equal to the number of trades we desire.
To get started, we’re going to assume that your EA should not allow any more than one trade to be active at any given time.
Add the code below to your EA, above the OnTick()
function if you are following the series:
//+------------------------------------------------------------------+
//| TradeManagement Function |
//+------------------------------------------------------------------+
bool TradeManagement(){
// Get the total number of orders
int totalOrders = OrdersTotal();
// Get the total number of positions
int totalPositions = PositionsTotal();
// If there are no orders or positions, return true
if(totalOrders == 0 && totalPositions == 0){
return(true);
}else{
int totalTrades = totalOrders + totalPositions;
if (totalTrades < 1){
return (true);
}else{
return (false);
}
}
}
This function:
true
if the number of trades is below the threshold of 1false
otherwiseNext, we need to incorporate these updates into the OnTick()
function. For code efficiencies sake, we’re going to make a design decision here that the first check that OnTick()
will make is to see if it can do any more trades.
Update your OnTick()
so that it looks like this:
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
bool tradeManagement = TradeManagement();
if(tradeManagement == true){
double rsi = GetRSI();
string signal = RSIAlgorithm(rsi);
bool success = OnSignal(signal);
}
}
Compile your code and add it to your MT5.
Congratulations, you’ve just added some simple Trade Management to Your EA!
Of course, you might prefer to a have different number of trades open. Depending on what you’re trying to do with your trading, maybe you want 2 or even 3 trades open at a time.
To do this, we’ll be adding a new input
parameter to your trading bot.
Start by adding this line to the bottom of all your current input
parameters:
input int concurrentTrades = 1; // Maximum number of concurrent trades
Then, update your TradeManagement()
function to include this input parameter, as follows:
//+------------------------------------------------------------------+
//| TradeManagement Function |
//+------------------------------------------------------------------+
bool TradeManagement(){
// Get the total number of orders
int totalOrders = OrdersTotal();
// Get the total number of positions
int totalPositions = PositionsTotal();
// If there are no orders or positions, return true
if(totalOrders == 0 && totalPositions == 0){
return(true);
}else{
int totalTrades = totalOrders + totalPositions;
if (totalTrades < concurrentTrades){
return (true);
}else{
return (false);
}
}
}
Compile your code and test it out.
By now you’ve got a fully featured EA which will happily trade away whenever the markets for your chose asset are open.
Pretty cool!
However, you might be wondering:
How could I test this algorithm to see if it actually works?
In the next episode, I’ll show you how to use the built in MT5 backtester to learn how to do that.
My name is James, and you’ll often see me online using the AppnologyJames handle. Although my background and training is in Cyber Security, I’ve spend the last few years building trading algorithms for clients, along with a powerful market analysis platform called TradeOxy.
I love hearing from my readers and viewers, so feel free to reach out and connect with me:
//+------------------------------------------------------------------+
//| RSI_EA_from_TradeOxy.mq5 |
//| AppnologyJames, TradeOxy.com |
//| https://www.tradeoxy.com |
//+------------------------------------------------------------------+
// CTrade Class
#include <Trade\Trade.mqh>
input bool liveRSIPrice = false; // Use live RSI price?
input int rsiHigh = 70; // RSI High threshold
input int rsiLow = 30; // RSI Low threshold
input int takeProfitPips = 20; // Take Profit in Pips
input int stopLossPips = 10; // Stop Loss in Pips
input double lotSize = 0.1; // Lot Size
input int concurrentTrades = 1; // Maximum number of concurrent trades
// Declare Global Variables
CTrade trade; // Trade Object
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Print the name of the Expert Advisor and a Welcome message
Print("RSI Trading Bot Expert Advisor from TradeOxy.com");
// Return value of initialization
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Deinitialization code
Print("Expert advisor deinitialized. Reason: ", reason);
}
//+------------------------------------------------------------------+
//| GetRSI |
//+------------------------------------------------------------------+
double GetRSI()
{
// Initialize a buffer
double rsiBuffer[];
// Make it into an array
ArraySetAsSeries(rsiBuffer, true);
// Get the RSI Handle
int rsiHandle = iRSI(_Symbol, _Period, 14, PRICE_CLOSE);
// If the handle is invalid, return 0
if (rsiHandle == INVALID_HANDLE)
{
return(0);
}
// Copy the RSI values to the buffer
int rsiCount = CopyBuffer(rsiHandle, 0, 0, 2, rsiBuffer);
// If the copy failed, return 0
if (rsiCount == 0)
{
return(0);
}
// Get the actual RSI value
if(liveRSIPrice == true)
{
double rsi = rsiBuffer[0];
return(rsi);
}else{
double rsi = rsiBuffer[1];
return(rsi);
}
}
//+------------------------------------------------------------------+
//| RSIAlgorithm Function |
//+------------------------------------------------------------------+
string RSIAlgorithm(double rsiValue){
// See if the value is below the 30 threshold
if(rsiValue < rsiLow){
return("BUY");
// See if the value is above the 70 threshold
}else if (rsiValue > rsiHigh){
return("SELL");
// Otherwise return HOLD
}else{
return("HOLD");
}
}
//+------------------------------------------------------------------+
// OnSignal Function |
//+------------------------------------------------------------------+
bool OnSignal(string signal){
// Get the current ask price
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
// Get the pip size for the current symbol
double pointSize = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
// Multiply the point size by 10 to get pips
double pipSize = pointSize * 10;
// Get the Take Profit, which is the pipSize * takeProfitPips
double takeProfitSize = pipSize * takeProfitPips;
// Get the Stop Loss, which is the pipSize * stopLossPips
double stopLossSize = pipSize * stopLossPips;
if(signal == "BUY"){
// Make the Take Profit above the current price
double takeProfit = ask + takeProfitSize;
// Make the Stop Loss below the current price
double stopLoss = ask - stopLossSize;
// Open a Buy Order
trade.Buy(lotSize, _Symbol, ask, stopLoss, takeProfit, "RSI Tutorial EA");
return(true);
}else if(signal == "SELL"){
// Make the Take Profit below the current price
double takeProfit = ask - takeProfitSize;
// Make the Stop Loss above the current price
double stopLoss = ask + stopLossSize;
// Open a Sell Order
trade.Sell(lotSize, _Symbol, ask, stopLoss, takeProfit, "RSI Tutorial EA");
return(true);
}else if (signal == "HOLD"){
return(true);
}else{
return(false);
}
}
//+------------------------------------------------------------------+
//| TradeManagement Function |
//+------------------------------------------------------------------+
bool TradeManagement(){
// Get the total number of orders
int totalOrders = OrdersTotal();
// Get the total number of positions
int totalPositions = PositionsTotal();
// If there are no orders or positions, return true
if(totalOrders == 0 && totalPositions == 0){
return(true);
}else{
int totalTrades = totalOrders + totalPositions;
if (totalTrades < concurrentTrades){
return (true);
}else{
return (false);
}
}
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
bool tradeManagement = TradeManagement();
if(tradeManagement == true){
double rsi = GetRSI();
string signal = RSIAlgorithm(rsi);
bool success = OnSignal(signal);
}
}