5 Querying current market data

5.1 Single-quote data

Let us start with a simple example where we retrieve the current market information for Google Inc., which trades using the GOOG symbol on IB’s SMART exchange (the default exchange), with USD currency (the default currency):

>> data = IBMatlab('action','query', 'symbol','GOOG')
data =
reqId: 22209874
reqTime: '02-Dec-2010 00:47:23'
dataTime: '02-Dec-2010 00:47:24'
dataTimestamp: 734474.032914491
lastEventTime: 734474.032914512
ticker: 'GOOG'
bidPrice: 563.68
askPrice: 564.47
open: 562.82
close: 555.71
low: 562.4
high: 571.57
lastPrice: -1
volume: 36891
tick: 0.01
bidSize: 3
askSize: 3
lastSize: 0
contract: [1x1 struct]
contractDetails: [1x1 struct]

Here is another example, this time for a future asset:

>> data = IBMatlab('action','query', 'LocalSymbol','YI   JUL 17', ...
'SecType','FUT', 'Exchange','NYSELIFFE')
data =
            reqId: 727929834
          reqTime: '11-May-2017 10:23:11'
         dataTime: '11-May-2017 10:23:12'
    dataTimestamp: 736826.432780035
    lastEventTime: 736826.432780521
           ticker: ''
         bidPrice: 16.263
         askPrice: 16.271
             open: 16.197
            close: 16.207
              low: 16.18
             high: 16.285
        lastPrice: 16.285
           volume: 25
             tick: 0.01
          bidSize: 3
          askSize: 3
         lastSize: 1

As can be seen, the returned data object is a Matlab struct whose fields are self-explanatory. To access any specific field, use the standard Matlab notation:

>> price = data.bidPrice; %=563.68 in this specific case

Note: reqTime, dataTime, dataTimestamp and lastEventTime fields reflect local time. If lastPrice is returned with valid data (not -1) then it is usually accompanied by a lastTimestamp field that reflects the server time in Java units (seconds since midnight 1/1/197029 as a string, for example: ‘1348563149’). We can convert lastTimestamp into Matlab format by converting the string into a number using Matlab’s datestr and datenum functions:30

>> datestr(datenum([1970 1 1 0 0 str2num(data.lastTimestamp)]))
ans =
25-Sep-2012 08:52:29

To retrieve live and historic market data, several pre-conditions must be met:

The IB account is subscribed to the information service for the stated security

The specified security can be found on the specified exchange using the specified classification properties (a.k.a. contract)

The security is currently traded (i.e., its market is currently open)

There is no other TWS with live data running on a different computer31

If you manage several accounts, they should be associated with the main account for live data, using the Manage Accounts window in TWS.

If any of these conditions is not met, the information returned by IB will be empty/invalid (the data fields will have a value of -1 or []). In some cases, IB-Matlab automatically attempts to re-fetch the data from IB, to ensure that the data is in fact missing. If condition 3 is not met, the empty data will not be accompanied by any error message; if condition 1 and/or 2 (but not 3) is not met, an error message will be displayed in the Matlab command window,32 as the following examples illustrate:

>> data = IBMatlab('action','query', 'symbol','GOOG')
[API.msg2] Requested market data is not subscribed.Error&BEST/STK/Top {153745220, 354}
data =
reqId: 779564761
reqTime: '30-Oct-2017 13:27:49'
dataTime: '30-Oct-2017 13:27:53'
dataTimestamp: 736998.561032893
lastEventTime: 736998.561035394
ticker: 'GOOG'
bidPrice: -1
askPrice: -1
open: -1
close: -1
low: -1
high: -1
lastPrice: -1
volume: -1
tick: 0.01
contract: [1×1 struct]
contractDetails: [1×1 struct]

This illustrates a situation where we are not subscribed to data for this specific security type and/or exchange, and delayed market data is not available. When delayed market data is available (depending on Exchange and SecType), the delayed quotes are shown in dedicated fields, together with an explanatory warning message:

>> data = IBMatlab('action','query', 'symbol','AAPL')
[API.msg2] Requested market data is not subscribed. Displaying delayed market data... {779573827, 10167}
data =
reqId: 779573829
reqTime: '30-Oct-2017 14:17:10'
dataTime: '30-Oct-2017 14:17:11'
dataTimestamp: 736998.595277546
lastEventTime: 736998.595283414
ticker: 'AAPL'
bidPrice: -1
askPrice: -1
open: -1
close: -1
low: -1
high: -1
lastPrice: -1
volume: -1
tick: 0.01
contract: [1×1 struct]
contractDetails: [1×1 struct]
delayed_bidPrice: 163.5
delayed_askPrice: 163.59
delayed_lastPrice: 163.5
delayed_volume: 991
delayed_close: 163.05
delayed_open: 0

