Show both MACD and indicator strat on figure

Prepare for strategy learner.
This commit is contained in:
2020-11-04 09:23:42 -05:00
parent 0519ae9336
commit c40ffcf84b
4 changed files with 61 additions and 28 deletions

View File

@@ -36,18 +36,21 @@ class ManualStrategy:
print(volume) print(volume)
def macd_strat(self, macd, orders): def macd_strat(self, macd, orders):
"""Strategy based on MACD cross."""
def strat(ser): def strat(ser):
m = macd.loc[ser.index] m = macd.loc[ser.index]
prev_macd, prev_signal = m.iloc[0] prev_macd, prev_signal, _ = m.iloc[0]
cur_macd, cur_signal = m.iloc[1] cur_macd, cur_signal, _ = m.iloc[1]
shares = 0 shares = 0
if cur_macd < -1 and prev_macd < prev_signal and cur_macd > cur_signal: if cur_macd < -1 and prev_macd < prev_signal \
and cur_macd > cur_signal:
if self.holding == 0: if self.holding == 0:
shares = 1000 shares = 1000
elif self.holding == -1000: elif self.holding == -1000:
shares = 2000 shares = 2000
elif cur_macd > 1 and prev_macd > prev_signal and cur_macd < cur_signal: elif cur_macd > 1 and prev_macd > prev_signal \
and cur_macd < cur_signal:
if self.holding == 0: if self.holding == 0:
shares = -1000 shares = -1000
elif self.holding == 1000: elif self.holding == 1000:
@@ -58,6 +61,8 @@ class ManualStrategy:
orders['Shares'] = orders['Shares'].rolling(2).apply(strat) orders['Shares'] = orders['Shares'].rolling(2).apply(strat)
def three_indicator_strat(self, macd, rsi, price_sma, orders): def three_indicator_strat(self, macd, rsi, price_sma, orders):
"""Strategy based on three indicators. Thresholds selected based on
scatter plots."""
def strat(row): def strat(row):
shares = 0 shares = 0
_, _, macd_diff = macd.loc[row.name] _, _, macd_diff = macd.loc[row.name]
@@ -87,7 +92,7 @@ class ManualStrategy:
def testPolicy(self, symbol="IBM", def testPolicy(self, symbol="IBM",
sd=dt.datetime(2009, 1, 1), sd=dt.datetime(2009, 1, 1),
ed=dt.datetime(2010, 1, 1), ed=dt.datetime(2010, 1, 1),
sv=10000): sv=10000, macd_strat=False):
self.holding = 0 self.holding = 0
df = util.get_data([symbol], pd.date_range(sd, ed)) df = util.get_data([symbol], pd.date_range(sd, ed))
@@ -102,7 +107,8 @@ class ManualStrategy:
rsi = indicators.rsi(df, symbol) rsi = indicators.rsi(df, symbol)
price_sma = indicators.price_sma(df, symbol, [8]) price_sma = indicators.price_sma(df, symbol, [8])
# self.macd_strat(macd, orders) if macd_strat:
self.macd_strat(macd, orders)
else:
self.three_indicator_strat(macd, rsi, price_sma, orders) self.three_indicator_strat(macd, rsi, price_sma, orders)
return orders return orders

View File

