Files
options_backtester/backtester/examples/short_atm_straddle_example.ipynb
T
2020-01-16 15:18:07 -03:00

1.2 MiB
Raw Blame History

In [1]:
import sys

sys.path.append('../..') # Add backtester base dir to $PYTHONPATH
In [2]:
%config InlineBackend.figure_format="retina"
%matplotlib inline
import pyfolio as pf
import pandas as pd
import os
import matplotlib.pyplot as plt
import altair as alt

plt.style.use("seaborn")
plt.rcParams["figure.figsize"] = (14, 8)
/usr/local/anaconda3/lib/python3.7/site-packages/pyfolio/pos.py:27: UserWarning: Module "zipline.assets" not found; mutltipliers will not be applied to position notionals.
  'Module "zipline.assets" not found; mutltipliers will not be applied' +
In [3]:
from backtester.datahandler import HistoricalOptionsData
from backtester.strategy import Strategy, StrategyLeg
from backtester.option import Type, Direction
from backtester import Backtest
from backtester.statistics import monthly_returns_heatmap, returns_histogram, returns_chart
In [4]:
# Cleaned up data
data = HistoricalOptionsData("allspx/options_data_clean_v2.h5", key="/SPX", where='quotedate >= "2006-12-06" & quotedate <= "2015-08-21"')
schema = data.schema

We run the backtest on the date range above to compare with this backtest. We do the comparison with a short (ATM) straddle 45 DTE. Essentially the strategy consists of selling both a call and a put with (approximately) the same strike and expiration date, profiting if the underlying asset's price does not move very much.

In [5]:
# Short ATM straddle
short_straddle = Strategy(schema)

leg1 = StrategyLeg("leg_1", schema, option_type=Type.CALL, direction=Direction.SELL)
leg1.entry_filter = (schema.underlying == "SPX") & (schema.dte >= 40) & (schema.dte <= 50) & (schema.strike >= schema.underlying_last * 0.95) & (schema.strike <= schema.underlying_last * 1.05)

leg1.exit_filter = (schema.dte <= 2)

leg2 = StrategyLeg("leg_2", schema, option_type=Type.PUT, direction=Direction.SELL)
leg2.entry_filter = (schema.underlying == "SPX") & (schema.dte >= 40) & (schema.dte <= 50) & (schema.strike >= schema.underlying_last * 0.95) & (schema.strike <= schema.underlying_last * 1.05)

leg2.exit_filter = (schema.dte <= 2)

