It's here - a beta you can use RIGHT NOW - Essential trade statistics - all in one place
-
Hey guys,
Have a quick look at this output.
You can find it in my branch "feature-analyzer-basicStats-002"
https://github.com/rich-oregan/backtrader/tree/feature-analyzer-basicStats-002QUICK EXPLANATION
I still need to tidy up code, complete comments and doc notes, also sort out formatting of table and some significant figure/decimal place rounding.. but essentially this beta is useable.My goal was to:
- Provide the essential statistics (that you will find in any backtesting platform).
- Enable these stats to be accessed easily.
- Display the output cleanly and efficiently in a human-readable table format.
QUICK HOW TO USE
With no parameters, output is a table shown above..
import backtrader as bt # ..code.. c = bt.Cerebro() # ..code.. c.addanalyzer(bt.analyzers.BasicTradeStats)
To use to the standard print display output i.e. not a table set useStandardPrint flag to true.
c.addanalyzer(bt.analyzers.BasicTradeStats, useStandardPrint=True)
Output now looks like this;
Personally I much prefer table format.. but whatever turns you on:)
There are two ways to run these statistics:
- Generate all statistics after every trade. e.g. if there are 1000 trades, then these statistics will run 1000 times.
- Generate statistics once after backtesting complete. e.g. if there are 1000 trades, then these statistics will run just once at end [quicker to execute].
The former is useful if you would like your system to monitor these particular statistics after each trade as strategy runs in realtime.
The later 'run once' is the default mode as is the most common used. Usually people want to just know statistics for whole system after trades made.
[NOTE: regardless of what mode you will use, the final output after all the trades made will be identical.]
# Default for 'calcStatsAfterEveryTrade' is False.. c.addanalyzer(bt.analyzers.BasicTradeStats, calcStatsAfterEveryTrade=True)
You can filter by LONG and SHORT trades also:
The default filter is 'all' --which means--> all trades, long & short
To view just long or just short trades, use; filter='long' or filter='short'.Example;
c.addanalyzer(bt.analyzers.BasicTradeStats, filter='all') # Default.. c.addanalyzer(bt.analyzers.BasicTradeStats, filter='short') c.addanalyzer(bt.analyzers.BasicTradeStats, filter='long')
This will create 3 analyzers and create 3 tables. There were reasons why I made it like this rather than combine together in one analyzer, I won't get into details right but i'm open to discussion.
And here is the output table:
Not the greatest example as there were no long trades in my system! (Personally my systems don't have long or short together, they are either long or short but not both. Generally the parameters between long and short are different and I find easier to seperate.. but hey, that's just me!)
QUICK GUIDE TO STATISTICS GIVEN
Most the stats are quite obvious. But here is a very quick summary. There are some notes in the code and doc string, but not fully updated yet.- Win Factor = number of wins / number of losses. e.g. 106 / 17 = 6.235
- Profit Factor = total profit from wins / total profit from losses
- Reward : Risk - also called Risk Reward Ratio = average win / average loss
- Expectancy % - this is the expectancy from system. e.g. for every unit risked what % can you expect to make. e.g. 28.7% means for every $1 you risked, your return was 28.7 cents.
[Technically the risk was not known, but we can estimate it from the losses. The more trades the more representative this figure will be.] - Kelly % - the optimal percentage (in hindsight) to have risked on your system per trade -> to make the maximum amount of profit.
- Z-Score - interesting this one, I've never used before. I wrote quite a bit in the doc string. Take a look. In a nutshell if the score is -2.0 or less or +2.0 or greater, you may be able to exploit the winning and losing streaks for extra edge. Here is a quick excerpt;
''' If system has a significant Z score then it is potentially possible to exploit the system for extra profit. A negative Z score means that there are fewer streaks in the trading system than would be expected statistically. This means that winning trades tend to follow winning trades and that losing trades tend to follower losers. A positive Z score means that there are more streaks in the trading system than would be expected. This means that winners tend to follow losers and vice versa. '''
Ok guys, I still have more to do to clean this up, but I need to work on my systems now, so need to move on.. hopefully this is something that will help you compare systems quicker. I'd love it if a few of you could try this and could post some screenshots of table output. BT is new for me and my sample of systems was limited. I can then improve and complete quickly. Nice one..sorted.. pukka.. Right 4am now, spent all day coding. No worries, tomorrow I'm out to party ..:)
-
very nice indeed.
I am impressed you have managed to get nice table output without using a 3rd party module.
Will download over the weekend and take it for a whirl.
-
Hey thanks Dave would would be great to get some output ran on other systems.
My table printing code is dynamic depending on the width of the columns.
It is half customisable and half hardwired. I possibly should have made a fully customisable and separated into a separate table printing module (so it could be used with other analyzers etc), but it was just a one off so I went for the quicker option. Can always improve later..
-
@Richard-O'Regan
Your wish is my command. Here is an example on my work machine - Windows + Powershell....
Ignore the poor performance :) Just a simple sample script.
-
@ThatBlokeDave Hey that's cool, thanks very much - next change would be to remove the many decimal places for Expectancy e.t.c. I started on that code already, wouldn
t take long to do. Cheers Dave, let me know if you find useful or espc if any bugs and I'll iron them out. -
@Richard-O'Regan
Not seen any bugs so far. I did think the rounding could be improved but you are already on it. :)
Very good overall. Thanks for sharing with the community.
-
Looks like a very interesting feature. Thanks for such a vibrant community! Could someone please provide guidelines to best way to install this?
-
This is very interesting, thank you!
-
Is there a way to use this outside of your tree @Richard-O-Regan? Or do I need to use your branch?
-
@Søren-Pallesen said in It's here - a beta you can use RIGHT NOW - Essential trade statistics - all in one place:
Looks like a very interesting feature. Thanks for such a vibrant community! Could someone please provide guidelines to best way to install this?
I might be a bit late to the party (and I don't know if it is the best way) but I do it like this:
- Checkout the repo like
git clone https://github.com/rich-oregan/backtrader.git
- Switch to the
master
branch (is it the right one?)git checkout master
- Install it as a python module with
python setup.py develop
That way python will load the modules directly from your checkout directory. You can change/update files there and python will use them.
- Checkout the repo like
-
Is it possible to use this without working from your branch @Richard-O-Regan ? It's quite behind the master backtrader branch now, but the stats here are very very useful!
-
Hi, very nice tool kit -- thanks for sharing! Is it still available? It seems like the links above are dead, unfortunately.
-
-
Can you let us know how it goes?
-
Can I use this to get short interest ratio?
-
Very nice!
-
for anyone else who stumbles across this thread, since some people are still trying to get this working outside of OP's original branch, wanted to pass along the following info:
you can still get this working if you take the BasicTradeStats analyzer class and import it as a custom analyzer of your own.To do so, follow the steps here to make modular code for backtrader, substituting "analyzers" for "indicators" where necessary: https://backtest-rookies.com/2017/11/01/backtrader-making-modular-code/
Under your extensions folder, create the analyzers.py file (along with init file), and paste the content from the analyzer found here: https://raw.githubusercontent.com/rich-oregan/backtrader/master/backtrader/analyzers/basictradestats.py
Finally, in your code, make sure you have something like the following lines:
# import the file at the top of your code where "BasicTradeStats" is the name of the class from extensions.analyzers import BasicTradeStats # add the strategy to cerebro cerebro.addanalyzer(BasicTradeStats, _name="BasicTradeStats") opt_runs = cerebro.run(maxcpus=1, runonce=False) for run in opt_runs: for strategy in run: # finally, this will print the analyzer print(strategy.analyzers.BasicTradeStats2.print())