From 4458e5386f1152f264e2ec3bd5784d9528c9ad07 Mon Sep 17 00:00:00 2001 From: Dmitry Maylarov Date: Sun, 30 Jan 2022 17:30:12 +0300 Subject: [PATCH] start_date, analyzers, monthly_sum, normal months --- dcavslsi.py | 50 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/dcavslsi.py b/dcavslsi.py index fbb2e00..a6a7d2a 100644 --- a/dcavslsi.py +++ b/dcavslsi.py @@ -9,9 +9,8 @@ import backtrader as bt stockList = ["VOO"] total_days_in_market = 365 * 10 month_sum = 500 # usd -period_months = 1 reserve = 5 # usd for comms etc -period_sum = month_sum * period_months +startDate = datetime.datetime.fromisoformat("2018-01-01") # import data @@ -21,7 +20,7 @@ def get_data(stocks, start, end): endDate = datetime.datetime.now() -startDate = endDate - datetime.timedelta(days=total_days_in_market) +# startDate = endDate - datetime.timedelta(days=total_days_in_market) stockData = get_data(stockList[0], startDate, endDate) actualStart: datetime.datetime = stockData.index[0] @@ -65,8 +64,6 @@ class PercentageCommisionScheme(bt.CommInfoBase): class FormulaInvesting(bt.Strategy): - params = dict(monthly_cash=month_sum, monthly_range=[5, 20]) - def __init__(self): self.order = None self.totalcost = 0 @@ -77,10 +74,10 @@ class FormulaInvesting(bt.Strategy): def log(self, txt, dt=None): dt = dt or self.datas[0].datetime.date(0) - # print("%s, %s" % (dt.isoformat(), txt)) + print("%s, %s" % (dt.isoformat(), txt)) def start(self): - self.broker.set_fundmode(fundmode=True, fundstartval=100.0) + # self.broker.set_fundmode(fundmode=True, fundstartval=100.0) self.cash_start = self.broker.get_cash() self.val_start = 100.0 @@ -88,7 +85,7 @@ class FormulaInvesting(bt.Strategy): # ADD A TIMER self.add_timer( when=bt.timer.SESSION_START, - monthdays=[i for i in self.p.monthly_range], + monthdays=[1], monthcarry=True # timername='buytimer', ) @@ -137,6 +134,9 @@ class FormulaInvesting(bt.Strategy): self.order = None def stop(self): + self.calc_params() + + def calc_params(self): # calculate actual returns self.roi = (self.broker.get_value() / self.cash_start) - 1 self.froi = self.broker.get_fundvalue() - self.val_start @@ -160,13 +160,13 @@ class FormulaInvesting(bt.Strategy): def notify_timer(self, timer, when, *args): self.periods += 1 - self.broker.add_cash(self.p.monthly_cash) + self.broker.add_cash(month_sum) self.formula() class VA(FormulaInvesting): def formula(self): - target_value = (self.periods) * self.p.monthly_cash - reserve + target_value = min(self.periods * month_sum - reserve, self.broker.get_value()) self.order_target_value(target=target_value) @@ -176,6 +176,18 @@ class DCA(FormulaInvesting): self.order_target_value(target=target_value) +class QVA(VA): + def formula(self): + if not self.periods % 3: + super().formula() + + +class QDCA(DCA): + def formula(self): + if not self.periods % 3: + super().formula() + + def run(strategy, data): cerebro = bt.Cerebro(stdstats=False) @@ -193,12 +205,20 @@ def run(strategy, data): comminfo = PercentageCommisionScheme() cerebro.broker.addcommissioninfo(comminfo) - cerebro.broker.set_cash(period_sum) - cerebro.run() + cerebro.broker.set_cash(month_sum) + # cerebro.addobserver(bt.observers.FundValue) + # cerebro.addobserver(bt.observers.FundShares) + cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown") + cerebro.addanalyzer(bt.analyzers.VWR, _name="returns") + thestrats = cerebro.run() + thestrat = thestrats[0] + dd = thestrat.analyzers.drawdown + print(dd.get_analysis().max) + ret = thestrat.analyzers.returns + print(ret.get_analysis()) cerebro.plot(iplot=False, style="candlestick") if __name__ == "__main__": - # run(LSI, 100000, data) - run(DCA, data) - run(VA, data) + for strategy in (DCA, QDCA, VA, QVA): + run(strategy, data)