short_straddle.add_legs([leg1, leg2])
# Exit thresholds: we exit if the loss or profit on the investment on an entry is greater than 25%.
short_straddle.exit_thresholds = (0.25, 0.25)
In [6]:
bt = Backtest()
bt.strategy = short_straddle
bt.data = data
bt.stop_if_broke = False
In [7]:
bt.run(monthly=False)
Out [7]:
0% [██████████████████████████████] 100% | ETA: 00:00:00
Total time elapsed: 00:04:21
leg_1 leg_2 totals
contract underlying expiration type strike cost order contract underlying expiration type strike cost order cost qty date
0 SXY070120C01350000 SPX 2007-01-20 call 1350.0 -7340.0 Order.STO SXY070120P01350000 SPX 2007-01-20 put 1350.0 -420.0 Order.STO -7760.0 129.0 2006-12-06
1 SXY070120C01340000 SPX 2007-01-20 call 1340.0 -7810.0 Order.STO SXY070120P01340000 SPX 2007-01-20 put 1340.0 -480.0 Order.STO -8290.0 121.0 2006-12-07
2 SXY070120C01345000 SPX 2007-01-20 call 1345.0 -7400.0 Order.STO SXY070120P01345000 SPX 2007-01-20 put 1345.0 -460.0 Order.STO -7860.0 128.0 2006-12-08
3 SXY070120C01355000 SPX 2007-01-20 call 1355.0 -6850.0 Order.STO SXY070120P01355000 SPX 2007-01-20 put 1355.0 -440.0 Order.STO -7290.0 138.0 2006-12-11
4 SXY070217C01350000 SPX 2007-02-17 call 1350.0 -8080.0 Order.STO SXY070217P01350000 SPX 2007-02-17 put 1350.0 -560.0 Order.STO -8640.0 116.0 2006-12-29
5 SXY070217C01355000 SPX 2007-02-17 call 1355.0 -7110.0 Order.STO SXY070217P01355000 SPX 2007-02-17 put 1355.0 -550.0 Order.STO -7660.0 131.0 2007-01-03
6 SXY070217C01360000 SPX 2007-02-17 call 1360.0 -6880.0 Order.STO SXY070217P01360000 SPX 2007-02-17 put 1360.0 -500.0 Order.STO -7380.0 136.0 2007-01-04
7 SXY070217C01340000 SPX 2007-02-17 call 1340.0 -7650.0 Order.STO SXY070217P01340000 SPX 2007-02-17 put 1340.0 -460.0 Order.STO -8110.0 124.0 2007-01-05
8 SXY070217C01345000 SPX 2007-02-17 call 1345.0 -7730.0 Order.STO SXY070217P01345000 SPX 2007-02-17 put 1345.0 -390.0 Order.STO -8120.0 124.0 2007-01-08
9 SXY070217C01340000 SPX 2007-02-17 call 1340.0 9980.0 Order.BTC SXY070217P01340000 SPX 2007-02-17 put 1340.0 175.0 Order.BTC 10155.0 124.0 2007-01-12
10 SXY070120C01350000 SPX 2007-01-20 call 1350.0 7820.0 Order.BTC SXY070120P01350000 SPX 2007-01-20 put 1350.0 10.0 Order.BTC 7830.0 129.0 2007-01-18
11 SXY070120C01340000 SPX 2007-01-20 call 1340.0 8820.0 Order.BTC SXY070120P01340000 SPX 2007-01-20 put 1340.0 5.0 Order.BTC 8825.0 121.0 2007-01-18
12 SXY070120C01345000 SPX 2007-01-20 call 1345.0 8320.0 Order.BTC SXY070120P01345000 SPX 2007-01-20 put 1345.0 5.0 Order.BTC 8325.0 128.0 2007-01-18
13 SXY070120C01355000 SPX 2007-01-20 call 1355.0 7320.0 Order.BTC SXY070120P01355000 SPX 2007-01-20 put 1355.0 10.0 Order.BTC 7330.0 138.0 2007-01-18
14 SXY070317C01355000 SPX 2007-03-17 call 1355.0 -7650.0 Order.STO SXY070317P01355000 SPX 2007-03-17 put 1355.0 -490.0 Order.STO -8140.0 123.0 2007-01-26
15 SXY070317C01360000 SPX 2007-03-17 call 1360.0 -7050.0 Order.STO SXY070317P01360000 SPX 2007-03-17 put 1360.0 -530.0 Order.STO -7580.0 132.0 2007-01-29
16 SXY070317C01365000 SPX 2007-03-17 call 1365.0 -7240.0 Order.STO SXY070317P01365000 SPX 2007-03-17 put 1365.0 -440.0 Order.STO -7680.0 131.0 2007-01-30
17 SXY070317C01370000 SPX 2007-03-17 call 1370.0 -7570.0 Order.STO SXY070317P01370000 SPX 2007-03-17 put 1370.0 -360.0 Order.STO -7930.0 127.0 2007-01-31
18 SXY070217C01345000 SPX 2007-02-17 call 1345.0 10350.0 Order.BTC SXY070217P01345000 SPX 2007-02-17 put 1345.0 50.0 Order.BTC 10400.0 124.0 2007-02-01
19 SXY070317C01360000 SPX 2007-03-17 call 1360.0 9390.0 Order.BTC SXY070317P01360000 SPX 2007-03-17 put 1360.0 295.0 Order.BTC 9685.0 132.0 2007-02-01
20 SXY070317C01375000 SPX 2007-03-17 call 1375.0 -7790.0 Order.STO SXY070317P01375000 SPX 2007-03-17 put 1375.0 -330.0 Order.STO -8120.0 124.0 2007-02-01
21 SXY070217C01355000 SPX 2007-02-17 call 1355.0 9580.0 Order.BTC SXY070217P01355000 SPX 2007-02-17 put 1355.0 50.0 Order.BTC 9630.0 131.0 2007-02-02
22 SXY070317C01355000 SPX 2007-03-17 call 1355.0 10040.0 Order.BTC SXY070317P01355000 SPX 2007-03-17 put 1355.0 230.0 Order.BTC 10270.0 123.0 2007-02-02
23 SXY070317C01380000 SPX 2007-03-17 call 1380.0 -7490.0 Order.STO SXY070317P01380000 SPX 2007-03-17 put 1380.0 -300.0 Order.STO -7790.0 129.0 2007-02-02
24 SXY070217C01360000 SPX 2007-02-17 call 1360.0 9190.0 Order.BTC SXY070217P01360000 SPX 2007-02-17 put 1360.0 50.0 Order.BTC 9240.0 136.0 2007-02-05
25 SXY070317C01385000 SPX 2007-03-17 call 1385.0 -7090.0 Order.STO SXY070317P01385000 SPX 2007-03-17 put 1385.0 -340.0 Order.STO -7430.0 135.0 2007-02-05
26 SXY070317C01365000 SPX 2007-03-17 call 1365.0 9580.0 Order.BTC SXY070317P01365000 SPX 2007-03-17 put 1365.0 155.0 Order.BTC 9735.0 131.0 2007-02-14
27 SXY070217C01350000 SPX 2007-02-17 call 1350.0 10700.0 Order.BTC SXY070217P01350000 SPX 2007-02-17 put 1350.0 5.0 Order.BTC 10705.0 116.0 2007-02-15
28 SXY070317C01370000 SPX 2007-03-17 call 1370.0 4010.0 Order.BTC SXY070317P01370000 SPX 2007-03-17 put 1370.0 1460.0 Order.BTC 5470.0 127.0 2007-02-27
29 SXY070317C01375000 SPX 2007-03-17 call 1375.0 3650.0 Order.BTC SXY070317P01375000 SPX 2007-03-17 put 1375.0 1590.0 Order.BTC 5240.0 124.0 2007-02-27
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1659 SPX150619C01990000 SPX 2015-06-19 call 1990.0 11010.0 Order.BTC SPX150619P01990000 SPX 2015-06-19 put 1990.0 40.0 Order.BTC 11050.0 83.0 2015-06-17
1660 SPX150619C01985000 SPX 2015-06-19 call 1985.0 11480.0 Order.BTC SPX150619P01985000 SPX 2015-06-19 put 1985.0 35.0 Order.BTC 11515.0 80.0 2015-06-17
1661 SPX150717C02015000 SPX 2015-07-17 call 2015.0 6270.0 Order.BTC SPX150717P02015000 SPX 2015-07-17 put 2015.0 2000.0 Order.BTC 8270.0 79.0 2015-06-29
1662 SPX150717C02010000 SPX 2015-07-17 call 2010.0 6650.0 Order.BTC SPX150717P02010000 SPX 2015-07-17 put 2010.0 1880.0 Order.BTC 8530.0 83.0 2015-06-29
1663 SPX150717C02020000 SPX 2015-07-17 call 2020.0 5890.0 Order.BTC SPX150717P02020000 SPX 2015-07-17 put 2020.0 2120.0 Order.BTC 8010.0 87.0 2015-06-29
1664 SPX150717C02005000 SPX 2015-07-17 call 2005.0 7060.0 Order.BTC SPX150717P02005000 SPX 2015-07-17 put 2005.0 1770.0 Order.BTC 8830.0 80.0 2015-06-29
1665 SPX150717C02025000 SPX 2015-07-17 call 2025.0 5520.0 Order.BTC SPX150717P02025000 SPX 2015-07-17 put 2025.0 2250.0 Order.BTC 7770.0 89.0 2015-06-29
1666 SPX150821C01975000 SPX 2015-08-21 call 1975.0 -11510.0 Order.STO SPX150821P01975000 SPX 2015-08-21 put 1975.0 -2020.0 Order.STO -13530.0 74.0 2015-07-02
1667 SPX150717C01990000 SPX 2015-07-17 call 1990.0 8670.0 Order.BTC SPX150717P01990000 SPX 2015-07-17 put 1990.0 540.0 Order.BTC 9210.0 78.0 2015-07-06
1668 SPX150717C01995000 SPX 2015-07-17 call 1995.0 8220.0 Order.BTC SPX150717P01995000 SPX 2015-07-17 put 1995.0 600.0 Order.BTC 8820.0 85.0 2015-07-06
1669 SPX150821C01965000 SPX 2015-08-21 call 1965.0 -11820.0 Order.STO SPX150821P01965000 SPX 2015-08-21 put 1965.0 -1820.0 Order.STO -13640.0 74.0 2015-07-06
1670 SPX150821C01980000 SPX 2015-08-21 call 1980.0 -11340.0 Order.STO SPX150821P01980000 SPX 2015-08-21 put 1980.0 -1580.0 Order.STO -12920.0 78.0 2015-07-07
1671 SPX150821C01950000 SPX 2015-08-21 call 1950.0 -11310.0 Order.STO SPX150821P01950000 SPX 2015-08-21 put 1950.0 -2210.0 Order.STO -13520.0 74.0 2015-07-08
1672 SPX150821C01955000 SPX 2015-08-21 call 1955.0 -10990.0 Order.STO SPX150821P01955000 SPX 2015-08-21 put 1955.0 -2320.0 Order.STO -13310.0 76.0 2015-07-09
1673 SPX150821C01985000 SPX 2015-08-21 call 1985.0 -10400.0 Order.STO SPX150821P01985000 SPX 2015-08-21 put 1985.0 -1790.0 Order.STO -12190.0 83.0 2015-07-10
1674 SPX150821C01950000 SPX 2015-08-21 call 1950.0 17520.0 Order.BTC SPX150821P01950000 SPX 2015-08-21 put 1950.0 390.0 Order.BTC 17910.0 74.0 2015-07-16
1675 SPX150821C01955000 SPX 2015-08-21 call 1955.0 17030.0 Order.BTC SPX150821P01955000 SPX 2015-08-21 put 1955.0 410.0 Order.BTC 17440.0 76.0 2015-07-16
1676 SPX150918C02005000 SPX 2015-09-18 call 2005.0 -10880.0 Order.STO SPX150918P02005000 SPX 2015-09-18 put 2005.0 -1170.0 Order.STO -12050.0 83.0 2015-07-30
1677 SPX150918C02000000 SPX 2015-09-18 call 2000.0 -10970.0 Order.STO SPX150918P02000000 SPX 2015-09-18 put 2000.0 -1150.0 Order.STO -12120.0 83.0 2015-07-31
1678 SPX150918C01995000 SPX 2015-09-18 call 1995.0 -10620.0 Order.STO SPX150918P01995000 SPX 2015-09-18 put 1995.0 -1100.0 Order.STO -11720.0 86.0 2015-08-03
1679 SPX150918C01990000 SPX 2015-09-18 call 1990.0 -10650.0 Order.STO SPX150918P01990000 SPX 2015-09-18 put 1990.0 -1080.0 Order.STO -11730.0 86.0 2015-08-04
1680 SPX150918C02010000 SPX 2015-09-18 call 2010.0 -9490.0 Order.STO SPX150918P02010000 SPX 2015-09-18 put 2010.0 -1180.0 Order.STO -10670.0 94.0 2015-08-05
1681 SPX150918C01985000 SPX 2015-09-18 call 1985.0 -10470.0 Order.STO SPX150918P01985000 SPX 2015-09-18 put 1985.0 -1210.0 Order.STO -11680.0 86.0 2015-08-06
1682 SPX150918C01975000 SPX 2015-09-18 call 1975.0 -10850.0 Order.STO SPX150918P01975000 SPX 2015-09-18 put 1975.0 -1100.0 Order.STO -11950.0 84.0 2015-08-07
1683 SPX150821C01975000 SPX 2015-08-21 call 1975.0 10390.0 Order.BTC SPX150821P01975000 SPX 2015-08-21 put 1975.0 20.0 Order.BTC 10410.0 74.0 2015-08-19
1684 SPX150821C01965000 SPX 2015-08-21 call 1965.0 11390.0 Order.BTC SPX150821P01965000 SPX 2015-08-21 put 1965.0 20.0 Order.BTC 11410.0 74.0 2015-08-19
1685 SPX150821C01980000 SPX 2015-08-21 call 1980.0 9890.0 Order.BTC SPX150821P01980000 SPX 2015-08-21 put 1980.0 20.0 Order.BTC 9910.0 78.0 2015-08-19
1686 SPX150821C01985000 SPX 2015-08-21 call 1985.0 9390.0 Order.BTC SPX150821P01985000 SPX 2015-08-21 put 1985.0 25.0 Order.BTC 9415.0 83.0 2015-08-19
1687 SPX150918C02005000 SPX 2015-09-18 call 2005.0 5680.0 Order.BTC SPX150918P02005000 SPX 2015-09-18 put 2005.0 3130.0 Order.BTC 8810.0 83.0 2015-08-20
1688 SPX150918C02000000 SPX 2015-09-18 call 2000.0 6030.0 Order.BTC SPX150918P02000000 SPX 2015-09-18 put 2000.0 3010.0 Order.BTC 9040.0 83.0 2015-08-20

