Moving Averages Trader Implementation for MetaTrader 4

Introduction

Moving averages trading is the most basic and common trading strategy. It is quoted in most of the trading books and articles and is very easy to follow and implement. The basic strategy is two moving averages, a fast one which is adjusting quicker to the current trend than a slow one.

A classic setup is looking at the 50 days moving average of a certain product and check whether it is above or below the 200 days moving average. If it is above, it is an indicator for going long with this product, if it is below, it is an indicator to short the product.

In this post, I will introduce a basic implementation of an expert adviser, which based on the inputs will trade the product using the price moving averages. You may use it as a basis for something else, modify it as you wish etc.

Input Parameters

These input parameters are controlling the moving average calculation:

input int FastMovingAveragePeriod=50;//Fast Moving Average Period 
input int SlowMovingAveragePeriod=100;//slow Moving Average Period 
input ENUM_TIMEFRAMES Timeframe=PERIOD_D1;//Moving Average Timeframe 
input ENUM_MA_METHOD AveragingMethod=MODE_SMA;//Moving Average Averaging Method 
input ENUM_APPLIED_PRICE AppliedPrice=PRICE_CLOSE;//Moving Average Applied Price 
input int Shift=0;//Moving Average Shift
input double Lots=0.01;//Order Lots


The periods are defined as 50 for the fast moving average and 100 for the slow moving average, which control how many periods will look back when calculating the average.

The Timeframe is the reference for the moving average calculation and data.

The applied price influences which values we use for calculating the moving average.

Shift is the moving average shift in value, the default value is 0, meaning calculating the present value. If you set it for 1 for example the moving average will be calculated on the previous period.

Lots captures the volume to open an order, you may change it to a larger value based on your risk appetite.

Initialization

The OnInit() function is short and verify the periods input parameters. If the fast period is longer than the slow period, the function will return an error and the expert adviser will fail to start. So, when entering values for the periods, make sure that the FastMovingAveragePeriod is smaller than the SlowMovingAveragePeriod:

int OnInit() { 
if(FastMovingAveragePeriod>=SlowMovingAveragePeriod) { 
SendNotification("Fast moving average period value must be smaller than the slow moving average period value"); 
return INIT_PARAMETERS_INCORRECT; 
} 
return INIT_SUCCEEDED; 
}


Trading Logic

Going Long

The first part of the algorithm checks whether the conditions match to go long on the product. It does so by comparing the current fast-moving average value to the slow one. If the fast-moving average value is larger than the short moving average, it will close the short position (if any) and open a long one.

Since we always have one order open, we can call the order select function, choose the only open order and close it safely, having in mind that if the fast is above the slow, there is a chance that the market trend is moving upwards:

if(iMA(Symbol(),Timeframe,FastMovingAveragePeriod,0,AveragingMethod,AppliedPrice,0)>iMA(Symbol(),Timeframe,SlowMovingAveragePeriod,0,AveragingMethod,AppliedPrice,0)) 
{
    if(OrdersTotal()>0 && OrderSelect(0,SELECT_BY_POS) && OrderType()==OP_SELL) 
    {
        if(OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_ASK),SLIPPAGE)==false) 
        { 
            SendNotification("Something went wrong when closing an order, existing"); ExpertRemove(); 
            return; 
         } 
    }
    if(OrdersTotal()==0)
    {
        if(OrderSend(Symbol(),OP_BUY,Lots,MarketInfo(Symbol(),MODE_ASK),SLIPPAGE,0,0)==-1) 
        { 
            SendNotification("Something went wrong when opening an order, existing"); 
            ExpertRemove(); 
            return;
        }   
    } 
}


Going Short

The same logic goes for the short direction. Here, we are checking that the fast-moving average value is smaller than the long moving average value. If this is the case, we close the long position (if any) and open a short one:

else 
{ 
    if(OrdersTotal()>0 && OrderSelect(0,SELECT_BY_POS) && OrderType()==OP_BUY) 
    { 
        if(OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_BID),SLIPPAGE)==false) 
        { 
            SendNotification("Something went wrong when closing an order, existing"); 
            ExpertRemove(); 
            return; 
        }
    }
    if(OrdersTotal()==0) 
    {
        if(OrderSend(Symbol(),OP_SELL,Lots,MarketInfo(Symbol(),MODE_BID),SLIPPAGE,0,0)==-1)
        { 
            SendNotification("Something went wrong when opening an order, existing"); 
            ExpertRemove(); 
            return; 
         }
     }
 }

Testing



To see how this basic implementation performs, I ran it using the default values with my favorite currency - EURUSD - for the year 2017:



As you see, most of the year, the fast-moving average was above the slow one, so the long position was dominant and captured more than 10,000 pips, or 103.56 dollars in profit. Towards the end of the year, the trend reversed and the a new sell position was opened.

Summary

I introduced a simple working MQL moving averages code for MetaTrader 4 which is available for download here. This strategy closes and opens a position as the trend changes using the moving averages crossover as an indicator. It is only a template and I would not recommend using it with real money, rather as an educational or a starting point for improved strategy such as the Martingale implementation article was.

As always, feel free to leave comments or join our discussion in Facebook.

Comments