We’ll break down the provided code, explaining its structure and functionality, to help you understand how to create your own automated trading system.
#include <Trade/Trade.mqh>
CTrade trade;
void ClosePosition(){}
ulong trade_ticket = 0;
bool time_passed = true;
int operacion_abierta = 0;
double price_flag = 0;
Explanation:
#include <Trade/Trade.mqh>
statement includes the Trade library, providing trading functions.CTrade trade;
creates an instance of the CTrade
class for managing trading operations.trade_ticket
, time_passed
, operacion_abierta
, and price_flag
are variables for tracking trade information.int stoch_h, rsi_h;
input int startHour = 8;
input int stopHour = 16;
input double coef_BUY_TP = 1.02;
input double coef_BUY_SL = 0.095;
input double coef_SELL_TP = 0.99;
input double coef_SELL_SL = 1.005;
input double Lot_size_BUY = 0.1;
input double Lot_size_SELL = 0.1;
Explanation:
stoch_h
and rsi_h
store the handlers for Stochastic and RSI indicators.startHour
and stopHour
define the start and stop hours for trading.double stoch0[], stoch1[], rsi[];
double global_TP = 0;
double global_SL = 0;
double global_lotsize = 0.1;
datetime global_trading_time = 0;
MqlRates price_information[];
Explanation:
stoch0
, stoch1
, rsi
) store indicator values.global_TP
, global_SL
, global_lotsize
, and global_trading_time
hold global trade information.price_information
is an array for storing historical price data.int CANDLES_TO_USE = 10;
int CANDLES_TO_CHECK = 20;
int TS = 530;
int MARGIN = 30;
int TP = 600;
int SL = 200;
Explanation:
CANDLES_TO_USE
and CANDLES_TO_CHECK
define the number of candles for different purposes.TS
, MARGIN
, TP
, and SL
set parameters for trailing stop, margin, take profit, and stop loss.This is the first part of the code breakdown. Let me know if you’d like to continue with the next sections!
handle_trade
void handle_trade(ulong t_ticket)
{
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double new_sl = 0, new_tp = 0;
double cur_price = PositionGetDouble(POSITION_PRICE_CURRENT);
if(type == POSITION_TYPE_BUY && cur_price > price_flag)
{
price_flag += 20*_Point;
new_tp = cur_price+MARGIN*_Point;
new_sl = cur_price-MARGIN*_Point*3;
trade.PositionModify(trade_ticket, new_sl, new_tp);
}
else if(type == POSITION_TYPE_SELL && cur_price < price_flag)
{
price_flag -= 20*_Point;
new_tp = cur_price-MARGIN*_Point;
new_sl = cur_price+MARGIN*_Point*3;
trade.PositionModify(trade_ticket, new_sl, new_tp);
}
}
Explanation:
OnInit
int OnInit()
{
/* Handlers */
stoch_h = iStochastic(_Symbol, _Period, 5, 3, 3, MODE_SMA, STO_LOWHIGH);
rsi_h = iRSI(_Symbol, _Period, 14, PRICE_CLOSE);
/* Settings the arrays */
ArraySetAsSeries(stoch0, true);
ArraySetAsSeries(stoch1, true);
ArraySetAsSeries(rsi, true);
ArraySetAsSeries(price_information, true);
return(INIT_SUCCEEDED);
}
Explanation:
OnInit
function initializes the Expert Advisor.stoch_sell_signal
, stoch_buy_signal
, rsi_buy_signal
, rsi_sell_signal
bool stoch_sell_signal()
{
if(stoch0[0] > 80 && stoch1[0] > 80)
return true;
return false;
}
bool stoch_buy_signal()
{
if(stoch0[0] < 20 && stoch1[0] < 20)
return true;
return false;
}
bool rsi_buy_signal()
{
return rsi[0] > 50;
}
bool rsi_sell_signal()
{
return rsi[0] < 50;
}
Explanation:
stoch_sell_signal
returns true if both Stochastic lines are above 80.IsTradingAllowed
bool IsTradingAllowed()
{
datetime currentServerTime = TimeCurrent();
MqlDateTime timeInfo;
TimeToStruct(currentServerTime, timeInfo);
int currentHour = timeInfo.hour;
if (currentHour >= startHour && currentHour < stopHour)
{
return true; // Trading is allowed
}
else
{
return false; // Trading is not allowed
}
}
Explanation:
startHour
to stopHour
).#include <Trade/Trade.mqh>
CTrade trade;
void ClosePosition(){}
ulong trade_ticket = 0;
bool time_passed = true;
int operacion_abierta = 0;
double price_flag = 0;
/* Handlers */
int stoch_h, rsi_h;
// Define the start and stop hours for trading
input int startHour = 8;
input int stopHour = 16;
input double coef_BUY_TP = 1.02 ;
input double coef_BUY_SL = 0.095 ;
input double coef_SELL_TP = 0.99 ;
input double coef_SELL_SL = 1.005 ;
input double Lot_size_BUY = 0.1 ;
input double Lot_size_SELL = 0.1 ;
/* Signal arrays */
double stoch0[], stoch1[], rsi[];
double global_TP = 0;
double global_SL = 0;
double global_lotsize = 0.1; // Set your initial lot size here
datetime global_trading_time = 0;
/* Candle array */
MqlRates price_information[];
int CANDLES_TO_USE = 10;
int CANDLES_TO_CHECK = 20; // For sl and tp
/* TS and TP */
int TS = 530; // Trailing stop
int MARGIN = 30; // Margin
int TP = 600; // Take profit
int SL = 200; // Stop loss
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void handle_trade(ulong t_ticket)
{
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
double new_sl = 0, new_tp = 0;
double cur_price = PositionGetDouble(POSITION_PRICE_CURRENT);
/* Modifying the stop loss during the ticks */
if(type == POSITION_TYPE_BUY && cur_price > price_flag)
{
price_flag += 20*_Point;
new_tp = cur_price+MARGIN*_Point;
new_sl = cur_price-MARGIN*_Point*3;
trade.PositionModify(trade_ticket, new_sl, new_tp);
}
else
if(type == POSITION_TYPE_SELL && cur_price < price_flag)
{
price_flag -= 20*_Point;
new_tp = cur_price-MARGIN*_Point;
new_sl = cur_price+MARGIN*_Point*3;
trade.PositionModify(trade_ticket, new_sl, new_tp);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OnInit()
{
/* Handlers */
stoch_h = iStochastic(_Symbol, _Period, 5, 3, 3, MODE_SMA, STO_LOWHIGH);
rsi_h = iRSI(_Symbol, _Period, 14, PRICE_CLOSE);
/* Settings the arrays */
ArraySetAsSeries(stoch0, true);
ArraySetAsSeries(stoch1, true);
ArraySetAsSeries(rsi, true);
ArraySetAsSeries(price_information, true);
return(INIT_SUCCEEDED);
}
/**** Private functions ****/
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool stoch_sell_signal()
{
if(stoch0[0] > 80 && stoch1[0] > 80)
return true;
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool stoch_buy_signal()
{
if(stoch0[0] < 20 && stoch1[0] < 20)
return true;
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool rsi_buy_signal()
{
return rsi[0] > 50;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool rsi_sell_signal()
{
return rsi[0] < 50;
}
bool IsTradingAllowed()
{
datetime currentServerTime = TimeCurrent();
// Get the current hour using StructTime
MqlDateTime timeInfo;
TimeToStruct(currentServerTime, timeInfo);
int currentHour = timeInfo.hour;
// Check if the current hour is within the allowed trading hours
if (currentHour >= startHour && currentHour < stopHour)
{
return true; // Trading is allowed
}
else
{
return false; // Trading is not allowed
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double nearest_high()
{
int i = 0;
double high = 0;
for(i = 0; i < CANDLES_TO_CHECK; i++)
if(high < price_information[i].close)
high = price_information[i].close;
return high;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double nearest_low()
{
int i = 0;
double low = 100000;
for(i = 0; i < CANDLES_TO_CHECK; i++)
if(low > price_information[i].close)
low = price_information[i].close;
return low;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnTick()
{
/* Loading indicator values */
CopyBuffer(stoch_h, MAIN_LINE, 0, CANDLES_TO_USE, stoch0);
CopyBuffer(stoch_h, SIGNAL_LINE, 0, CANDLES_TO_USE, stoch1);
CopyBuffer(rsi_h, 0, 0, CANDLES_TO_USE, rsi);
CopyRates(_Symbol, _Period, 0, CANDLES_TO_CHECK, price_information);
/* This won't allow two open operations at the same time */
if(PositionSelectByTicket(trade_ticket) == false){
trade_ticket = 0;}
/* Buy? */
if(trade_ticket == 0 && time_passed && operacion_abierta == 0
&& IsTradingAllowed()
&& stoch_buy_signal() // Current stoch is in buy
&& rsi_buy_signal()){ // Current rsi is in buy
/* Current price */
double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
//--- Open Buy
double sl = coef_BUY_SL*Ask;
double tp = coef_BUY_TP*Ask ;
trade.Buy(Lot_size_BUY, _Symbol, Ask, sl, tp, NULL);
trade_ticket = trade.ResultOrder();
global_TP = tp;
global_SL = sl;
global_lotsize = Lot_size_BUY; // Update with your actual lot size
global_trading_time = TimeCurrent();
operacion_abierta = 2;}
if(operacion_abierta == 2
&& IsTradingAllowed()
&& stoch_sell_signal() // Current stoch is in sell
&& rsi_sell_signal()){ // Current rsi is in sell
double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);
double sl = coef_SELL_SL*Bid;
double tp = coef_SELL_TP*Bid;
trade.PositionClose(_Symbol);
trade.Sell(Lot_size_SELL, _Symbol, Bid, sl, tp, NULL);
trade_ticket = trade.ResultOrder();
global_TP = tp;
global_SL = sl;
global_lotsize = Lot_size_SELL; // Update with your actual lot size
global_trading_time = TimeCurrent();
operacion_abierta = 3;
}
if(trade_ticket == 0 && time_passed
&& operacion_abierta == 0
&& IsTradingAllowed()
&& stoch_sell_signal() // Current stoch is in sell
&& rsi_sell_signal()){ // Current rsi is in sell
double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);
double sl = coef_SELL_SL*Bid;
double tp = coef_SELL_TP*Bid;
global_TP = tp;
global_SL = sl;
global_lotsize = Lot_size_SELL; // Update with your actual lot size
global_trading_time = TimeCurrent();
trade.Sell(Lot_size_SELL, _Symbol, Bid, sl, tp, NULL);
trade_ticket = trade.ResultOrder();
operacion_abierta = 3;
}
if(operacion_abierta == 3
&& IsTradingAllowed()
&& stoch_buy_signal() // Current stoch is in sell
&& rsi_buy_signal()){ // Current rsi is in sell
double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
double sl = coef_BUY_SL*Ask;
double tp = coef_BUY_TP*Ask ;
trade.PositionClose(_Symbol);
global_TP = tp;
global_SL = sl;
global_lotsize = Lot_size_BUY; // Update with your actual lot size
global_trading_time = TimeCurrent();
trade.Buy(Lot_size_BUY, _Symbol, Ask, sl, tp, NULL);
trade_ticket = trade.ResultOrder();
operacion_abierta = 2;
}
// Displaying information in the chart
string info = StringFormat("Lot Size: %.2f\nTP: %.5f\nSL: %.5f\nTrading Time: %s",
global_lotsize, global_TP, global_SL, TimeToString(global_trading_time));
Comment(info);
}
//+------------------------------------------------------------------+
Understanding the provided MQL5 code is a crucial step in building your own trading bot. It covers key aspects such as indicator signals, trade management, and environment setup. As you delve deeper into algorithmic trading with MT5, you can customize and expand upon this code to create more sophisticated EAs tailored to your trading strategy.
Remember to thoroughly test your strategies on historical data and consider the associated risks before deploying them in live trading environments.