Multi-Stock Wealth Tracker & Plotter



  • Hi,

    I have a strategy with multiple stocks which I want to track the total portfolio value and cash over time.

    I have created the following analyzer.

    class WealthTracker(bt.Analyzer):
        args = parse_args()
        def start(self):
            self.PortfolioValue = pd.DataFrame(columns=('Date', 'TotalWealth','Invested','Cash'))
            self.i = 0
        def prenext(self):
            self.next()
        def next(self): 
            cash = self.strategy.broker.getcash()
            totalwealth = self.strategy.broker.get_value()
            invested = totalwealth - cash
            date = self.strategy.getdatabyname(args.marketindex).datetime.date(0)
            self.PortfolioValue.loc[self.i] = [date,totalwealth,invested,cash]
            self.i+=1
    
            entries = []
            self.rets[date] = entries.append([totalwealth,invested,cash])
    
        def stop(self):
            print(self.PortfolioValue)
    

    Because I have many stocks, I cant use the standard cerebro.plot(numfigs=args.numfigs, volume=False, zdown=False) because its a rainbow mess of colours :-D ... how can I utilise my analyzer, or a version of it, to get the standard backtrader plot and plot information??

    If that isn't possible, how can I best plot my portoflio / analyser?

    Thank you :-)


  • administrators

    Analyzers are not lines objects and not meant for plotting. The usual pattern to plot the values generated by an Analyzer is to have an associated Observer.

    The DrawDown observer is implemented following this pattern.

    class DrawDown(Observer):
        '''This observer keeps track of the current drawdown level (plotted) and
        the maxdrawdown (not plotted) levels
    
        Params: None
        '''
        _stclock = True
    
        lines = ('drawdown', 'maxdrawdown',)
    
        plotinfo = dict(plot=True, subplot=True)
    
        plotlines = dict(maxdrawdown=dict(_plotskip=True,))
    
        def __init__(self):
            self._dd = self._owner._addanalyzer_slave(bt.analyzers.DrawDown)
    
        def next(self):
            self.lines.drawdown[0] = self._dd.rets.drawdown  # update drawdown
            self.lines.maxdrawdown[0] = self._dd.rets.max.drawdown  # update max
    


  • Portfolio and cash diagram is in the standard bt plot. If you need to remove indicators and prices, then just set plot=False as a parameter for each of them.



  • Thanks @backtrader and @ab_trader.

    @ab_trader, do you have a code snippet to only plot the portfolio and cash values?? I tried searching for examples of what you recommend but cant find any - though it sounds like a good option.

    I assume its something along the lines of: cerebro.plot(numfigs=args.numfigs, volume=False, zdown=False, close.plot=False) ??

    Thank you,
    CWE


  • administrators

    You can disable the standard plotted observers with stdstats=False.

    And add the bt.observers.Broker. This is done for example here: Blog - Futures and Spot Compensation



  • plot=False need to be passed to indicator and data feed.

    To hide data plot:
    data = bt.feeds.YahooFinanceCSVData(other parameters , plot=False)

    To hide indicator:
    self.ema = bt.indicators.ExponentialMovingAverage(period=N, plot=False)


  • administrators

    This is all described in Docs - Plotting in the section Plotting Options which also describes the obj.plotinfo.plot = False usage pattern



  • Thanks @backtrader,
    Getting closer, but I tried the following and my plot is still not working (see plot image below):

    cerebro.addobserver(bt.obs.Broker)  # removed below with stdstats=False
    cerebro.addobserver(bt.obs.Trades)  # removed below with stdstats=False
    
    cerebro.run(runonce=False, stdstats=False, writer=True)
    cerebro.plot(volume=False, stdstats=False)
    

    0_1490935625599_ploterror.JPG

    Please advise how I can fix this code?
    Thank you!


  • administrators

    By seeing the red and green spots in the background there seems to be many many things. But "fixing" a non-posted code will be difficult for anyone.



  • @cwse can you limit list of your tickers by 3-4 tickers for test purposes and re-run the code? it will probably be less diagrams and more clear picture.



  • Hi guys (@backtrader @ab_trader),

    I guess there are many lines because I am working with over 200 stocks.. all I want is a way to disable all lines, and just show the CASH and PORTFOLIO lines (that should be just 2??). Is there an easy way to disable all others?

    Thanks,
    CWE



  • @cwse if you passed plot=False to data and indicators, it should be only broker value, cash and trades shown (if no other observers were added). I've showed above how to turn off data and indicators:

    To hide data plot:

    data = bt.feeds.YahooFinanceCSVData(data parameters , plot=False)

    To hide indicator:

    self.ema = bt.indicators.ExponentialMovingAverage(period=N, plot=False)



  • Worked it out guys!

    Just before you adddata to cerebro, you do data.plotinfo.plot=False (y)


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.