Plotting Number of stocks held over time
cwse last edited by
I am hoping to plot the number of stocks held over time on my final output chart.
Are there any examples of this already?
I believe I should create an observer, but not sure the best (/easiest) way to do this.
I am currently logging how many stocks are held in each
next()statement under a variable "num_long" which I add 1 unit to whenever a stock iteration has
Any examples here would be much appreciated :)
ab_trader last edited by ab_trader
First I would set the counter in the strategy
__init__()as series object:
self.num_long = bt.LineNum(0)
then in the strategy
next()I would change value of
self.num_longbased on the counting rules. And then the following observer can be implemented:
class StockCounter(bt.Observer): lines = ('num_long',) plotinfo = dict(plot=True, subplot=True) def next(self): self.lines.num_long = self._owner.num_long
I think this should work.
That's a nice approach. A couple of variations on the topic
class MyStrategy(bt.Strategy): lines = ('numlong',) ...
which avoids using
LineNumby integrating the line definition in the definition of the strategy.
class StockCounter(bt.Observer): lines = ('num_long',) def __init__(self): self.lines.num_long = self._owner.lines.num_long
should also work by establishing a binding between the 2 lines.
The actual number of holding objects can be quickly calculated in the strategy with:
holding = len([1 for d, p in self.getpositions() if p.size])
With the latter also being possible as for example
holding = sum(bool(pos) for pos in self.getpositions().values())
# For 100% equivalence between Python2/3 from backtrader.utils.py3 import itervalues holding = sum(bool(pos) for pos in itervalues(self.getpositions()))
In practical terms it really shouldn't make a difference to use
.values()even if that generates a copy in Python2, because the number of items being held is not going to have needed magnitude to matter.
To change items to values
cwse last edited by
Awesome thank you guys!
@backtrader, when I use my old counting method it works perfectly, however when I use
holding = sum(bool(pos) for pos in self.getpositions().items())it always plots 200 as a flat line (i.e. it thinks I am holding every possible stock... so somehow this method is counting everything, not just those in market? Note: I am using Python 3.
itemsalways returns a tuple and that evaluates to
True. It should have said
values. The answer has been updated to avoid future miscopying.