diff --git a/strategy_evaluation/QLearner.py b/strategy_evaluation/QLearner.py new file mode 100644 index 0000000..eecc6ed --- /dev/null +++ b/strategy_evaluation/QLearner.py @@ -0,0 +1,84 @@ +import datetime as dt +import pandas as pd +import util +import indicators +from qlearning_robot.QLearner import QLearner as Learner + + +class QLearner(object): + + def __init__(self, verbose=False, impact=0.0, commission=0.0, testing=False): + self.verbose = verbose + self.impact = impact + self.commission = commission + self.testing = testing + + def _get_volume(self): + """For reference.""" + volume_all = ut.get_data(syms, dates, colname="Volume") + volume = volume_all[syms] # only portfolio symbols + # volume_SPY = volume_all['SPY'] # only SPY, for comparison later + if self.verbose: + print(volume) + + def _add_indicators(self, df, symbol): + """Add indicators for learning to DataFrame.""" + df.drop(columns=["SPY"], inplace=True) + indicators.macd(df, symbol) + indicators.rsi(df, symbol) + indicators.price_sma(df, symbol, [8]) + indicators.price_delta(df, symbol, 3) + df.dropna(inplace=True) + + def addEvidence(self, symbol="IBM", + sd=dt.datetime(2008, 1, 1), + ed=dt.datetime(2009, 1, 1), + sv=10000): + + self.indicators = ['macd_diff', 'rsi', 'price_sma_8'] + df = util.get_data([symbol], pd.date_range(sd, ed)) + self._add_indicators(df, symbol) + + self.learner = Learner() + # self.learner.query(data_x, y.to_numpy()) + # data_x = df[self.indicators].to_numpy() + + def strat(self, data_y, orders): + self.holding = 0 + + def strat(row): + y = int(data_y.loc[row.name][0]) + shares = 0 + if self.holding == 0 and y == 1: + shares = 1000 + elif self.holding == -1000 and y == 1: + shares = 2000 + elif self.holding == 0 and y == -1: + shares = -1000 + elif self.holding == 1000 and y == -1: + shares = -2000 + self.holding += shares + return shares + + orders["Shares"] = orders.apply(strat, axis=1) + + def testPolicy(self, symbol="IBM", + sd=dt.datetime(2009, 1, 1), + ed=dt.datetime(2010, 1, 1), + sv=10000): + df = util.get_data([symbol], pd.date_range(sd, ed)) + self._add_indicators(df, symbol) + # data_x = df[self.indicators].to_numpy() + # data_y = pd.DataFrame(index=df.index, data=self.learner.query(data_x)) + + orders = pd.DataFrame(index=df.index) + orders["Symbol"] = symbol + orders["Order"] = "" + orders["Shares"] = 0 + return orders + + if self.testing: + return orders + else: + return orders[["Shares"]] + diff --git a/strategy_evaluation/experiment1.py b/strategy_evaluation/experiment1.py index e4bf31f..53909d3 100644 --- a/strategy_evaluation/experiment1.py +++ b/strategy_evaluation/experiment1.py @@ -10,6 +10,7 @@ from matplotlib.widgets import MultiCursor from BenchmarkStrategy import BenchmarkStrategy from ManualStrategy import ManualStrategy from StrategyLearner import StrategyLearner +from QLearner import QLearner def plot_indicators(symbol, df): @@ -92,7 +93,42 @@ def compare_manual_strategies(symbol, sv, sd, ed): plt.savefig('figure_1.png', dpi=fig.dpi) -def experiment1(): +def compare_all_strategies(symbol, sv, sd, ed): + df = util.get_data([symbol], pd.date_range(sd, ed)) + df.drop(columns=["SPY"], inplace=True) + normalize = indicators.normalize + + bs = BenchmarkStrategy() + orders = bs.testPolicy(symbol, sd, ed, sv) + df["Benchmark"] = normalize(marketsim.compute_portvals(orders, sv)) + df["Orders Benchmark"] = orders["Shares"] + + ms = ManualStrategy() + orders = ms.testPolicy(symbol, sd, ed, sv) + df["Manual"] = normalize(marketsim.compute_portvals(orders, sv)) + df["Orders Manual"] = orders["Shares"] + + sl = StrategyLearner(testing=True) + sl.addEvidence(symbol, sd, ed, sv) + orders = sl.testPolicy(symbol, sd, ed, sv) + df["Strategy"] = normalize(marketsim.compute_portvals(orders, sv)) + df["Orders Strategy"] = orders["Shares"] + + fig, ax = plt.subplots(3, sharex=True) + df[[symbol]].plot(ax=ax[0]) + df[["Benchmark", "Manual", "Strategy"]].plot(ax=ax[1]) + df[["Orders Benchmark", "Orders Manual", "Orders Strategy"]].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_2.png', dpi=fig.dpi) + + +def experiment1(create_report=False): symbol = "JPM" sv = 10000 sd = dt.datetime(2008, 1, 1) # in-sample @@ -103,25 +139,29 @@ def experiment1(): df = util.get_data([symbol], pd.date_range(sd, ed_out)) df.drop(columns=["SPY"], inplace=True) + if create_report: + compare_manual_strategies(symbol, sv, sd, ed) + compare_all_strategies(symbol, sv, sd, ed) + return + # visualize_correlations(symbol, df) # plot_indicators(symbol, df) - # compare_manual_strategies(symbol, sv, sd, ed) bs = BenchmarkStrategy() orders = bs.testPolicy(symbol, sd_out, ed_out, sv) df["Benchmark"] = marketsim.compute_portvals(orders, sv) df["Orders Benchmark"] = orders["Shares"] - sl = StrategyLearner(testing=True) - sl.addEvidence(symbol, sd, ed, sv) - orders = sl.testPolicy(symbol, sd_out, ed_out, sv) - df["SL"] = marketsim.compute_portvals(orders, sv) - df["Orders SL"] = orders["Shares"] + ql = QLearner(testing=True) + ql.addEvidence(symbol, sd, ed, sv) + orders = ql.testPolicy(symbol, sd_out, ed_out, sv) + df["QL"] = marketsim.compute_portvals(orders, sv) + df["Orders QL"] = orders["Shares"] fig, ax = plt.subplots(3, sharex=True) df[[symbol]].plot(ax=ax[0]) - df[["Benchmark", "SL"]].plot(ax=ax[1]) - df[["Orders Benchmark", "Orders SL"]].plot(ax=ax[2]) + df[["Benchmark", "QL"]].plot(ax=ax[1]) + df[["Orders Benchmark", "Orders QL"]].plot(ax=ax[2]) for a in ax: a.grid() diff --git a/strategy_evaluation/figure_2.png b/strategy_evaluation/figure_2.png new file mode 100644 index 0000000..19b160e Binary files /dev/null and b/strategy_evaluation/figure_2.png differ diff --git a/strategy_evaluation/testproject.py b/strategy_evaluation/testproject.py index e69de29..866ad19 100644 --- a/strategy_evaluation/testproject.py +++ b/strategy_evaluation/testproject.py @@ -0,0 +1,6 @@ +from experiment1 import experiment1 + + +if __name__ == "__main__": + experiment1(create_report=True) +