It's here - a beta you can use RIGHT NOW - Essential trade statistics - all in one place
Have a quick look at this output.
You can find it in my branch "feature-analyzer-basicStats-002"
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.
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'.
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..
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.
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.