Slippage Analysis
When evaluating a strategy using backtest results, we often want to know how sensitive it's performance is to implementation shortfall or slippage. pyfolio's transactions tear sheet can create "slippage sweep" plots that display strategy performance under various slippage assumptions.
Additional per-dollar slippage can be applied to returns before running a tear sheet by providing create_full_tear_sheet
with the a level of slippage in basis points (1% == 100 basis points) as the slippage
keyword argument. The slippage plots in the transactions tear sheet will display returns with slippage added to the unadjusted returns.
For example, if you run a backtest with no transaction costs and call create_full_tear_sheet(returns, positions, transactions, slippage=5)
, 5 bps of slippage will be applied to returns
before all plots and figures, with the exception of the slippage sweep plots, are generated.
It is important to emphasize that the slippage plots will display performance under additional slippage. If the passed performance data already has slippage applied, the 5 bps slippage equity curve will represent performance under 5 bps of slippage in addition to the already simulated slippage penalty. If slippage is already applied to the performance results, pass slippage=0
to the create_full_tear_sheet
to trigger the creation of the additional slippage sweep plots without applying any additional slippage to the returns time series used throughout the rest of the tear sheet.
%matplotlib inline
import pyfolio as pf
import gzip
import pandas as pd
# silence warnings
import warnings
warnings.filterwarnings('ignore')
transactions = pd.read_csv(gzip.open('../tests/test_data/test_txn.csv.gz'),
index_col=0, parse_dates=True)
positions = pd.read_csv(gzip.open('../tests/test_data/test_pos.csv.gz'),
index_col=0, parse_dates=True)
returns = pd.read_csv(gzip.open('../tests/test_data/test_returns.csv.gz'),
index_col=0, parse_dates=True, header=None)[1]
returns.index = returns.index.tz_localize("UTC")
positions.index = positions.index.tz_localize("UTC")
transactions.index = transactions.index.tz_localize("UTC")
pf.create_full_tear_sheet(returns, positions, transactions, slippage=0)
Entire data start date: 2004-01-09
Entire data end date: 2009-12-31
Backtest months: 71
|
Backtest |
Annual return |
8.8% |
Cumulative returns |
65.4% |
Annual volatility |
26.3% |
Sharpe ratio |
0.45 |
Calmar ratio |
0.15 |
Stability |
0.00 |
Max drawdown |
-60.4% |
Omega ratio |
1.09 |
Sortino ratio |
0.66 |
Skew |
0.14 |
Kurtosis |
5.88 |
Tail ratio |
0.99 |
Daily value at risk |
-3.3% |
Gross leverage |
1.03 |
Daily turnover |
11.1% |
Alpha |
0.08 |
Beta |
0.83 |
Worst drawdown periods |
Net drawdown in % |
Peak date |
Valley date |
Recovery date |
Duration |
0 |
60.39 |
2007-11-06 |
2009-03-09 |
NaT |
NaN |
1 |
24.10 |
2005-07-28 |
2006-09-07 |
2007-05-22 |
474 |
2 |
11.89 |
2004-06-25 |
2004-08-12 |
2004-11-05 |
96 |
3 |
10.87 |
2004-11-15 |
2005-04-18 |
2005-07-14 |
174 |
4 |
9.51 |
2007-07-16 |
2007-08-06 |
2007-09-13 |
44 |
Stress Events |
mean |
min |
max |
Lehmann |
-0.27% |
-4.70% |
4.11% |
Aug07 |
0.32% |
-2.96% |
2.92% |
Mar08 |
-0.43% |
-3.26% |
3.36% |
Sept08 |
-0.68% |
-4.38% |
4.08% |
2009Q1 |
-0.36% |
-5.02% |
3.39% |
2009Q2 |
0.74% |
-4.03% |
6.13% |
Low Volatility Bull Market |
0.01% |
-6.07% |
6.43% |
GFC Crash |
-0.09% |
-11.76% |
10.13% |
Recovery |
0.35% |
-4.03% |
6.01% |
Top 10 long positions of all time |
max |
COST |
90.01% |
DELL |
85.73% |
CERN |
83.53% |
MMM |
82.09% |
INTC |
78.59% |
AMD |
75.76% |
GPS |
62.24% |
Top 10 short positions of all time |
max |
AMD |
-30.12% |
DELL |
-26.58% |
CERN |
-25.51% |
MMM |
-22.62% |
GPS |
-20.09% |
INTC |
-18.47% |
COST |
-16.44% |
Top 10 positions of all time |
max |
COST |
90.01% |
DELL |
85.73% |
CERN |
83.53% |
MMM |
82.09% |
INTC |
78.59% |
AMD |
75.76% |
GPS |
62.24% |
All positions ever held |
max |
COST |
90.01% |
DELL |
85.73% |
CERN |
83.53% |
MMM |
82.09% |
INTC |
78.59% |
AMD |
75.76% |
GPS |
62.24% |