From e7e58a60d2d899088a75a5852ef7b03466514d45 Mon Sep 17 00:00:00 2001 From: Dmitry Maylarov Date: Mon, 7 Feb 2022 22:54:41 +0300 Subject: [PATCH] 8,17 and plots --- strategies.py | 16 +++++++--------- year_intervals.py | 37 +++++++++++++++++++++++++++---------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/strategies.py b/strategies.py index a376079..eb6629f 100644 --- a/strategies.py +++ b/strategies.py @@ -111,7 +111,7 @@ class Investing(bt.Strategy): elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log("Order Canceled/Margin/Rejected") - print(order.status, [order.Canceled, order.Margin, order.Rejected]) + print(order, order.status, [order.Canceled, order.Margin, order.Rejected]) self.order = None @@ -176,8 +176,8 @@ class QDCA(DCA): class SmaCross(Investing): params = dict( - pfast=50, # period for the fast moving average - pslow=200, # period for the slow moving average + pfast=8, # period for the fast moving average + pslow=17, # period for the slow moving average ) # list of parameters which are configurable for the strategy def __init__(self, *args, **kwargs): @@ -187,12 +187,10 @@ class SmaCross(Investing): self.crossover = bt.ind.CrossOver(sma1, sma2) # crossover signal def next(self): - if not self.position: # not in the market - if self.crossover > 0: # if fast crosses slow to the upside - self.order_target_value(target=self.broker.get_cash()) # enter long - - elif self.crossover < 0: # in the market & cross to the downside - self.close() # close long position + if self.crossover > 0: # if fast crosses slow to the upside + self.order_target_value( + target=self.broker.get_value() - reserve + ) # enter long class SmaVA(SmaCross): diff --git a/year_intervals.py b/year_intervals.py index 44da8b4..c646ab8 100644 --- a/year_intervals.py +++ b/year_intervals.py @@ -6,21 +6,29 @@ import pandas as pd if __name__ == "__main__": stockList = ["^GSPC"] - monthly_params = dict(sum=100000, coef=1.005, t_rate=1 + 0.02 / 12) + monthly_params = dict(sum=1000, coef=1, t_rate=1 + 0.02 / 12) # startDate = datetime.datetime.fromisoformat("2000-01-01") # endDate = datetime.datetime.fromisoformat("2022-01-01") print(stockList[0]) - stockData = lib.get_data( - stockList[0], - ) + stockData = lib.get_data(stockList[0]) start_date = stockData.index[0] year_step = 5 - print( - "Investing monthly, increasing {:.2f}%, starting from ${}".format( - (monthly_params["coef"] * 100) - 100, - monthly_params["sum"], - ) + label_string = "Investing to {} monthly over {} years, increasing {:.2f}%, starting from ${}".format( + stockList[0], + year_step, + (monthly_params["coef"] * 100) - 100, + monthly_params["sum"], ) + print(label_string) + plot_param = "annual%" + strategies = ( + st.DCA, + st.QDCA, + st.SmaCross, + ) + + df_comp = pd.DataFrame(index=list(st.__name__ for st in strategies)) + df_vwr = pd.DataFrame(index=list(st.__name__ for st in strategies)) for start_year in range(start_date.year, datetime.datetime.today().year, year_step): start_date = datetime.date(start_year, 1, 1) end_date = datetime.date(start_year + year_step - 1, 12, 31) @@ -38,9 +46,18 @@ if __name__ == "__main__": newdf = pd.concat( [ lib.test_strategy(stockData, strategy, monthly_params) - for strategy in (st.DCA, st.QDCA) + for strategy in strategies ] ) print(newdf.to_string()) + df_comp[start_year] = newdf[plot_param].values # print(df[["annual%", "froi%", "cost", "total_value", "max_dd%", "max_md"]]) # print(newdf["annual%"]) + + print(df_comp.to_string()) + df_comp.T.plot() + plt.grid() + plt.title(label_string) + plt.ylabel(plot_param) + plt.xlabel("year") + plt.show()