@@ -9,6 +9,7 @@ import matplotlib.pyplot as plt
from matplotlib.widgets import MultiCursor from matplotlib.widgets import MultiCursor
from BenchmarkStrategy import BenchmarkStrategy from BenchmarkStrategy import BenchmarkStrategy
from ManualStrategy import ManualStrategy from ManualStrategy import ManualStrategy
from StrategyLearner import StrategyLearner
def plot_indicators(symbol, df): def plot_indicators(symbol, df):
@@ -16,7 +17,6 @@ def plot_indicators(symbol, df):
price_sma = indicators.price_sma(df, symbol, [8]) price_sma = indicators.price_sma(df, symbol, [8])
bb = indicators.bollinger_band(df, symbol) bb = indicators.bollinger_band(df, symbol)
sma = indicators.sma(df, symbol, [8])
rsi = indicators.rsi(df, symbol) rsi = indicators.rsi(df, symbol)
macd = indicators.macd(df, symbol).copy() macd = indicators.macd(df, symbol).copy()
@@ -57,6 +57,40 @@ def visualize_correlations(symbol, df):
sys.exit(0) sys.exit(0)
def compare_manual_strategies(symbol, sv, sd, ed):
df = util.get_data([symbol], pd.date_range(sd, ed))
df.drop(columns=["SPY"], inplace=True)
bs = BenchmarkStrategy()
orders = bs.testPolicy(symbol, sd, ed, sv)
df["Benchmark"] = marketsim.compute_portvals(orders, sv)
df["Orders Benchmark"] = orders["Shares"]
ms = ManualStrategy()
orders = ms.testPolicy(symbol, sd, ed, sv, macd_strat=True)
df["MACD Strat"] = marketsim.compute_portvals(orders, sv)
df["Orders MACD"] = orders["Shares"]
# df["Holding Manual"] = orders["Shares"].cumsum()
orders = ms.testPolicy(symbol, sd, ed, sv)
df["Three Strat"] = marketsim.compute_portvals(orders, sv)
df["Orders Three"] = orders["Shares"]
fig, ax = plt.subplots(3, sharex=True)
df[[symbol]].plot(ax=ax[0])
df[["Benchmark", "MACD Strat", "Three Strat"]].plot(ax=ax[1])
df[["Orders Benchmark", "Orders MACD", "Orders Three"]].plot(ax=ax[2])
for a in ax:
a.grid()
MultiCursor(fig.canvas, ax, color='r', lw=0.5)
# plt.show()
fig.set_size_inches(10, 8, forward=True)
plt.savefig('figure_1.png', dpi=fig.dpi)
def experiment1(): def experiment1():
symbol = "JPM" symbol = "JPM"
start_value = 10000 start_value = 10000
@@ -65,33 +99,33 @@ def experiment1():
# sd = dt.datetime(2010, 1, 1) # out-sample # sd = dt.datetime(2010, 1, 1) # out-sample
# ed = dt.datetime(2011, 12, 31) # 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) # visualize_correlations(symbol, df)
# plot_indicators(symbol, df) # plot_indicators(symbol, df)
# compare_manual_strategies(symbol, start_value, sd, ed)
df = util.get_data([symbol], pd.date_range(sd, ed))
df.drop(columns=["SPY"], inplace=True)
bs = BenchmarkStrategy() bs = BenchmarkStrategy()
orders = bs.testPolicy(symbol, sd, ed, start_value) orders = bs.testPolicy(symbol, sd, ed, start_value)
df["Benchmark"] = marketsim.compute_portvals(orders, start_value) df["Benchmark"] = marketsim.compute_portvals(orders, start_value)
df["Orders Benchmark"] = orders["Shares"] df["Orders Benchmark"] = orders["Shares"]
ms = ManualStrategy() sl = StrategyLearner()
orders = ms.testPolicy(symbol, sd, ed, start_value) orders = ms.testPolicy(symbol, sd, ed, start_value)
df["Manual"] = marketsim.compute_portvals(orders, start_value) df["SL"] = marketsim.compute_portvals(orders, start_value)
df["Orders Manual"] = orders["Shares"] df["Orders SL"] = orders["Shares"]
df["Holding Manual"] = orders["Shares"].cumsum() # df["Holding Manual"] = orders["Shares"].cumsum()
fig, ax = plt.subplots(3, sharex=True) fig, ax = plt.subplots(3, sharex=True)
df[[symbol]].plot(ax=ax[0]) df[[symbol]].plot(ax=ax[0])
df[["Benchmark", "Manual"]].plot(ax=ax[1]) df[["Benchmark", "SL"]].plot(ax=ax[1])
df[["Orders Benchmark", "Orders Manual"]].plot(ax=ax[2]) df[["Orders Benchmark", "Orders SL"]].plot(ax=ax[2])
for a in ax: for a in ax:
a.grid() a.grid()
multi = MultiCursor(fig.canvas, ax, color='r', lw=0.5) MultiCursor(fig.canvas, ax, color='r', lw=0.5)
plt.show() plt.show()
# plt.savefig('figure_1.png')
if __name__ == "__main__": if __name__ == "__main__":

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 112 KiB

View File

@@ -73,7 +73,7 @@ def rsi(df, symbol, period=14):
(avg_loss / period)))) (avg_loss / period))))
return rsi return rsi
key = f"rsi" key = "rsi"
# Add one to get 'period' price changes (first change is nan). # Add one to get 'period' price changes (first change is nan).
period += 1 period += 1
df[key] = df[symbol].rolling(period).apply(rsi) df[key] = df[symbol].rolling(period).apply(rsi)
@@ -91,13 +91,6 @@ def macd(df, symbol):
return df[[k1, k2, k3]] return df[[k1, k2, k3]]
def price_delta(df, symbol, period=1):
"""Calculate delta between previous day and today."""
k = f"diff_{period}"
df[k] = df[symbol].diff(periods=period)
return df[k]
def price_delta(df, symbol, period=1): def price_delta(df, symbol, period=1):
"""Calculate percentage change for period.""" """Calculate percentage change for period."""
k = f"pct_{period}" k = f"pct_{period}"