# Option Screening
get_option_screen(request)
Description
Option screening. Mixes underlying-property and option-property filters. Underlying-property and option-property filters cannot be applied together within the same group, so the SDK opens new filter groups as needed: by default each filter condition is AND-joined with the previous (a new group is opened); when
or_with_previous=Trueis set explicitly and the indicator_type matches the previous condition, the new condition is OR-joined with it (same group).Parameters
Parameter Type Description request OptionScreenRequest Option screening request object; market_categories must be passed at construction OptionScreenRequest fields:
Field Type Description market_categories list[int] Option market category list page_from int Pagination start position page_count int Maximum results per page Filter builder methods (by default each call automatically opens a new filter group AND-joined with previous conditions; with
or_with_previous=Trueand a matching indicator_type, the new condition is OR-joined with the previous one in the same group. Underlying-property and option-property filters cannot be applied together within the same group):Method Description add_underlying_filter(indicator_type, values=None, lower=None, upper=None, plate_list=None, parent_plate_id=None, or_with_previous=False) Underlying property filter add_option_filter(indicator_type, values=None, lower=None, upper=None, or_with_previous=False) Option property filter new_filter_group() Manually start a new filter group add_sort(indicator_type, desc=False) Sort add_option_retrieve(indicator_type) Declare additional option fields to return add_underlying_retrieve(indicator_type) Declare underlying fields to return
Returns
Parameter Type Description ret RET_CODE API result data tuple When ret == RET_OK, returns (last_page, all_count, DataFrame) str When ret != RET_OK, an error description is returned Returned DataFrame fields:
Field Type Description code str Option code option_name str Option name strike_price float Strike price strike_date str Strike date option_type int Call / Put exercise_type int Exercise type expiration_type int Expiration type in_the_money bool Whether in the money left_day int Days remaining price float Option price mid_price float Mid price bid_price float Bid price ask_price float Ask price bid_ask_spread float Bid-ask spread bid_volume int Bid volume ask_volume int Ask volume bid_ask_volume_ratio float Bid-ask volume ratio change_ratio float Change ratio volume int Volume turnover float Turnover open_interest int Open interest open_interest_market_cap float Open interest market cap vol_oi_ratio float Volume / open interest ratio premium float Premium implied_volatility float Implied volatility history_volatility float Historical volatility iv_hv_ratio float IV/HV delta float Greeks Delta gamma float Greeks Gamma vega float Greeks Vega theta float Greeks Theta rho float Greeks Rho leverage_ratio float Leverage ratio effective_gearing float Effective leverage itm_probability float In-the-money probability buy_to_bep float Buy-to-break-even ratio sell_to_bep float Sell-to-break-even ratio buy_profit_probability float Buy profit probability sell_profit_probability float Sell profit probability intrinsic_value_per float Intrinsic value percentage time_value_per float Time value percentage itm_degree float In-the-money degree otm_degree float Out-of-the-money degree otm_probability float Out-of-the-money probability sell_annualized_return float Sell annualized return interval_return float Sell interval return underlying dict Underlying info (returned only when add_underlying_retrieve is called)
Example
from futu import (
OpenQuoteContext, RET_OK, OptionScreenRequest,
OptMarketCategory, OptIndicator, OptUnderlyingIndicator,
)
quote_ctx = OpenQuoteContext(host='127.0.0.1', port=11111)
# Example 1: US underlyings with IV>30% + near-the-money CALL
req = OptionScreenRequest(market_categories=[OptMarketCategory.US_STOCK])
req.add_underlying_filter(OptUnderlyingIndicator.IV, lower=0.3) # Underlying IV >= 30% (decimal)
req.add_option_filter(OptIndicator.OPTION_TYPE, values=[1]) # CALL
req.add_option_filter(OptIndicator.DELTA, lower=0.3, upper=0.7) # Delta 0.3~0.7
req.add_option_filter(OptIndicator.LEFT_DAY, lower=7, upper=60) # 7~60 days remaining
req.add_sort(OptIndicator.VOLUME, desc=True) # Volume descending
req.add_option_retrieve(OptIndicator.DELTA)
req.add_option_retrieve(OptIndicator.VOLUME)
req.page_count = 30
ret, data = quote_ctx.get_option_screen(req)
if ret == RET_OK:
last_page, all_count, df = data
print(df[['code', 'option_name', 'delta', 'volume']].head(10))
else:
print('error: ', data)
# Example 2: HK options for a specific underlying + return underlying info
# Note: STOCK_LIST takes security code strings directly (e.g. "HK.00700", "US.AAPL").
req = OptionScreenRequest(market_categories=[OptMarketCategory.HK_STOCK])
req.add_underlying_filter(OptUnderlyingIndicator.STOCK_LIST,
values=["HK.00700"]) # Underlying = Tencent
req.add_option_filter(OptIndicator.OPTION_TYPE, values=[1]) # CALL
req.add_option_filter(OptIndicator.OPTION_TYPE, values=[2],
or_with_previous=True) # OR with previous: CALL + PUT
req.add_underlying_retrieve(OptUnderlyingIndicator.IV)
req.add_underlying_retrieve(OptUnderlyingIndicator.MARKET_CAP)
req.add_sort(OptIndicator.OPEN_INTEREST, desc=True) # Open interest descending
req.page_count = 50
ret, data = quote_ctx.get_option_screen(req)
if ret == RET_OK:
last_page, all_count, df = data
print(df[['code', 'option_name', 'option_type', 'open_interest', 'underlying']].head(10))
else:
print('error: ', data)
quote_ctx.close()
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
- Output
# Example 1:
code option_name delta volume
0 US.GT260717C7000 GT 260717 7.00C 0.33809 38831
1 US.INTC260717C150000 INTC 260717 150.00C 0.30582 19548
2 US.MU260626C1050000 MU 260626 1050.00C 0.43334 18949
3 US.TSLA260710C400000 TSLA 260710 400.00C 0.58114 16002
4 US.CRWV260717C120000 CRWV 260717 120.00C 0.30415 15932
5 US.COMP260717C9000 COMP 260717 9.00C 0.47409 15645
6 US.SLV260717C65500 SLV 260717 65.50C 0.35809 13291
7 US.TSLA260710C410000 TSLA 260710 410.00C 0.50861 13010
8 US.SPCE260717C5000 SPCE 260717 5.00C 0.41268 12701
9 US.HOOD260717C100000 HOOD 260717 100.00C 0.41248 12572
# Example 2:
code option_name option_type open_interest underlying
0 HK.TCH260730C610000 腾讯 260730 610.00 购 1 70474 {'stock_id': 54047868453564, 'iv': 0.36337, 'h...
1 HK.TCH260629C500000 腾讯 260629 500.00 购 1 56334 {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
2 HK.TCH260929C550000 腾讯 260929 550.00 购 1 46470 {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
3 HK.TCH260730C520000 腾讯 260730 520.00 购 1 44071 {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
4 HK.TCH260929C650000 腾讯 260929 650.00 购 1 38316 {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
5 HK.TCH260629C530000 腾讯 260629 530.00 购 1 34532 {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
6 HK.TCH260629C540000 腾讯 260629 540.00 购 1 34085 {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
7 HK.TCH270330P230000 腾讯 270330 230.00 沽 2 30586 {'stock_id': 54047868453564, 'iv': 0.36337, 'h...
8 HK.TCH270330C230000 腾讯 270330 230.00 购 1 30000 {'stock_id': 54047868453564, 'iv': 0.36337, 'h...
9 HK.TCH260629C600000 腾讯 260629 600.00 购 1 27394 {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Per-field examples (by category)
All examples below assume the US_STOCK market: first
req = OptionScreenRequest(market_categories=[OptMarketCategory.US_STOCK]), then stack the filter / retrieve / sort conditions from each section, and finallyquote_ctx.get_option_screen(req)to obtain(last_page, all_count, df). The measuredheadis taken directly from the returned DataFrame; theunderlying.<field>column in the underlying-property examples is expanded byadd_underlying_retrieve(...).# Underlying properties (OptUnderlyingIndicator)
Passed via
add_underlying_filter(indicator_type, lower, upper, values, ...). Percentage indicators such as IV/HV/IV_RANK take decimal values (30% as 0.3), andadd_underlying_retrieve(...)is required for values to appear in theunderlyingdict#
IV(id=203 · interval · OptUnderlyingIndicator) Underlying implied volatilityUnit: %; SDK takes decimals directly (30% as 0.3). add_underlying_retrieve is required for the value to show up in the underlying dict
req.add_underlying_filter(OptUnderlyingIndicator.IV, lower=0.3) req.add_underlying_retrieve(OptUnderlyingIndicator.IV) req.add_sort(OptIndicator.VOLUME, desc=True)1
2
3Measured response (US_STOCK · all_count=1456207, 10 rows matched, head top 5):
code option_name volume underlying.iv US.NVDA260612C205000 NVDA 260612 205.00C 226041 0.45135 US.NVDA260612P200000 NVDA 260612 200.00P 184565 0.45135 US.NVDA260612C202500 NVDA 260612 202.50C 163991 0.45135 US.NVDA260612C210000 NVDA 260612 210.00C 147236 0.45135 US.NVDA260612C207500 NVDA 260612 207.50C 143944 0.451351
2
3
4
5
6#
HV(id=204 · interval · OptUnderlyingIndicator) Underlying historical volatilityUnit: %; SDK takes decimals directly
req.add_underlying_filter(OptUnderlyingIndicator.HV, lower=0.3) req.add_underlying_retrieve(OptUnderlyingIndicator.HV) req.add_sort(OptIndicator.VOLUME, desc=True)1
2
3Measured response (US_STOCK · all_count=1336194, 10 rows matched, head top 5):
code option_name volume underlying.hv US.NVDA260612C205000 NVDA 260612 205.00C 226041 0.46845 US.NVDA260612P200000 NVDA 260612 200.00P 184565 0.46845 US.NVDA260612C202500 NVDA 260612 202.50C 163991 0.46845 US.NVDA260612C210000 NVDA 260612 210.00C 147236 0.46845 US.NVDA260612C207500 NVDA 260612 207.50C 143944 0.468451
2
3
4
5
6#
IV_RANK(id=205 · interval · OptUnderlyingIndicator) Underlying IV rank0~100; measures the relative position of the current IV in its historical range
req.add_underlying_filter(OptUnderlyingIndicator.IV_RANK, lower=50.0) req.add_underlying_retrieve(OptUnderlyingIndicator.IV_RANK) req.add_sort(OptIndicator.VOLUME, desc=True)1
2
3Measured response (US_STOCK · all_count=0, 0 rows matched): no data. Reason: No data in the OpenD sample; can lower the threshold and retry
#
MARKET_CAP(id=401 · interval · OptUnderlyingIndicator) Underlying market capUnit: in currency; SDK takes the raw value (10 billion as 10_000_000_000)
req.add_underlying_filter(OptUnderlyingIndicator.MARKET_CAP, lower=100_000_000_000.0) req.add_underlying_retrieve(OptUnderlyingIndicator.MARKET_CAP) req.add_sort(OptIndicator.VOLUME, desc=True)1
2
3Measured response (US_STOCK · all_count=357921, 10 rows matched, head top 5):
code option_name volume underlying.market_cap US.NVDA260612C205000 NVDA 260612 205.00C 226041 4957854000000.0 US.NVDA260612P200000 NVDA 260612 200.00P 184565 4957854000000.0 US.NVDA260612C202500 NVDA 260612 202.50C 163991 4957854000000.0 US.NVDA260612C210000 NVDA 260612 210.00C 147236 4957854000000.0 US.NVDA260612C207500 NVDA 260612 207.50C 143944 4957854000000.01
2
3
4
5
6#
STOCK_PRICE(id=402 · interval · OptUnderlyingIndicator) Underlying priceUnit: in currency; SDK takes the raw price directly
req.add_underlying_filter(OptUnderlyingIndicator.STOCK_PRICE, lower=50.0, upper=500.0) req.add_underlying_retrieve(OptUnderlyingIndicator.STOCK_PRICE) req.add_sort(OptIndicator.VOLUME, desc=True)1
2
3Measured response (US_STOCK · all_count=1055665, 10 rows matched, head top 5):
code option_name volume underlying.price US.NVDA260612C205000 NVDA 260612 205.00C 226041 204.87 US.NVDA260612P200000 NVDA 260612 200.00P 184565 204.87 US.NVDA260612C202500 NVDA 260612 202.50C 163991 204.87 US.NVDA260612C210000 NVDA 260612 210.00C 147236 204.87 US.NVDA260612C207500 NVDA 260612 207.50C 143944 204.871
2
3
4
5
6# Option properties (OptIndicator)
Passed via
add_option_filter(indicator_type, lower, upper, values, ...). Greeks (DELTA/GAMMA/THETA/VEGA/RHO) and probability indicators (ITM_PROBABILITY etc.) take 0~1 decimal values#
STRIKE_PRICE(id=1001 · interval · OptIndicator) Strike priceUnit: in currency; SDK takes the raw price directly
req.add_option_filter(OptIndicator.STRIKE_PRICE, lower=50.0, upper=100.0) req.add_sort(OptIndicator.VOLUME, desc=True)1
2Measured response (US_STOCK · all_count=400354, 10 rows matched, head top 5):
code option_name strike_price volume US.HYG260717P75000 HYG 260717 75.00P 75.0 72679 US.BAC260618C55000 BAC 260618 55.00C 55.0 55636 US.TQQQ260612P72000 TQQQ 260612 72.00P 72.0 43326 US.IEF260618C95000 IEF 260618 95.00C 95.0 42077 US.HYG260918P75000 HYG 260918 75.00P 75.0 420121
2
3
4
5
6#
LEFT_DAY(id=1002 · interval · OptIndicator) Days to expirationUnit: days; integer. Near-month is typically < 30
req.add_option_filter(OptIndicator.LEFT_DAY, lower=7, upper=60) req.add_sort(OptIndicator.VOLUME, desc=True)1
2Measured response (US_STOCK · all_count=553649, 10 rows matched, head top 5):
code option_name left_day volume US.HYG260717P75000 HYG 260717 75.00P 35 72679 US.POET260717P17000 POET 260717 17.00P 35 60754 US.HYG260717P78000 HYG 260717 78.00P 35 40594 US.HYG260717P79000 HYG 260717 79.00P 35 34919 US.IEF260717P93000 IEF 260717 93.00P 35 348071
2
3
4
5
6#
OPTION_TYPE(id=1003 · values · OptIndicator) Call/PutEnum: 1=CALL, 2=PUT; values takes an enum array
req.add_option_filter(OptIndicator.OPTION_TYPE, values=[1]) # CALL req.add_sort(OptIndicator.VOLUME, desc=True)1
2Measured response (US_STOCK · all_count=972181, 10 rows matched, head top 5):
code option_name option_type volume US.NVDA260612C205000 NVDA 260612 205.00C 1 226041 US.NVDA260612C202500 NVDA 260612 202.50C 1 163991 US.NVDA260612C210000 NVDA 260612 210.00C 1 147236 US.NVDA260612C207500 NVDA 260612 207.50C 1 143944 US.SPY260612C740000 SPY 260612 740.00C 1 1149061
2
3
4
5
6#
IN_THE_MONEY(id=2001 · values · OptIndicator) In the money or notEnum: 1=ITM, 0=OTM
req.add_option_filter(OptIndicator.IN_THE_MONEY, values=[1]) # 仅价内 req.add_sort(OptIndicator.VOLUME, desc=True)1
2Measured response (US_STOCK · all_count=972389, 10 rows matched, head top 5):
code option_name in_the_money volume US.NVDA260612C202500 NVDA 260612 202.50C 1 163991 US.AAPL260612C295000 AAPL 260612 295.00C 1 87879 US.SPY260612C735000 SPY 260612 735.00C 1 77126 US.TSLA260612C390000 TSLA 260612 390.00C 1 70408 US.SPY260612C730000 SPY 260612 730.00C 1 628811
2
3
4
5
6#
PRICE(id=2002 · interval · OptIndicator) Option priceUnit: in currency; SDK takes the raw price directly
req.add_option_filter(OptIndicator.PRICE, lower=1.0, upper=10.0) req.add_sort(OptIndicator.VOLUME, desc=True)1
2Measured response (US_STOCK · all_count=644732, 10 rows matched, head top 5):
code option_name price volume US.NVDA260612C205000 NVDA 260612 205.00C 2.0 226041 US.NVDA260612C202500 NVDA 260612 202.50C 3.55 163991 US.NVDA260612C207500 NVDA 260612 207.50C 1.04 143944 US.SPY260612C740000 SPY 260612 740.00C 2.97 114906 US.TSLA260612C400000 TSLA 260612 400.00C 6.45 937561
2
3
4
5
6#
VOLUME(id=2011 · interval · OptIndicator) VolumeUnit: contracts
req.add_option_filter(OptIndicator.VOLUME, lower=1000) req.add_sort(OptIndicator.VOLUME, desc=True)1
2Measured response (US_STOCK · all_count=8010, 10 rows matched, head top 5):
code option_name volume US.NVDA260612C205000 NVDA 260612 205.00C 226041 US.NVDA260612P200000 NVDA 260612 200.00P 184565 US.NVDA260612C202500 NVDA 260612 202.50C 163991 US.NVDA260612C210000 NVDA 260612 210.00C 147236 US.NVDA260612C207500 NVDA 260612 207.50C 1439441
2
3
4
5
6#
OPEN_INTEREST(id=2013 · interval · OptIndicator) Open interestUnit: contracts
req.add_option_filter(OptIndicator.OPEN_INTEREST, lower=1000) req.add_sort(OptIndicator.OPEN_INTEREST, desc=True)1
2Measured response (US_STOCK · all_count=92911, 10 rows matched, head top 5):
code option_name open_interest US.HYG260618P79000 HYG 260618 79.00P 451310 US.BKLN260717P20000 BKLN 260717 20.00P 406177 US.HYG261120C81000 HYG 261120 81.00C 386200 US.HYG260618P77000 HYG 260618 77.00P 332022 US.HYG260618P75000 HYG 260618 75.00P 3240961
2
3
4
5
6#
IMPLIED_VOLATILITY(id=3001 · interval · OptIndicator) Implied volatilityUnit: %; SDK takes decimals directly (50% as 0.5)
req.add_option_filter(OptIndicator.IMPLIED_VOLATILITY, lower=0.3) req.add_sort(OptIndicator.VOLUME, desc=True)1
2Measured response (US_STOCK · all_count=1480382, 10 rows matched, head top 5):
code option_name implied_volatility volume US.NVDA260612C205000 NVDA 260612 205.00C 0.70232 226041 US.NVDA260612P200000 NVDA 260612 200.00P 0.77927 184565 US.NVDA260612C202500 NVDA 260612 202.50C 0.72661 163991 US.NVDA260612C210000 NVDA 260612 210.00C 0.76536 147236 US.NVDA260612C207500 NVDA 260612 207.50C 0.72576 1439441
2
3
4
5
6#
DELTA(id=3004 · interval · OptIndicator) Greeks DeltaCALL∈[0,1], PUT∈[-1,0]; SDK takes decimals directly
req.add_option_filter(OptIndicator.DELTA, lower=0.3, upper=0.7) req.add_sort(OptIndicator.VOLUME, desc=True)1
2Measured response (US_STOCK · all_count=219233, 10 rows matched, head top 5):
code option_name delta volume US.NVDA260612C205000 NVDA 260612 205.00C 0.49538 226041 US.NVDA260612C202500 NVDA 260612 202.50C 0.68114 163991 US.NVDA260612C207500 NVDA 260612 207.50C 0.31335 143944 US.SPY260612C740000 SPY 260612 740.00C 0.45037 114906 US.TSLA260612C400000 TSLA 260612 400.00C 0.48887 937561
2
3
4
5
6#
GAMMA(id=3005 · interval · OptIndicator) Greeks Gamma≥0; SDK takes decimals directly
req.add_option_filter(OptIndicator.GAMMA, lower=0.01) req.add_sort(OptIndicator.VOLUME, desc=True)1
2Measured response (US_STOCK · all_count=810281, 10 rows matched, head top 5):
code option_name gamma volume US.NVDA260612C205000 NVDA 260612 205.00C 0.07901 226041 US.NVDA260612P200000 NVDA 260612 200.00P 0.0477 184565 US.NVDA260612C202500 NVDA 260612 202.50C 0.06835 163991 US.NVDA260612C210000 NVDA 260612 210.00C 0.0481 147236 US.NVDA260612C207500 NVDA 260612 207.50C 0.06793 1439441
2
3
4
5
6#
THETA(id=3007 · interval · OptIndicator) Greeks ThetaTypically ≤0 (time decay); SDK takes decimals directly
req.add_option_filter(OptIndicator.THETA, upper=-0.01) req.add_sort(OptIndicator.VOLUME, desc=True)1
2Measured response (US_STOCK · all_count=1238755, 10 rows matched, head top 5):
code option_name theta volume US.NVDA260612C205000 NVDA 260612 205.00C -2.30979 226041 US.NVDA260612P200000 NVDA 260612 200.00P -1.67055 184565 US.NVDA260612C202500 NVDA 260612 202.50C -2.13163 163991 US.NVDA260612C210000 NVDA 260612 210.00C -1.62903 147236 US.NVDA260612C207500 NVDA 260612 207.50C -2.10361 1439441
2
3
4
5
6#
ITM_PROBABILITY(id=3019 · interval · OptIndicator) ITM probability0~1 decimal; SDK takes the value as-is
req.add_option_filter(OptIndicator.ITM_PROBABILITY, lower=0.3, upper=0.7) req.add_sort(OptIndicator.VOLUME, desc=True)1
2Measured response (US_STOCK · all_count=417899, 10 rows matched, head top 5):
code option_name itm_probability volume US.NVDA260612C205000 NVDA 260612 205.00C 0.48389 226041 US.SPY260612C740000 SPY 260612 740.00C 0.36646 114906 US.TSLA260612C400000 TSLA 260612 400.00C 0.46733 93756 US.AAPL260612C295000 AAPL 260612 295.00C 0.57372 87879 US.SPY260612C735000 SPY 260612 735.00C 0.66411 771261
2
3
4
5
6
Interface Limitations
- A maximum of 10 requests per 30 seconds