0
# Options Trading
1
2
Specialized options trading capabilities including options chain retrieval, expiration dates, strike price filtering, and options-specific order placement and management.
3
4
## Prerequisites
5
6
Options trading requires:
7
1. Successful login with valid session
8
2. Trading token obtained via `get_trade_token()`
9
3. Options trading approval on your Webull account
10
11
## Capabilities
12
13
### Options Chain Data
14
15
Retrieve complete options chains with call and put contracts for any underlying security.
16
17
```python { .api }
18
def get_options(self, stock=None, count=-1, includeWeekly=1, direction='all', expireDate=None, queryAll=0):
19
"""
20
Get options chain for a stock.
21
22
Parameters:
23
- stock (str, optional): Stock symbol (e.g., 'AAPL')
24
- count (int): Number of strike prices to retrieve (-1 for all)
25
- includeWeekly (int): Include weekly options (0=no, 1=yes)
26
- direction (str): Filter by option type - 'all', 'call', 'put'
27
- expireDate (str, optional): Specific expiration date (YYYY-MM-DD)
28
- queryAll (int): Query all available data (0=no, 1=yes)
29
30
Returns:
31
list: List of options contracts containing:
32
- derivativeId: Unique options contract ID
33
- symbol: Options symbol
34
- strikePrice: Strike price
35
- expireDate: Expiration date
36
- direction: 'call' or 'put'
37
- lastPrice: Last traded price
38
- bid: Current bid price
39
- ask: Current ask price
40
- volume: Trading volume
41
- openInterest: Open interest
42
- impliedVolatility: Implied volatility
43
- delta: Options delta
44
- gamma: Options gamma
45
- theta: Options theta
46
- vega: Options vega
47
"""
48
49
def get_options_by_strike_and_expire_date(self, stock=None, expireDate=None, strike=None, direction='all'):
50
"""
51
Get specific options by strike price and expiration date.
52
53
Parameters:
54
- stock (str, optional): Stock symbol
55
- expireDate (str): Expiration date (YYYY-MM-DD)
56
- strike (float): Strike price
57
- direction (str): 'all', 'call', or 'put'
58
59
Returns:
60
list: Filtered options contracts matching criteria
61
"""
62
```
63
64
Usage examples:
65
66
```python
67
# Get full options chain for Apple
68
options_chain = wb.get_options(stock='AAPL', includeWeekly=1)
69
70
print(f"Found {len(options_chain)} options contracts")
71
72
# Filter for calls only
73
calls = wb.get_options(stock='AAPL', direction='call')
74
75
# Get options for specific expiration
76
jan_options = wb.get_options(
77
stock='AAPL',
78
expireDate='2024-01-19',
79
direction='all'
80
)
81
82
# Get specific strike and expiration
83
specific_option = wb.get_options_by_strike_and_expire_date(
84
stock='AAPL',
85
expireDate='2024-01-19',
86
strike=150.0,
87
direction='call'
88
)
89
```
90
91
### Options Expiration Dates
92
93
Get available expiration dates for options trading.
94
95
```python { .api }
96
def get_options_expiration_dates(self, stock=None, count=-1):
97
"""
98
Get available options expiration dates for a stock.
99
100
Parameters:
101
- stock (str, optional): Stock symbol
102
- count (int): Number of expiration dates to retrieve (-1 for all)
103
104
Returns:
105
list: List of expiration dates in YYYY-MM-DD format, sorted chronologically
106
"""
107
```
108
109
Usage example:
110
111
```python
112
# Get all expiration dates for Apple options
113
exp_dates = wb.get_options_expiration_dates(stock='AAPL')
114
115
print("Available expiration dates:")
116
for date in exp_dates[:10]: # Show first 10
117
print(f" {date}")
118
119
# Get next 5 expiration dates
120
next_expirations = wb.get_options_expiration_dates(stock='AAPL', count=5)
121
```
122
123
### Options Quotes
124
125
Get real-time quotes and pricing for specific options contracts.
126
127
```python { .api }
128
def get_option_quote(self, stock=None, tId=None, optionId=None):
129
"""
130
Get real-time quote for an options contract.
131
132
Parameters:
133
- stock (str, optional): Underlying stock symbol
134
- tId (int, optional): Underlying ticker ID
135
- optionId (int): Options contract derivative ID
136
137
Returns:
138
dict: Options quote containing:
139
- lastPrice: Last traded price
140
- bid: Current bid price
141
- ask: Current ask price
142
- bidSize: Bid size
143
- askSize: Ask size
144
- volume: Daily volume
145
- openInterest: Open interest
146
- impliedVolatility: Implied volatility
147
- delta: Delta value
148
- gamma: Gamma value
149
- theta: Theta value
150
- vega: Vega value
151
- change: Price change
152
- changeRatio: Percentage change
153
"""
154
```
155
156
Usage example:
157
158
```python
159
# First get options to find derivative ID
160
options = wb.get_options(stock='AAPL', direction='call', count=5)
161
option_id = options[0]['derivativeId']
162
163
# Get real-time quote for the option
164
quote = wb.get_option_quote(optionId=option_id)
165
166
print(f"Option Quote:")
167
print(f"Last Price: ${quote['lastPrice']}")
168
print(f"Bid/Ask: ${quote['bid']} / ${quote['ask']}")
169
print(f"Volume: {quote['volume']}")
170
print(f"Open Interest: {quote['openInterest']}")
171
print(f"IV: {quote['impliedVolatility']:.2f}%")
172
print(f"Delta: {quote['delta']:.3f}")
173
```
174
175
### Options Order Placement
176
177
Place buy and sell orders for options contracts.
178
179
```python { .api }
180
def place_order_option(self, optionId=None, lmtPrice=None, stpPrice=None, action=None, orderType='LMT', enforce='DAY', quant=0):
181
"""
182
Place an options order.
183
184
Parameters:
185
- optionId (int): Options contract derivative ID
186
- lmtPrice (float, optional): Limit price for limit orders
187
- stpPrice (float, optional): Stop price for stop orders
188
- action (str): 'BUY' or 'SELL'
189
- orderType (str): Order type - 'LMT', 'MKT', 'STP', 'STP_LMT'
190
- enforce (str): Time in force - 'DAY', 'GTC', 'IOC', 'FOK'
191
- quant (int): Number of option contracts
192
193
Returns:
194
dict: Order placement result with order ID and status
195
196
Raises:
197
ValueError: If required parameters missing or invalid
198
"""
199
```
200
201
Usage examples:
202
203
```python
204
# Get options and select one to trade
205
options = wb.get_options(stock='AAPL', direction='call')
206
call_option = options[0] # First call option
207
208
# Buy call option with limit order
209
buy_result = wb.place_order_option(
210
optionId=call_option['derivativeId'],
211
lmtPrice=5.50,
212
action='BUY',
213
orderType='LMT',
214
enforce='DAY',
215
quant=1
216
)
217
218
print(f"Buy order placed: {buy_result['orderId']}")
219
220
# Sell put option
221
put_options = wb.get_options(stock='AAPL', direction='put')
222
put_option = put_options[0]
223
224
sell_result = wb.place_order_option(
225
optionId=put_option['derivativeId'],
226
lmtPrice=3.25,
227
action='SELL',
228
orderType='LMT',
229
quant=2
230
)
231
```
232
233
### Options Order Modification
234
235
Modify existing options orders.
236
237
```python { .api }
238
def modify_order_option(self, order=None, lmtPrice=None, stpPrice=None, enforce=None, quant=0):
239
"""
240
Modify an existing options order.
241
242
Parameters:
243
- order (dict): Existing options order object to modify
244
- lmtPrice (float, optional): New limit price
245
- stpPrice (float, optional): New stop price
246
- enforce (str, optional): New time in force
247
- quant (int): New quantity
248
249
Returns:
250
dict: Modification result
251
"""
252
```
253
254
Usage example:
255
256
```python
257
# Get current options orders
258
current_orders = wb.get_current_orders()
259
options_orders = [o for o in current_orders if o.get('optionId')]
260
261
if options_orders:
262
# Modify first options order
263
order_to_modify = options_orders[0]
264
265
modify_result = wb.modify_order_option(
266
order=order_to_modify,
267
lmtPrice=6.00, # New limit price
268
quant=2 # New quantity
269
)
270
271
print(f"Order modified: {modify_result}")
272
```
273
274
### Options Historical Data
275
276
Get historical price data for options contracts.
277
278
```python { .api }
279
def get_options_bars(self, derivativeId=None, interval='1m', count=1, direction=1, timeStamp=None):
280
"""
281
Get historical price bars for options contracts.
282
283
Parameters:
284
- derivativeId (int): Options contract derivative ID
285
- interval (str): Time interval - '1m', '5m', '15m', '30m', '1h', '1d'
286
- count (int): Number of bars to retrieve
287
- direction (int): Direction flag (1 for ascending, -1 for descending)
288
- timeStamp (int, optional): Start timestamp for historical data
289
290
Returns:
291
list: Options price bars containing:
292
- open: Opening price
293
- high: High price
294
- low: Low price
295
- close: Closing price
296
- volume: Volume
297
- timestamp: Bar timestamp
298
"""
299
```
300
301
Usage example:
302
303
```python
304
# Get options historical data
305
options = wb.get_options(stock='AAPL', direction='call', count=1)
306
option_id = options[0]['derivativeId']
307
308
# Get daily bars for last 30 days
309
option_bars = wb.get_options_bars(
310
derivativeId=option_id,
311
interval='1d',
312
count=30
313
)
314
315
print(f"Options price history ({len(option_bars)} days):")
316
for bar in option_bars[-5:]: # Last 5 days
317
print(f" {bar['timestamp']}: ${bar['close']}")
318
```
319
320
## Options Strategy Examples
321
322
### Covered Call Strategy
323
324
```python
325
def covered_call_strategy(wb, symbol, strike_price):
326
"""
327
Implement a covered call strategy.
328
"""
329
330
# Check current stock position
331
positions = wb.get_positions()
332
stock_position = None
333
334
for pos in positions:
335
if pos['ticker']['symbol'] == symbol:
336
stock_position = pos
337
break
338
339
if not stock_position or stock_position['position'] < 100:
340
print(f"Need at least 100 shares of {symbol} for covered call")
341
return
342
343
# Get call options above current price
344
options = wb.get_options(stock=symbol, direction='call')
345
346
# Filter for desired strike price
347
suitable_calls = [
348
opt for opt in options
349
if opt['strikePrice'] >= strike_price
350
]
351
352
if not suitable_calls:
353
print(f"No suitable call options found at ${strike_price}")
354
return
355
356
# Select the first suitable call
357
call_to_sell = suitable_calls[0]
358
359
# Sell covered call
360
result = wb.place_order_option(
361
optionId=call_to_sell['derivativeId'],
362
lmtPrice=call_to_sell['ask'] * 0.95, # Slightly below ask
363
action='SELL',
364
orderType='LMT',
365
enforce='DAY',
366
quant=1
367
)
368
369
print(f"Covered call placed: {result}")
370
return result
371
372
# Usage
373
covered_call_strategy(wb, 'AAPL', 160.0)
374
```
375
376
### Options Scanner
377
378
```python
379
def scan_high_iv_options(wb, symbols, min_iv=30):
380
"""
381
Scan for high implied volatility options.
382
"""
383
384
high_iv_options = []
385
386
for symbol in symbols:
387
try:
388
options = wb.get_options(stock=symbol, direction='all')
389
390
for option in options:
391
iv = option.get('impliedVolatility', 0)
392
if iv >= min_iv:
393
high_iv_options.append({
394
'symbol': symbol,
395
'strike': option['strikePrice'],
396
'expiry': option['expireDate'],
397
'type': option['direction'],
398
'iv': iv,
399
'lastPrice': option['lastPrice']
400
})
401
402
except Exception as e:
403
print(f"Error scanning {symbol}: {e}")
404
405
# Sort by IV descending
406
high_iv_options.sort(key=lambda x: x['iv'], reverse=True)
407
408
print(f"High IV Options (IV >= {min_iv}%):")
409
for opt in high_iv_options[:10]: # Top 10
410
print(f"{opt['symbol']} {opt['strike']} {opt['type']} {opt['expiry']}: IV={opt['iv']:.1f}%, Price=${opt['lastPrice']}")
411
412
return high_iv_options
413
414
# Usage
415
symbols = ['AAPL', 'TSLA', 'MSFT', 'NVDA', 'AMD']
416
high_iv = scan_high_iv_options(wb, symbols, min_iv=40)
417
```
418
419
## Complete Options Trading Example
420
421
```python
422
from webull import webull
423
from datetime import datetime, timedelta
424
425
wb = webull()
426
wb.login('your_email@example.com', 'your_password')
427
wb.get_trade_token('your_trading_password')
428
429
symbol = 'AAPL'
430
431
try:
432
# Get options expiration dates
433
exp_dates = wb.get_options_expiration_dates(stock=symbol)
434
next_expiry = exp_dates[1] # Skip current week, use next
435
436
print(f"Analyzing {symbol} options expiring {next_expiry}")
437
438
# Get options chain for next expiration
439
options = wb.get_options(
440
stock=symbol,
441
expireDate=next_expiry,
442
direction='all'
443
)
444
445
# Get current stock price for reference
446
quote = wb.get_quote(stock=symbol)
447
current_price = float(quote['close'])
448
449
print(f"Current {symbol} price: ${current_price}")
450
451
# Analyze call options
452
calls = [opt for opt in options if opt['direction'] == 'call']
453
puts = [opt for opt in options if opt['direction'] == 'put']
454
455
print(f"\nCall Options (Strike >= ${current_price}):")
456
otm_calls = [c for c in calls if c['strikePrice'] >= current_price][:5]
457
458
for call in otm_calls:
459
strike = call['strikePrice']
460
price = call['lastPrice']
461
iv = call.get('impliedVolatility', 0)
462
delta = call.get('delta', 0)
463
464
print(f" ${strike} Call: ${price} (IV: {iv:.1f}%, Delta: {delta:.3f})")
465
466
print(f"\nPut Options (Strike <= ${current_price}):")
467
otm_puts = [p for p in puts if p['strikePrice'] <= current_price][:5]
468
469
for put in otm_puts:
470
strike = put['strikePrice']
471
price = put['lastPrice']
472
iv = put.get('impliedVolatility', 0)
473
delta = put.get('delta', 0)
474
475
print(f" ${strike} Put: ${price} (IV: {iv:.1f}%, Delta: {delta:.3f})")
476
477
# Example: Buy a slightly out-of-the-money call
478
if otm_calls:
479
target_call = otm_calls[0] # First OTM call
480
481
print(f"\nPlacing order for ${target_call['strikePrice']} call...")
482
483
order_result = wb.place_order_option(
484
optionId=target_call['derivativeId'],
485
lmtPrice=target_call['ask'] * 0.98, # Slightly below ask
486
action='BUY',
487
orderType='LMT',
488
enforce='DAY',
489
quant=1
490
)
491
492
print(f"Order placed: {order_result}")
493
494
except ValueError as e:
495
print(f"Options trading error: {e}")
496
```
497
498
## Options Risk Management
499
500
Key considerations for options trading:
501
502
```python
503
def analyze_options_risk(option_data, position_size=1):
504
"""
505
Analyze risk metrics for an options position.
506
"""
507
508
strike = option_data['strikePrice']
509
premium = option_data['lastPrice']
510
option_type = option_data['direction']
511
512
# Calculate maximum risk/reward
513
if option_type == 'call':
514
max_loss = premium * position_size * 100 # Premium paid
515
max_gain = "Unlimited"
516
breakeven = strike + premium
517
else: # put
518
max_loss = premium * position_size * 100 # Premium paid
519
max_gain = (strike - premium) * position_size * 100
520
breakeven = strike - premium
521
522
print(f"Options Risk Analysis:")
523
print(f"Maximum Loss: ${max_loss}")
524
print(f"Maximum Gain: {max_gain}")
525
print(f"Breakeven Price: ${breakeven}")
526
527
# Time decay analysis
528
theta = option_data.get('theta', 0)
529
if theta:
530
daily_decay = abs(theta) * position_size * 100
531
print(f"Daily Time Decay: ${daily_decay:.2f}")
532
533
# Usage with options data
534
option = wb.get_options(stock='AAPL', direction='call')[0]
535
analyze_options_risk(option, position_size=2)
536
```