Moving Averages in Algorithmic Trading: Types, Calculations, and Strategies

Moving averages (MAs) are among the most widely used indicators in algorithmic trading, helping to smooth price data and reveal underlying trends. By calculating the average price over a set period, MAs enable traders to identify trends and filter out market “noise.” In this article, we’ll discuss the different types of moving averages, explain how to calculate them, and explore their applications in trading algorithms. We’ll also provide an MQL4 example of a moving average crossover strategy.

What is a Moving Average (MA)?

A moving average (MA) is a statistical calculation used to smooth out price data by creating a constantly updated average price. The MA helps reveal trends by reducing the impact of random, short-term price fluctuations.

Primary Types of Moving Averages:

  1. Simple Moving Average (SMA): An unweighted average of prices over a specified period.
  2. Exponential Moving Average (EMA): A weighted average that gives more importance to recent prices, making it more responsive to price changes.
  3. Weighted Moving Average (WMA): A moving average where each price point is assigned a weight based on its age, giving the most recent prices higher significance.

Calculations of Different Moving Averages

1. Simple Moving Average (SMA)

Simple Moving Average Calculation

The SMA averages prices over a specific period without assigning more weight to recent data, making it a stable indicator but slower to react to price changes.

2. Exponential Moving Average (EMA)

Exponential Moving Average

Where:

Exponential Moving Average

The EMA applies more weight to recent prices, making it faster to respond to new price information than the SMA.

3. Weighted Moving Average (WMA)

Weighted Moving Average

In the WMA, each price point within the selected period is multiplied by a specific weight, with recent prices given higher weights.

Applications of Moving Averages in Algorithmic Trading

  1. Trend-Following: MAs are often used to identify market trends. For example, when prices are above the moving average, it may indicate an uptrend, and when below, a downtrend.
  2. Moving Average Crossover Strategy: In a crossover strategy, a shorter-period moving average crossing above a longer-period moving average triggers a buy signal, while a crossover below triggers a sell signal.
  3. Dynamic Support and Resistance: MAs can act as dynamic support and resistance levels, with prices often “bouncing” off these lines, indicating areas of buying or selling interest.
  4. Smoothing Volatility: By averaging prices, MAs help smooth out market volatility, making it easier to see the overall trend direction without getting distracted by price noise.

Moving Average Crossover Strategy Example in MQL4

In this MQL4 example, we’ll implement a basic moving average crossover strategy, where a short-term EMA crossing above a long-term EMA signals a buy, and a crossover below signals a sell.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Moving Average Crossover Strategy in MQL4
input int FastMAPeriod = 10;         // Period for fast EMA
input int SlowMAPeriod = 30;         // Period for slow EMA
input double LotSize = 0.1;          // Lot size for orders
 
// Global variables to track trade status
bool buyTradeOpen = false;
bool sellTradeOpen = false;
 
void OnTick() {
   double fastEMA = iMA(NULL, 0, FastMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0);
   double slowEMA = iMA(NULL, 0, SlowMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0);
 
   // Buy signal: Fast EMA crosses above Slow EMA
   if (fastEMA > slowEMA && !buyTradeOpen) {
       if (sellTradeOpen) CloseSell();
       OpenBuy();
   }
   // Sell signal: Fast EMA crosses below Slow EMA
   else if (fastEMA < slowEMA && !sellTradeOpen) { if (buyTradeOpen) CloseBuy(); OpenSell(); } } // Function to open a buy position void OpenBuy() { int ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, 0, 0, "EMA Crossover Buy", 0, 0, clrGreen); if (ticket > 0) {
       buyTradeOpen = true;
       sellTradeOpen = false;
       Print("Buy order opened.");
   } else {
       Print("Error opening buy order: ", GetLastError());
   }
}
 
// Function to open a sell position
void OpenSell() {
   int ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, 0, 0, "EMA Crossover Sell", 0, 0, clrRed);
   if (ticket > 0) {
       sellTradeOpen = true;
       buyTradeOpen = false;
       Print("Sell order opened.");
   } else {
       Print("Error opening sell order: ", GetLastError());
   }
}
 
// Function to close any open buy position
void CloseBuy() {
   for (int i = OrdersTotal() - 1; i >= 0; i--) {
       if (OrderSelect(i, SELECT_BY_POS) && OrderType() == OP_BUY) {
           OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrGreen);
           buyTradeOpen = false;
           Print("Buy order closed.");
       }
   }
}
 
// Function to close any open sell position
void CloseSell() {
   for (int i = OrdersTotal() - 1; i >= 0; i--) {
       if (OrderSelect(i, SELECT_BY_POS) && OrderType() == OP_SELL) {
           OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrRed);
           sellTradeOpen = false;
           Print("Sell order closed.");
       }
   }
}

Explanation of the Strategy

1. Parameters:

  • FastMAPeriod and SlowMAPeriod define the periods for the short and long EMAs, respectively.
  • LotSize controls the trade size for each position.

2. Trade Execution:

  • A buy signal is generated when the fast EMA crosses above the slow EMA, and a sell signal is triggered when the fast EMA crosses below the slow EMA.

3. Functions:

  • OpenBuy() and OpenSell() open buy and sell trades based on crossover signals.
  • CloseBuy() and CloseSell() close positions when an opposing signal appears.

This strategy is a simple yet effective way to capture trends using moving averages and can be adapted by adjusting the fast and slow periods or incorporating additional indicators.

Tips for Optimising Moving Average Strategies

  1. Optimise Periods: Test different periods for the fast and slow MAs to find the most profitable configuration.
  2. Add a Volume Filter: Volume indicators like OBV can confirm strong trends and help avoid false signals in low-volume markets.
  3. Combine with Other Indicators: Use indicators like RSI or MACD for confirmation, reducing the likelihood of entering trades on weak signals.

Conclusion

Moving averages are versatile and reliable indicators in algo trading, helping traders identify trends, smooth volatility, and build effective crossover strategies. By understanding different types of moving averages and their applications, you can start implementing these indicators in your own algorithms. In the next article, we’ll explore Relative Strength Index (RSI) and Momentum Trading, covering calculations, coding, and how to leverage momentum in algorithmic trading.