More on multi-symbol portfolio tracking...
-
For those of us who have a habit of mixing trading with investing :), I thought that a portfolio tracking observer/plot might be of value. Sharing it to solicit feedback and further ideas. A (naive) portfolio below, rebalancing every month to have SPY, QQQ and AGG represent 33% each of the overall portfolio (actually 100% - 5% buffer then 1/3 of that each). The idea is to visualize a portion of each investment in the overall portfolio, so the $CASH line is cash, then SPY line is $CASH+SPY, then QQQ is $CASH+SPY+QQQ etc. It would look better with filled plots (since these are cumulative contributions of each investment to the overall portfolio value), but alas, no controls to fill the plot... Vertical ticks on the bottom represent rebalancing events (trades) --
Implementation --
class PortfolioObserver0(bt.observer.Observer): _stclock = True lines = () CASH_LINE = '$CASH' REBALANCE_LINE = '_REBALANCE' plotinfo = dict(plot=True, subplot=True, plotlinelabels=True, plotlinevalues=False) plotlines = dict(_REBALANCE=dict(marker='|', markersize=8.0, color='gray')) def next(self): # add cash cumsum = self._owner.broker.get_cash() self.set_line(self.CASH_LINE, 0, cumsum) # add symbol positions for data in self.datas: dname = data._name cumsum += self._owner.broker.get_value([data]) self.set_line(dname, 0, cumsum) # is this a rebalancing day? if self._owner._orderspending: self.set_line(self.REBALANCE_LINE, 0, 0) def set_line(self, dname, ind, value): """Set named line value at index""" getattr(self.lines, dname)[ind] = value
...then --
def make_portfolio_observer(symbols: tuple): """Make portfolio observer with customized list of symbols""" return type('PortfolioObserver', (PortfolioObserver0,), {'lines': (symbols + (PortfolioObserver0.CASH_LINE, PortfolioObserver0.REBALANCE_LINE))})
...then in __main__ --
symbols = ('SPY', 'QQQ', 'AGG',) cerebro.addobserver(make_portfolio_observer(symbols))
Thoughts? Reinventing the wheel here?
-
...and an alternative implementation showing % contribution of each asset to overall portfolio value --
class PortfolioObserverPercent0(bt.observer.Observer): _stclock = True lines = () CASH_LINE = '$CASH' REBALANCE_LINE = '_REBALANCE' plotinfo = dict(plot=True, subplot=True, plotlinelabels=True, plotlinevalues=False, plothlines=[100.0]) plotlines = dict(_REBALANCE=dict(marker='|', markersize=8.0, color='gray')) def next(self): # total portfolio value tot_value = self._owner.broker.get_value() # add cash cumsum = self._owner.broker.get_cash() self.set_line(self.CASH_LINE, 0, cumsum / tot_value * 100) # add symbol positions for data in self.datas: dname = data._name cumsum += self._owner.broker.get_value([data]) self.set_line(dname, 0, cumsum / tot_value * 100) # is this a rebalancing day? if self._owner._orderspending: self.set_line(self.REBALANCE_LINE, 0, 0) def set_line(self, dname, ind, value): """Set named line value at index""" getattr(self.lines, dname)[ind] = value def make_portfolio_observer_percent(symbols: tuple): """Make portfolio observer with customized list of symbols""" return type('PortfolioObserverPercent', (PortfolioObserverPercent0,), {'lines': (symbols + (PortfolioObserver0.CASH_LINE, PortfolioObserver0.REBALANCE_LINE))})
-
thx for sharing.
i have been thinking about tracking the performance of different strategies, maybe the observer can also help