How to calculate an EMA Death Cross with Python 3, MetaTrader 5, and Pandas
Learn how to calculate a classic EMA Cross of Death event for your Python Trading Bot. The article uses Python, Pandas, and MetaTrader 5
Learn how to calculate a classic EMA Cross of Death event for your Python Trading Bot. The article uses Python, Pandas, and MetaTrader 5
There are a ton of signals to analyze when using quantitative analysis for stock/crypto/futures/FOREX trading!
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).
Requirements and assumed knowledge as follows:
What would it take for Crypto, AI, and Cyber to truly change the world?
No spam. Unsubscribe anytime.
The ‘Cross of Death’ (aka Death Cross) is a stock market chart pattern reflecting recent price weakness. In generic terms, it occurs when a shorter-term moving average drops below a longer-term moving average.
For EMA stock calculations, these time periods are frequently the 15-day moving average and 50-day moving average. I.e. a death cross occurs when the 15-day moving average drops below the 50-day moving average. Visually this might look like this:
A Death Cross occurs mathematically when the previous short-term moving average is above the previous long-term moving average and the current short-term moving average is below the current long-term moving average.
Simplified into pseudo-code:
prev_15
prev_50
curr_15
curr_50
prev_15 > prev_50
AND curr_15 < curr_50
: cross_of_death = True
This can be calculated using the Simple Moving Average (SMA) and Exponential Moving Average (EMA).
Before demonstrating the code to calculate an EMA Death Cross, I’ll outline a couple of considerations:
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.
Let’s start with a generic EMA function that returns an intact Pandas Dataframe. Here’s the code:
# Define function to calculate an arbitrary EMA and return Dataframe
def calc_generic_ema_with_dataframe(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_close]*(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
The previous function returns a list of all EMA’s for the last 1000 candles (required for a weighted moving average). Therefore, to determine if a Cross of Death event has occurred, extract the close
values for the last 2 candles and compare them.
Here’s the code:
import generic_ema
import pandas
# Function to calculate a generic Cross of Death
def generic_ema_death_cross(symbol, timeframe):
# Retrieve the 15 candle EMA
ema_15 = generic_ema.calc_generic_ema_with_dataframe(symbol=symbol, timeframe=timeframe, ema_size=15, num_rows=1000)
# Retrieve the 50 candle EMA
ema_50 = generic_ema.calc_generic_ema_with_dataframe(symbol=symbol, timeframe=timeframe, ema_size=50, num_rows=1000)
# Extract the previous values. Number_of_rows - 2 for both EMA 15 and EMA 50
prev_15 = ema_15.loc[998, 'close']
prev_50 = ema_50.loc[998, 'close']
# Extract the current values. Number_of_rows - 1 for EMA 15 and EMA 50
curr_15 = ema_15.loc[999, 'close']
curr_50 = ema_50.loc[999, 'close']
# Compare
if prev_15 > prev_50 and curr_15 < curr_50:
return True
return False
Finally, the function to calculate a ‘classic’ death cross is as follows:
# Calculate a 'classic' cross of death event
def ema_death_cross(symbol):
return generic_ema_death_cross(symbol=symbol, timeframe="D1")
Nice. Calculating an EMA Death Cross can really help your trading algorithm make smarter decisions. Let me know how you’re planning to use it in the comments below!
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.
❤