1689 rows × 17 columns

In [8]:
bt.summary()
Out [8]:
Strategy
Total trades 842
Number of wins 400
Number of losses 442
Win % 47.51%
Largest loss $528640.00
Profit factor 0.90
Average profit $-7624.90
Average P&L % -3.99%
Total P&L % 302.89%
In [9]:
pf.create_returns_tear_sheet(returns = bt.balance['% change'].dropna())
/usr/local/anaconda3/lib/python3.7/site-packages/empyrical/stats.py:445: RuntimeWarning: invalid value encountered in double_scalars
  return ending_value ** (1 / num_years) - 1
/usr/local/anaconda3/lib/python3.7/site-packages/empyrical/stats.py:1492: RuntimeWarning: invalid value encountered in log1p
  cum_log_returns = np.log1p(returns).cumsum()
Start date2006-12-06
End date2015-08-21
Total months104
Backtest
Annual return nan%
Cumulative returns -243.9%
Annual volatility 3995.6%
Sharpe ratio -0.25
Calmar ratio NaN
Stability NaN
Max drawdown -342.0%
Omega ratio 0.65
Sortino ratio -0.33
Skew -1.20
Kurtosis 657.07
Tail ratio 0.86
Daily value at risk -507.4%
/usr/local/anaconda3/lib/python3.7/site-packages/numpy/core/fromnumeric.py:61: FutureWarning: 
The current behaviour of 'Series.argmin' is deprecated, use 'idxmin'
instead.
The behavior of 'argmin' will be corrected to return the positional
minimum in the future. For now, use 'series.values.argmin' or
'np.argmin(np.array(values))' to get the position of the minimum
row.
  return bound(*args, **kwds)
Worst drawdown periods Net drawdown in % Peak date Valley date Recovery date Duration
0 341.99 2007-01-05 2007-05-18 2007-11-19 227
1 139.82 2011-12-19 2014-04-02 NaT NaN
2 60.76 2007-12-04 2007-12-10 2007-12-14 9
3 59.22 2006-12-07 2006-12-14 2006-12-22 12
4 52.66 2006-12-22 2006-12-27 2007-01-05 11