-
Notifications
You must be signed in to change notification settings - Fork 37
/
ib_straddle_adjustments.py
executable file
·125 lines (108 loc) · 3.2 KB
/
ib_straddle_adjustments.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/usr/bin/env -S uv run --quiet --script
# /// script
# dependencies = [
# "ib_async",
# "pyyaml",
# "pandas",
# "requests",
# "dotmap",
# "flatten-dict",
# "python-dotenv",
# "matplotlib",
# "seaborn",
# ]
# ///
"""
Simulate adjusting a Straddle position by adding another Straddle
$ python3 ib_straddle_adjustments.py --help
Eg:
$ python3 ib_straddle_adjustments.py --expiry-date 20240816 --plot
$ python3 ib_straddle_adjustments.py --expiry-date 20240816 --plot --apply-adjustment
"""
from ib_async import *
from common import RawTextWithDefaultsFormatter
from common.ib import (
find_options_for_expiry,
get_next_futures_expiry,
open_contracts_for_expiry,
setup_ib,
)
from common.options import calculate_nearest_strike, get_mid_price
from options_payoff import *
def apply_straddle_adjustment(expiry_date, ib, spot_price, quantity=1):
nearest_strike = calculate_nearest_strike(spot_price)
put_contract = FuturesOption(
symbol="ES",
lastTradeDateOrContractMonth=expiry_date,
strike=nearest_strike,
right="P",
)
call_contract = FuturesOption(
symbol="ES",
lastTradeDateOrContractMonth=expiry_date,
strike=nearest_strike,
right="C",
)
new_contracts = ib.reqTickers(
*(ib.qualifyContracts(*[put_contract, call_contract]))
)
return [
OptionContract(
strike_price=con.contract.strike,
premium=get_mid_price(con.bid, con.ask),
contract_type="call" if con.contract.right == "C" else "put",
position="short",
)
for con in new_contracts
for _ in range(quantity)
]
def main(args):
ib = setup_ib()
positions = ib.positions()
expiry_date = args.expiry_date
open_options = find_options_for_expiry(positions, expiry_date)
open_contracts = open_contracts_for_expiry(ib, open_options)
contract = Future(
"ES",
exchange="CME",
lastTradeDateOrContractMonth=get_next_futures_expiry(expiry_date),
)
[ticker] = ib.reqTickers(*[contract])
spot_price = ticker.marketPrice()
OptionPlot(open_contracts, spot_price).plot("Current Position", show_plot=args.plot)
if args.apply_adjustment:
# Apply ATM Straddle
straddle_adjustment = apply_straddle_adjustment(expiry_date, ib, spot_price)
OptionPlot(open_contracts + straddle_adjustment, spot_price).plot(
"ATM Straddle", show_plot=args.plot
)
ib.disconnect()
def parse_args():
parser = ArgumentParser(
description=__doc__, formatter_class=RawTextWithDefaultsFormatter
)
parser.add_argument(
"-e",
"--expiry-date",
type=str,
required=True,
help="Expiry date for filter open contracts",
)
parser.add_argument(
"-p",
"--plot",
action="store_true",
default=False,
help="Generate Plot for final position",
)
parser.add_argument(
"-a",
"--apply-adjustment",
action="store_true",
default=False,
help="Apply straddle adjustment to the position",
)
return parser.parse_args()
if __name__ == "__main__":
args = parse_args()
main(args)