Welcome Forex EA downloads & MT4/MT5 auto-trading resources — EAs, Gold EAs, quant tools and real-world automation.
Sign In Sign Up

Moving Average - MetaTrader 5 Expert | Forex Indicator Download - MT4/MT5 Resources - MetaTrader 5 Resources

author EAcpu | 2 reads | 0 comments |

Moving Average - expert for MetaTrader 5

Moving Average - expert for MetaTrader 5

Moving Average - expert for MetaTrader 5

The Moving Average EA is included with the MetaTrader 5 client and is an example Moving Average indicator for trading with an EA.

The EA file Moving Average.mq5 is located in the folder "terminal_data_folder\MQL5\Experts\Examples\Moving Average\". This EA is a standard library using sample technical indicators , trade history functions and trading classes . Additionally, the EA includes a money management system based on trading results.

Let's consider the structure of the Expert Advisor and how it works.

1. EA properties

 //+------------------------------------------------------------------+
//| moving average.mq5 |
//| Copyright 2009-2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#Property Copyright "Copyright 2009-2013, MetaQuotes Software Corp."
#Property association "https://www.mql5.com"
#propertyversion " 1.00

The first 5 lines contain comments, the next three lines use preprocessor directives to set the properties of the MQL5 program (copyright, link, version) #property .

When you run the Expert Advisor, they will be displayed in the "Public" tab:

Moving Average - expert for MetaTrader 5

Figure 1. Common parameters of moving average EA

1.2.Include files

Next, the #include directive tells the compiler to include the "Trade.mqh" file.

This file is the standard library , which contains classes used by TradeNet to easily access trading functionality.

 #includes <trade\trade.mqh>

The name of the include file appears in brackets "<>;", so the path is set relative to the directory: "terminal_data_folder\Include\".

Then there are types, names, default values, and comments. Their functions are shown in the figure. 2.

 Enter double the maximum risk = 0.02 ; // Maximum risk percentage
Enter double reduction factor = 3 ; // reduction factor
Input integer moving period = 12 ; // moving average period
Input integer moving shift = 6 ; // Moving average shift

The MaximumRisk and DecreaseFactor parameters will be used for money management, MovingPeriod and MovingShift to set the period and Moving Average will be used or to check the technical indicators for trading conditions.

The text in the input parameter line comment and the default value are displayed in the Options tab instead of the name of the input parameter:

Moving Average - expert for MetaTrader 5

Figure 2. Input parameters of Moving Average EA

1.4.Global variables

Then declare the global variable ExtHandle. It will be used to store the Handle Moving Average indicator.

 //---
integer extension handle = 0 ;

Next are 6 functions. Their respective uses are described in the comments before the function body:

The last three functions are event handlers ; the first three service functions are called in their code.

2. Event handling function

2.1. OnInit() initialization function

This OnInit() function is called once during the first startup of the Expert Advisor. Usually in the OnInit() event handler, the EA is ready to run: input parameters are checked, indicators and parameters are initialized, etc. In case of a serious error, when further work is pointless, the function will exit with code INIT_FAILED.

 //+------------------------------------------------------------------+
//|Expert initialization function |
//+------------------------------------------------------------------+
When initialized with integer ( blank )
  { //--- extension handle = ima ( _symbol , _period , movement period, movement translation, mode_SMA , PRICE_CLOSE );
if (extended handle == INVALID_HANDLE )
    {
print function ( "Error while creating MA indicator" );
Return ( initialization failed );
    } //--- return ( initialization successful );
  }

Since the Expert Advisor is based on the moving average indicator, this moving average indicator has been created by calling iMA() , and its handle is saved in the global variable ExtHandle.

If an error occurs, OnInit() will exit with return code Initialization failed - this is the correct way to complete EA/indicator operation in case of unsuccessful initialization.

2.2. OnTick() function

This OnTick() function will be called every time a new quote is received for the chart symbol on which the EA is running.

 //+------------------------------------------------------------------+
