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.
This commit is contained in:
parent
43e297c075
commit
0519ae9336
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user