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

png

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%

png

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%

png

png