MetaTrader MQL Course. Module 9: Using MQL Time Functions

Using MQL Time Functions

In the last module we use the MarketInfo MQL function to open trades for any symbol.   If you’d like to review that module, click here: Opening Trades for Any MetaTrader Symbol.

In this module we will learn to create time-based rules using MQL Time functions.  MetaTrader offers many MQL functions of accessing different time values. The most useful functions for a typical Expert Advisor are the DayOfWeek and Hour functions.

The DayOfWeek function returns the day of week as an integer, where Sunday=0, Monday=1, etc.

The Hour function returns the hour of the day as an integer, using a 24 hour clock (no AM or PM).

We are going to use the DayOfWeek and Hour functions to close any open trades at 2:00 PM on Friday.  We’ll create a new user function called “fnCheckForFridayExit“.  This function will return “true” if it is time to close the trade, otherwise it will return false.

This is the MQL code for the function “fnCheckForFridayExit”.

// returns true to indicate it’s time to close

bool fnCheckForFridayExit()
{
// if today is Friday(5) AND the hour is at, or past, 2:00 PM
if( (DayOfWeek() == 5) && (Hour() >= 14) )

      return(true);

 

return(false);

}

We’ll call this function whenever we have an open trade.  I know, it seems excessive to call this function all the time, but that’s what computers are for!

This the MQL programming code of our Expert Advisor making full use of the “fnCheckForFridayExit” function.  Notice where and how the function is used.

// these are all externs so they can be changed when the EA is attached to a chart
// the values set are default values
extern int stoploss=200;
extern int takeprofit=200;
extern double lots = 1.0;
extern int magic_number=12345;
extern int rsi_period=12;
extern double rsi_buy_level=75.0;
extern double rsi_sell_level=25.0;

int start()
{
// get the rsi value
double rsi_value = iRSI(Symbol(), Period(), rsi_period, PRICE_CLOSE, 0);
// this variable will hold the number of trades open for this EA (as defined by magic number)
int my_trades=0;
// this variable will holds the total number of trades for the entire account
int all_trades=OrdersTotal();

// use a for loop to cycle through all of the trades, from 0 up to all_trades
for( int cnt=0;cnt<all_trades;cnt++ )
{
// use OrderSelect to get the info for each trade, cnt=0 the first time, then 1, 2, .., etc
// if OrderSelect fails it returns false, so we just continue
if( OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES) == false )
continue;

// compare the magic_number of our EA (as passed in as an input parameter) to the order’s magic number
// if they are equal, increment my_trades
if( magic_number == OrderMagicNumber() )
{
my_trades++;

if( OrderType() == OP_BUY )
{
// this is the explicit close logic for a buy order
// if the rsi OR it is friday
if( (rsi_value < rsi_sell_level) || (fnCheckForFridayExit() == true) )
{
// use the ticket info to close
// note: the price should be Bid for a Buy order
// using OrderLots()will close the entire order
OrderClose(OrderTicket(), OrderLots(), Bid, 3, Green);
}
}

if( OrderType() == OP_SELL )
{
// this is the explicit close logic for a sell order
// if the rsi OR it is friday
if( (rsi_value > rsi_buy_level) || (fnCheckForFridayExit() == true) )
{
// use the ticket info to close
// note: the price should be Ask for a Sell order
// using OrderLots()will close the entire order
OrderClose(OrderTicket(), OrderLots(), Ask, 3, Green);
}
}
}
}

// my_trades should either be 1 or 0. if it is greater than zero, then we just exit
if( my_trades > 0 )
return(0);

// if the rsi_value is larger than rsi_buy_level, we open a buy
if(rsi_value > rsi_buy_level)
{
// call our user function with a SELL parameter
fnOpenTrade(Symbol(), OP_BUY);
// exit after trying to open a trade
return(0);
}

// if the rsi_value is larger than rsi_buy_level, we open a buy
if(rsi_value < rsi_sell_level)
{
// call our user function with a SELL parameter
fnOpenTrade(Symbol(), OP_SELL);
// exit after trying to open a trade
return(0);
}

return(0);
}

void fnOpenTrade(string symbol, int type)
{
// notice that the symbol is passed in as a parameter
// get the bid value for whatever symbol was sent in
double my_bid = MarketInfo(symbol, MODE_BID);
// get the ask value for whatever symbol was sent in
double my_ask = MarketInfo(symbol, MODE_ASK);
// get the point value for whatever symbol was sent in
double my_point = MarketInfo(symbol, MODE_POINT);

// now instead of using the Bid, Ask and Point values that give the value for the
// symbol that the EA is running, use our values from above

int status =
OrderSend( symbol, // the synbol for this chart
type, // a buy order
lots, // number of lots
my_bid, // use the ask price for a BUY
3, // allow the price up to move 3 points
my_bid + (stoploss*my_point), // stop
my_ask – (takeprofit*my_point), // limit
“My Simple EA”, // comment to see in Terminal
magic_number, // a unique # to id this trade
0, // expiration, doesn’t work
Red // a blue arrow
);

if( status < 0 )
Comment(“OrderSend Failed!! Error=”, GetLastError());
}

// This function returns true to indicate it’s time to close
bool fnCheckForFridayExit()
{
// if today is Friday(5) AND the hour is at, or past, 2:00 PM
if( (DayOfWeek() == 5) && (Hour() >= 14) )
   return(true);

return(false);
}

Copy and paste this code into your MetaEditor and experiment with it. Try changing the name of the “fnCheckForFridayExit” function and adding parameters, for example:

bool fnCheckForTimeExit( int day, int hour)   

Then create extern variables for the day and hour so the exact close time can be set when configuring the Expert Advisor.  I’ll provide a solution in the next module.

In our next module, we are going to implement the infamous crossover in our Expert Advisor.