Option Chains
The option chain for a given security can be returned using the function reqContractDetails. If an option contract is incompletely defined (for instance with the strike undefined) and used as an argument to IBApi::EClient::reqContractDetails, a list of all matching option contracts will be returned.
The example below shows an "incomplete" option IBApi.Contract with no last trading day, strike nor multiplier defined. In most cases using such a contract would result into a contract ambiguity error since there are lots of instruments matching the same description. IBApi.EClient.reqContractDetails will instead use it to obtain the whole option chain from the TWS.
-
Contract contract = new Contract();
contract.Symbol = "FISV";
contract.SecType = "OPT";
contract.Exchange = "SMART";
contract.Currency = "USD";
... client.reqContractDetails(209, ContractSamples.OptionForQuery());
client.reqContractDetails(210, ContractSamples.EurGbpFx());
client.reqContractDetails(211, ContractSamples.Bond());
client.reqContractDetails(212, ContractSamples.FuturesOnOptions());
client.reqContractDetails(213, ContractSamples.SimpleFuture());
client.reqContractDetails(214, ContractSamples.USStockAtSmart());
client.reqContractDetails(215, ContractSamples.CryptoContract());
client.reqContractDetails(216, ContractSamples.ByIssuerId());
client.reqContractDetails(217, ContractSamples.Fund());
-
Contract contract = new Contract();
contract.symbol("FISV");
contract.secType("OPT");
contract.currency("USD");
contract.exchange("SMART");
... client.reqContractDetails(210, ContractSamples.OptionForQuery());
client.reqContractDetails(211, ContractSamples.EurGbpFx());
client.reqContractDetails(212, ContractSamples.Bond());
client.reqContractDetails(213, ContractSamples.FuturesOnOptions());
client.reqContractDetails(214, ContractSamples.SimpleFuture());
client.reqContractDetails(215, ContractSamples.USStockAtSmart());
client.reqContractDetails(216, ContractSamples.CryptoContract());
client.reqContractDetails(217, ContractSamples.ByIssuerId());
client.reqContractDetails(218, ContractSamples.Fund());
-
Dim contract As Contract = New Contract
contract.Symbol = "FISV"
contract.SecType = "OPT"
contract.Exchange = "SMART"
contract.Currency = "USD"
... client.reqContractDetails(209, ContractSamples.EurGbpFx())
client.reqContractDetails(210, ContractSamples.OptionForQuery())
client.reqContractDetails(211, ContractSamples.Bond())
client.reqContractDetails(212, ContractSamples.FuturesOnOptions())
client.reqContractDetails(213, ContractSamples.SimpleFuture())
client.reqContractDetails(214, ContractSamples.USStockAtSmart())
client.reqContractDetails(215, ContractSamples.CryptoContract())
client.reqContractDetails(216, ContractSamples.ByIssuerId())
client.reqContractDetails(219, ContractSamples.FundContract())
-
Contract contract;
contract.symbol = "FISV";
contract.secType = "OPT";
contract.exchange = "SMART";
contract.currency = "USD";
... m_pClient->reqContractDetails(210, ContractSamples::OptionForQuery());
m_pClient->reqContractDetails(212, ContractSamples::IBMBond());
m_pClient->reqContractDetails(213, ContractSamples::IBKRStk());
m_pClient->reqContractDetails(214, ContractSamples::Bond());
m_pClient->reqContractDetails(215, ContractSamples::FuturesOnOptions());
m_pClient->reqContractDetails(216, ContractSamples::SimpleFuture());
m_pClient->reqContractDetails(219, ContractSamples::Fund());
-
2 contract.symbol =
"FISV"
3 contract.secType =
"OPT"
4 contract.exchange =
"SMART"
5 contract.currency =
"USD"
... 1 self.reqContractDetails(210, ContractSamples.OptionForQuery())
2 self.reqContractDetails(211, ContractSamples.EurGbpFx())
3 self.reqContractDetails(212, ContractSamples.Bond())
4 self.reqContractDetails(213, ContractSamples.FuturesOnOptions())
5 self.reqContractDetails(214, ContractSamples.SimpleFuture())
6 self.reqContractDetails(215, ContractSamples.USStockAtSmart())
7 self.reqContractDetails(216, ContractSamples.CryptoContract())
8 self.reqContractDetails(217, ContractSamples.ByIssuerId())
9 self.reqContractDetails(219, ContractSamples.FundContract())
One limitation of this technique is that the return of option chains will be throttled and take a longer time the more ambiguous the contract definition. Starting in version 9.72 of the API, a new function IBApi::EClient::reqSecDefOptParams is introduced that does not have the throttling limitation.
- It is not recommended to use reqContractDetails to receive complete option chains on an underlying, e.g. all combinations of strikes/rights/expiries.
- For very large option chains returned from reqContractDetails, unchecking the setting in TWS Global Configuration at API -> Settings -> "Expose entire trading schedule to the API" will decrease the amount of data returned per option and help to return the contract list more quickly.
-
client.reqSecDefOptParams(0, "IBM", "", "STK", 8314);
... public void securityDefinitionOptionParameter(int reqId, string exchange, int underlyingConId, string tradingClass, string multiplier, HashSet<string> expirations, HashSet<double> strikes)
{
Console.WriteLine("Security Definition Option Parameter. Reqest: {0}, Exchange: {1}, Undrelying contract id: {2}, Trading class: {3}, Multiplier: {4}, Expirations: {5}, Strikes: {6}",
reqId, exchange, Util.IntMaxString(underlyingConId), tradingClass, multiplier, string.Join(", ", expirations), string.Join(", ", strikes));
}
-
client.reqSecDefOptParams(0, "IBM", "", "STK", 8314);
... @Override
public void securityDefinitionOptionalParameter(int reqId, String exchange, int underlyingConId, String tradingClass, String multiplier,
Set<String> expirations, Set<Double> strikes) {
System.out.println("Security Definition Optional Parameter: " + EWrapperMsgGenerator.securityDefinitionOptionalParameter(reqId, exchange, underlyingConId, tradingClass, multiplier, expirations, strikes));
}
-
client.reqSecDefOptParams(0, "IBM", "", "STK", 8314)
... Public Sub securityDefinitionOptionParameter(reqId As Integer, exchange As String, underlyingConId As Integer, tradingClass As String, multiplier As String, expirations As HashSet(Of String), strikes As HashSet(Of Double)) Implements EWrapper.securityDefinitionOptionParameter
Console.WriteLine("securityDefinitionOptionParameter: " & reqId & " tradingClass: " & tradingClass & " multiplier: ")
End Sub
-
m_pClient->reqSecDefOptParams(0, "IBM", "", "STK", 8314);
... void TestCppClient::securityDefinitionOptionalParameter(int reqId, const std::string& exchange, int underlyingConId, const std::string& tradingClass,
const std::string& multiplier, const std::set<std::string>& expirations, const std::set<double>& strikes) {
printf("Security Definition Optional Parameter. Request: %d, Trading Class: %s, Multiplier: %s\n", reqId, tradingClass.c_str(), multiplier.c_str());
}
-
1 self.reqSecDefOptParams(0,
"IBM",
"",
"STK", 8314)
... 1 def securityDefinitionOptionParameter(self, reqId: int, exchange: str,
2 underlyingConId: int, tradingClass: str, multiplier: str,
3 expirations: SetOfString, strikes: SetOfFloat):
4 super().securityDefinitionOptionParameter(reqId, exchange,
5 underlyingConId, tradingClass, multiplier, expirations, strikes)
6 print(
"SecurityDefinitionOptionParameter.",
7 "ReqId:", reqId,
"Exchange:", exchange,
"Underlying conId:", intMaxString(underlyingConId),
"TradingClass:", tradingClass,
"Multiplier:", multiplier,
8 "Expirations:", expirations,
"Strikes:", str(strikes))
IBApi::EClient::reqSecDefOptParams returns a list of expiries and a list of strike prices. In some cases it is possible there are combinations of strike and expiry that would not give a valid option contract.
The API can return the greek values in real time for options, as well as calculate the implied volatility given a hypothetical price or calculate the hypothetical price given an implied volatility.
Exercising options
Options are exercised or lapsed from the API with the function IBApi.EClient.exerciseOptions
- Option exercise will appear with order status side = "BUY" and limit price of 0, but only at the time the request is made
- Option exercise can be distinguished by price = 0
-
client.exerciseOptions(5003, ContractSamples.OptionWithTradingClass(), 1, 1, null, 1, "20231018-12:00:00");
-
client.exerciseOptions(5003, ContractSamples.OptionWithTradingClass(), 1, 1, "", 1, "20231018-12:00:00");
-
'** Exercising options ***
client.exerciseOptions(5003, ContractSamples.OptionWithTradingClass(), 1, 1, Nothing, 1, "20231018-12:00:00")
-
m_pClient->exerciseOptions(5003, ContractSamples::OptionWithTradingClass(), 1, 1, "", 1, "20231018-12:00:00");
-
1 self.exerciseOptions(5003, ContractSamples.OptionWithTradingClass(), 1,
2 1, self.account, 1,
"20231018-12:00:00")