# How to calculate a 15-Day EMA with Python 3, Pandas, and MetaTrader 5

#### Automated Trading Bot with MetaTrader5 and Python

There are a ton of signals to analyze when using quantitative analysis for stock/crypto/futures/FOREX trading!

### About This Series

This series demonstrates the automated analysis of 8 different market signals.

Using Python 3, Python Pandas, and MetaTrader5, I’ll show you how to calculate 8 common signals.

All code for this tutorial can be found on my GitHub, and I’ve included working code samples throughout (use at your own risk, give me a shout-out if you do).

#### What You Need

Requirements and assumed knowledge as follows:

- Already connected to MetaTrader 5. This article shows you how, I’m using the variant from IC Markets.
- Windows 10 or above. For reasons known only to MetaTrader, the Python API only works on Windows 😊
- Python 3. This series was built with Python 3.10

### The EMA

#### Introduction to the Exponential Moving Average

In chart pattern analysis of stocks/forex/crypto/futures, the Exponential Moving Average (EMA) plays an important role. It is technically a weighted moving average and is frequently used to see price trends over time. Investopedia states that “the EMA is designed to improve on the idea of an SMA (Simple Moving Average) by giving more weight to the most recent price data”. As a result, the EMA is believed to respond more quickly to price changes than the SMA.

Including an EMA calculation in your Python Trading Bot could be a great way to help it make algorithmic decisions about Buy and Sell movements more effectively.

Let’s do just that!

#### How to Calculate

The formula for an EMA is:

**EMA = Todays_Price * multiplier + Yesterdays_EMA * (1 — multiplier)**

Where the multiplier is: **2/(Number_of_Periods + 1)**

The very first EMA value is the SMA.

While this sounds a bit abstract, I’ll demonstrate how to do it in code in the next section.

### How to Code

Before demonstrating the code to calculate an EMA, I’ll outline a couple of considerations:

**Precision.**Because the EMA is a weighted average, any imprecision in the price will continue to replicate, effectively forever. The only way to eliminate any imprecision would be to calculate the EMA using every available data point for a given timeframe.**Compute Time.**Depending on your system, the compute time required to calculate an EMA can be huge. For example, in my testing, I calculated the EMA across 50,000 1-minute candles, taking approximately 15 minutes. Clearly, that is unworkable. There are techniques such as multiprocessing to speed this up, however, I’ve chosen to limit the calculation for this series.

As a result, you’ll need to figure out what level of precision you’re comfortable with. I’ve chosen to use a candle limit of 1000 rows for this series, on my system this completes in < 1 second.

#### Generic EMA Function

Let’s start by building a generic EMA function. This function can calculate an EMA on an arbitrary timeframe for a specified number of candles. Here’s how it works:

- Retrieve the raw_data from MetaTrader 5
- Calculate the multiplier for the most recent data
- Calculate the initial SMA
- Iterate through the Dataframe, storing each result in a new column called
`ema_<whatever_ema_you_choose>`

- Return the final EMA value (this can be easily modified to return the entire Dataframe if desired)

Here’s the code:

```
import mt5_interface
import pandas
# Define function to calculate an arbitrary EMA
def calc_generic_ema(symbol, timeframe, ema_size, num_rows):
raw_data = mt5_interface.query_historic_data(symbol=symbol, timeframe=timeframe, number_of_candles=num_rows)
# Convert into Dataframe
dataframe = pandas.DataFrame(raw_data)
# Create column string
ema_name = "ema_" + str(ema_size)
# Create the multiplier
multiplier = 2/(ema_size + 1)
# Calculate the initial value (SMA)
# pandas.set_option('display.max_columns', None) # <- use this to show all columns
# pandas.set_option('display.max_rows', None) # <- use this to show all the rows
initial_mean = dataframe['close'].head(ema_size).mean()
# Iterate through Dataframe
for i in range(len(dataframe)):
if i == ema_size:
dataframe.loc[i, ema_name] = initial_mean
elif i > ema_size:
ema_value = dataframe.loc[i, 'close'] * multiplier + dataframe.loc[i-1, ema_name]*(1-multiplier)
dataframe.loc[i, ema_name] = ema_value
else:
dataframe.loc[i, ema_name] = 0.00
# print(dataframe) # <- use this to print the dataframe if you want to inspect
return dataframe.loc[num_rows-1, ema_name]
```

A couple of things to note if you’re inspecting the code:

- If you want to review the Dataframe,
`pandas.set_option('display.max_columns', None)`

will set Pandas to show you all the columns.`pandas.set_option('display.max_rows', None)`

will set Pandas to show you all the rows. I’ve left these commented out in the code (along with a print statement) - The first rows equal to
`ema_size`

will be`0.00`

. This is because it is not possible to calculate the initial SMA value until the number of rows equal to EMA size is reached.

#### 15-Day EMA Function

To create a function to calculate the 15-Day EMA, all that’s required is to set the variables in this function.

Here’s mine:

```
import generic_ema
# Function to calculate 15-day EMA. Precision set to 1000 rows
def calc_ema_15(symbol):
return generic_ema.calc_generic_ema(symbol=symbol, timeframe="D1", ema_size=15, num_rows=1000)
```

**Note.** If you’re looking for how to connect to MetaTrader, the file `mt5_interface.py`

has the details.

### Wrapping Up

And that’s it. Put in the symbol you’d like to query and let it rip!

Let me know how you’re planning to use it in the comments below 😊

### Say Hi!

I love hearing from my readers, so feel free to reach out. It means a ton to me when you clap for my articles or drop a friendly comment — it helps me know that my content is helping.

❤