Created
October 9, 2020 15:46
-
-
Save pratiknabriya/1b288187c1e7bac98a79b5ea56d24fb0 to your computer and use it in GitHub Desktop.
Generating trade signals using moving average(SMA/EMA) crossover strategy.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# import necessary libraries | |
%matplotlib inline | |
import numpy as np | |
import pandas as pd | |
import matplotlib.pyplot as plt | |
import datetime | |
from tabulate import tabulate | |
import warnings | |
warnings.filterwarnings('ignore') | |
import pandas_datareader.data as web | |
def MovingAverageCrossStrategy(stock_symbol = 'ULTRACEMCO.NS', start_date = '2018-01-01', end_date = '2020-01-01', | |
short_window = 20, long_window = 50, moving_avg = 'SMA', display_table = True): | |
''' | |
The function takes the stock symbol, time-duration of analysis, | |
look-back periods and the moving-average type(SMA or EMA) as input | |
and returns the respective MA Crossover chart along with the buy/sell signals for the given period. | |
''' | |
# stock_symbol - (str)stock ticker as on Yahoo finance. Eg: 'ULTRACEMCO.NS' | |
# start_date - (str)start analysis from this date (format: 'YYYY-MM-DD') Eg: '2018-01-01' | |
# end_date - (str)end analysis on this date (format: 'YYYY-MM-DD') Eg: '2020-01-01' | |
# short_window - (int)lookback period for short-term moving average. Eg: 5, 10, 20 | |
# long_window - (int)lookback period for long-term moving average. Eg: 50, 100, 200 | |
# moving_avg - (str)the type of moving average to use ('SMA' or 'EMA') | |
# display_table - (bool)whether to display the date and price table at buy/sell positions(True/False) | |
# import the closing price data of the stock for the aforementioned period of time in Pandas dataframe | |
start = datetime.datetime(*map(int, start_date.split('-'))) | |
end = datetime.datetime(*map(int, end_date.split('-'))) | |
stock_df = web.DataReader(stock_symbol, 'yahoo', start = start, end = end)['Close'] | |
stock_df = pd.DataFrame(stock_df) # convert Series object to dataframe | |
stock_df.columns = {'Close Price'} # assign new colun name | |
stock_df.dropna(axis = 0, inplace = True) # remove any null rows | |
# column names for long and short moving average columns | |
short_window_col = str(short_window) + '_' + moving_avg | |
long_window_col = str(long_window) + '_' + moving_avg | |
if moving_avg == 'SMA': | |
# Create a short simple moving average column | |
stock_df[short_window_col] = stock_df['Close Price'].rolling(window = short_window, min_periods = 1).mean() | |
# Create a long simple moving average column | |
stock_df[long_window_col] = stock_df['Close Price'].rolling(window = long_window, min_periods = 1).mean() | |
elif moving_avg == 'EMA': | |
# Create short exponential moving average column | |
stock_df[short_window_col] = stock_df['Close Price'].ewm(span = short_window, adjust = False).mean() | |
# Create a long exponential moving average column | |
stock_df[long_window_col] = stock_df['Close Price'].ewm(span = long_window, adjust = False).mean() | |
# create a new column 'Signal' such that if faster moving average is greater than slower moving average | |
# then set Signal as 1 else 0. | |
stock_df['Signal'] = 0.0 | |
stock_df['Signal'] = np.where(stock_df[short_window_col] > stock_df[long_window_col], 1.0, 0.0) | |
# create a new column 'Position' which is a day-to-day difference of the 'Signal' column. | |
stock_df['Position'] = stock_df['Signal'].diff() | |
# plot close price, short-term and long-term moving averages | |
plt.figure(figsize = (20,10)) | |
plt.tick_params(axis = 'both', labelsize = 14) | |
stock_df['Close Price'].plot(color = 'k', lw = 1, label = 'Close Price') | |
stock_df[short_window_col].plot(color = 'b', lw = 1, label = short_window_col) | |
stock_df[long_window_col].plot(color = 'g', lw = 1, label = long_window_col) | |
# plot 'buy' signals | |
plt.plot(stock_df[stock_df['Position'] == 1].index, | |
stock_df[short_window_col][stock_df['Position'] == 1], | |
'^', markersize = 15, color = 'g', alpha = 0.7, label = 'buy') | |
# plot 'sell' signals | |
plt.plot(stock_df[stock_df['Position'] == -1].index, | |
stock_df[short_window_col][stock_df['Position'] == -1], | |
'v', markersize = 15, color = 'r', alpha = 0.7, label = 'sell') | |
plt.ylabel('Price in ₹', fontsize = 16 ) | |
plt.xlabel('Date', fontsize = 16 ) | |
plt.title(str(stock_symbol) + ' - ' + str(moving_avg) + ' Crossover', fontsize = 20) | |
plt.legend() | |
plt.grid() | |
plt.show() | |
if display_table == True: | |
df_pos = stock_df[(stock_df['Position'] == 1) | (stock_df['Position'] == -1)] | |
df_pos['Position'] = df_pos['Position'].apply(lambda x: 'Buy' if x == 1 else 'Sell') | |
print(tabulate(df_pos, headers = 'keys', tablefmt = 'psql')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment