There may be times when you want to limit your EA’s operation to certain time frames instead of running it 24/7. For example,
By following the steps in this article, you can add a time restriction feature to your custom EA.
EA Base Model
In this tutorial, we will be using the EA created in the following article as the “base model” and adding new features to it.
The article explains how to create a simple cost-averaging Martingale EA from scratch. Please check it out alongside this tutorial.
Input Settings
In the base model, the following input items were set:
input double first_lot = 0.01;//Initial lot size
input double nanpin_range = 200;//Cost-averaging range
input double profit_target = 1.00;//Profit target
input int magic_number = 10001; //Magic number
static int ticket_number;//Ticket number
double slippage = 10;//Slippage
Now, we will add more input items for the time restriction feature.
input bool time_limit = false;//Entry time restriction (true: enabled, false: disabled)
input string start_time = "02:00";//Entry start time
input string end_time = "10:00";//Entry end time
input bool forced_close = false;//Forced close (true: enabled, false: disabled)
Entry Time Restriction (time_limit)
We will add the entry time restriction feature, but we also want to make sure that the EA can operate without it if desired. To achieve this, we will create an input item to enable or disable the time restriction feature.
The “bool” data type can take one of two values: true or false.
We will proceed with the understanding that if “true” is set, the time restriction is enabled, and if “false” is set, the time restriction is disabled.
Entry Start Time (start_time)
This is the setting for the entry start time. Since it is of the string type, it is assumed that you input the time as a string like “02:00”. Also, the time input here should be in XM’s Cyprus time.
In Cyprus time, it is from 1:05 to 23:55 (closing at 23:50 on Fridays).
Entry End Time (end_time)
This is the setting for the entry end time. Here too, you should input the time in XM’s Cyprus time.
Between the entry start time and the entry end time, new entry orders will be placed. However, during other times, no new entry orders will be placed. We will proceed with this assumption.
Forced Close (forced_close)
This setting determines whether or not to perform a forced close at the entry end time.
If set to true, a forced close will be performed, and if set to false, no forced close will be performed.
When a forced close is enabled, it is assumed that the logic will close all open positions at the entry end time.
Adding Custom Functions
We will add two custom functions for implementing the entry time restriction feature.
entryTime Function
We will define the entryTime function as a function to check if it is within the entry time period.
//+----Entry Time Period Check-----------------------------------------------+
bool entryTime(string stime,string etime){
string startDate=TimeToStr(TimeCurrent(),TIME_DATE); //Current year, month, and day
datetime startTime=StrToTime(startDate+" "+stime); //Year, month, day + start time
datetime endTime=StrToTime(startDate+" "+etime); //Year, month, day + end time
if(startTime<endTime){
if(startTime<=TimeCurrent() && TimeCurrent()<endTime)return(true);
else return(false); //If the current time is within the entry time, return true
}else{
if(endTime<=TimeCurrent() && TimeCurrent()<startTime)return(false);
else return(true); //If the current time is outside the entry time, return false
}
return(false);
}
//+-----------------------------------------------------------------------+
Here’s an overview of the function:
- First, the TimeCurrent function is used to obtain the current time, and the TimeToStr function is used to extract the year, month, and day parts.
- Next, the StrToTime function is used to convert the year, month, and day + start time and year, month, and day + end time into datetime type.
- Then, by comparing the three datetime types for the current time, entry start time, and entry end time, it is determined whether or not it is within the entry time and returns true or false.
allClose Function
In the base model, the buyClose function was defined as a function to close buy positions, and the sellClose function was defined as a function to close sell positions. However, we define the allClose function to close all positions for both buy and sell.
//+----Function to close all positions----------------------------------------------------+
void allClose(color clr)
{
int i;
for(i=OrdersTotal()-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)
continue;
if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=magic_number)
continue;
if(OrderType()==OP_BUY)
OrderClose(OrderTicket(),OrderLots(),Bid,NormalizeDouble(slippage,0),clr);
if(OrderType()==OP_SELL)
OrderClose(OrderTicket(),OrderLots(),Ask,NormalizeDouble(slippage,0),clr);
}
}
//+---------------------------------------------------------------------------------+
The function itself is very simple, and we just added a part to the buyClose function to close the sell position.
Loop Processing
The necessary pre-processing is complete, and we will now move on to adding functionality within the loop processing.
void OnTick()
void OnTick()
{
From here on, we will add the contents within the void OnTick() function.
Variable Definition
In the base model, we defined the following variables.
int cnt; int current_buy_position; // The latest buy position
int current_sell_position; // The latest sell position
int buy_position; // The number of buy positions
int sell_position; // The number of sell positions
double buy_profit; // The unrealized profit and loss of buy positions
double sell_profit; // The unrealized profit and loss of sell positions
We will add the following two definitions here.
bool entry_flag; // Entry flag
bool close_flag; // Close flag
entry flag(entry_flag)
The entry flag is used to determine whether to make a new entry.
If it is true, a new entry is made, and if it is false, a new entry is not made.
close flag(close_flag)
The close flag is used to determine whether to perform a forced close.
If it is true, a forced close is performed, and if it is false, a forced close is not performed.
Checking the entry time:
Next, we will add a process to check the entry time. It is OK to place it just before the process to check the position.
// + ---- Check the entry time ---- ------------------------------------ +
entry_flag = false; // Initialize the entry flag
close_flag = false; // Initialize the close flag
if (!time_limit){ // If there is no entry time limit (false)
entry_flag = true;
} else
if (entryTime(start_time, end_time)){ // If it is within the entry time (true)
entry_flag = true;
} else
if (forced_close){ // If forced close is enabled (true)
allClose(GreenYellow);
}
// + ------------------------------------------------------------------ +
First, if the entry time limit is not set to true, the entry flag is set to true. This means that entry is allowed without any time restrictions.
Next, if the entry time limit is set to true and it is within the entry time, the entry flag is set to true. This means that entry is allowed only within the specified time limit.
Finally, if the entry time limit is set to true and it is outside the entry time, the entry flag remains false, which was initialized earlier. If forced close is enabled at this point, the allClose function will be executed.
New Entry Orders
Next, we will add the entry flag condition to the entry conditions for new entry orders, and change the conditions to “if there is no position and the entry flag is true”.
To extract only the condition part, we had a simple condition that only checks the position:
if(buy_position==0)// If there is no buy position
if(sell_position==0)// If there is no sell position
We will now add the entry flag as follows:
if(buy_position==0&&entry_flag)// If there is no buy position and the entry flag is true
if(sell_position==0&&entry_flag)// If there is no sell position and the entry flag is true
Since entry_flag is of type bool, simply adding && entry_flag means “if the entry_flag is true”.
Additional Entry (Martingale) Orders
We do not need to add anything to the part for adding Martingale orders. This is because the additional function we have added is only for setting entry time restrictions, and we assume that the logic for continuing Martingale orders even outside the entry time will be implemented.
As long as there is a position, Martingale orders will continue even outside the entry time, and no new entry orders will be placed until the entry start time after closing a position once.
Position Close Order
There is no need to make any changes to the part for position closing orders.
For position closing, we added logic for forced closing, but this is already set in the “Check the entry time” section.
Conclusion
With the above changes, we have completed adding the entry time restriction function to the Martingale EA base model.
Other Articles on Creating EAs
Introducing the use of the CoCoMo method
Adding the ability to change take profit patterns
Creating an FX Automated Trading Tool (Bot) in Python
Here, we will introduce how to create an FX automated trading tool (bot) using Python.
Comments