Note that some of the delayed data fields may be missing or invalid. Specifically, the delayed_close field is very often not provided, and the delayed_open field is often 0.

Note: Delayed data may be sent by IB even if you are subscribed to IB’s real-time data, in case IB-Matlab is connected to a paper-trading account at the same time that a live account is also logged-in from another computer. In such cases, IB will always stream the real-time data to the live-account TWS/Gateway, and the delayed data to the paper-trading TWS/Gateway. IB will only stream real-time live data to a paper-trading account (and IB-Matlab) when a live trading account is not actively logged-in, or when it is connected on the same computer (with some non-default settings).33

A similar yet different error message is returned when we try to get historical data for a security type or exchange that is not subscribed:

>> data = IBMatlab('action','history', 'symbol','GOOG')
[API.msg2] Historical Market Data Service error message:
No market data permissions for ISLAND STK {153745241, 162}
data =
dateTime: {1x0 cell}
open: []
high: []
low: []
close: []
volume: []
count: []
WAP: []
hasGaps: []

In this case, there is no delayed data: IB only provides delayed quotes for single-quote and streaming data. IB will not return historical data if you do not have the necessary market perrmissions/subscription.

If you specify incorrect or missing security name or classification properties, the data is similarly not returned, and an error message is displayed:

>> data = IBMatlab('action','query', 'symbol','EUR')
[API.msg2] No security definition has been found for the request.

>> data = IBMatlab('action','query','symbol','GOOG','secType','opt',...
'expiry','202212', 'strike',97, 'side','CALL')

[API.msg2] The contract description specified for GOOG is ambiguous.
Recheck the contract parameters, or try adding parameters such as SecType, Exchange, Currency, Multiplier, Expiry (see User Guide sections 3.2, 14.2)

As the last error message suggests, adding specific values for contract properties may help resolve the problem; see §14.2 for additional details.

In some cases, querying a contract may return some invalid (<0) field values. For example, querying the NIFTY50 index only returns valid close and lastPrice fields; other fields return -1. The reason is that NIFTY50 is not a tradable security by itself, so it has no bid/ask/open/high/low/volume values. Only NIFTY50 futures are tradable securities, and these indeed return valid field values. Another common reason for receiving -1 field values is querying when the market is closed. To prevent IB-Matlab from waiting a long time for the missing fields, set the Timeout parameter.

When querying option contracts, IB sometimes appends greeks information, typically in the modelOptComp field.34 IB often sends this information long after the main bulk of the data, causing the IBMatlab query to return without it. To ensure that the query waits until the greeks data is received, set the WaitForGreeks parameter to 1 (or true), together with a finite Timeout value (otherwise the query might wait forever):

>> data = IBMatlab('action', 'query', 'symbol','GOOG', 'right','C', ...
'secType'
,'OPT', 'expiry','20230120', 'strike',95,...
'multiplier'
,100, 'WaitForGreeks',true, 'timeout',5))
data =
reqId: 1334289666
reqTime: '22-Nov-2022 16:51:57'
dataTime: '22-Nov-2022 16:52:02'
dataTimestamp: 738847.702803113
lastEventTime: 738847.702803264
ticker: 'GOOG'
bidPrice: 5.25
askPrice: 5.3
open: -1
close: 5.94
low: 5.36
high: 6
lastPrice: 5.36
volume: 17
halted: 0
tick: 0.01
contract: [1×1 struct]
contractDetails: [1×1 struct]
lastTimestamp: '1669128439'
lastSize: 1
bidSize: 165
askSize: 3563
bidExch: 'CNBQZWT'
askExch: 'ACIXNBQZWTMHE'
bidOptComp: [1×1 struct]
askOptComp: [1×1 struct]
lastOptComp: [1×1 struct]
modelOptComp: [1×1 struct]

>> data.modelOptComp
ans =
EventName: 'tickOptionComputation'
tickerId: 1334289666
field: 13
impliedVol: 0.3266003491091
delta: 0.54214843505144
optPrice: 5.21056937905062
pvDividend: 0
gamma: 0.0319889840549273
vega: 0.151219099645397
theta: -0.0474963712975894
undPrice: 94.84
omega: 9.86789616255852
lambda: 9.86789616255852
rho: 7.30011198156273
crho: 8.12331873181594

Notes:

WaitForGreeks is a synchronous mechanism that is only available for single-quote (snapshot) non-combo query of derivatives (options/futures). It is not available for other security types, nor for streaming/combo/historic queries.

Some of the top-level data fields are not always available. For example, outside regular trading hours the bidExch, askExch, bidOptComp, askOptComp, and lastOptComp fields are usually not available (although modelOptComp is).

To receive live greek values it is necessary to have market data subscriptions for both the option and the underlying contract.35

The IB 30-day volatility is the at-market volatility estimated for a maturity thirty calendar days forward of the current trading day, and is based on option prices from two consecutive expiration months.

All the field values reported beneath undPrice (omega=lambda, rho and crho) are computed by IB-Matlab based on the reported IB values; the other fields are reported exactly as reported by IB.

The omega and lambda fields are exactly equal; both fields are reported because different literature and data-sources sometimes use one term or the other. You can use either of them in your code.

Additional greek values (vanna, charm, vomma/volga, veta, speed, zomma, color and ultima) can be computed using the calcGreeks function (freely available on the Matlab File Exchange),36 using the data reported by IB-Matlab and user-specified interest/yield rates.

5.2 Market depth (Level II) data

For some exchanges and security types, and possibly also depending on your IB account subscription, IB enables the user to retrieve market depth (Level II order book) information. In IB-Matlab, this information can either be retrieved as a one-time data snapshot, or in continuous streaming mode. To get snapshot data, set the QuotesNumber parameter to 1 (=default); to get streaming data set QuotesNumber to a larger value. This section describes the one-time data snapshot mechanism; see §7.3 below for a description of the streaming data mechanism, and §11.5 for a usage example of a continuously-updating order-book GUI.

In general, retrieving market depth is very similar to retrieving single-quote data, the only difference being that for market depth, the NumberOfRows parameter should be set to a positive number between 2-5 (i.e., 2, 3, 4 or 5).37

Here is a simple example of retrieving the top 3 rows of the EUR.USD order-book:

>> dataStruct = IBMatlab('action','query', 'symbol','EUR', ...
'LocalSymbol','EUR.USD', 'SecType','CASH', ...
'Exchange','IDEALPRO', 'NumberOfRows',3)
dataStruct =
reqId: 464868253
reqTime: '16-Dec-2014 14:03:48'
lastEventDateNum: 735949.585989664
lastEventDateTime: '16-Dec-2014 14:03:49'
symbol: 'EUR'
localSymbol: 'EUR.USD'
isActive: 0
quotesReceived: 6
quotesToReceive: 6
bid: [1x3 struct]
ask: [1x3 struct]
contract: [1x1 struct]

>> dataStruct.bid(1)
ans =
price: 1.25345
size: 1000000
marketMaker: ''
dateNum: 735949.585989618
dateTime: '16-Dec-2014 14:03:49'

>> dataStruct.ask(1)
ans =
price: 1.2535
size: 8320000
marketMaker: ''
dateNum: 735949.585989653
dateTime: '16-Dec-2014 14:03:49'

Note that in this case, 6 quotes were received, corresponding to the requested 3 rows for both the bid and the ask sides. You can request up to 10 market-depth rows (some exchanges may limit the number of available market-depth rows to a lower number). Note that in some cases, the market depth of the bid/ask sides may not be the same. For example, it is possible that at some time there are 5 bid rows, but only 4 ask rows.

Naturally, dataStruct.bid(1) is the highest bid, dataStruct.ask(1) is the lowest ask:

>> [dataStruct.bid.price]
ans =
1.25345 1.2534 1.25335

>> [dataStruct.ask.price]
ans =
1.2535 1.25355 1.2536

In some cases (again, depending on the market, security and your IB subscription level), Level 2 market-maker date may be available. In such cases, the marketMaker field will contain the name of the exchange hosting the order for that row.

As noted above, market depth is not always available. Only certain combinations of Exchange, SecType and Currency are supported for Level 2, even if you have the necessary market-data subscription. For example, the 'SMART' exchange is typically not supported, only specific exchange names. In all such cases, you may receive an applicable error message from the IB server, and the returned data will be empty:

>> data = IBMatlab('Action','query', 'Symbol','IBM', 'NumberOfRows',3)

[API.msg2] Deep market data is not supported for this combination of security type/exchange {464879606, 10092}

data =
reqId: 464879606
reqTime: '16-Dec-2014 14:22:06'
lastEventDateNum: -1
lastEventDateTime: ''
symbol: 'IBM'
localSymbol: ''
isActive: 1
quotesReceived: 0
quotesToReceive: 6
bid: [0x0 struct]
ask: [0x0 struct]
contract: [1x1 struct]

5.3 Scanner data

IB’s scanner data functionality returns a list of securities that match the specified scan criteria. IB provides a long list of predefined scanners,38 including MOST_ACTIVE, TOP_PERC_GAIN, HOT_BY_VOLUME, HOT_BY_PRICE etc. The scan can be limited to security type and trading location, as well as to a variety of criteria on the security attributes (price, volume, maturity date, market cap, Moody/S&P rating, coupon rate etc.).39 This is an extensive list, which covers much of the demand.

