mirror of
https://github.com/wassname/options_backtester.git
synced 2026-07-18 12:30:10 +08:00
1.2 MiB
1.2 MiB
In [1]:
import sys
sys.path.append('../..') # Add backtester base dir to $PYTHONPATHIn [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_chartIn [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.schemaIn [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 = FalseIn [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 date | 2006-12-06 | |
|---|---|---|
| End date | 2015-08-21 | |
| Total months | 104 | |
| 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 |