Option Screen
POST/api/v1.0/quote/option-screenOption screener: within a specified market category (US/HK/JP stocks x stocks/indices/futures), filter option contracts from the entire market using multi-group conditions expressed by strategy (underlying, strike price, expiration date, option direction, Greeks, implied volatility, chain statistics, etc.). Supports sorting and pagination.
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
strategy | object | body | yes | Screening strategy. Structure: {market_category_list, filter_group_list}. market_category_list values: 0=US_STOCK / 1=US_INDEX / 2=US_FUTURE / 3=HK_STOCK / 4=HK_INDEX / 5=JP_STOCK / 6=JP_INDEX (multiple elements form a union). filter_group_list multiple groups intersect; within a single group, same-field indicator arrays form a union; each group must have exactly one non-empty list among underlying_list / option_list / chain_list / combo_list. |
strategy_param | object | body | no | Strategy additional parameters. Required only when the strategy uses watchlist or stock screener results as underlying source: watch_stock_id_list:[uint64] / stock_screener_stock_id_list:[uint64]. |
field_filter | object | body | no | Declare which indicator fields to return. When not provided, only the default 4 fields (volume / price / chg_ratio / implied_volatility) + option_id are returned. Use 1 as placeholder for int fields, string placeholder (e.g. "x") for string fields. Nested fields use proto field names, e.g. underlying_info:{iv:1, hv:1}. |
sort_obj | object | body | no | Sort method: {sort_field: OptionItem, is_asc}. sort_field sets only 1 field (e.g. {"volume":1}). is_asc non-zero for ascending, 0/omit for descending. Default: by volume descending. |
next_key | string | body | no | Pagination cursor. Leave empty for first page; pass back previous page's pagination.next_key. |
limit | int | body | no | Page size. Default 100, max 1000; can pass 0 (query total count only, used with request_exact_data=0). |
request_exact_data | int | body | no | Whether to return exact detail: 0=return total count only (option_list is empty), 1=return detail list (default). |
Request Example
bash
curl -X POST "https://webapi.moomoo.com/api/v1.0/quote/option-screen" \
-H "Content-Type: application/json" \
-d '{
"strategy": {
"market_category_list": [0],
"filter_group_list": [
{"underlying_list":[{"indicator_type":101,"indicator_value":{"value_list":[205189]}}]},
{"option_list":[{"indicator_type":1003,"indicator_value":{"value_list":[1]}}]}
]
},
"field_filter": {
"hp_strike_price": 1, "option_type": 1, "exercise_type": 1, "expiration_type": 1,
"in_the_money": 1, "left_day": 1, "price": 1, "volume": 1, "delta": 1,
"implied_volatility": 1, "option_name": "x",
"underlying_info": {"price": 1, "iv": 1, "iv_rank": 1}
},
"sort_obj": {"sort_field": {"volume": 1}},
"next_key": "",
"limit": 5
}' | jqResponse Fields
General contract fields:
| Field | Type | Description |
|---|---|---|
code | string | Option contract code, e.g. US.AAPL260115C00200000. |
option_name | string | Option contract name, e.g. AAPL 260526 312.50C. |
strike_price | double | Strike price (divided by 1e9 to restore). |
strike_date | string | Strike date, format yyyyMMdd. |
strike_date_timestamp | int64 | Strike date timestamp (milliseconds). |
option_type | string | Option direction: CALL / PUT. |
exercise_type | string | Exercise type: AMERICAN / EUROPEAN. |
expiration_type | string | Expiration type: WEEK / MONTH / QUARTER etc. |
in_the_money | string | Moneyness: IN_THE_MONEY / OUT_OF_THE_MONEY. |
left_day | int | Days to expiration. |
multiplier | double | Contract multiplier (divided by 1e9). |
contract_share_size | double | Shares per contract (divided by 1e9). |
product_code | string | Option chain product_code. |
Quote and order book fields:
| Field | Type | Description |
|---|---|---|
price | double | Last price (divided by 1e9). |
mid_price | double | Bid-ask mid price (divided by 1e9). |
bid_price | double | Best bid price (divided by 1e9). |
ask_price | double | Best ask price (divided by 1e9). |
bid_ask_spread | double | Bid-ask spread (divided by 1e9). |
bid_volume | int | Best bid volume. |
ask_volume | int | Best ask volume. |
change_ratio | double | Change ratio (percentage, divided by 1e5). |
volume | int | Volume. |
turnover | double | Turnover (divided by 1e3). |
open_interest | int | Open interest. |
Volatility and Greeks:
| Field | Type | Description |
|---|---|---|
implied_volatility | double | Implied volatility (percentage, divided by 1e5). |
history_volatility | double | Historical volatility (percentage, divided by 1e5). |
delta | double | Delta (divided by 1e5). |
gamma | double | Gamma (divided by 1e5). |
vega | double | Vega (divided by 1e5). |
theta | double | Theta (divided by 1e5). |
rho | double | Rho (divided by 1e5). |
leverage_ratio | double | Leverage ratio (divided by 1e5). |
Underlying statistics:
| Field | Type | Description |
|---|---|---|
underlying.stock_id | uint64 | Underlying stock_id. |
underlying.volume | int | Total volume of all options on the underlying. |
underlying.open_interest | int | Total open interest of all options on the underlying. |
underlying.iv | double | Underlying IV (percentage, divided by 1e5). |
underlying.hv | double | Underlying HV-30 day (percentage, divided by 1e5). |
underlying.iv_rank | double | IV Rank (percentage, divided by 1e5). |
underlying.price | double | Underlying last price (divided by 1e9). |
underlying.change_ratio | double | Underlying change ratio (percentage, divided by 1e5). |
Pagination:
| Field | Type | Description |
|---|---|---|
pagination.has_more | bool | Whether there is more data. |
pagination.next_key | string | Next page cursor; "-1" when no more pages. |
pagination.total | int | Total number of options matching the criteria (request_exact_data=0 caps at 9999). |
Scope & Limits
- Supported market categories: US_STOCK / US_INDEX / US_FUTURE / HK_STOCK / HK_INDEX / JP_STOCK / JP_INDEX.
- Unsupported market_category values are silently ignored by the backend, returning an empty option_list with
pagination.total=0. strategyis required; withinfilter_group_list, each group must have exactly one non-empty list among underlying_list / option_list / chain_list / combo_list.- Pagination: opaque next_key cursor;
limitrange [0, 1000]. - When
request_exact_data=0,pagination.totalcaps at 9999 and option_list is always empty (count only). - When
min_value/max_valueexceeds 2^53, use string format (strike price x1e9 may overflow).
Error Codes
| ret_code | error.code | Trigger Condition | Handling |
|---|---|---|---|
| -3 | invalid_parameter | Missing required strategy; limit out of range (>1000); invalid next_key; field_filter subfield type mismatch with proto; invalid indicator values in strategy. | Correct request body and retry. |
| 1 | permission_denied | User lacks option screening permission. | Check account quote/option permissions. |
| -5 | backend_biz_error | Backend business error. | Retry later or contact support. |
Response Example
json
{
"ret_code": 0,
"ret_msg": "success",
"data": {
"option_list": [
{
"code": "US.AAPL260526C00312500",
"option_name": "AAPL 260526 312.50C",
"strike_price": 312.5,
"option_type": "CALL",
"exercise_type": "AMERICAN",
"expiration_type": "WEEK",
"in_the_money": "IN_THE_MONEY",
"left_day": 5,
"price": 0.01,
"volume": 108815,
"delta": 0.01459,
"implied_volatility": 3.27059,
"underlying_info": {
"price": 200.5,
"iv": 32.5,
"iv_rank": 45.3
}
}
]
},
"pagination": { "has_more": true, "next_key": "5", "total": 1923817 }
}