Note: IB scanners are only limited to the predefined scanner types and options above. We cannot define a generic scan criteria based on attributes that are not on the predefined list. In such cases, we would need to use other means to scan the markets. For example, consider using finviz.com, which provides a very detailed online scanner (free for online browsing; premium service to download CSV data file).40 Many additional screeners are available online.41

To use IB’s market scanner in IB-Matlab, set the Action parameter to 'Scanner', and either use the default criteria values (see table below) or override them. For example, to return the current most active stock in NASDAQ (the default criteria):

>> dataStruct = IBMatlab('action','scanner')
dataStruct =
EventName: 'scannerData'
reqId: 349661732
rank: 0
contractDetails: [1x1 struct]
distance: []
benchmark: []
projection: []
legsStr: []
symbol: 'QQQ'
localSymbol: 'QQQ'
contract: [1x1 struct]

Additional information about the returned security (QQQ in this case) can be seen in the contract and contractDetails fields of the returned data structure.

By default, IB-Matlab only returns the top single security matching the scan criteria. We can change this using the NumberOfRows parameter. IB limits the amount of returned data, so it is quite possible that we will receive fewer results than requested:

>> dataStruct = IBMatlab('Action','scanner', 'NumberOfRows',100)
dataStruct =
1x23 struct array with fields:
EventName
reqId
rank
contractDetails
distance
benchmark
projection
legsStr
symbol
localSymbol
contract

>> dataStruct(end)
ans =
EventName: 'scannerData'
reqId: 349662602
rank: 22
contractDetails: [1x1 struct]
distance: []
benchmark: []
projection: []
legsStr: []
symbol: 'AMZN'
localSymbol: 'AMZN'
contract: [1x1 struct]

The most important parameters for scanner requests are Instrument (default value: 'STK'), LocationCode (default value: ‘STK.NASDAQ’) and ScanCode (default value: ‘MOST_ACTIVE’). Additional parameters are listed at the end of this section.

Note: You will only receive scan data that corresponds to your paid IB market subscription. For example, if you are only subscribed to NASDAQ data but not to NYSE or other exchanges, then you will only receive NASDAQ scan results, regardless of your specified LocationCode. In other words, scanner parameters only narrow down (filter) scan results; they cannot be used to provide unsubscribed data.

IB’s documentation about the possible scanner parameter values is quite limited and incomplete. If you are unsure of the parameter values that are required for a specific scan, contact IB’s customer service and ask them for the specific set of “API ScannerSubscription parameters” that are required for your requested scan.

One feature that could help in determining the possible parameter values is an XML document that the IB server provides which describes the possible combinations. We can retrieve this document by specifying Type='parameters' in IB-Matlab:

>> xmlStr = IBMatlab('Action','scanner', 'Type','parameters')
xmlStr =
<?xml version="1.0" encoding="UTF-8"?>
<ScanParameterResponse>
<InstrumentList varName="instrumentList">
<Instrument>
<name>US Stocks</name>
<type>STK</type>

<filters>PRICE,PRICE_USD,VOLUME,VOLUME_USD,AVGVOLUME,AVGVOLUME_USD,HALTED,...,FIRSTTRADEDATE,HASOPTIONS</filters>

<group>STK.GLOBAL</group>
<shortName>US</shortName>
</Instrument>
<Instrument>
<name>US Futures</name>
<type>FUT.US</type>
<secType>FUT</secType>

<filters>PRICE,PRICE_USD,VOLUME,VOLUME_USD,PRODCAT,LEADFUT,CHANGEPERC,CHANGEOPENPERC,OPENGAPPERC,PRICERANGE,TRADERATE</filters>

<group>FUT.GLOBAL</group>
<shortName>US</shortName>
</Instrument>
... (~20K additional lines!)

This XML string is quite long (~1MB, ~20K lines). We can store it in a *.xml file and open this file in an XML reader (for example, a browser). Alternatively, we can ask IB-Matlab to parse this XML and present us with a more manageable Matlab struct that we can then process in Matlab. This is done by setting ParametersType='struct'. Note that this XML parsing could take a long time (a full minute or even longer):

>> params = IBMatlab('Action','scanner', 'Type','parameters', ...
'ParametersType','struct') %may take a long time!
params =
Name: 'ScanParameterResponse'
InstrumentList: [1x1 struct]
LocationTree: [1x1 struct]
ScanTypeList: [1x2 struct]
SettingList: [1x1 struct]
FilterList: [1x2 struct]
ScannerLayoutList: [1x1 struct]
InstrumentGroupList: [1x1 struct]
SimilarProductsDefaults: [1x1 struct]
MainScreenDefaultTickers: [1x1 struct]
ColumnSets: [1x1 struct]
SidecarScannerDefaults: [1x1 struct]

>> params.InstrumentList
ans =
Name: 'InstrumentList'
Attributes: [1x1 struct]
Instrument: [1x23 struct]

