nice table over years

master
Dmitry Maylarov 4 years ago
parent 9efa0aee58
commit fb7fda1e27

@ -6,27 +6,11 @@ import matplotlib.pyplot as plt
from pandas_datareader import data as pdr from pandas_datareader import data as pdr
import backtrader as bt import backtrader as bt
stockList = ["VOO"] stockList = ["SWPPX"]
total_days_in_market = 365 * 10
month_sum = 500 # usd month_sum = 500 # usd
reserve = 5 # usd for comms etc reserve = 5 # usd for comms etc
startDate = datetime.datetime.fromisoformat("2000-01-01") # startDate = datetime.datetime.fromisoformat("2000-01-01")
endDate = datetime.datetime.fromisoformat("2022-01-30") # endDate = datetime.datetime.fromisoformat("2022-01-01")
# import data
def get_data(stocks, start, end):
stockData = pdr.get_data_yahoo(stocks, start, end)
return stockData
# endDate = datetime.datetime.now()
# startDate = endDate - datetime.timedelta(days=total_days_in_market)
stockData = get_data(stockList[0], startDate, endDate)
actualStart: datetime.datetime = stockData.index[0]
data = bt.feeds.PandasData(dataname=stockData)
class LSI(bt.Strategy): class LSI(bt.Strategy):
@ -53,12 +37,15 @@ class LSI(bt.Strategy):
class PercentageCommisionScheme(bt.CommInfoBase): class PercentageCommisionScheme(bt.CommInfoBase):
paras = ( params = (
("commission", 0.004), ("commission", 0.004),
("stocklike", True), ("stocklike", True),
("commtype", bt.CommInfoBase.COMM_PERC), ("commtype", bt.CommInfoBase.COMM_PERC),
) )
def _getcommission(self, size, price, pseudoexec):
return size * price * self.p.commission + 4 # 290rub/month
class FormulaInvesting(bt.Strategy): class FormulaInvesting(bt.Strategy):
def __init__(self): def __init__(self):
@ -71,10 +58,10 @@ class FormulaInvesting(bt.Strategy):
def log(self, txt, dt=None): def log(self, txt, dt=None):
dt = dt or self.datas[0].datetime.date(0) dt = dt or self.datas[0].datetime.date(0)
print("%s, %s" % (dt.isoformat(), txt)) # print("%s, %s" % (dt.isoformat(), txt))
def start(self): 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.cash_start = self.broker.get_cash()
self.val_start = 100.0 self.val_start = 100.0
@ -93,32 +80,23 @@ class FormulaInvesting(bt.Strategy):
if order.status in [order.Completed]: if order.status in [order.Completed]:
if order.isbuy(): if order.isbuy():
self.log(
"BUY EXECUTED, Price %.2f, Cost %.2f, Comm %.2f, Size %.0f"
% (
order.executed.price,
order.executed.value,
order.executed.comm,
order.executed.size,
)
)
self.units += order.executed.size self.units += order.executed.size
self.cost += order.executed.value self.cost += order.executed.value
self.comms += order.executed.comm
elif order.issell(): elif order.issell():
self.log(
"SELL EXECUTED, Price %.2f, Cost %.2f, Comm %.2f, Size %.0f"
% (
order.executed.price,
order.executed.value,
order.executed.comm,
order.executed.size,
)
)
self.units -= order.executed.size self.units -= order.executed.size
self.log(
"%s Price %.2f, Units %.0f, Value %.2f, Comm %.2f, "
% (
"BUY" if order.isbuy else "SELL",
order.executed.price,
order.executed.size,
order.executed.value,
order.executed.comm,
)
)
self.comms += order.executed.comm self.comms += order.executed.comm
self.times += 1 self.times += 1
@ -128,19 +106,15 @@ class FormulaInvesting(bt.Strategy):
self.order = None self.order = None
def stop(self):
self.calc_params()
def calc_params(self): def calc_params(self):
# calculate actual returns # calculate actual returns
self.froi = self.broker.get_fundvalue() - self.val_start self.froi = self.broker.get_fundvalue() - self.val_start
value = self.datas[0].close * self.units + self.broker.get_cash()
return ( return (
# Annual # Annual
100 * ((1 + self.froi / 100) ** (365 / (endDate - actualStart).days) - 1), 100 * ((1 + self.froi / 100) ** (365 / (endDate - actualStart).days) - 1),
self.froi, self.froi,
self.cost, self.cost,
value, self.broker.get_value() + self.broker.get_cash(),
self.times, self.times,
self.units, self.units,
self.comms, self.comms,
@ -179,6 +153,7 @@ class QDCA(DCA):
def run(strategy, data, fund_mode=False): def run(strategy, data, fund_mode=False):
if fund_mode: if fund_mode:
cerebro = bt.Cerebro() cerebro = bt.Cerebro()
cerebro.addobserver(bt.observers.FundShares)
else: else:
cerebro = bt.Cerebro(stdstats=False) cerebro = bt.Cerebro(stdstats=False)
cerebro.addobserver(bt.observers.Broker) cerebro.addobserver(bt.observers.Broker)
@ -186,8 +161,6 @@ def run(strategy, data, fund_mode=False):
cerebro.adddata(data) cerebro.adddata(data)
cerebro.addstrategy(strategy) cerebro.addstrategy(strategy)
print("-" * 50)
print(strategy.__name__)
# Broker Information # Broker Information
broker_args = dict(coc=True) broker_args = dict(coc=True)
@ -206,7 +179,7 @@ def run(strategy, data, fund_mode=False):
) )
thestrats = cerebro.run() thestrats = cerebro.run()
thestrat = thestrats[0] thestrat = thestrats[0]
cerebro.plot(iplot=False, style="candlestick") # cerebro.plot(iplot=False, style="candlestick")
return thestrat return thestrat
@ -226,19 +199,32 @@ if __name__ == "__main__":
"twr", "twr",
] ]
) )
for i, strategy in enumerate((DCA, QDCA, VA, QVA)): # import data
therun = run(strategy, data) def get_data(stocks, start, end):
dd = therun.analyzers.drawdown stockData = pdr.get_data_yahoo(stocks, start, end)
ret = therun.analyzers.returns return stockData
# tr = thestrat.analyzers.tr
# print(next(reversed(tr.get_analysis()))) for period_years in (1, 2, 5, 10, 15, 20, 25):
# print(tr.get_analysis()) endDate = datetime.datetime.now()
df.loc[strategy.__name__] = therun.calc_params() + ( startDate = endDate - datetime.timedelta(days=period_years * 365)
dd.get_analysis().max.len, stockData = get_data(stockList[0], startDate, endDate)
dd.get_analysis().max.drawdown, actualStart: datetime.datetime = stockData.index[0]
dd.get_analysis().max.moneydown, data = bt.feeds.PandasData(dataname=stockData)
ret.get_analysis()["vwr"],
) for i, strategy in enumerate((DCA, QDCA)): # , VA, QVA)):
print("Starting from:", actualStart) therun = run(strategy, data)
print("Time in Market: {:.1f} years".format((endDate - actualStart).days / 365)) dd = therun.analyzers.drawdown
print(df) ret = therun.analyzers.returns
# tr = thestrat.analyzers.tr
# print(next(reversed(tr.get_analysis())))
# print(tr.get_analysis())
df.loc[strategy.__name__] = therun.calc_params() + (
dd.get_analysis().max.len,
dd.get_analysis().max.drawdown,
dd.get_analysis().max.moneydown,
ret.get_analysis()["vwr"],
)
print("Starting from:", actualStart)
print("Time in Market: {:.1f} years".format((endDate - actualStart).days / 365))
print(df[["annual%", "froi", "cost", "total_value"]])
# print(df)

Loading…
Cancel
Save