1
0
Fork 0

Finish manual strategy for project 8

I struggled with the manual strategy, mostly because I tried to read
good triggers from the price action charts. Finally, I had the ingenious
(hmm) idea to scatter plot the 1, 3, and 5 day percentage returns over
different indicators. I can also use this information to train my Q
learner.
master
Felix Martin 2020-11-03 19:05:43 -05:00
parent 43e297c075
commit 0519ae9336
3 changed files with 108 additions and 46 deletions

View File

@ -58,19 +58,32 @@ class ManualStrategy:
orders['Shares'] = orders['Shares'].rolling(2).apply(strat)
def three_indicator_strat(self, macd, rsi, price_sma, orders):
# XXX: continue here
def strat(row):
m = macd.loc[row.index]
print(m)
# mac, signal = m.iloc[0]
# print(mac, signal)
return 0
shares = 0
_, _, macd_diff = macd.loc[row.name]
cur_rsi = rsi.loc[row.name][0]
cur_price_sma = price_sma.loc[row.name][0]
if self.holding == -1000 and cur_price_sma < 0.9:
shares = 2000
elif self.holding == 0 and cur_price_sma < 0.9:
shares = 1000
elif self.holding == -1000 and cur_rsi > 80:
shares = 2000
elif self.holding == 0 and cur_rsi > 80:
shares = 1000
elif self.holding == -1000 and macd_diff < -0.5:
shares = 2000
elif self.holding == 0 and macd_diff < -0.5:
shares = 1000
elif self.holding == 1000 and cur_price_sma > 1.1:
shares = -2000
elif self.holding == 0 and cur_price_sma > 1.1:
shares = -1000
self.holding += shares
return shares
orders['Shares'] = orders.apply(strat, axis=1)
raise Exception()
# this method should use the existing policy and test it against new data
def testPolicy(self, symbol="IBM",
sd=dt.datetime(2009, 1, 1),
ed=dt.datetime(2010, 1, 1),
@ -87,10 +100,9 @@ class ManualStrategy:
macd = indicators.macd(df, symbol)
rsi = indicators.rsi(df, symbol)
price_sma = indicators.price_sma(df, symbol, [21])
price_sma = indicators.price_sma(df, symbol, [8])
# self.macd_strat(macd, orders)
self.three_indicator_strat(macd, rsi, price_sma, orders)
# heers = orders[orders["Shares"] != 0]
return orders

View File

@ -1,22 +1,76 @@
import pandas as pd
import datetime as dt
import marketsim.marketsim as marketsim
import indicators
import sys
import util
import indicators
import marketsim.marketsim as marketsim
import matplotlib.pyplot as plt
from matplotlib.widgets import MultiCursor
from BenchmarkStrategy import BenchmarkStrategy
from ManualStrategy import ManualStrategy
def plot_indicators(symbol, df):
fig, ax = plt.subplots(4, sharex=True)
price_sma = indicators.price_sma(df, symbol, [8])
bb = indicators.bollinger_band(df, symbol)
sma = indicators.sma(df, symbol, [8])
rsi = indicators.rsi(df, symbol)
macd = indicators.macd(df, symbol).copy()
df[[symbol]].plot(ax=ax[0])
bb.plot(ax=ax[0])
price_sma.plot(ax=ax[1])
macd.plot(ax=ax[2])
rsi.plot(ax=ax[3])
for a in ax.flat:
a.grid()
plt.show()
sys.exit(0)
def visualize_correlations(symbol, df):
indicators.price_sma(df, symbol, [8, 21])
indicators.price_delta(df, symbol, 5)
indicators.price_delta(df, symbol, 3)
indicators.price_delta(df, symbol, 1)
indicators.macd(df, symbol)
indicators.rsi(df, symbol)
# df = df[df['rsi'] > 80]
fig, ax = plt.subplots(3, 2) # sharex=True)
df.plot.scatter(x="price_sma_8", y="pct_5", ax=ax[0, 0])
df.plot.scatter(x="price_sma_8", y="pct_3", ax=ax[1, 0])
df.plot.scatter(x="price_sma_8", y="pct_1", ax=ax[2, 0])
# df.plot.scatter(x="rsi", y="pct_5", ax=ax[0, 1])
# df.plot.scatter(x="rsi", y="pct_3", ax=ax[1, 1])
# df.plot.scatter(x="rsi", y="pct_1", ax=ax[2, 1])
df.plot.scatter(x="macd_diff", y="pct_5", ax=ax[0, 1])
df.plot.scatter(x="macd_diff", y="pct_3", ax=ax[1, 1])
df.plot.scatter(x="macd_diff", y="pct_1", ax=ax[2, 1])
for a in ax.flat:
a.grid()
plt.show()
sys.exit(0)
def experiment1():
symbol = "JPM"
start_value = 10000
sd = dt.datetime(2008, 1, 1)
ed = dt.datetime(2009, 12, 31)
sd = dt.datetime(2008, 1, 1) # in-sample
ed = dt.datetime(2009, 12, 31) # in-sample
# sd = dt.datetime(2010, 1, 1) # out-sample
# ed = dt.datetime(2011, 12, 31) # out-sample
df = util.get_data([symbol], pd.date_range(sd, ed))
df.drop(columns=["SPY"], inplace=True)
# visualize_correlations(symbol, df)
# plot_indicators(symbol, df)
bs = BenchmarkStrategy()
orders = bs.testPolicy(symbol, sd, ed, start_value)
df["Benchmark"] = marketsim.compute_portvals(orders, start_value)
@ -26,21 +80,12 @@ def experiment1():
orders = ms.testPolicy(symbol, sd, ed, start_value)
df["Manual"] = marketsim.compute_portvals(orders, start_value)
df["Orders Manual"] = orders["Shares"]
df["Holding Manual"] = orders["Shares"].cumsum()
price_sma = indicators.price_sma(df, symbol, [21])
bb = indicators.bollinger_band(df, symbol)
sma = indicators.sma(df, symbol, [9, 21])
rsi = indicators.rsi(df, symbol)
macd = indicators.macd(df, symbol).copy()
fig, ax = plt.subplots(4, sharex=True)
fig, ax = plt.subplots(3, sharex=True)
df[[symbol]].plot(ax=ax[0])
# bb.plot(ax=ax[0])
price_sma.plot(ax=ax[1])
macd.plot(ax=ax[2])
rsi.plot(ax=ax[3])
# df[["Benchmark", "Manual"]].plot(ax=ax[1])
# df[["Orders Benchmark", "Orders Manual"]].plot(ax=ax[2])
df[["Benchmark", "Manual"]].plot(ax=ax[1])
df[["Orders Benchmark", "Orders Manual"]].plot(ax=ax[2])
for a in ax:
a.grid()
@ -48,11 +93,7 @@ def experiment1():
plt.show()
# plt.savefig('figure_1.png')
# You may use data from other symbols (such as SPY) to inform both your
# Manual Learner and Strategy Learner. The in-sample/development period is
# January 1, 2008 to December 31 2009. The out-of-sample/testing period is
# January 1, 2010 to December 31 2011.
if __name__ == "__main__":
experiment1()

View File

@ -17,9 +17,7 @@ def bollinger_band(df, symbol, period=20, m=2):
std = df[symbol].rolling(period).std()
boll_up = boll_sma + m * std
boll_lo = boll_sma - m * std
key_sma = f"{symbol}-Boll({period})-sma"
key_up = f"{symbol}-Boll({period})-up"
key_lo = f"{symbol}-Boll({period})-lo"
key_sma, key_up, key_lo = "boll_sma", "boll_up", "boll_lo"
df[key_sma] = boll_sma
df[key_up] = boll_up
df[key_lo] = boll_lo
@ -32,7 +30,7 @@ def sma(df, symbol, period):
period = [period]
keys = []
for p in period:
key = f"{symbol}-sma({p})"
key = f"sma_{p}"
df[key] = df[symbol].rolling(p).mean()
keys.append(key)
return df[keys]
@ -44,8 +42,8 @@ def ema(df, symbol, period):
period = [period]
keys = []
for p in period:
key = f"{symbol}-ema({p})"
df[key] = df[symbol].ewm(span=period).mean()
key = f"ema_{p}"
df[key] = df[symbol].ewm(span=p).mean()
keys.append(key)
return df[keys]
@ -56,7 +54,7 @@ def price_sma(df, symbol, period):
period = [period]
keys = []
for p in period:
key = f"{symbol}-price/sma({p})"
key = f"price_sma_{p}"
sma = df[symbol].rolling(p).mean()
df[key] = df[symbol] / sma
keys.append(key)
@ -84,16 +82,28 @@ def rsi(df, symbol, period=14):
def macd(df, symbol):
macd = df[symbol].ewm(span=12).mean() - df[symbol].ewm(span=26).mean()
k1 = f"macd"
k2 = k1 + "-signal"
k1 = "macd"
k2 = "macd_signal"
k3 = "macd_diff"
df[k1] = macd
df[k2] = macd.rolling(9).mean()
return df[[k1, k2]]
df[k3] = df[k1] - df[k2]
return df[[k1, k2, k3]]
def price_delta(df, symbol, period=1):
"""Calculate delta between previous day and today."""
df[f"{symbol}-diff({period})"] = df[symbol].diff(periods=period)
k = f"diff_{period}"
df[k] = df[symbol].diff(periods=period)
return df[k]
def price_delta(df, symbol, period=1):
"""Calculate percentage change for period."""
k = f"pct_{period}"
df[k] = df[symbol].pct_change(periods=period)
df[k] = df[k].shift(-period)
return df[k]
def test_indicators():
@ -135,4 +145,3 @@ def test_indicators():
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')