>> params.InstrumentList.Instrument(2)
ans =
Name: 'Instrument'
name: 'US Futures'
type: 'FUT.US'
filters: [1x108 char]
group: 'FUT.GLOBAL'
shortName: 'US'
secType: 'FUT'
nscanSecType: []
permSecType: []

>> params.InstrumentList.Instrument(2).filters
ans =
PRICE,PRICE_USD,VOLUME,VOLUME_USD,PRODCAT,LEADFUT,CHANGEPERC,CHANGEOPENPERC,OPENGAPPERC,PRICERANGE,TRADERATE

The parameters that affect scanner data retrieval closely mirror those expected by IB’s Java API:42

Parameter

Data type

Default

Description

Type

string

'Scan'

One of:

'Scan' scanner data (default)

'Parameters' – possible scanner param values

ParametersType

string

'XML'

One of:

'XML' (default)

'struct' – Matlab struct

AbovePrice

number

0.0

Filter out contracts with a price lower than this value

AboveVolume

integer

0

Filter out contracts with a volume lower than this value

AverageOptionVolumeAbove

integer

0

Filter out contracts with avg. options volume lower than this

BelowPrice

number

Inf

Filter out contracts with a price higher than this value

CouponRateAbove

number

0.0

Filter out contracts with a coupon rate lower than this

CouponRateBelow

number

Inf

Filter out contracts with a coupon rate higher than this

ExcludeConvertible

string

''
(empty string)

Filter out convertible bonds

Instrument

string

'STK'

Defines the instrument type

LocationCode

string

'STK.NASDAQ'

Defines the scanned markets

MarketCapAbove

number

0.0

Filter out contracts with a market cap lower than this

MarketCapBelow

number

Inf

Filter out contracts with a market cap above this value

MaturityDateAbove

string

''
(empty string)

Filter out contracts with a maturity date earlier than this

MaturityDateBelow

string

''
(empty string)

Filter out contracts with a maturity date later than this

MoodyRatingAbove

string

''
(empty string)

Filter out contracts with a Moody rating below this value

MoodyRatingBelow

string

''
(empty string)

Filter out contracts with a Moody rating above this value

NumberOfRows

integer

1

The maximal number of rows of data to return for the query

ScanCode

string

'MOST_ACTIVE'

A long list... - see the API doc43

ScannerSettingPairs

string

''
(empty string)

For example, a pairing of 'Annual, true' used on the “Top Option Implied Vol % Gainers” scan returns annualized volatilities

SPRatingAbove

string

''
(empty string)

Filter out contracts with an S&P rating below this value

SPRatingBelow

string

''
(empty string)

Filter out contracts with an S&P rating above this value

StockTypeFilter

string

'ALL'

One of:

'ALL' (default)

'CORP' – Corporation

'ADR' American Depositary
Receipt

'ETF' Exchange Traded Fund

'REIT' – Real Estate
Investment Trust

'CEF' – Closed Ended Fund

5.4 Contract details and options chain

Contract details for any security can be retrieved using the parameters Action='query' with Type='contract'. If the security is well-defined, then IB-Matlab will return a data struct containing various details on the contract, which is basically a merge of the contract and contractDetails structs that are returned by the single-quote query (§5.1). For example:

>> dataStruct = IBMatlab('action','contract', 'symbol','IBM')
dataStruct =
conId: 8314
symbol: 'IBM'
secType: 'STK'
expiry: []
strike: 0
right: []
multiplier: []
exchange: 'SMART'
currency: 'USD'
localSymbol: 'IBM'
primaryExch: 'NYSE'
includeExpired: 0
secIdType: []
secId: []
comboLegsDescrip: []
comboLegs: []
underComp: []
summary: [1x1 struct]
marketName: 'IBM'
tradingClass: 'IBM'
minTick: 0.01
priceMagnifier: 1
orderTypes: 'ACTIVETIM,ADJUST,ALERT,ALGO,ALLOC,AON, AVGCOST,BASKET,COND,CONDORDER,DARKPOLL,DAY,DEACT,DEACTDIS,DEACTEOD,DIS,GAT,GTC,GTD,GTT,HID,IBDARK,ICE,IMB,IOC,LIT,LMT,LOC,MIT,MKT,MOC,MTL,...'
validExchanges: 'SMART,NYSE,CBOE,ISE,CHX,ARCA,ISLAND,VWAP, IBSX,DRCTEDGE,BEX,BATS,EDGEA,LAVA,CSFBALGO,JEFFALGO,BYX,IEX,TPLUS2,PSX'
underConId: 0
longName: 'INTL BUSINESS MACHINES CORP'
contractMonth: []
industry: 'Technology'
category: 'Computers'
subcategory: 'Computer Services'
timeZoneId: 'EST'
tradingHours: '20150325:0400-2000;20150326:0400-2000'
liquidHours: '20150325:0930-1600;20150326:0930-1600'
...
(
many additional data fields, some of them empty)

