top of page

Exponential Moving Average in Python

Learn how to calculate one of the most popular technical analysis measurements in python! Similar to the Simple Moving Average (SMA), the Exponential Moving Average (EMA) is a rolling average value that adds some spice! The EMA has additional weight on values closer to the present day to increase the importance of most recent data. This blog post will show you how to perform Exponential Moving Averages in Python!



stock trader looking at charts


Import Needed Libraries

import yfinance as yf 
import pandas as pd 
import matplotlib.pyplot as plt 
from datetime import timedelta, datetime, date

Create a Custom Yahoo Finance GET Data Function

def GetYahooFinanceData(ticker, start, end):
    formatDate = "%Y-%m-%d"
    
    # Add 1 day to end date
    end = datetime.strptime(end, formatDate)
    end = end + timedelta(days = 1) #add one day to end date to get desired result
    end = end.strftime(formatDate) #converts back to a string type date 
    
    df = yf.download(ticker, start, end)
    return df 
symbol = 'AAPL'
stock_data = GetYahooFinanceData(symbol,'2022-01-01','2024-02-15')
stock_data

[*********************100%%**********************] 1 of 1 completed

Out[1]:


Open

High

Low

Close

Adj Close

Volume

Date







2022-01-03

177.830002

182.880005

177.710007

182.009995

179.724564

104487900

2022-01-04

182.630005

182.940002

179.119995

179.699997

177.443573

99310400

2022-01-05

179.610001

180.169998

174.639999

174.919998

172.723587

94537600

2022-01-06

172.699997

175.300003

171.639999

172.000000

169.840240

96904000

2022-01-07

172.889999

174.139999

171.029999

172.169998

170.008118

86709100

...

...

...

...

...

...

...

2024-02-09

188.649994

189.990005

188.000000

188.850006

188.850006

45155200

2024-02-12

188.419998

188.669998

186.789993

187.149994

187.149994

41781900

2024-02-13

185.770004

186.210007

183.509995

185.039993

185.039993

56529500

2024-02-14

185.320007

185.529999

182.440002

184.149994

184.149994

54630500

2024-02-15

183.550003

184.490005

181.350006

183.860001

183.860001

65434500

533 rows × 6 columns


Now Calculate the EMA!

# Calculate EMA12, EMA128 EMA200 
stock_data['EMA12'] = stock_data['Close'].ewm(span=12, min_periods=0, adjust=False).mean() 
stock_data['EMA128'] = stock_data['Close'].ewm(span=128, min_periods=0, adjust=False).mean() 
stock_data['EMA200'] = stock_data['Close'].ewm(span=200, min_periods=0, adjust=False).mean() 
stock_data



Open

High

Low

Close

Adj Close

Volume

EMA12

EMA128

EMA200

Date










2022-01-03

177.830002

182.880005

177.710007

182.009995

179.724564

104487900

182.009995

182.009995

182.009995

2022-01-04

182.630005

182.940002

179.119995

179.699997

177.443573

99310400

181.654610

181.974181

181.987009

2022-01-05

179.610001

180.169998

174.639999

174.919998

172.723587

94537600

180.618516

181.864813

181.916691

2022-01-06

172.699997

175.300003

171.639999

172.000000

169.840240

96904000

179.292591

181.711871

181.818017

2022-01-07

172.889999

174.139999

171.029999

172.169998

170.008118

86709100

178.196807

181.563935

181.722017

...

...

...

...

...

...

...

...

...

...

2024-02-09

188.649994

189.990005

188.000000

188.850006

188.850006

45155200

188.726492

184.599864

180.690855

2024-02-12

188.419998

188.669998

186.789993

187.149994

187.149994

41781900

188.483954

184.639401

180.755125

2024-02-13

185.770004

186.210007

183.509995

185.039993

185.039993

56529500

187.954114

184.645612

180.797760

2024-02-14

185.320007

185.529999

182.440002

184.149994

184.149994

54630500

