5 Checks to Enhance your MQL4 Code

Introduction



Throughout my years as an algotrader, I gained a lot experience with writing optimized MQL4 code. In this post, I am going to share some patterns I am using in my on robots. Some check for connectivity, some for spread, some for volatility etc. Embedding these code snippets in your own, will make your robot more resilient and you will more relax, as you will add self monitoring capabilities to it as well as better trade entry rules.

 

Server Connectivity Check



From time to time, MetaTrader station losses connectivity with the broker's server. And when that happens, normally, the only thing which works is to restart the platform (or hopefully wait the problem will fix itself). But how can you monitor the platform and get a notification once it is happening?

That's exactly the solution I built for myself. Since the function OnTick() is not called anymore as there is no connectivity. The only solution was to place the monitoring in the OnTimer() function and check every X minutes, normally I do it once per hour.

First, in the OnInit() function, I initialize the timer by calling:

EventSetTimer(PERIOD_H1*60);


This is to call it once per hour, but you may also call it more frequently if you want.

Then, in the OnTimer() function I use the following code:

void OnTimer()
  {
   static bool IsDisconnectedFlag=false;
   if(IsDisconnectedFlag==false && IsConnected()==false)
     {
      SendNotification(StringConcatenate(IntegerToString(AccountNumber()),": Broker connection lost..."));
      IsDisconnectedFlag=true;
     }
   else if(IsDisconnectedFlag==true && IsConnected()==true)
     {
      SendNotification(StringConcatenate(IntegerToString(AccountNumber()),": Broker connection retrieved..."));
      IsDisconnectedFlag=false;
     }
}


First, I set a static variable called IsDisconnectedFlag to false. Then, I check, if the flag is false and the system is disconnected, I send a notification and set the flag to true (so I won't send the notification more than once). Then, in the next calls, if the system is still disconnected, I do nothing as the flag is already set to false. But, if the system got connected from its own, then I will send a notification to inform myself about it and set the IsDisconnectedFlag back to false.

Finally, in the DeInit() function, I call EventKillTimer() to delete the timer.

With this simple code pattern, I don't have the hassle anymore of checking server connectivity. My expert adviser runs and checks itself if the terminal connected to the broker or not, and notify me so I only need to act when needed.

 

Platform Running Check



What happens if the platform itself shut down unexpectedly? How would you know? It happened to me from time to time that the terminal itself crashed from whatever reason and I missed some good trades. If I wasn't checking the platform or paying attention that something is wrong, I would probably have missed it. So how can you get a notification as soon as the platform crashes?

For that, I am using the following function which is placed within the OnDeinit() function:

void OnDeinit(const int reason)
{
SendNotification(GetUninitReasonText(reason));
}


where

string GetUninitReasonText(int reasonCode) export
{
switch(reasonCode)
{
case REASON_PROGRAM:
return "Expert Advisor terminated its operation by calling the ExpertRemove() function";
case REASON_REMOVE:
return MQLInfoString(MQL_PROGRAM_NAME)+" has been deleted from the chart";
case REASON_RECOMPILE:
return MQLInfoString(MQL_PROGRAM_NAME)+" has been recompiled";
case REASON_CHARTCHANGE:
return "Symbol or chart period has been changed";
case REASON_CHARTCLOSE:
return "Chart was closed";
case REASON_PARAMETERS:
return MQLInfoString(MQL_PROGRAM_NAME)+" input parameters have been changed by a user";
case REASON_ACCOUNT:
return "Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings";
case REASON_TEMPLATE:
return "A new template has been applied";
case REASON_INITFAILED:
return MQLInfoString(MQL_PROGRAM_NAME)+" OnInit() handler has returned a nonzero value";
case REASON_CLOSE:
return "Terminal has been closed";
default:
return "Another reason";
}
}


As you can see in the function body, there are many reasons for the DeInit function to be called and one of them is the REASON_CLOSE which is closing the terminal. With this function, I am notified immediately once the terminal shut down from any reason. Normally, the other reasons are within your control, such as program compiling or closing the chart, but I included them as well for the sake of completion.

 

Spread Check



I always use this check before opening an order, making sure that the BId-Ask spread is not too big so I don't finance the broker. For that, I am using a fixed value saved as a constant at the global scope of the robot:

const int SPREAD=25;

Then, whenever I want to open an order, I do the following check:

if(MarketInfo(TheSymbol,MODE_SPREAD)<=SPREAD)


Basically, if the symbol spread is below the value I set up, then I will perform the action. In my case is opening an order, but you may do whatever you want, depending on the spread. If the spread is big, it will take longer until you will start profiting from this trade.

For example, let's assume you opened a buy order with a spread of 30 pips. The bid has to move 30 pips and only then you will start seeing some profits. If the volatility for this pair is low, 30 pips will be a long time to wait or it might reach it but turn around after it. As I am mainly trading EURUSD, the spread is not a concern, but there are always events where the broker increases the spread due to some news event or liquidity and I want to be protected for it.

 

Volatility Check



Volatility can impact your trading significantly. If a currency has a high volatility, it basically means that this currency is vibrating strongly around its price, which means that there are higher chances for your take profit as well as your stop-loss to get hit. As a trader, you have a view on the market, and the last thing you want is to lose it because of the volatility noise (unless you are trading volatility, then you may use this pattern to enter the market when the volatility is high).

To solve this problem, I am only entering the market when the volatility is low in the last hour compare to the last 24 hours. I do it by checking the standard deviation of the price, which is a really good indicator of the volatility:

double STD=iStdDev(Symbol(),PERIOD_H1,24,0,MODE_SMA,PRICE_CLOSE,0);
for(int i=1;i<=24;i++)
if(STD==0 || STD>iStdDev(Symbol(),PERIOD_H1,24,0,MODE_SMA,PRICE_CLOSE,i))
return;


In the first line, I store the current volatility in a variable called STD. Then, I check if in compare to the last 24 hours, the volatility is lower than the current one. If the answer is yes, then I return and do nothing, But, if the volatility is lower than the previous 24 hours. Then, I may continue and trade during this time period.

With a small modification, you may check if the volatility is the highest in the last 24 hours. If you are trading the news, or want to enter only the volatility is high, just use the following code:

double STD=iStdDev(Symbol(),PERIOD_H1,24,0,MODE_SMA,PRICE_CLOSE,0);
for(int i=1;i<=24;i++)
if(STD==0 || STD<iStdDev(Symbol(),PERIOD_H1,24,0,MODE_SMA,PRICE_CLOSE,i))
return;


With that, if in the last 24 hours the product was more volatile than now, the function will return and do nothing.

Worth mentioning. I chose 24 hours as I believe it's enough time to look back and see how the product behave, but you may use different periods and checks.

 

Chart Period Check



In case your expert adviser must run on a specific chart period (as mine only runs on the 1M). Use the following code and place it at the beginning of the OnInit() function to verify that:

if(ChartPeriod()!=PERIOD_M1)
ChartSetSymbolPeriod(ChartID(),TheSymbol,PERIOD_M1);


It will check whether the chart period is the one you expect to use. If not, it will change the chart period immediately. In this example, I checked if it's the 1M chart, otherwise, I restart the chart into this period.

 

Summary



In this post, I introduced 5 code snippets which you can add to your existing MQL4 programs to improve its stability and resilience. I use these patterns in most of the expert advisers I run and have them included in an external library available for purchase here. I hope you will find it useful for your trading.

Comments

Post a Comment