Is it possible to get the realized PnL from Backtrader?
-
Hi,
I would like to ask, whether and how I could retrieve the realized Profit and Loss from Backtrader?
Thanks in advance!
-
You can use analyzers for this purpose.
TradeAnalyzer has extensive calculation on trades. When turned into a dataframe it looks like this:
total_total 10 total_open 1 total_closed 9 streak_won_current 0 streak_won_longest 3 streak_lost_current 1 streak_lost_longest 1 pnl_gross_total 23.16975 pnl_gross_average 2.574416667 pnl_net_total 23.16975 pnl_net_average 2.574416667 won_total 6 won_pnl_total 42.99625 won_pnl_average 7.166041667 won_pnl_max 16.645 lost_total 3 lost_pnl_total -19.8265 lost_pnl_average -6.608833333 lost_pnl_max -6.6445 long_total 6 long_pnl_total 19.77975 long_pnl_average 3.296625 long_pnl_won_total 26.35125 long_pnl_won_average 5.27025 long_pnl_won_max 16.35125 long_pnl_lost_total -6.5715 long_pnl_lost_average -6.5715 long_pnl_lost_max -6.5715 long_won 5 long_lost 1 short_total 3 short_pnl_total 3.39 short_pnl_average 1.13 short_pnl_won_total 16.645 short_pnl_won_average 16.645 short_pnl_won_max 16.645 short_pnl_lost_total -13.255 short_pnl_lost_average -6.6275 short_pnl_lost_max -6.6445 short_won 1 short_lost 2 len_total 2282 len_average 253.5555556 len_max 383 len_min 12 len_won_total 1508 len_won_average 251.3333333 len_won_max 383 len_won_min 12 len_lost_total 774 len_lost_average 258 len_lost_max 382 len_lost_min 29 len_long_total 1169 len_long_average 194.8333333 len_long_max 383 len_long_min 12 len_long_won_total 1140 len_long_won_average 228 len_long_won_max 383 len_long_won_min 12 len_long_lost_total 29 len_long_lost_average 29 len_long_lost_max 29 len_long_lost_min 29 len_short_total 1113 len_short_average 371 len_short_max 382 len_short_min 363 len_short_won_total 368 len_short_won_average 368 len_short_won_max 368 len_short_won_min 368 len_short_lost_total 745 len_short_lost_average 372.5 len_short_lost_max 382 len_short_lost_min 363
Trade_list is awesome... thank you @ab_trader
ref ticker dir datein pricein dateout priceout chng% pnl pnl% size value cumpnl nbars pnl/bar mfe% mae% win 1 ES short 2020-01-10 09:35:00 3,279 2020-01-10 15:43:00 3,263 -51% 17 17% -1 -3,279 17 368 0 56% -14% 1 2 ES long 2020-01-10 15:45:00 3,263 2020-01-10 15:57:00 3,266 10% 3 3% 1 3,263 20 12 0 14% -5% 1 3 ES long 2020-01-13 09:37:00 3,270 2020-01-13 15:54:00 3,287 50% 16 16% 1 3,270 36 377 0 51% -7% 1 4 ES long 2020-01-14 09:32:00 3,286 2020-01-14 10:01:00 3,279 -20% -7 -7% 1 3,286 30 29 0 2% -21% 0 5 ES long 2020-01-14 10:02:00 3,282 2020-01-14 15:57:00 3,283 2% 1 0% 1 3,282 30 355 0 40% -14% 1 6 ES long 2020-01-15 09:34:00 3,285 2020-01-15 15:57:00 3,289 12% 4 4% 1 3,285 34 383 0 43% -11% 1 7 ES short 2020-01-16 09:31:00 3,305 2020-01-16 15:34:00 3,312 20% -7 -7% -1 -3,305 28 363 0 8% -20% 0 8 ES long 2020-01-16 15:44:00 3,313 2020-01-16 15:57:00 3,315 7% 2 2% 1 3,313 30 13 0 11% -2% 1 9 ES short 2020-01-17 09:33:00 3,322 2020-01-17 15:55:00 3,329 20% -7 -7% -1 -3,322 23 382 0 10% -20% 0
-
One more. I'm pretty sure I got this from somewhere but for the life of me cannot find the source. This is clean and simple and shows you how to make your own custom analyzer.
class TradeClosed(bt.analyzers.Analyzer): """ Analyzer returning closed trade information. """ def start(self): super(TradeClosed, self).start() def create_analysis(self): self.rets = {} self.vals = tuple() def notify_trade(self, trade): """Receives trade notifications before each next cycle""" if trade.isclosed: self.vals = ( self.strategy.datetime.datetime(), trade.data._name, round(trade.pnl, 2), round(trade.pnlcomm, 2), trade.commission, (trade.dtclose - trade.dtopen), ) self.rets[trade.ref] = self.vals def get_analysis(self): return self.rets
Then add this to cerebro.
self.cerebro.addanalyzer(TradeClosed, _name="trade_closed")
The output is a dictionary that converts to this...
 ```trade_id date_closed ticker pnl pnlcomm commission days_open 1 2020-01-10 15:43:00 ES 17 17 0 0.25556 2 2020-01-10 15:57:00 ES 3 3 0 0.00833 3 2020-01-13 15:54:00 ES 16 16 0 0.26181 4 2020-01-14 10:01:00 ES -7 -7 0 0.02014 5 2020-01-14 15:57:00 ES 1 1 0 0.24653 6 2020-01-15 15:57:00 ES 4 4 0 0.26597 7 2020-01-16 15:34:00 ES -7 -7 0 0.25208 8 2020-01-16 15:57:00 ES 2 2 0 0.00903 9 2020-01-17 15:55:00 ES -7 -7 0 0.26528
-
Hi @run-out ,
thanks for your very good and concise answer.
I made a mistake in my question.
I forgot to mention that I would like to get the realized Profit and Loss at any moment in time and specially also for the case that I have staggered buys and sells.
E. g.:
I buy one stock at (1) and another one at (2) for 50 each.
At (3) the stock price rises from 50 to 75.
At (4) I sell one stock. The realized PnL should rise accordingly from 0 to 25.
At (5) I sell the other stock. The realized PnL should rise from 25 to 50.My intention is how I could get the realized PnL (in red in the picture) at any point in time directly from Backtrader.
-
I believe the chart I provided you with is doing what you asked. The date is the closed date of all trades. pnl is the profit or loss for that trade. pnlcomm is the pnl after commission. Commission is 0 in this case.
All you need to do is graph it.
-
If you need a diagram of the realized PnL, than you can write an observer based on the analyzer shown above. In this case
bt
will show you the diagram and it will be no need to import it somewhere else. -
Thanks.
So in the end I was able to get the realized PnL from the analyzer described here: analyzer to calculate and save realized pnl and opened positions for each strategy date to date.
But your posts were very helpful to direct me in the direction to look more at analyzers in general!
Thanks again.