Here are representative usage examples of IB-Matlab [1]. Many more examples and detailed information are available in the IB-Matlab User Guide [2]. Please email me [3] if you have any questions.
The following examples are listed below:
- Buy a security [4]
- Sell a security [5]
- Get portfolio data [6]
- Get account data [7]
- Get market data (snapshot) for a security [8]
- Get historic/intra-day data [9]
- Get streaming quotes data [10]
- Get realtime bars data [11]
- Get detailed contract information [12]
- Get options-chain information [13]
- Get scanner filter data [14]
- Access, modify and cancel open orders [15]
[16]
- Get executions data [17]
- Specify event callback – ExecDetails [18]
- Specify event callback – TickGeneric [19]
- Using the underlying Java connection object [20]
1) Buy a security
Note the two alternative manners in which the parameters can be specified (you can use whichever is more convenient to you):
% Matlab struct alternative:
paramsStruct = [];
paramsStruct.action = 'buy';
paramsStruct.symbol = 'GOOG';
paramsStruct.quantity = 100;
paramsStruct.limitPrice = 600;
orderId = IBMatlab(paramsStruct);
% Name/value pairs alternative:
orderId = IBMatlab('action','buy', 'symbol','GOOG', 'quantity',100, 'limitPrice',600);
2) Sell a security
orderId = IBMatlab('action','sell', 'symbol','GOOG', 'quantity',100, 'limitPrice',600);
3) Get portfolio data
>> data = IBMatlab('action','portfolio')
data =
1x12 struct array with fields:
symbol
localSymbol
exchange
secType
currency
right
expiry
strike
position
marketValue
marketPrice
averageCost
contract
>> data(1)
ans =
symbol: 'AMZN'
localSymbol: 'AMZN'
exchange: 'NASDAQ'
secType: 'STK'
currency: 'USD'
right: '0'
expiry: ''
strike: 0
position: 9200
marketValue: 1715800
marketPrice: 186.5
averageCost: 169.03183335
contract: [1x1 struct]
4) Get account data
>> data = IBMatlab('action','account')
data =
AccountCode: 'DU12345'
currency: []
accountName: 'DU12345'
AccountReady: 'true'
AccountType: 'INDIVIDUAL'
AccruedCash: -456.4
AccruedDividend: 0
AvailableFunds: 261700.68
Billable: 0
BuyingPower: 779656.96
CashBalance: -825400.37
CorporateBondValue: 0
Currency: 'USD'
Cushion: 0.361508
DayTradesRemaining: -1
DayTradesRemainingT_plus_1: -1
DayTradesRemainingT_plus_2: -1
DayTradesRemainingT_plus_3: -1
DayTradesRemainingT_plus_4: -1
EquityWithLoanValue: 723913.41
ExcessLiquidity: 261700.68
ExchangeRate: 1
FullAvailableFunds: 261700.68
FullExcessLiquidity: 261700.68
FullInitMarginReq: 462212.73
FullMaintMarginReq: 462212.73
FundValue: 0
FutureOptionValue: 0
FuturesPNL: 0
FxCashBalance: 0
GrossPositionValue: 1540709.11
IndianStockHaircut: 0
InitMarginReq: 462212.73
Leverage: 2.13
LookAheadAvailableFunds: 261700.68
LookAheadExcessLiquidity: 261700.68
LookAheadInitMarginReq: 462212.73
LookAheadMaintMarginReq: 462212.73
LookAheadNextChange: 0
MaintMarginReq: 462212.73
MoneyMarketFundValue: 0
MutualFundValue: 0
NetDividend: 0
NetLiquidation: 723913.41
NetLiquidationByCurrency: 714852.34
OptionMarketValue: 0
PASharesValue: 0
PNL: 'true'
PreviousDayEquityWithLoanValue: 696109.82
RealizedPnL: 0
RegTEquity: 723913.41
RegTMargin: 770354.56
SMA: 78512.41
StockMarketValue: 1540709.11
TBillValue: 0
TBondValue: 0
TotalCashBalance: -825400.37
TotalCashValue: -816339.3
TradingType: 'STKNOPT'
UnalteredInitMarginReq: -1
UnalteredMaintMarginReq: -1
UnrealizedPnL: -40731.17
WarrantValue: 0
WhatIfPMEnabled: 'true'
5) Get market data (snapshot) for a security
>> data = IBMatlab('action','query', 'symbol','GOOG')
data =
reqId: 22209874
reqTime: '02-Dec-2010 00:47:23'
dataTime: '02-Dec-2010 00:47:23'
dataTimestamp: 734474.032914491
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
contractDetails: [1x1 struct]
6) Get historic/intra-day data
Supported Historical data parameters (explanations here [21]): EndDateTime, DurationValue, DurationUnits, BarSize, WhatToShow, UseRTH, FormatDate. Note IB’s pace limitations [22] for historical data.
>> data = IBMatlab('action','history', 'symbol','IBM', 'barSize','1 hour', 'useRTH',1)
data =
dateNum: [1x7 double]
dateTime: {1x7 cell}
open: [161.08 160.95 161.66 161.17 161.57 161.75 162.07]
high: [161.35 161.65 161.70 161.60 161.98 162.09 162.34]
low: [160.86 160.89 161.00 161.13 161.53 161.61 161.89]
close: [160.93 161.65 161.18 161.60 161.74 162.07 162.29]
volume: [5384 6332 4580 2963 4728 4465 10173]
count: [2776 4387 2990 1921 2949 2981 6187]
WAP: [161.07 161.25 161.35 161.31 161.79 161.92 162.14]
hasGaps: [0 0 0 0 0 0 0]
>> data.dateTime
ans =
'20110225 16:30:00' '20110225 17:00:00' '20110225 18:00:00' '20110225 19:00:00'
'20110225 20:00:00' '20110225 21:00:00' '20110225 22:00:00'
7) Get streaming quotes data
The initial request to send streaming quotes:
>> reqId = IBMatlab('action','query', 'symbol','EUR', 'localsymbol','EUR.USD', ...
'currency','USD', 'sectype','cash', 'exchange','idealpro', 'QuotesNumber',100)
reqId =
147898050
Subsequent requests to retrieve the latest accumulated QuotesBuffer data return a dataStruct that looks like this:
>> dataStruct = IBMatlab('action','query', 'symbol','EUR', 'localsymbol','EUR.USD', 'QuotesNumber',-1)
dataStruct =
reqId: 147898050
symbol: 'EUR'
localSymbol: 'EUR.USD'
isActive: 1
quotesReceived: 6
quotesToReceive: 10
quotesBufferSize: 1
genericTickList: ''
data: [1x1 struct]
contract: [1x1 com.ib.client.Contract]
Note that you only need to specify the Symbol/LocalSymbol and the QuotesNumber in the subsequent requests, all other parameters are unnecessary since the system already knows about this symbol’s parameters from the initial streaming request.
To get the actual data, simply read the data
field of this dataStruct
:
>> dataStruct.data
ans =
dataTimestamp: 734892.764653854
high: 1.3061
highTimestamp: 734892.762143183
low: 1.29545
lowTimestamp: 734892.762143183
close: 1.30155
closeTimestamp: 734892.762143183
bidPrice: 1.2986
bidPriceTimestamp: 734892.764653854
bidSize: 1000000
bidSizeTimestamp: 734892.764653854
askPrice: 1.29865
askPriceTimestamp: 734892.764499421
askSize: 18533000
askSizeTimestamp: 734892.764653854
Note that each data item has an associated timestamp, because different data items are sent separately from the IB server. You can convert the timestamps into human-readable string by using Matlab’s datestr function, as follows:
>> datestr(dataStruct.data.dataTimestamp)
ans =
24-Jan-2012 23:56:32
If instead of using QuotesBufferSize=1 (which is the default value), I had used QuotesBufferSize=4, then I would see not the latest quote but the latest 4 quotes:
>> reqId = IBMatlab('action','query', 'symbol','EUR', 'localsymbol', 'EUR.USD', 'currency','USD', ...
'sectype','cash', 'exchange','idealpro', 'QuotesNumber',10, 'QuotesBufferSize',4);
% now at any following point in time run the following command to get the latest 4 quotes:
>> dataStruct = IBMatlab('action','QUERY', 'localsymbol','EUR.USD', 'QuotesNumber',-1);
>> dataStruct.data
ans =
dataTimestamp: [734892.99760235 734892.99760235 734892.99760235 734892.997756076]
high: 1.3061
highTimestamp: 734892.99740162
low: 1.29545
lowTimestamp: 734892.99740162
bidPrice: [1.3035 1.30355 1.3035 1.30345]
bidPriceTimestamp: [734892.99760235 734892.99760235 734892.99760235 734892.997756076]
bidSize: [3000000 2000000 4000000 4000000]
bidSizeTimestamp: [734892.997743958 734892.997756076 734892.997756076 734892.997756076]
askPrice: [1.3036 1.30355 1.3036 1.30355]
askPriceTimestamp: [734892.997523681 734892.997667824 734892.997667824 734892.997756076]
askSize: [2153000 3153000 2153000 4153000]
askSizeTimestamp: [734892.997756076 734892.997756076 734892.997756076 734892.997756076]
close: 1.30155
closeTimestamp: 734892.997407037
Note that the high, low and close fields are only sent once by the IB server, as we would expect. Only the bid and ask information is sent as a continuous stream of data from the IB server.
8) Get realtime bars data
Real-time 5-sec bars can be retrieved in either streaming or snapshot (latest bars) mode (details [23]). Here is an example to retrieve the latest bar data for IBM:
>> data = IBMatlab('action','realtime', 'symbol','IBM')
data =
dateNum: 735551.017997685
dateTime: {'13-Nov-2013 00:25:55'}
open: 183
high: 183
low: 183
close: 183
volume: 0
WAP: 183
count: 0
And here is a slightly more complex example, with QuotesNumber=3. The data struct that is returned in this case is correspondingly more complex:
>> reqId = IBMatlab('action','realtime', 'symbol','AMZN', 'QuotesNumber',3, 'QuotesBufferSize',10);
reqId =
345327051
% (now wait 15 seconds or more for the 3 bars to be received)
>> dataStruct = IBMatlab('action','realtime', 'symbol','AMZN', 'QuotesNumber',-1);
dataStruct =
reqId: 345327051
symbol: 'AMZN'
localSymbol: ''
isActive: 0
quotesReceived: 3
quotesToReceive: 3
quotesBufferSize: 10
genericTickList: ''
data: [1x1 struct]
contract: [1x1 com.ib.client.Contract]
>> dataStruct.data
ans =
dateNum: [735551.008912037 735551.008969907 735551.009027778]
dateTime: {1x3 cell}
open: [349.97 349.97 349.97]
high: [349.97 349.97 349.97]
low: [349.97 349.97 349.97]
close: [349.97 349.97 349.97]
volume: [0 0 0]
WAP: [349.97 349.97 349.97]
count: [0 0 0]
>> dataStruct.data.dateTime
ans =
'13-Nov-2013 00:12:50' '13-Nov-2013 00:12:55' '13-Nov-2013 00:13:00'
9) Get detailed contract information
Get detailed contract information on a specified security
>> data = IBMatlab('action','contract', 'symbol','IBM')
data =
m_conId: 8314
m_symbol: 'IBM'
m_secType: 'STK'
m_expiry: []
m_strike: 0
m_right: []
m_multiplier: []
m_exchange: 'SMART'
m_currency: 'USD'
m_localSymbol: 'IBM'
m_primaryExch: 'NYSE'
m_includeExpired: 0
m_secIdType: []
m_secId: []
m_comboLegsDescrip: []
m_comboLegs: [0 java.util.Vector]
m_underComp: []
m_summary: [1x1 com.ib.client.Contract]
m_marketName: 'IBM'
m_tradingClass: 'IBM'
m_minTick: 0.01
m_priceMagnifier: 1
m_orderTypes: 'ACTIVETIM,ADJUST,ALERT,ALGO,ALLOC,AON, AVGCOST,BASKET,COND,CONDORDER,DARKPOLL,DAY,DEACT,DEACTDIS,DEACTEOD,DIS,GAT,GTC,GTD,GTT,...'
m_validExchanges: 'SMART,NYSE,CBOE,ISE,CHX,ARCA,ISLAND,VWAP, IBSX,DRCTEDGE,BEX,BATS,EDGEA,LAVA,CSFBALGO,JEFFALGO,BYX,IEX,TPLUS2,PSX'
m_underConId: 0
m_longName: 'INTL BUSINESS MACHINES CORP'
m_contractMonth: []
m_industry: 'Technology'
m_category: 'Computers'
m_subcategory: 'Computer Services'
m_timeZoneId: 'EST'
m_tradingHours: '20150325:0400-2000;20150326:0400-2000'
m_liquidHours: '20150325:0930-1600;20150326:0930-1600'
...
(many additional data fields)
10) Get options-chain information
Retrieve the contract information for all futures options for the 10-year US Treasury Note (ZN) of December 2015:
>> data = IBMatlab('action','contract', 'symbol','ZN', 'secType','FOP', 'expiry','201512', 'exchange','ecbot')
data =
224x1 struct array with fields:
m_conId
m_symbol
m_secType
m_expiry
m_strike
...
>> data(1)
ans =
m_conId: 168043528
m_symbol: 'ZN'
m_secType: 'FOP'
m_expiry: '20151120'
m_strike: 128.5
m_right: 'P'
m_multiplier: '1000'
m_exchange: 'ECBOT'
m_currency: 'USD'
m_localSymbol: 'P OZN DEC 15 12850'
...
>> data(2)
ans =
m_conId: 168043533
m_symbol: 'ZN'
m_secType: 'FOP'
m_expiry: '20151120'
m_strike: 131
m_right: 'P'
m_multiplier: '1000'
m_exchange: 'ECBOT'
m_currency: 'USD'
m_localSymbol: 'P OZN DEC 15 13100'
...
Retrieve the contract information for all options on the IBM stock:
>> data = IBMatlab('action','contract', 'symbol','IBM', 'secType','OPT', 'exchange','CBOE2')
data =
900x1 struct array with fields:
m_conId
m_symbol
m_secType
...
11) Get scanner filter data
Scan for the top-5 most active stocks on NASDAQ (additional details [24]):
>> data = IBMatlab('action','scanner', 'NumberOfRows',5, 'ScanCode','MOST_ACTIVE', 'LocationCode','STK.NASDAQ')
data =
1x5 struct array with fields:
EventName
reqId
rank
contractDetails
distance
benchmark
projection
legsStr
symbol
localSymbol
contract
>> data(end)
ans =
EventName: 'scannerData'
reqId: 349662602
rank: 4
contractDetails: [1x1 struct]
distance: []
benchmark: []
projection: []
legsStr: []
symbol: 'AMZN'
localSymbol: 'AMZN'
contract: [1x1 struct]
12) Access, modify and cancel open orders
To retrieve the list of open IB orders use Action=’query’ and Type=’open’ as follows:
>> data = IBMatlab('action','query', 'type','open')
data =
1x3 struct array with fields:
orderId
contract
order
orderState
status
filled
remaining
avgFillPrice
permId
parentId
lastFillPrice
clientId
whyHeld
message
>> data(1)
ans =
orderId: 154410310
contract: [1x1 struct]
order: [1x1 struct]
orderState: [1x1 struct]
status: 'Submitted'
filled: 0
remaining: 100
avgFillPrice: 0
permId: 989560927
parentId: 0
lastFillPrice: 0
clientId: 8981
whyHeld: []
message: [1x162 char]
We can filter the results based on a specific Symbol and/or OrderId. For example:
% Check whether a specific order ID is still open (active)
>> data = IBMatlab('action','query', 'type','open', 'OrderId',154410310)
data =
orderId: 154410310
contract: [1x1 struct]
order: [1x1 struct]
orderState: [1x1 struct]
(etc.)
% Alternatively - filter using the symbol name (check if there are any open GOOG orders):
>> data = IBMatlab('action','query', 'type','open', 'symbol','goog');
To modify an open order, simply reissue the order using the modified parameters and the order’s ID:
orderId = IBMatlab('action','buy', 'symbol','GOOG', 'quantity',100, 'type','LMT', 'limitPrice',600);
% Let some time pass...
% If the requested order is still open
if ~isempty(IBMatlab('action','query', 'type','open', 'OrderId',orderId))
% Send the trade with modified parameters
IBMatlab('action','buy', 'symbol','GOOG', 'quantity',50, 'type','MKT', 'orderID',orderId);
end
To cancel the trade, simply use Action=’cancel’ with the specific order ID:
% If the requested order is still open
if ~isempty(IBMatlab('action','query', 'type','open', 'OrderId',orderId))
% Cancel the requested order
data = IBMatlab('action','cancel', 'orderID',orderId);
end
13) Get executions data
To retrieve the list of trade executions done in the IB account today, use Action=’query’ and Type=’executions’ as follows:
>> data = IBMatlab('action','query', 'type','executions')
data =
1x3 struct array with fields:
orderId
execId
time
exchange
side
shares
symbol
price
permId
liquidation
cumQty
avgPrice
contract
execution
>> data(2)
ans =
orderId: 154737092
execId: '00018037.4ff2a3b8.01.01'
time: '20120216 18:58:57'
exchange: 'BEX'
side: 'SLD'
shares: 3
symbol: 'GOOG'
price: 605.19
permId: 300757711
liquidation: 0
cumQty: 3
avgPrice: 605.19
contract: [1x1 struct]
execution: [1x1 struct]
We can filter the results based on a specific Symbol and/or OrderId. For example:
>> data = IBMatlab('action','query','type','executions','OrderId',154737092)
data =
orderId: 154737092
execId: '00018037.4ff2a3b8.01.01'
(etc.)
Or alternately (note that symbol filtering is case insensitive):
>> data = IBMatlab('action','query','type','executions','symbol','goog')
14) Specify event callback – ExecDetails
Attach a user callback function to ExecDetails events (that occur upon any order execution – more details here [25]):
orderId = IBMatlab('action','buy', 'symbol','GOOG', 'quantity',1, 'limitPrice',600, ...
'CallbackExecDetails',@IBMatlab_CallbackExecDetails);
where the function IBMatlab_CallbackExecDetails is defined as follows (for example, in a file called IBMatlab_CallbackExecDetails.m):
% See: https://interactivebrokers.github.io/tws-api/interfaceIBApi_1_1EWrapper.html#a09f82de3d0666d13b00b5168e8b9313d
function IBMatlab_CallbackExecDetails(hObject, eventData, varargin)
% Extract the basic event data components
contractData = eventData.contract;
executionData = eventData.execution;
% Example of extracting data from the contract object:
% See: https://interactivebrokers.github.io/tws-api/classIBApi_1_1Contract.html
symbol = char(eventData.contract.m_symbol);
secType = char(eventData.contract.m_secType);
% ... and several other contract data available - see the above webpage
% Example of extracting data from the execution object:
% https://interactivebrokers.github.io/tws-api/classIBApi_1_1Execution.html
orderId = eventData.execution.m_orderId;
execId = char(eventData.execution.m_execId);
time = char(eventData.execution.m_time);
exchange = char(eventData.execution.m_exchange);
side = char(eventData.execution.m_side);
shares = eventData.execution.m_shares;
price = eventData.execution.m_price;
permId = eventData.execution.m_permId;
liquidation = eventData.execution.m_liquidation;
cumQty = eventData.execution.m_cumQty;
avgPrice = eventData.execution.m_avgPrice;
% ... and several other contract data available - see the above webpage
% Now do something useful with all this information...
end % IBMatlab_CallbackExecDetails
15) Specify event callback – TickGeneric
Attach a user callback function to TickGeneric events in order to check whether a security is shortable [26]
Note: according to IB [27], “Generic Tick Tags cannot be specified if you elect to use the Snapshot market data subscription“, and therefore we need to use the streaming-quotes mechanism, so QuotesNumber>1:
orderId = IBMatlab('action','query', 'symbol','GOOG', 'GenericTicklist','236', 'QuotesNumber',2, ...
'CallbackTickGeneric',@IBMatlab_CallbackTickGeneric);
where the function IBMatlab_CallbackTickGeneric is defined as follows:
function IBMatlab_CallbackTickGeneric(hObject,eventData,varargin)
% Only check the shortable tick type =46, according to
% https://interactivebrokers.github.io/tws-api/tick_types.html#shortable
% https://investors.interactivebrokers.com/php/apiguide/interoperability/generictick.htm
if eventData.field == 46 % 46=Shortable
% Get this event's tickerId (=orderId as returned from the original IBMatlab command)
tickerId = eventData.tickerId;
% Get the corresponding shortable value
shortableValue = eventData.generic;
% Now check whether the security is shortable or not
title = sprintf('Shortable info for request %d', tickerId);
if (shortableValue > 2.5) % 3.0
msgbox('There are at least 1000 shares available for a short sale', title, 'help');
elseif (shortableValue > 1.5) % 2.0
msgbox('This contract will be available for short sale if shares can be located', title, 'warn');
elseif (shortableValue > 0.5) % 1.0
msgbox('Not available for short sale', title, 'warn');
else
msgbox(sprintf('Unknown shortable value: %g',shortableValue), title, 'error');
end
end % if shortable tickType
end % IBMatlab_CallbackTickGeneric
16) Use the underlying Java connector to cancel or customize an order
Example 1: Cancel an open order (one example of the many possible actions that can be done via ibConnectionObject):
% Place an order, return the orderId and the Java connector object
[orderId, ibConnectionObject] = IBMatlab('action','buy', ...);
% Cancel the order using the underlying Java connector object:
ibConnectionObject.cancelOrder(orderId);
% Alternatively, we can also cancel the order using the regular Matlab wrapper:
IBMatlab('action','cancel', 'orderId',orderId);
Example 2: Holding and modifying a Buy/Sell trade order before submitting:
% Prepare the order
[orderId, ibConnectionObject, contract, order] = IBMatlab('action','sell', 'Hold',1, ...);
% Modify some contract and/or order parameters
contract.m_secIdType = 'ISIN';
contract.m_secId = 'US0378331005'; % =Apple Inc.
order.m_clearingIntent = 'Away';
order.m_settlingFirm = 'CSBLO';
order.m_allOrNone = true;
% Send the modified order to IB
ibConnectionObject.placeOrder(orderId, contract, order);
No other solution provides this rich set of features – not even close.
Don’t take our word for it – request a fully-functional free trial version, and check for yourself! You will not be disappointed.
Trial request
To use the IB-Matlab trial, you only need the basic Matlab, no toolbox is required. You can be up and running within minutes. We are confident that you will love the product, so we encourage you to test it:
You will receive the trial installation instructions to your specified email within 24 hours. If you do not get an email within 24 hours, then please check your email’s spam folder, or send a direct email to altmany at gmail.com