# 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=True is 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=True and 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()
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
  • 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.001          70474  {'stock_id': 54047868453564, 'iv': 0.36337, 'h...
1  HK.TCH260629C500000  腾讯 260629 500.001          56334  {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
2  HK.TCH260929C550000  腾讯 260929 550.001          46470  {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
3  HK.TCH260730C520000  腾讯 260730 520.001          44071  {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
4  HK.TCH260929C650000  腾讯 260929 650.001          38316  {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
5  HK.TCH260629C530000  腾讯 260629 530.001          34532  {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
6  HK.TCH260629C540000  腾讯 260629 540.001          34085  {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
7  HK.TCH270330P230000  腾讯 270330 230.002          30586  {'stock_id': 54047868453564, 'iv': 0.36337, 'h...
8  HK.TCH270330C230000  腾讯 270330 230.001          30000  {'stock_id': 54047868453564, 'iv': 0.36337, 'h...
9  HK.TCH260629C600000  腾讯 260629 600.001          27394  {'stock_id': 54047868453564, 'iv': 0.36406, 'h...
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
  • 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 finally quote_ctx.get_option_screen(req) to obtain (last_page, all_count, df). The measured head is taken directly from the returned DataFrame; the underlying.<field> column in the underlying-property examples is expanded by add_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), and add_underlying_retrieve(...) is required for values to appear in the underlying dict

    # IV(id=203 · interval · OptUnderlyingIndicator) Underlying implied volatility

    Unit: %; 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
    3

    Measured 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.45135
    
    1
    2
    3
    4
    5
    6
    # HV(id=204 · interval · OptUnderlyingIndicator) Underlying historical volatility

    Unit: %; 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
    3

    Measured 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.46845
    
    1
    2
    3
    4
    5
    6
    # IV_RANK(id=205 · interval · OptUnderlyingIndicator) Underlying IV rank

    0~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
    3

    Measured 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 cap

    Unit: 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
    3

    Measured 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.0
    
    1
    2
    3
    4
    5
    6
    # STOCK_PRICE(id=402 · interval · OptUnderlyingIndicator) Underlying price

    Unit: 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
    3

    Measured 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.87
    
    1
    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 price

    Unit: 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
    2

    Measured 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   42012
    
    1
    2
    3
    4
    5
    6
    # LEFT_DAY(id=1002 · interval · OptIndicator) Days to expiration

    Unit: 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
    2

    Measured 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   34807
    
    1
    2
    3
    4
    5
    6
    # OPTION_TYPE(id=1003 · values · OptIndicator) Call/Put

    Enum: 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
    2

    Measured 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  114906
    
    1
    2
    3
    4
    5
    6
    # IN_THE_MONEY(id=2001 · values · OptIndicator) In the money or not

    Enum: 1=ITM, 0=OTM

    req.add_option_filter(OptIndicator.IN_THE_MONEY, values=[1])  # 仅价内
    req.add_sort(OptIndicator.VOLUME, desc=True)
    
    1
    2

    Measured 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   62881
    
    1
    2
    3
    4
    5
    6
    # PRICE(id=2002 · interval · OptIndicator) Option price

    Unit: 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
    2

    Measured 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   93756
    
    1
    2
    3
    4
    5
    6
    # VOLUME(id=2011 · interval · OptIndicator) Volume

    Unit: contracts

    req.add_option_filter(OptIndicator.VOLUME, lower=1000)
    req.add_sort(OptIndicator.VOLUME, desc=True)
    
    1
    2

    Measured 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  143944
    
    1
    2
    3
    4
    5
    6
    # OPEN_INTEREST(id=2013 · interval · OptIndicator) Open interest

    Unit: contracts

    req.add_option_filter(OptIndicator.OPEN_INTEREST, lower=1000)
    req.add_sort(OptIndicator.OPEN_INTEREST, desc=True)
    
    1
    2

    Measured 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         324096
    
    1
    2
    3
    4
    5
    6
    # IMPLIED_VOLATILITY(id=3001 · interval · OptIndicator) Implied volatility

    Unit: %; 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
    2

    Measured 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  143944
    
    1
    2
    3
    4
    5
    6
    # DELTA(id=3004 · interval · OptIndicator) Greeks Delta

    CALL∈[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
    2

    Measured 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   93756
    
    1
    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
    2

    Measured 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  143944
    
    1
    2
    3
    4
    5
    6
    # THETA(id=3007 · interval · OptIndicator) Greeks Theta

    Typically ≤0 (time decay); SDK takes decimals directly

    req.add_option_filter(OptIndicator.THETA, upper=-0.01)
    req.add_sort(OptIndicator.VOLUME, desc=True)
    
    1
    2

    Measured 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  143944
    
    1
    2
    3
    4
    5
    6
    # ITM_PROBABILITY(id=3019 · interval · OptIndicator) ITM probability

    0~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
    2

    Measured 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   77126
    
    1
    2
    3
    4
    5
    6

Interface Limitations

  • A maximum of 10 requests per 30 seconds