187.368865

184.637928

180.831116

2024-02-15

183.550003

184.490005

181.350006

183.860001

183.860001

65434500

186.829039

184.625867

180.861254

533 rows × 9 columns


Why Stop Here? Automate Buy and Sell Signals!

# Initialize buy and sell columns 
stock_data['Buy_Signal'] = 0 
stock_data['Sell_Signal'] = 0
#iterate through the dataframe using a for loop 
for i in range(1,len(stock_data)):
    if (stock_data['EMA12'][i] > stock_data['EMA128'][i]) and (stock_data['EMA12'][i-1] <= stock_data['EMA128'][i-1]):
        stock_data['Buy_Signal'][i] = 1 
    elif (stock_data['EMA12'][i] < stock_data['EMA128'][i]) and (stock_data['EMA12'][i-1] >= stock_data['EMA128'][i-1]):
        stock_data['Sell_Signal'][i] = -1

Visualize Your New Trading Algorithm!

plt.figure(figsize=(20,8))
#Lines - Close and EMA Lines
plt.plot(stock_data.index, stock_data['Close'], label='Close Price', color = 'black')
plt.plot(stock_data.index, stock_data['EMA12'], label='EMA12', color = 'blue')
plt.plot(stock_data.index, stock_data['EMA128'], label='EMA128', color = 'red')
plt.plot(stock_data.index, stock_data['EMA200'], label='EMA200', color = 'green')
# Plot buy and sell signals 
buy_signals = stock_data[stock_data['Buy_Signal'] == 1]
plt.scatter(buy_signals.index, buy_signals['Close'], marker='^', color='g', label='Buy Signal', s=100) 
sell_signals = stock_data[stock_data['Sell_Signal'] == -1]
plt.scatter(sell_signals.index, sell_signals['Close'], marker='v', color='r', label='Sell Signal', s=100)
plt.title(f'{symbol} Price with EMA and Trading Signals')
plt.xlabel('Date')
plt.ylabel(f'{symbol} Price')
plt.legend() 
Exponential Moving Average AAPL Stock
EMA Lines for AAPL Stock

But How Does the Algorithm Perform?

initial_capital = 10000
position = 0
capital = initial_capital
bought_and_held_capital = capital 
bought_and_held_shares = capital / stock_data['Close'][0]
#Simulate trading 
for i in range(len(stock_data)):
    if stock_data['Buy_Signal'][i] == 1:
        #Buy 10,000 worth of the asset 
        shares_to_buy = capital / stock_data['Close'][i] 
        position += shares_to_buy 
        capital -= shares_to_buy * stock_data['Close'][i]
        
    elif stock_data['Sell_Signal'][i] == -1:
        #Sell all shares 
        capital += position * stock_data['Close'][i]
        position = 0 
        
    # Update bought and held strategy 
    bought_and_held_capital = bought_and_held_shares * stock_data['Close'][i] 
    
#Calculate final value 
algorithm_final_value = capital + position * stock_data['Close'][-1]
bought_and_held_final_value = bought_and_held_capital
algorithm_final_percent = (algorithm_final_value - initial_capital)/initial_capital
bought_and_held_final_percent = (bought_and_held_final_value - initial_capital)/initial_capital
# Print results
print("Algorithm Final Value: $", algorithm_final_value, "%: ", round(algorithm_final_percent*100,1))
print("Bought and Held Final Value: $", bought_and_held_final_value, "%: ", round(bought_and_held_final_percent*100,1))

Algorithm Final Value: $ 10217.106243115186 %: 2.2 Bought and Held Final Value: $ 10101.643105288162 %: 1.0


We see the algorithm slightly performing better on AAPL stock compared to a buy and held position with the algorithm up 2.2% while AAPL itself is up 1%. The algorithm is not perfect and not expected to outperform in each scenario. I hope you enjoy the EMA algorithm and the code! Happy trading!


*Intrendias is not financial advice.



Comments


bottom of page