mirror of
https://github.com/wassname/options_backtester.git
synced 2026-07-16 11:20:21 +08:00
1.0 MiB
1.0 MiB
In [33]:
import sys
sys.path.append('../..') # Add backtester base dir to $PYTHONPATHIn [34]:
%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)In [35]:
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 [36]:
# Cleaned up data
data = HistoricalOptionsData("options_data_clean_v2.h5", key="/SPX", where='quotedate >= "2006-12-06" & quotedate <= "2015-08-21"')
schema = data.schemaIn [37]:
# Long (ATM) straddle
long_straddle = Strategy(schema)
leg1 = StrategyLeg("leg_1", schema, option_type=Type.CALL, direction=Direction.BUY)
leg1.entry_filter = (schema.underlying == "SPX") & (schema.dte >= 40) & (schema.dte <= 50) & (schema.strike <= schema.underlying_last * 1.05) & (schema.strike >= schema.underlying_last * 0.95)
leg1.exit_filter = (schema.dte <= 2)
leg2 = StrategyLeg("leg_2", schema, option_type=Type.PUT, direction=Direction.BUY)
leg2.entry_filter = (schema.underlying == "SPX") & (schema.dte >= 40) & (schema.dte <= 50) & (schema.strike <= schema.underlying_last * 1.05) & (schema.strike >= schema.underlying_last * 0.95)
leg2.exit_filter = (schema.dte <= 2)
long_straddle.add_legs([leg1, leg2])
long_straddle.exit_thresholds = (0.25, 0.25)In [38]:
bt = Backtest()
bt.strategy = long_straddle
bt.data = data
bt.stop_if_broke = FalseIn [39]:
bt.run(monthly=False)Out [39]:
0% [██████████████████████████████] 100% | ETA: 00:00:00 Total time elapsed: 00:04:40
| 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 | 7520.0 | Order.BTO | SXY070120P01350000 | SPX | 2007-01-20 | put | 1350.0 | 470.0 | Order.BTO | 7990.0 | 125.0 | 2006-12-06 |
| 1 | SXY070120C01340000 | SPX | 2007-01-20 | call | 1340.0 | 7990.0 | Order.BTO | SXY070120P01340000 | SPX | 2007-01-20 | put | 1340.0 | 570.0 | Order.BTO | 8560.0 | 116.0 | 2006-12-07 |
| 2 | SXY070120C01345000 | SPX | 2007-01-20 | call | 1345.0 | 7580.0 | Order.BTO | SXY070120P01345000 | SPX | 2007-01-20 | put | 1345.0 | 550.0 | Order.BTO | 8130.0 | 123.0 | 2006-12-08 |
| 3 | SXY070120C01355000 | SPX | 2007-01-20 | call | 1355.0 | 7030.0 | Order.BTO | SXY070120P01355000 | SPX | 2007-01-20 | put | 1355.0 | 510.0 | Order.BTO | 7540.0 | 132.0 | 2006-12-11 |
| 4 | SXY070217C01350000 | SPX | 2007-02-17 | call | 1350.0 | 8130.0 | Order.BTO | SXY070217P01350000 | SPX | 2007-02-17 | put | 1350.0 | 580.0 | Order.BTO | 8710.0 | 114.0 | 2006-12-29 |
| 5 | SXY070217C01355000 | SPX | 2007-02-17 | call | 1355.0 | 7310.0 | Order.BTO | SXY070217P01355000 | SPX | 2007-02-17 | put | 1355.0 | 650.0 | Order.BTO | 7960.0 | 125.0 | 2007-01-03 |
| 6 | SXY070217C01360000 | SPX | 2007-02-17 | call | 1360.0 | 7080.0 | Order.BTO | SXY070217P01360000 | SPX | 2007-02-17 | put | 1360.0 | 600.0 | Order.BTO | 7680.0 | 130.0 | 2007-01-04 |
| 7 | SXY070120C01355000 | SPX | 2007-01-20 | call | 1355.0 | -5470.0 | Order.STC | SXY070120P01355000 | SPX | 2007-01-20 | put | 1355.0 | -115.0 | Order.STC | -5585.0 | 132.0 | 2007-01-05 |
| 8 | SXY070217C01340000 | SPX | 2007-02-17 | call | 1340.0 | 7850.0 | Order.BTO | SXY070217P01340000 | SPX | 2007-02-17 | put | 1340.0 | 540.0 | Order.BTO | 8390.0 | 119.0 | 2007-01-05 |
| 9 | SXY070217C01345000 | SPX | 2007-02-17 | call | 1345.0 | 7930.0 | Order.BTO | SXY070217P01345000 | SPX | 2007-02-17 | put | 1345.0 | 470.0 | Order.BTO | 8400.0 | 119.0 | 2007-01-08 |
| 10 | SXY070120C01350000 | SPX | 2007-01-20 | call | 1350.0 | -7420.0 | Order.STC | SXY070120P01350000 | SPX | 2007-01-20 | put | 1350.0 | -0.0 | Order.STC | -7420.0 | 125.0 | 2007-01-18 |
| 11 | SXY070120C01340000 | SPX | 2007-01-20 | call | 1340.0 | -8420.0 | Order.STC | SXY070120P01340000 | SPX | 2007-01-20 | put | 1340.0 | -0.0 | Order.STC | -8420.0 | 116.0 | 2007-01-18 |
| 12 | SXY070120C01345000 | SPX | 2007-01-20 | call | 1345.0 | -7920.0 | Order.STC | SXY070120P01345000 | SPX | 2007-01-20 | put | 1345.0 | -0.0 | Order.STC | -7920.0 | 123.0 | 2007-01-18 |
| 13 | SXY070317C01355000 | SPX | 2007-03-17 | call | 1355.0 | 7850.0 | Order.BTO | SXY070317P01355000 | SPX | 2007-03-17 | put | 1355.0 | 570.0 | Order.BTO | 8420.0 | 118.0 | 2007-01-26 |
| 14 | SXY070317C01360000 | SPX | 2007-03-17 | call | 1360.0 | 7250.0 | Order.BTO | SXY070317P01360000 | SPX | 2007-03-17 | put | 1360.0 | 630.0 | Order.BTO | 7880.0 | 126.0 | 2007-01-29 |
| 15 | SXY070317C01365000 | SPX | 2007-03-17 | call | 1365.0 | 7440.0 | Order.BTO | SXY070317P01365000 | SPX | 2007-03-17 | put | 1365.0 | 520.0 | Order.BTO | 7960.0 | 125.0 | 2007-01-30 |
| 16 | SXY070317C01370000 | SPX | 2007-03-17 | call | 1370.0 | 7770.0 | Order.BTO | SXY070317P01370000 | SPX | 2007-03-17 | put | 1370.0 | 440.0 | Order.BTO | 8210.0 | 121.0 | 2007-01-31 |
| 17 | SXY070217C01340000 | SPX | 2007-02-17 | call | 1340.0 | -10650.0 | Order.STC | SXY070217P01340000 | SPX | 2007-02-17 | put | 1340.0 | -20.0 | Order.STC | -10670.0 | 119.0 | 2007-02-01 |
| 18 | SXY070317C01375000 | SPX | 2007-03-17 | call | 1375.0 | 7900.0 | Order.BTO | SXY070317P01375000 | SPX | 2007-03-17 | put | 1375.0 | 370.0 | Order.BTO | 8270.0 | 120.0 | 2007-02-01 |
| 19 | SXY070317C01380000 | SPX | 2007-03-17 | call | 1380.0 | 7690.0 | Order.BTO | SXY070317P01380000 | SPX | 2007-03-17 | put | 1380.0 | 350.0 | Order.BTO | 8040.0 | 124.0 | 2007-02-02 |
| 20 | SXY070217C01345000 | SPX | 2007-02-17 | call | 1345.0 | -10480.0 | Order.STC | SXY070217P01345000 | SPX | 2007-02-17 | put | 1345.0 | -25.0 | Order.STC | -10505.0 | 119.0 | 2007-02-05 |
| 21 | SXY070317C01385000 | SPX | 2007-03-17 | call | 1385.0 | 7290.0 | Order.BTO | SXY070317P01385000 | SPX | 2007-03-17 | put | 1385.0 | 400.0 | Order.BTO | 7690.0 | 130.0 | 2007-02-05 |
| 22 | SXY070317C01360000 | SPX | 2007-03-17 | call | 1360.0 | -9860.0 | Order.STC | SXY070317P01360000 | SPX | 2007-03-17 | put | 1360.0 | -105.0 | Order.STC | -9965.0 | 126.0 | 2007-02-14 |
| 23 | SXY070217C01350000 | SPX | 2007-02-17 | call | 1350.0 | -10560.0 | Order.STC | SXY070217P01350000 | SPX | 2007-02-17 | put | 1350.0 | -0.0 | Order.STC | -10560.0 | 114.0 | 2007-02-15 |
| 24 | SXY070217C01355000 | SPX | 2007-02-17 | call | 1355.0 | -10060.0 | Order.STC | SXY070217P01355000 | SPX | 2007-02-17 | put | 1355.0 | -0.0 | Order.STC | -10060.0 | 125.0 | 2007-02-15 |
| 25 | SXY070217C01360000 | SPX | 2007-02-17 | call | 1360.0 | -9560.0 | Order.STC | SXY070217P01360000 | SPX | 2007-02-17 | put | 1360.0 | -0.0 | Order.STC | -9560.0 | 130.0 | 2007-02-15 |
| 26 | SXY070317C01355000 | SPX | 2007-03-17 | call | 1355.0 | -10600.0 | Order.STC | SXY070317P01355000 | SPX | 2007-03-17 | put | 1355.0 | -60.0 | Order.STC | -10660.0 | 118.0 | 2007-02-20 |
| 27 | SXY070317C01365000 | SPX | 2007-03-17 | call | 1365.0 | -4010.0 | Order.STC | SXY070317P01365000 | SPX | 2007-03-17 | put | 1365.0 | -1000.0 | Order.STC | -5010.0 | 125.0 | 2007-02-27 |
| 28 | SXY070317C01370000 | SPX | 2007-03-17 | call | 1370.0 | -3650.0 | Order.STC | SXY070317P01370000 | SPX | 2007-03-17 | put | 1370.0 | -1120.0 | Order.STC | -4770.0 | 121.0 | 2007-02-27 |
| 29 | SXY070317C01375000 | SPX | 2007-03-17 | call | 1375.0 | -3290.0 | Order.STC | SXY070317P01375000 | SPX | 2007-03-17 | put | 1375.0 | -1250.0 | Order.STC | -4540.0 | 120.0 | 2007-02-27 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1656 | SPX150717C02010000 | SPX | 2015-07-17 | call | 2010.0 | -6320.0 | Order.STC | SPX150717P02010000 | SPX | 2015-07-17 | put | 2010.0 | -1730.0 | Order.STC | -8050.0 | 79.0 | 2015-06-29 |
| 1657 | SPX150717C02020000 | SPX | 2015-07-17 | call | 2020.0 | -5630.0 | Order.STC | SPX150717P02020000 | SPX | 2015-07-17 | put | 2020.0 | -1970.0 | Order.STC | -7600.0 | 83.0 | 2015-06-29 |
| 1658 | SPX150717C02005000 | SPX | 2015-07-17 | call | 2005.0 | -6780.0 | Order.STC | SPX150717P02005000 | SPX | 2015-07-17 | put | 2005.0 | -1610.0 | Order.STC | -8390.0 | 77.0 | 2015-06-29 |
| 1659 | SPX150717C02025000 | SPX | 2015-07-17 | call | 2025.0 | -5280.0 | Order.STC | SPX150717P02025000 | SPX | 2015-07-17 | put | 2025.0 | -2090.0 | Order.STC | -7370.0 | 84.0 | 2015-06-29 |
| 1660 | SPX150717C01990000 | SPX | 2015-07-17 | call | 1990.0 | -7910.0 | Order.STC | SPX150717P01990000 | SPX | 2015-07-17 | put | 1990.0 | -1320.0 | Order.STC | -9230.0 | 75.0 | 2015-06-29 |
| 1661 | SPX150717C01995000 | SPX | 2015-07-17 | call | 1995.0 | -7590.0 | Order.STC | SPX150717P01995000 | SPX | 2015-07-17 | put | 1995.0 | -1420.0 | Order.STC | -9010.0 | 81.0 | 2015-06-29 |
| 1662 | SPX150821C01975000 | SPX | 2015-08-21 | call | 1975.0 | 11750.0 | Order.BTO | SPX150821P01975000 | SPX | 2015-08-21 | put | 1975.0 | 2190.0 | Order.BTO | 13940.0 | 71.0 | 2015-07-02 |
| 1663 | SPX150821C01965000 | SPX | 2015-08-21 | call | 1965.0 | 12120.0 | Order.BTO | SPX150821P01965000 | SPX | 2015-08-21 | put | 1965.0 | 1970.0 | Order.BTO | 14090.0 | 70.0 | 2015-07-06 |
| 1664 | SPX150821C01980000 | SPX | 2015-08-21 | call | 1980.0 | 11620.0 | Order.BTO | SPX150821P01980000 | SPX | 2015-08-21 | put | 1980.0 | 1730.0 | Order.BTO | 13350.0 | 74.0 | 2015-07-07 |
| 1665 | SPX150821C01950000 | SPX | 2015-08-21 | call | 1950.0 | 11580.0 | Order.BTO | SPX150821P01950000 | SPX | 2015-08-21 | put | 1950.0 | 2380.0 | Order.BTO | 13960.0 | 71.0 | 2015-07-08 |
| 1666 | SPX150821C01955000 | SPX | 2015-08-21 | call | 1955.0 | 11330.0 | Order.BTO | SPX150821P01955000 | SPX | 2015-08-21 | put | 1955.0 | 2480.0 | Order.BTO | 13810.0 | 72.0 | 2015-07-09 |
| 1667 | SPX150821C01985000 | SPX | 2015-08-21 | call | 1985.0 | 10680.0 | Order.BTO | SPX150821P01985000 | SPX | 2015-08-21 | put | 1985.0 | 1940.0 | Order.BTO | 12620.0 | 79.0 | 2015-07-10 |
| 1668 | SPX150821C01950000 | SPX | 2015-08-21 | call | 1950.0 | -17290.0 | Order.STC | SPX150821P01950000 | SPX | 2015-08-21 | put | 1950.0 | -300.0 | Order.STC | -17590.0 | 71.0 | 2015-07-17 |
| 1669 | SPX150918C02005000 | SPX | 2015-09-18 | call | 2005.0 | 11190.0 | Order.BTO | SPX150918P02005000 | SPX | 2015-09-18 | put | 2005.0 | 1330.0 | Order.BTO | 12520.0 | 79.0 | 2015-07-30 |
| 1670 | SPX150918C02000000 | SPX | 2015-09-18 | call | 2000.0 | 11310.0 | Order.BTO | SPX150918P02000000 | SPX | 2015-09-18 | put | 2000.0 | 1230.0 | Order.BTO | 12540.0 | 79.0 | 2015-07-31 |
| 1671 | SPX150918C01995000 | SPX | 2015-09-18 | call | 1995.0 | 10910.0 | Order.BTO | SPX150918P01995000 | SPX | 2015-09-18 | put | 1995.0 | 1180.0 | Order.BTO | 12090.0 | 82.0 | 2015-08-03 |
| 1672 | SPX150918C01990000 | SPX | 2015-09-18 | call | 1990.0 | 11000.0 | Order.BTO | SPX150918P01990000 | SPX | 2015-09-18 | put | 1990.0 | 1200.0 | Order.BTO | 12200.0 | 81.0 | 2015-08-04 |
| 1673 | SPX150918C02010000 | SPX | 2015-09-18 | call | 2010.0 | 9860.0 | Order.BTO | SPX150918P02010000 | SPX | 2015-09-18 | put | 2010.0 | 1350.0 | Order.BTO | 11210.0 | 89.0 | 2015-08-05 |
| 1674 | SPX150918C01985000 | SPX | 2015-09-18 | call | 1985.0 | 10820.0 | Order.BTO | SPX150918P01985000 | SPX | 2015-09-18 | put | 1985.0 | 1390.0 | Order.BTO | 12210.0 | 81.0 | 2015-08-06 |
| 1675 | SPX150821C01975000 | SPX | 2015-08-21 | call | 1975.0 | -10130.0 | Order.STC | SPX150821P01975000 | SPX | 2015-08-21 | put | 1975.0 | -170.0 | Order.STC | -10300.0 | 71.0 | 2015-08-07 |
| 1676 | SPX150821C01980000 | SPX | 2015-08-21 | call | 1980.0 | -9660.0 | Order.STC | SPX150821P01980000 | SPX | 2015-08-21 | put | 1980.0 | -190.0 | Order.STC | -9850.0 | 74.0 | 2015-08-07 |
| 1677 | SPX150821C01985000 | SPX | 2015-08-21 | call | 1985.0 | -9170.0 | Order.STC | SPX150821P01985000 | SPX | 2015-08-21 | put | 1985.0 | -230.0 | Order.STC | -9400.0 | 79.0 | 2015-08-07 |
| 1678 | SPX150918C01975000 | SPX | 2015-09-18 | call | 1975.0 | 11190.0 | Order.BTO | SPX150918P01975000 | SPX | 2015-09-18 | put | 1975.0 | 1210.0 | Order.BTO | 12400.0 | 80.0 | 2015-08-07 |
| 1679 | SPX150821C01965000 | SPX | 2015-08-21 | call | 1965.0 | -10830.0 | Order.STC | SPX150821P01965000 | SPX | 2015-08-21 | put | 1965.0 | -10.0 | Order.STC | -10840.0 | 70.0 | 2015-08-19 |
| 1680 | SPX150821C01955000 | SPX | 2015-08-21 | call | 1955.0 | -11830.0 | Order.STC | SPX150821P01955000 | SPX | 2015-08-21 | put | 1955.0 | -5.0 | Order.STC | -11835.0 | 72.0 | 2015-08-19 |
| 1681 | SPX150918C02005000 | SPX | 2015-09-18 | call | 2005.0 | -8030.0 | Order.STC | SPX150918P02005000 | SPX | 2015-09-18 | put | 2005.0 | -1360.0 | Order.STC | -9390.0 | 79.0 | 2015-08-19 |
| 1682 | SPX150918C02000000 | SPX | 2015-09-18 | call | 2000.0 | -5810.0 | Order.STC | SPX150918P02000000 | SPX | 2015-09-18 | put | 2000.0 | -2760.0 | Order.STC | -8570.0 | 79.0 | 2015-08-20 |
| 1683 | SPX150918C01995000 | SPX | 2015-09-18 | call | 1995.0 | -6160.0 | Order.STC | SPX150918P01995000 | SPX | 2015-09-18 | put | 1995.0 | -2650.0 | Order.STC | -8810.0 | 82.0 | 2015-08-20 |
| 1684 | SPX150918C01990000 | SPX | 2015-09-18 | call | 1990.0 | -6520.0 | Order.STC | SPX150918P01990000 | SPX | 2015-09-18 | put | 1990.0 | -2530.0 | Order.STC | -9050.0 | 81.0 | 2015-08-20 |
| 1685 | SPX150918C02010000 | SPX | 2015-09-18 | call | 2010.0 | -5120.0 | Order.STC | SPX150918P02010000 | SPX | 2015-09-18 | put | 2010.0 | -3080.0 | Order.STC | -8200.0 | 89.0 | 2015-08-20 |
1686 rows × 17 columns
In [40]:
bt.summary()Out [40]:
| Strategy | |
|---|---|
| Total trades | 842 |
| Number of wins | 298 |
| Number of losses | 544 |
| Win % | 35.39% |
| Largest loss | $998310.00 |
| Profit factor | 0.55 |
| Average profit | $-98444.02 |
| Average P&L % | -0.03% |
| Total P&L % | -8371.90% |
In [41]:
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 | -8313.2% | |
| Annual volatility | 1571.6% | |
| Sharpe ratio | -0.01 | |
| Calmar ratio | NaN | |
| Stability | NaN | |
| Max drawdown | -2191.1% | |
| Omega ratio | 0.99 | |
| Sortino ratio | -0.01 | |
| Skew | -8.31 | |
| Kurtosis | 693.21 | |
| Tail ratio | 1.23 | |
| Daily value at risk | -198.0% | |
/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 | 2191.08 | 2007-05-02 | 2015-08-20 | NaT | NaN |
| 1 | 130.67 | 2007-02-20 | 2007-03-13 | 2007-04-16 | 40 |
| 2 | 126.35 | 2006-12-15 | 2007-01-05 | 2007-01-12 | 21 |
| 3 | 96.30 | 2007-01-12 | 2007-01-29 | 2007-02-01 | 15 |
| 4 | 81.62 | 2007-02-07 | 2007-02-12 | 2007-02-14 | 6 |
In [ ]: