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 :-)
-
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 setplot=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 -
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)
-
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)
Please advise how I can fix this code?
Thank you! -
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 dodata.plotinfo.plot=False
(y)