import datetime import math import numpy as np import pandas as pd import matplotlib.pyplot as plt from pandas_datareader import data as pdr import backtrader as bt 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: cerebro = bt.Cerebro() cerebro.addobserver(bt.observers.FundShares) else: cerebro = bt.Cerebro(stdstats=False) cerebro.addobserver(bt.observers.Broker) cerebro.addobserver(bt.observers.BuySell) cerebro.adddata(data) cerebro.addstrategy(strategy) # Broker Information broker_args = dict(coc=True) cerebro.broker = bt.brokers.BackBroker(**broker_args) comminfo = st.PercentageCommisionScheme() cerebro.broker.addcommissioninfo(comminfo) if fund_mode: cerebro.broker.set_fundmode(True) cerebro.broker.set_cash(st.month_sum) cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown") cerebro.addanalyzer(bt.analyzers.VWR, _name="returns") cerebro.addanalyzer( bt.analyzers.TimeReturn, timeframe=bt.TimeFrame.NoTimeFrame, _name="tr" ) thestrats = cerebro.run() thestrat = thestrats[0] # cerebro.plot(iplot=False, style="candlestick") return thestrat if __name__ == "__main__": df = pd.DataFrame( columns=[ "froi", "cost", "total_value", "times", "units", "comms", "annual%", "max_dd_len", "max_dd", "max_md", "twr", "tr", ] ) stockList = ["^GSPC"] # startDate = datetime.datetime.fromisoformat("2000-01-01") # endDate = datetime.datetime.fromisoformat("2022-01-01") print(stockList[0]) for period_years in (1, 2, 5): endDate = datetime.datetime.now() startDate = endDate - datetime.timedelta(days=period_years * 365) stockData = get_data(stockList[0], startDate, endDate) actualStart: datetime.datetime = stockData.index[0] data = bt.feeds.PandasData(dataname=stockData) for i, strategy in enumerate( (st.SmaCross, st.DCA, st.QDCA, st.VA, st.QVA, st.SmaVA) ): therun = run(strategy, data) dd = therun.analyzers.drawdown ret = therun.analyzers.returns tr = therun.analyzers.tr # print(next(reversed(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, ret.get_analysis()["vwr"], list(tr.get_analysis().items())[0][1], ) print("Starting from:", actualStart) print("Time in Market: {:.1f} years".format((endDate - actualStart).days / 365)) # print(df[["annual%", "froi", "cost", "total_value", "max_dd", "max_md"]]) print(df)