Easy Backtest using Backtrader: Rebalance Edition

1 min read
Modified

Backtrader is powerful library facilitating backtest in Python. In this article, I explain method to implement Rebalance and perform backtest using data of past 10 years simply.

1. Preparation of Environment

Installation of library

Terminal window
# install requirement
%pip install backtrader yfinance matplotlib

2. Import of Library

Import necessary libraries

Terminal window
# import libs
import datetime
import backtrader as bt
import yfinance as yf
import matplotlib.pyplot as plt

3. Parameter Setting

Set necessary parameters.

Terminal window
## ticker and ratio
TICKERS = {"VTI": 0.4, "BND": 0.4, "GLD": 0.2}
## start date and end date
FROMDATE = datetime.datetime(2014, 7, 1)
TODATE = datetime.datetime(2024, 7, 1)

4. Implement Strategy

Strategy - Backtrader

python backtesting trading algotrading algorithmic quant quantitative analysis

www.backtrader.com
Terminal window
# Implement strategy of rebalance
class RebalanceOncePerMonth(bt.Strategy):
def __init__(self):
self.last_rebalance = None # Date last rebalanced
def next(self):
dt = self.datetime.date()
if self.last_rebalance is None or (dt - self.last_rebalance).days >= 30: # If 30 days or more passed
# self.broker.add_cash(1000) # In case of accumulation, do add_cash every certain period
self.rebalance_portfolio()
self.last_rebalance = dt
def rebalance_portfolio(self):
total_value = self.broker.getvalue()
for data in self.datas:
ticker = data._name
allocation = data.target
target_value = total_value * allocation
current_value = self.getposition(data).size * data.close[0]
difference = target_value - current_value
if difference > 0:
# Buy
size = difference // data.close[0]
self.buy(data=data, size=size)
elif difference < 0:
# Sell
size = -difference // data.close[0]
self.sell(data=data, size=size)

5. Execute Backtest

Perform data reading, and execute backtest.

Terminal window
# Initialization of backtrader
cerebro = bt.Cerebro()
cerebro.broker.set_cash(10000)
cerebro.addstrategy(RebalanceOncePerMonth)
# Read data from yahoofinance
for ticker, target in TICKERS.items():
data = bt.feeds.PandasData(
dataname=yf.download(ticker, start=FROMDATE, end=TODATE)
)
data.target = target
cerebro.adddata(data, name=ticker)
# Execution of backtest
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
Starting Portfolio Value: 10000.00
Final Portfolio Value: 13314.38

6. Visualize result of backtest

It can be seen that Buy and Sell are performed appropriately.

Terminal window
plt.rcParams['figure.figsize'] = [12, 10]
cerebro.plot(iplot=False)
Backtest Result of Rebalance
Backtest Result of Rebalance