//|Expert check function |
//+------------------------------------------------------------------+
Blank check ( blank )
  { //--- if ( position select ( _symbol ))
      checkClose();
Others check open(); //--- }

This position selection() function is used to define whether there is a position in the current trading variety.

If there is an open position, the CheckForClose() function is called, which analyzes the current state of the market and closes the open position, otherwise the CheckForOpen() function is called, which checks the market entry conditions and opens a new position if such conditions occur.

2.3. OnDeInit() deinitialization function

OnDeInit() is called when the EA is removed from the chart. If the program places graphical objects during runtime, they can be removed from the chart.

 //+------------------------------------------------------------------+
//|Expert to initialize function |
//+------------------------------------------------------------------+
Blank solution initialization ( constant integer reason)
  {
  } //+------------------------------------------------------------------+

In this case, no operations will be performed during EA deinitialization.

3. Service functions

3.1. Function TradeSizeOptimized()

The function calculates and returns the value of the optimal lot size for opening a position at a specified risk level and trading result.

//+------------------------------------------------------------------+
//|Calculate optimal batch size|
//+------------------------------------------------------------------+
Double transaction size optimization ( blank )
  {
Double price = 0.0 ;
Double margin = 0.0 ; //--- Calculate lot size if (! symbol info double ( _symbol , SYMBOL_ASK , price))
return ( 0.0 );
if (! ordercalculatemargin ( ordertypebuy , _token , 1.0 ,price,profit))
return ( 0.0 );
if (margin <= 0.0 )
return ( 0.0 );

double lots = normalized double ( account_freemarkin ( ACCOUNT_FREEMARKIN )*max risk/margin, 2 ); //--- Calculate the length of a series of consecutive losing trades if (reduction factor > 0 )
    {
//--- Request the entire transaction history history selection ( 0 , time current ());
//-- integer orders = total number of historical transactions (); // total number of transactions integer loss = 0 ; // the number of losing transactions in the series is ( integer i = order - 1 ; i >= 0 ; i -)
        {
Own ticket = Historical transaction GetTicket (i);
if (tickets == 0 )
          {
print ( "HistoryDealGetTicket failed, no transaction history" );
rest ;
          }
//--- check transaction symbol if ( historical transaction get string (ticket, DEAL_SYMBOL )!= _symbol )
continue ;
//--- check profit double profit = historical transactions get double (ticket, transaction profit );
if (profit> 0.0 )
rest ;
if (profit < 0.0 )
            Loss++;
        }
//--- if (loss > 1 )
        lot = normalized double (lot*loss/reductionfactor, 1 );
    } //--- normalize and check the allowed value of volume double step = symbolinfo double ( _symbol , SYMBOL_VOLUME_STEP );
  lot size = number of steps * normalized double (lot/step volume, 0 );

double minimum volume = symbolinfo double ( _symbol , SYMBOL_VOLUME_MIN );
if (number of lots double maximum capacity = symbolinfo double ( _symbol , SYMBOL_VOLUME_MAX );
if (batch>maxvolume)
      Lot size = maximum capacity; //--- return the value of the trading volume (many);
  }

The SymbolInfoDouble() function is used to check the availability of the current symbol price, followed by the Order Calculate Margin() function to request the margin required to place an order (in this case a buy order). The initial lot size is determined by the margin value required to place an order and the available margin of the account ( AccountInfoDouble(ACCOUNT_FREEMARGIN) ) and the maximum risk allowed value specified in the input parameter MaximumRisk.

If the value of the input parameter DecreaseFactor is positive, historical trades are analyzed and the lot size is adjusted taking into account information about the largest losing trade series: the initial lot size multiplied by the size (1-losses/DecreaseFactor).

The trading volume will then be "rounded" to a value that is a multiple of the minimum allowed trading volume step (stepvol) for the current symbol. A minimum (minvol) and maximum possible value (maxvol) of trading volume are also required and will be adjusted if the lot size exceeds the allowed limits. As a result, the function returns the calculated value of the trading volume.

3.2. Function CheckForOpen()

CheckForOpen() is used to check the opening conditions and open the position when the trading conditions occur (in this case when the price crosses the moving average).

 //+------------------------------------------------------------------+
//|Check vacancy conditions |
//+------------------------------------------------------------------+
Blank check on ( blank )
  {
Mql rate rt[ 2 ]; //--- copy price value if ( copy rate ( _symbol , _period , 0 , 2 , rt)!= 2 )
    {
print ( "replication rate" , _symbol , "failed, no history" );
return ;
    } //--- trade only on the first tick of the new bar if (rt[ 1 ].tick_volume > 1 )
Return ; //--- Get the current value of the moving average indicator double the horse[ 1 ];
if ( copybuffer (extendHandle, 0 , 0 , 1 , mom) != 1 )
    {
print ( "Failed to copy buffer from iMA, no data" );
return ;
    } //--- Check signal ENUM_ORDER_TYPE signal = error_value ;

if (rt[ 0 ].open>ma[ 0 ] && rt[ 0 ].close  0 ])
      Signal= Order type_Sell ; //Sell conditions other {
if (rt[ 0 ].open  0 ] && rt[ 0 ].close>ma[ 0 ])
        signal = order type buy ; // buy condition } //--- additional check if (signal != error_value )
if ( terminal information integer ( TERMINAL_TRADE_ALLOWED ))
if ( bar ( _symbol , _period )> 100 )
          {
            CTrade Trading;
            trade.PositionOpen( _symbol ,signal,TradeSizeOptimized(),
Symbol Info Double ( _Symbol , Signal == Order Type_Sell ? SYMBOL_BID : SYMBOL_ASK ),
0 , 0 );
          } //--- }

When trading with moving averages, you need to check if the price crosses the moving average. Using the copyrate() function, two values ​​of the current price are copied into the structure array rt[], rt[1] corresponds to the current bar, rt[0] - the completed bar.

A new bar is started by checking the tick volume of the current bar, if it is equal to 1, then a new bar has been started. It should be noted that this method of detecting new bars may fail in some cases (when quotes appear in groups), so the fact of the beginning of the formation of a new bar should be done by saving and comparing the time of the current quotes (see Is a new bar ).

Request the current value of the Moving Average indicator using the copy buffer() function and save it in a ma[] array containing only one value. Then, the program checks whether the price crosses the moving average and performs additional checks (whether it is possible to trade using the EA and whether bars exist historically). If successful, the appropriate position for the trading symbol is opened by calling the following function: PositionOpen() method of the trading object (Instance Trade Network ).

The opening price is a function that returns the bid or ask price based on the value of the signal variable using SymbolInfoDouble() with the following settings. The position size is determined by calling TradeSizeOptimized() above.

3.3. Function CheckForClose()

CheckForClose() checks the closing condition and closes the position if it occurs.

 //+------------------------------------------------------------------+
//|Check closing conditions |
//+------------------------------------------------------------------+
Blank check off( blank )
  {
Mql rate rt[ 2 ]; //--- copy price value if ( copy rate ( _symbol , _period , 0 , 2 , rt)!= 2 )
    {
print ( "replication rate" , _symbol , "failed, no history" );
return ;
    } //--- trade only on the first tick of the new bar if (rt[ 1 ].tick_volume > 1 )
Return ; //--- Get the current value of the moving average indicator double the horse[ 1 ];
if ( copybuffer (extendHandle, 0 , 0 , 1 , mom) != 1 )
    {
print ( "Failed to copy buffer from iMA, no data" );
return ;
    } //--- Get the position type previously selected using PositionSelect() boolean signal = wrong ;
long type = position getInteger ( positionType );

if (type == ( long ) POSITION_TYPE_BUY && rt[ 0 ].open>ma[ 0 ] && rt[ 0 ].close  0 ])
      signal = true ;
if (type == ( long ) POSITION_TYPE_SELL && rt[ 0 ].open  0 ] && rt[ 0 ].close>ma[ 0 ])
      signal = true ; //--- additional check if (signal)
if ( terminal information integer ( TERMINAL_TRADE_ALLOWED ))
if ( bar ( _symbol , _period )> 100 )
          {
            CTrade Trading;
            trade.Close( _symbol , 3 );
          } //--- }

The algorithm of the CheckForClose() function is similar to the algorithm of CheckForOpen(). The closing conditions are rechecked based on the direction of the current open position (price crosses the moving average downward for buying or upward for selling). Open positions are closed by calling the Close() method of the trading object (Instance Trade Network ).

The optimal values ​​for the parameters of the Strategy Tester MetaTrader 5 terminal can be found using the following methods.

For example, when optimizing the MovingPeriod parameter in the 2012.01.01-2013.08.01 interval, the best results are obtained when MovingPeriod=45:

Moving Average - expert for MetaTrader 5

Moving average EA trading backtest results

The Moving Average Expert Advisor included in the standard package of the MetaTrader 5 terminal is a standard library of examples of technical indicators , trade history functionality and trade categories . Additionally, the EA includes a money management system based on trading results.


Attachment download

📎 moving_average.mq5 (6.5 KB)

Source: MQL5 #1921

Verification code Refresh