From e4701b3d45124bcdaaaac6a79e44d2154265eae1 Mon Sep 17 00:00:00 2001 From: Dmitry Maylarov Date: Sun, 30 Jan 2022 23:36:46 +0300 Subject: [PATCH] test --- compare.py | 32 ++++++++++++++++++-------------- strategies.py | 39 ++++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/compare.py b/compare.py index 534a49e..bf26b3d 100644 --- a/compare.py +++ b/compare.py @@ -6,14 +6,13 @@ import matplotlib.pyplot as plt from pandas_datareader import data as pdr import backtrader as bt -stockList = ["SWPPX"] -month_sum = 500 # usd -reserve = 5 # usd for comms etc -# startDate = datetime.datetime.fromisoformat("2000-01-01") -# endDate = datetime.datetime.fromisoformat("2022-01-01") - import strategies as st +# import data +def get_data(stocks, start, end): + stockData = pdr.get_data_yahoo(stocks, start, end) + return stockData + def run(strategy, data, fund_mode=False): if fund_mode: @@ -36,7 +35,7 @@ def run(strategy, data, fund_mode=False): if fund_mode: cerebro.broker.set_fundmode(True) - cerebro.broker.set_cash(month_sum) + cerebro.broker.set_cash(st.month_sum) cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown") cerebro.addanalyzer(bt.analyzers.VWR, _name="returns") cerebro.addanalyzer( @@ -44,31 +43,31 @@ def run(strategy, data, fund_mode=False): ) thestrats = cerebro.run() thestrat = thestrats[0] - # cerebro.plot(iplot=False, style="candlestick") + cerebro.plot(iplot=False, style="candlestick") return thestrat if __name__ == "__main__": df = pd.DataFrame( columns=[ - "annual%", "froi", "cost", "total_value", "times", "units", "comms", + "annual%", "max_dd_len", "max_dd", "max_md", "twr", ] ) - # import data - def get_data(stocks, start, end): - stockData = pdr.get_data_yahoo(stocks, start, end) - return stockData + stockList = ["SWPPX"] + # startDate = datetime.datetime.fromisoformat("2000-01-01") + # endDate = datetime.datetime.fromisoformat("2022-01-01") + print(stockList[0]) for period_years in (1, 2, 5, 10, 15, 20, 25): endDate = datetime.datetime.now() startDate = endDate - datetime.timedelta(days=period_years * 365) @@ -83,7 +82,12 @@ if __name__ == "__main__": # tr = thestrat.analyzers.tr # print(next(reversed(tr.get_analysis()))) # print(tr.get_analysis()) + params = therun.calc_params() + annual = 100 * ( + (1 + params[0] / 100) ** (365 / (endDate - actualStart).days) - 1 + ) df.loc[strategy.__name__] = therun.calc_params() + ( + annual, dd.get_analysis().max.len, dd.get_analysis().max.drawdown, dd.get_analysis().max.moneydown, @@ -91,5 +95,5 @@ if __name__ == "__main__": ) print("Starting from:", actualStart) print("Time in Market: {:.1f} years".format((endDate - actualStart).days / 365)) - # print(df[["annual%", "froi", "cost", "total_value"]]) + # print(df[["annual%", "froi", "cost", "total_value", "max_dd", "max_md"]]) print(df) diff --git a/strategies.py b/strategies.py index 70f1100..5eced69 100644 --- a/strategies.py +++ b/strategies.py @@ -6,6 +6,9 @@ import matplotlib.pyplot as plt from pandas_datareader import data as pdr import backtrader as bt +reserve = 5 # usd for comms etc cause I cant math +month_sum = 500 # usd + class LSI(bt.Strategy): def start(self): @@ -50,11 +53,11 @@ class FormulaInvesting(bt.Strategy): self.comms = 0 self.units = 0 self.times = 0 - self.periods = 0 + self.months = 0 def log(self, txt, dt=None): dt = dt or self.datas[0].datetime.date(0) - # print("%s, %s" % (dt.isoformat(), txt)) + # print( "%s, V:%.2f, C:%.2f, %s" % (dt.isoformat(), self.broker.get_value(), self.broker.get_cash(), txt)) def start(self): self.broker.set_fundmode(fundmode=True, fundstartval=100.0) @@ -73,19 +76,11 @@ class FormulaInvesting(bt.Strategy): def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return - - if order.status in [order.Completed]: - if order.isbuy(): - self.units += order.executed.size - self.cost += order.executed.value - - elif order.issell(): - self.units -= order.executed.size - + else: self.log( "%s Price %.2f, Units %.0f, Value %.2f, Comm %.2f, " % ( - "BUY" if order.isbuy else "SELL", + "BUY" if order.isbuy() else "SELL", order.executed.price, order.executed.size, order.executed.value, @@ -93,6 +88,14 @@ class FormulaInvesting(bt.Strategy): ) ) + if order.status in [order.Completed]: + if order.isbuy(): + self.units += order.executed.size + self.cost += order.executed.value + + elif order.issell(): + self.units -= order.executed.size + self.comms += order.executed.comm self.times += 1 @@ -106,8 +109,6 @@ class FormulaInvesting(bt.Strategy): # calculate actual returns self.froi = self.broker.get_fundvalue() - self.val_start return ( - # Annual - 100 * ((1 + self.froi / 100) ** (365 / (endDate - actualStart).days) - 1), self.froi, self.cost, self.broker.get_value() + self.broker.get_cash(), @@ -117,15 +118,15 @@ class FormulaInvesting(bt.Strategy): ) def notify_timer(self, timer, when, *args): - self.periods += 1 + self.months += 1 self.broker.add_cash(month_sum) self.formula() class VA(FormulaInvesting): def formula(self): - target_value = min(self.periods * month_sum - reserve, self.broker.get_value()) - self.order_target_value(target=target_value) + target_value = min(self.months * month_sum, self.broker.get_value()) - reserve + self.order_target_value(target=target_value), class DCA(FormulaInvesting): @@ -136,11 +137,11 @@ class DCA(FormulaInvesting): class QVA(VA): def formula(self): - if not self.periods % 3: + if not self.months % 3: super().formula() class QDCA(DCA): def formula(self): - if not self.periods % 3: + if not self.months % 3: super().formula()