Note that the data is returned even outside market trading hours, unlike the single-quote query that typically returns empty pricing data outside trading hours. Also note that no pricing information is returned, only the contract information.

Retrieving the options chain of a security uses the same mechanism. In this case, when SecType='OPT' (stock options) or 'FOP' (futures options), multiple option contracts are returned in an array of data structs similar to the above, for those options that match our query. For example, to retrieve all futures options for the 10-year US Treasury Note (ZN), which have a contract month of December 2015:

>> dataStruct = IBMatlab('action','contract', 'symbol','ZN', ...
'secType','FOP', 'expiry','201512', ...
'exchange','ecbot'
)
dataStruct =
224x1 struct array with fields:
conId
symbol
...

>> dataStruct(1)
ans =
conId: 168043528
symbol: 'ZN'
secType: 'FOP'
expiry: '20151120'
strike: 128.5
right: 'P'
multiplier: '1000'
exchange: 'ECBOT'
currency: 'USD'
localSymbol: 'P OZN DEC 15 12850'
...

>> dataStruct(2)
ans =
conId: 168043533
symbol: 'ZN'
secType: 'FOP'
expiry: '20151120'
strike: 131
right: 'P'
multiplier: '1000'
exchange: 'ECBOT'
currency: 'USD'
localSymbol: 'P OZN DEC 15 13100'
...

Note: we need to specify the SecType and Exchange for options, since IB cannot find the security using the default parameter values ('STK' and 'SMART', respectively):44

>> dataStruct = IBMatlab('action','contract', 'symbol','ZN', ...
'secType','FOP', 'expiry','201512')

[API.msg2] No security definition has been found for the request {494601749, 200}

dataStruct =
[]

Also note that the reported expiry field is the last trading date for the contract (in this case, November 20, 2015), not the contract’s actual expiration date (Dec’ 2015).

We can limit the results by specifying a combination of the Expiry, Strike, Multiplier and/or Right parameters. For example, to limit ZN options only to Calls:

>> dataStruct = IBMatlab('action','contract', 'symbol','ZN', ...
'secType','FOP', 'expiry','201512', ...
'exchange','ecbot'
, 'right','Call')
dataStruct =
112x1 struct array with fields:
conId
symbol
secType
...

Similarly, to get all options (Calls & Puts), in all expiry dates, that have Strike=$130:

>> dataStruct = IBMatlab('action','contract', 'symbol','ZN', ...
'secType','FOP', 'strike',130, ...
'exchange','ecbot'
)
dataStruct =
22x1 struct array with fields:
conId
symbol
secType
...

To retrieve the full options-chain without any filtering, remove the limiting parameters. Note that it might take several long seconds for all the contracts to be sent from IB:

>> dataStruct = IBMatlab('action','contract', 'symbol','IBM', ...
'secType','OPT', 'exchange','CBOE2')
dataStruct =
900x1 struct array with fields:
conId
symbol
secType
...

The options are not ordered, so do not rely on their order in the returned dataStruct.

A different way of retrieving the options chain is explained in §11.4 below, using IB event callabacks. The difference between the mechanism here and in §11.4 is that the the command here is synchronous (i.e., Matlab waits for all the data to be received from IB before returning a unified dataStruct). In §11.4, the contracts data are received and processed in parallel (asynchronously) to the main Matlab program.

warningNote: The options chain query only returns the list of contract names/details, without any market data. We cannot receive the entire list of option prices in a single command; each contract requires a separate IB-Matlab query (§5.1) to get its market data. To get the latest market quotes for these contracts, loop over the returned options chain contracts and query their market data one by one, in separate IB-Matlab queries.

5.5 Fundamental data

IB’s fundamental data functionality returns Reuters global fundamental data for stocks. You must have a subscription to Reuters Fundamental set up in your IB Account Management before you can receive most of the reports. The following data reports are available using this functionality:45

ReportSnapshot (company overview)

ReportsOwnership (company ownership; note: may be large in size)

ReportRatios (financial ratios; note: may not be available in some cases)

ReportsFinSummary (financial summary)

ReportsFinStatements (financial statements)

RESC (analyst estimates)

CalendarReport (company calendar)

Ratios (fundamental ratios – different from other reports: see below)

Note: Fundamental data is only available for stocks, not for any other security type.

To use IB’s market scanner in IB-Matlab, set the Action parameter to 'Fundamental', and the Type parameter to one of the report names above, and specify the requested contract information (Symbol, Exchange, Currency etc.). For example:

>> xmlStr = IBMatlab('Action','fundamental', 'Type','ReportSnapshot',...
'Symbol','IBM')
xmlStr =
<?xml version="1.0" encoding="UTF-8"?>
<ReportSnapshot Major="1" Minor="0" Revision="1">
<CoIDs>
<CoID Type="RepNo">4741N</CoID>
<CoID Type="CompanyName">International Business Machines Corp.</CoID>
<CoID Type="IRSNo">130871985</CoID>
<CoID Type="CIKNo">0000051143</CoID>
</CoIDs>
<Issues>
<Issue ID="1" Type="C" Desc="Common Stock" Order="1">
<IssueID Type="Name">Ordinary Shares</IssueID>
<IssueID Type="Ticker">IBM</IssueID>
<IssueID Type="CUSIP">459200101</IssueID>
<IssueID Type="ISIN">US4592001014</IssueID>
<IssueID Type="RIC">IBM</IssueID>
<IssueID Type="SEDOL">2005973</IssueID>
<IssueID Type="DisplayRIC">IBM.N</IssueID>
<IssueID Type="InstrumentPI">261483</IssueID>
<IssueID Type="QuotePI">1090370</IssueID>
<Exchange Code="NYSE" Country="USA">New York Stock Exchange</Exchange>
<MostRecentSplit Date="1999-05-27">2.0</MostRecentSplit>
</Issue>
<Issue ID="2" Type="P" Desc="Preferred Stock" Order="1">
<IssueID Type="Name">Preference Shares Series A</IssueID>
<IssueID Type="Ticker">IBMPP</IssueID>
<IssueID Type="CUSIP">459200200</IssueID>
<IssueID Type="ISIN">US4592002004</IssueID>
<IssueID Type="RIC">IBMPP.PK^C06</IssueID>
<IssueID Type="InstrumentPI">1883112</IssueID>
<IssueID Type="QuotePI">25545447</IssueID>
<Exchange Code="OTC" Country="USA">Over The Counter</Exchange>
</Issue>
</Issues>
<CoGeneralInfo>
<CoStatus Code="1">Active</CoStatus>
<CoType Code="EQU">Equity Issue</CoType>
<LastModified>2016-06-29</LastModified>
<LatestAvailableAnnual>2015-12-31</LatestAvailableAnnual>
<LatestAvailableInterim>2016-03-31</LatestAvailableInterim>
<Employees LastUpdated="2015-12-31">377757</Employees>
<SharesOut Date="2016-03-31" TotalFloat="959386999.0">959961852.0</SharesOut>
<CommonShareholders Date="2015-12-31">444582</CommonShareholders>
<ReportingCurrency Code="USD">U.S. Dollars</ReportingCurrency>
<MostRecentExchange Date="2016-07-07">1.0</MostRecentExchange>
</CoGeneralInfo>
<TextInfo>
<Text Type="Business Summary" lastModified="2016-04-21T03:03:49">International Business Machines Corporation (IBM) is a technology company...
...

The fundamental data is returned as an XML string by default, as shown above. This XML string can be quite long, depending on the requested report and security. We can store this string in a *.xml file and open this file in an XML reader (for example, a browser). Alternatively, we can ask IB-Matlab to parse this XML and return a simple Matlab struct by setting ParametersType='struct'. Note: this XML parsing could take a long time (a full minute or even longer in some cases, such as long RESC reports):46

>> data = IBMatlab('Action','fundamental', 'Type','ReportSnapshot',...
'Symbol','IBM', 'ParametersType','struct')
data =
Name: 'ReportSnapshot'
Attributes: [1×1 struct]
CoIDs: [1×1 struct]
Issues: [1×1 struct]
CoGeneralInfo: [1×1 struct]
TextInfo: [1×1 struct]
contactInfo: [1×1 struct]
webLinks: [1×1 struct]
peerInfo: [1×1 struct]
officers: [1×1 struct]
Ratios: [1×1 struct]
ForecastData: [1×1 struct]

>> data.Issues.Issue(2).IssueID(4)
ans =
Name: 'IssueID'
Attributes: [1×1 struct]
Data: 'US4592002004'

>> data.Issues.Issue(2).IssueID(4).Attributes
ans =
Type: 'ISIN'

In some cases, some fields are not reported for some contracts. For example, in the Issues section above, SEDOL and DisplayRIC values are only reported for IBM, not for IBMPP.

In some cases, some of the fundamental reports may not be available for a certain security for some reason, while other reports for the same security may be available:

>> data = IBMatlab('Action','fundamental', 'Symbol','IBM', ...
'Type','ReportRatios')
[API.msg2] We are sorry, but fundamentals data for the security specified is not available. failed to fetch {636789740, 430}

data =
[]

>> data = IBMatlab('Action','fundamental', 'Symbol','IBM', ...
'Type','CalendarReport')
[API.msg2] We are sorry, but fundamentals data for the security specified is not available. Not allowed {636789744, 430}

