跳转到内容

期权链总览

期权链不是一张具体合约,而是一组“可以用来拼期权合约的参数”。例如你要交易 AAPL 期权,不能只写 AAPL,还要知道可用的到期日、行权价、看涨/看跌、乘数、交易类别和交易所。

TWS API 获取期权链参数主要使用:

app.reqSecDefOptParams(
reqId,
underlyingSymbol,
futFopExchange,
underlyingSecType,
underlyingConId,
)

返回结果通过两个回调接收:

def securityDefinitionOptionParameter(
self,
reqId,
exchange,
underlyingConId,
tradingClass,
multiplier,
expirations,
strikes,
):
...
def securityDefinitionOptionParameterEnd(self, reqId):
...
你要知道的问题对应返回字段AAPL 示例
哪些交易所返回了参数exchangeSMARTCBOEPHLX
这组参数属于哪个标的underlyingConId265598
交易类别是什么tradingClassAAPL
一张合约代表多少股multiplier100
有哪些到期日expirations2026061520281215
有哪些行权价strikes5.0600.0

reqSecDefOptParams() 返回的是“参数集合”,不是所有具体期权合约列表。拿到到期日和行权价后,还要选择方向 right,例如 C 表示看涨、P 表示看跌,再构造具体 Contract 去查询合约详情或请求行情。

为什么不用 reqContractDetails() 扫整条期权链

Section titled “为什么不用 reqContractDetails() 扫整条期权链”

旧写法可以用一个不完整的期权 Contract 调用 reqContractDetails(),让 TWS 返回匹配的期权合约。但官方文档明确提醒,这种方式在期权链很大时会被节流,合约定义越模糊越慢。API 9.72 及之后版本,更推荐用 reqSecDefOptParams() 先拿到到期日和行权价参数。

方式适合场景注意点
reqSecDefOptParams()先获取期权链参数快速拿到交易所、到期日、行权价、乘数
reqContractDetails()查询某张具体期权合约详情不建议用来扫完整期权链

示例连接使用 AAPL 股票 conId=265598 请求期权链参数,接口返回正常:

CONNECTED=True
OPTION_END_RECEIVED=True
OPTION_ROW_COUNT=20
OPTION_EXCHANGE_COUNTS=AMEX:1,BATS:1,BOX:1,CBOE:1,CBOE2:1,EDGX:1,EMERALD:1,GEMINI:1,IBUSOPT:1,ISE:1,MEMX:1,MERCURY:1,MIAX:1,NASDAQBX:1,NASDAQOM:1,PEARL:1,PHLX:1,PSE:1,SAPPHIRE:1,SMART:1
OPTION_SAMPLE=exchange=SMART;underlyingConId=265598;tradingClass=AAPL;multiplier=100;expirationCount=26;strikeCount=123;firstExpiration=20260615;lastExpiration=20281215;minStrike=5.0;maxStrike=600.0
NON_INFO_ERROR_COUNT=0

OPTION_ROW_COUNT=20 表示有 20 个交易所维度的参数返回,不是 20 张期权。SMART 这一行返回了 26 个到期日和 123 个行权价。

官方文档说明,reqSecDefOptParams() 返回到期日列表和行权价列表,但某些到期日与行权价组合可能并不能组成有效期权合约。因此程序不要直接把任意 expiration + strike + right 当作可交易合约。

更稳的流程是:

  1. 先用股票合约详情确认标的 conId
  2. reqSecDefOptParams() 获取期权链参数。
  3. 按策略筛选到期日、行权价和方向。
  4. 用具体期权 Contract 调用 reqContractDetails() 确认合约存在。
  5. 合约详情确认成功后,再请求行情、希腊值或下单。