import pandas as pd import datetime as dt import matplotlib.pyplot as plt from util import get_data def author(): return "felixm" def normalize(timeseries): return timeseries / timeseries.iloc[0] def bollinger_band(df, symbol, period=20, m=2): boll_sma = df[symbol].rolling(period).mean() std = df[symbol].rolling(period).std() boll_up = boll_sma + m * std boll_lo = boll_sma - m * std df[f"{symbol}-Boll({period})-sma"] = boll_sma df[f"{symbol}-Boll({period})-up"] = boll_up df[f"{symbol}-Boll({period})-lo"] = boll_lo def sma(df, symbol, period): """Adds SMA for one or multiple periods to df and returns SMAs""" if type(period) is int: period = [period] keys = [] for p in period: key = f"{symbol}-sma({p})" df[key] = df[symbol].rolling(p).mean() keys.append(key) return df[keys] def ema(df, symbol, period): """Adds a new column to the dataframe EMA(period)""" df[f"{symbol}-ema({period})"] = df[symbol].ewm(span=period).mean() def price_sma(df, symbol, period): """Calculates SMA and adds new column price divided by SMA to the df.""" sma = df[symbol].rolling(period).mean() df[f"{symbol}-price/sma({period})"] = df[symbol] / sma def rsi(df, symbol, period=14): """Calculates relative strength index over given period.""" def rsi(x): pct = x.pct_change() avg_gain = pct[pct > 0].mean() avg_loss = pct[pct <= 0].abs().mean() rsi = 100 - (100 / (1 + ((avg_gain / period) / (avg_loss / period)))) return rsi key = f"rsi" # Add one to get 'period' price changes (first change is nan). period += 1 df[key] = df[symbol].rolling(period).apply(rsi) return df[key] def macd(df, symbol): macd = df[symbol].ewm(span=12).mean() - df[symbol].ewm(span=26).mean() k1 = f"macd" k2 = k1 + "-signal" df[k1] = macd df[k2] = macd.rolling(9).mean() return df[[k1, k2]] def price_delta(df, symbol, period=1): """Calculate delta between previous day and today.""" df[f"{symbol}-diff({period})"] = df[symbol].diff(periods=period) def test_indicators(): symbol = "JPM" sd = dt.datetime(2008, 1, 1) ed = dt.datetime(2009, 12, 31) df = get_data([symbol], pd.date_range(sd, ed)) df.drop(columns=["SPY"], inplace=True) df_orig = df.copy() # df = normalize(df) sma(df, symbol, 21) ema(df, symbol, 21) df.plot(title="21 SMA and EMA") plt.savefig('figure_1.png') df = df_orig.copy() sma(df, symbol, 8) price_sma(df, symbol, 8) df.plot(title="SMA and price / SMA", subplots=True) plt.savefig('figure_2.png') df = df_orig.copy() bollinger_band(df, symbol) df.plot(title="Bollinger Band") plt.savefig('figure_3.png') df = df_orig.copy() rsi(df, symbol) fig, axes = plt.subplots(nrows=2, sharex=True) df[symbol].plot(ax=axes[0], title="JPM price action") df["JPM-rsi(14)"].plot(ax=axes[1], title="RSI") plt.savefig('figure_4.png') df = df_orig.copy() macd(df, symbol) fig, axes = plt.subplots(nrows=2, sharex=True) df[symbol].plot(ax=axes[0], title="JPM price action") df[["JPM-macd", "JPM-macd-signal"]].plot(ax=axes[1]) plt.savefig('figure_5.png')