data =
[]

The fundamental ratios report (Type='Ratios') differs from other reports: it requires no Reuters subscription; it is always returned in struct (not XML) format regardless of the ParametersType; and it is only reported when the security trades. The reason for this is that this report uses IB’s internal mechanism for reporting fundamental ratios of streaming quotes (see §7.1 below) with a GenericTickList of '258',47 rather than Reuters data. For a description of the various data fields, refer to IB’s documentation.48

>> data=IBMatlab('Action','fundamental','Symbol','IBM','Type','Ratios')
data =
TTMNPMGN: 16.03988
NLOW: 116.901
REVTRENDGR: -3.92708
TTMEPSXCLX: 13.27684
QTANBVPS: -24.7614
TTMPRCFPS: 17.78968
TTMGROSMGN: 49.38146
TTMCFSHR: 15.23175
QCURRATIO: 1.37385
PRICE2BK: 9.93472
MKTCAP: 148275.7
...
(and so on: dozens of different fields)

The parameters that affect fundamental data retrieval are as follows (for the contract properties, see §3.2 above):

Parameter

Data type

Default

Description

Type

string

'Ratios'

One of:

'Ratios' (default) – fundamental ratios

'ReportSnapshot' – company overview

'ReportRatios' – financial ratios

'ReportsOwnership' – company owners

'ReportsFinSummary' –
financial summary

'ReportsFinStatements' –
financial statements

'RESC' – analyst estimates

'CalendarReport' – company calendar

ParametersType

string

'XML'

One of:

'XML' (default)

'struct' – Matlab struct


29 http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Date.html (note the units [seconds/milliseconds] – this can be tricky…)

30 http://www.mathworks.com/support/solutions/en/data/1-9B9H2S/

31 IB only sends live/historic data to a single computer, so retrieving such data requires IB-Matlab to be connected to the TWS that gets the live data, not to another TWS on a different computer. So if you connect TWS to your live account on computer A, and another TWS to your paper-trading account on computer B, then IB-Matlab can retrieve data only via computer A.

32 The error messages can be suppressed using the MsgDisplayLevel parameter, and can also be trapped and processed using the CallbackMessage parameter – see §14.1 below for details

33 https://reddit.com/r/interactivebrokers/comments/14217u0/using_live_data_in_paper_trading_after_paying_for (despite the message that the settings change go into effect “in 24 working hours”, in practice this often happens within 10-15 minutes).

34 https://interactivebrokers.github.io/tws-api/interfaceIBApi_1_1EWrapper.html#aaabfb00bd637027793c34387690b58d2

35 https://interactivebrokers.github.io/tws-api/option_computations.html

36 https://www.mathworks.com/matlabcentral/fileexchange/69544-calcgreeks-calculate-option-greeks-european-black-scholes

37 The default value of NumberOfRows (=1) in indicates a single-quote query rather than a market-depth query.

38 http://interactivebrokers.com/en/software/webtrader/webtrader.htm#webtrader/marketscanners/about market scanners.htm

39 http://interactivebrokers.github.io/tws-api/classIBApi_1_1ScannerSubscription.html

40 http://finviz.com/screener.ashx

41 For example: http://nasdaq.com/reference/stock-screener.aspx, http://caps.fool.com/Screener.aspx, http://finance.google.com/finance#stockscreener, http://screener.finance.yahoo.com/stocks.html, http://stockscreener.us.reuters.com/Stock/US/index, http://marketwatch.com/tools/stockresearch/screener

42 https://interactivebrokers.github.io/tws-api/classIBApi_1_1ScannerSubscription.html

43 https://www.interactivebrokers.com/en/software/webtrader/webtrader/marketscanners/about%20market%20scanners.htm. The latest version of this webpage only contains a description of the scanners, not their scan codes (e.g. “Most active” instead of MOST_ACTIVE). To get the scan codes, see the Reference chapter, “Available Market Scanners” section (around p. 566) in IB’s downloadable API documentation: http://institutions.interactivebrokers.com/download/newMark/PDFs/APIprintable.pdf. Alternatively, ask IB support to tell you the specific scan codes for your requested market scanners. An unofficial list of scan codes is provided in https://groups.io/g/insync/topic/22402297#1650 ; it is not known whether this list is accurate or complete.

44 Exchange can be omitted (or set to 'SMART') for stock options but not for futures options; SecType must be set in either case.

45 https://interactivebrokers.github.io/tws-api/fundamentals.html

46 Note: the format of the returned struct was simplified and improved starting in IBMatlab version 2.10 (2019-12-31)

47 http://interactivebrokers.github.io/tws-api/tick_types.html

48 http://interactivebrokers.github.io/tws-api/fundamental_ratios_tags.html