14 Handling errors, problems, and IB messages

14.1 Messages sent from IB

IB constantly sends messages of various severity levels to IB-Matlab. These range from the mundane (e.g., “Market data farm connection is OK: cashfarm {-1, 2104}”) to the problematic (e.g., “No security definition has been found for the request {153745243, 200}”). All these messages arrive as regular events of type error, just like all the other information sent from IB (see §11 above for details).

IB-Matlab automatically infers whether an IB message is an error, warning or informational message. Errors are sent to the standard error stream (stderr) and displayed in red in the Matlab console.152 Other messages are sent to the standard output (stdout) and displayed in regular black text on the Matlab console.

Users can control the display of IB messages in the Matlab console using the MsgDisplayLevel parameter, which accepts the following possible values:

-2 – most verbose output, including all the information contained in all incoming IB events (not just messages)

-1 – display all messages as well as basic events information

0 (default) – display all messages, but not other events

1 – only display error messages, not informational messages

2 – do not display any automated output onscreen (not even errors)

The information contained in the message events varies depending on message type.153 The events have one of the following data sets:

Contents

Description

Displayed as

Displayed onscreen if

Message

general error messages

[API.msg1]

MsgDisplayLevel < 2

message, id (data1), code (data2)

errors and informational messages

[API.msg2]

MsgDisplayLevel < 1 or: data2<2000, data2>3000

message,
exception object

severe IB errors (exceptions)

[API.msg3]

MsgDisplayLevel < 2

Note: no IB message (regardless of data1, data2) is displayed if MsgDisplayLevel>=2

A typical example of such messages is the following:

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

Most IB messages are of type msg2 (as in this example) and contain two numeric fields: data1 contains message-specific ID, which typically corresponds to the order ID or request ID that caused the problem; data2 contains the message code (type). In the example above, type='msg2', id (data1) =153745243, and code (data2) =200. This tells us that this error (code=200) occurred for request ID 153745227, so we can correlate between the error and our request. Some messages do not have an associated message-specific ID; in such cases id (data1) = -1. For example, “Market data farm connection is OK:cashfarm” (code 2104) is a general message about IB connectivity that is not related to any specific user request or order, so its id (data1) field is -1.

The full list of message codes (data2) for API.msg2 (which is the most common message type) is listed online.154 It is sub-divided into three groups:

Error messages (data2 codes between 100-999 or >10000)

System messages (data2 codes between 1000-1999)

Warning messages (data2 codes between 2000-2999)

The most recent message from IB can be queried programmatically, as follows: IBMatlab('lastIBError') returns the latest error message, which is a subset of all messages; IBMatlab('lastIBMessage') returns the latest message of any type (error, system or warning). The lastIBMessage will typically have a more recent timestamp than lastIBError, except if the latest IB message was an error (in this case both queries will return the same result):

>> IBMatlab('lastIBError')
ans =
dateNum: 738475.78192559
dateTime: '2021-11-15 18:45:58.371'
msg: 'Historical Market Data Service error message:Trading TWS session is connected from a different IP address'
type: 'msg2'
id: 1222731061
code: 162

>> IBMatlab('lastIBMessage')
ans =
dateNum: 738476.496878067
dateTime: '2021-11-16 11:55:30.265'
msg: 'Market data farm connection is OK:usfarm'
type: 'msg2'
id: -1
code: 2104

We can use this feature to handle IB errors within our program logic, for example:

data = IBMatlab('action','query', ...);
lastError = IBMatlab(
'lastIBError');
ONE_SECOND = 1 / 24/ 3600;
if now – lastError.dateNum < ONE_SECOND
msgbox(lastError.msg,
'IB error', 'error');
end

In order to ensure that we refer to a recent IB error due to the last request, rather than to a very old message, we can check the time that passed since the error timestamp (as in the code snippet above, which checked for an error message in the past second). Alternatively, add an optional 'clear' parameter to the IBMatlab('lastIBError') or IBMatlab('lastIBMessage') call, to clear the last error/message before sending our main query to IB. This ensures that any error/message that arrives after then can indeed be attributed to our main query:

IBMatlab('lastIBError', 'clear'); %clear the lastError
data = IBMatlab(
'action','query', ...); %send the main data query
lastError = IBMatlab(
'lastIBError'); %lastError due to the data query
if ~isempty(lastError)
msgbox(lastError.msg,
'IB error', 'error');
end

We can trap and process the message events just like any other IB events, using Matlab callbacks. Note that the parameter for message callback is CallbackMessage, although for some unknown reason the IB event is called error:

data = IBMatlab('action','query', ..., 'MsgDisplayLevel',-1, ...
'CallbackMessage',@IBMatlab_CallbackMessage);

In this example, all IB messages will be passed through IBMatlab_CallbackMessage, which is a Matlab function that we should create (it is not part of IBMatlab). Here is a sample implementation of such a message processing function that you can adapt:155

% Processing function for IB messages
function IBMatlab_CallbackMessage(ibConnector, eventData)

% Process messages based on their code:
if strcmp(eventData.type, 'msg2') % most common message: API.msg2
switch eventData.data2 % data2 contains the message code
case 100 % Max rate of message has been exceeded
msgbox(eventData.message,
'IB error');
case 200 % Ambiguous/non-existing contract specification
disp(
'Ambiguous (or invalid) contract specs')
...
otherwise % Any other message type
end
else
% msg1 or msg3
...
end

end

IB’s error messages are often cryptic. It is sometimes difficult to understand the problem’s root cause.156 Several mechanisms can help us with this detective work:

We can set IBMatlab’s MsgDisplayLevel parameter to -1 or -2 (see above).

We can set IBMatlab’s Debug parameter to 1 (default=0). This will display in the Matlab Command Window a long list of parameters used by IBMatlab to prepare the request for IB. Check this list for any default values that should actually be set to some non-default values.

We can set the API logging level to “Detailed” in the TWS/Gateway API configuration window.157 By default it is set to “Error”, and can be changed at any time. This affects the amount of information (verbosity) logged in IB’s log files that are located in IB’s installation folder (e.g., C:\Jts).158 The log files are separated by the day of week, and have names such as: ibgateway.Thu.log, log.Wed.txt, api.8981.Tue.log. These refer, respectively, to the main Gateway log, the main TWS log, and a log of requests/responses for a specific ClientID. The api.*.log file reflects the contents of the corresponding tab in the IB Gateway application (see screenshot below159). Note that setting the logging level to “Detail” has a performance overhead and should be avoided except when debugging a specific issue. In other cases, you can set the level to “Information”, “Warning” or back to the default “Error”.

Gateway ClientID

14.2 Ambiguous/invalid security errors

Much of IBMatlab’s functionality relates to a specific security that you choose to query or trade. IB is not very forgiving if you do not provide the exact security specifications (a.k.a. contract) that it expects: in such a situation, data is not returned, and an often-cryptic error message is displayed in Matlab’s Command Window:160

>> data = IBMatlab('action','query', 'symbol','EUR')
[API.msg2] No security definition has been found for the request {153745243,200}
data =
reqId: 153745243
reqTime: '13-Feb-2012 21:25:42'
dataTime: ''
dataTimestamp: -1
ticker: 'EUR'
bidPrice: -1
askPrice: -1
open: -1
close: -1
low: -1
high: -1
lastPrice: -1
volume: -1
tick: 0.01

IB does not report the specific error cause; we need to discover this ourselves. It turns out that in this specific case, some default parameter values (SecType='STK', Exchange='SMART', LocalSymbol=Symbol) are incorrect and must be overridden:

>> data = IBMatlab('action','query', 'symbol','EUR', ...
'localSymbol','EUR.USD', 'secType','cash', ...
'exchange','idealpro')
data =
reqId: 153745244
reqTime: '13-Feb-2012 21:28:51'
dataTime: '13-Feb-2012 21:28:52'
dataTimestamp: 734912.895051898
ticker: 'EUR'
bidPrice: 1.32565
askPrice: 1.32575
open: -1
close: 1.3197
low: 1.32075
high: 1.32835
lastPrice: -1
volume: -1
tick: 5e-005
bidSize: 26000000
askSize: 20521000

Some assets are traded on multiple exchanges (for example, MSFT is traded on both ISLAND and AEB); using the default Exchange='SMART' will thus cause an error.

In other cases, we may also need to specify the Currency (default='USD'). For example, the Russell 2000 index (RUT) is listed on the Toronto Stock Exchange (TSE) and trades in CAD currency. Likewise, the USD.JPY currency pair trades in Yens (JPY currency), not USD.161 Similarly, when Exchange='SMART' and Symbol='IBM', the Currency must be specified since IBM trades in either GBP or USD. Due to such potential ambiguities it is a good idea to always specify Currency.

For options/future we also need to specify the Expiry, Strike and Right parameters. In some cases, specifying the Expiry in YYYYMM format is ambiguous because the underlying contract has several separate futures/options expiring in the same month:

>> data = IBMatlab('action','query','symbol','TNA','secType','opt',...
'expiry','201202', 'strike',47, 'right','CALL')

[API.msg2] The contract description specified for TNA is ambiguous; you must specify the multiplier. {149386474, 200}

The solution is to specify the Expiry date in YYYYMMDD format (i.e., specify the exact full date rather than just the month), or to specify the Multiplier parameter.

If you are unsure of a security’s contract details, try using different parameter values. Alternatively, right-click the ticker in TWS and select “Contract Info / Description”:

?????? ???

Contract descriptions for USD.JPY and an IBM option, as reported in TWS

This specific example shows that the LocalSymbol for the IBM OCT12 PUT option is ‘IBM 121020P00100000’ (Symbol is ‘IBM’). This LocalSymbol has multiple spaces162. For this reason, it is best to copy-paste the value directly from the window.

Alternatively, use your TWS paper-trade (simulated trading) account to buy a virtual unit of the security, then use IB-Matlab to read the portfolio (see §4 below) and check the reported contract data. For example:

>> data = IBMatlab('action','portfolio');
>> data(3)
ans =
symbol: 'EUR'
localSymbol: 'EUR.USD'
exchange: 'IDEALPRO'
secType: 'CASH'
currency: 'USD'
right: '0'
...

As a last resort, contact IB’s API customer support help-desk (see Appendix A.1 below) to request the necessary parameters for a particular security.

Here are some examples of IB symbols:163

LocalSymbol

Exchange

SecType

Currency

Description

CO

SMART

STK

USD

Cisco Corp., SMART (NASDAQ)

GE

SMART

STK

USD

General Electric, SMART (NYSE)

VOD

LSE

STK

GBP

Vodafone Group, London Stock Exch.

SPX

CBOE

IND

USD

S&P 500 Index

INDU

NYSE

IND

USD

Dow Jones Industrials Average Index

ESM1

GLOBEX

FUT

USD

Emini S&P 500 (ES) 6/2011 futures

ES

GLOBEX

CONTFUT

USD

Emini S&P continuous (rolling) future

YM JUN 11

ECBOT

FUT

USD

Emini Dow (YM) 6/2011 future
Note: 3 spaces between symbol and month,1 space between month, year

QMN5

NYMEX

FUT

USD

Crude Oil (QM) 6/2005 future

FGBL DEC 23

EUREX

FUT

EUR

German Bund 12/2023 future

P OZN DEC 15 13100

ECBOT

FOP

USD

10-year T-note (ZN) 11/2015, 131.0 Put future-option. Note 2 spaces, twice

XAUUSD

SMART

CMDTY

USD

London Gold Spot

EUR.USD

IDEALPRO

CASH

USD

Euro/Dollar currency pair

To get the full option chain list, see §5.4 and §11.4.

14.3 Programmatic errors

In addition to messages reported by IB, the user’s program must check for and handle cases of exceptions caused by IB-Matlab. In the vast majority of cases, these are due to invalid input parameters being passed to IBMatlab (for example, an invalid Action parameter value). However, an exception could also happen due to network problems, or even an occasional internal bug due to an unhandled edge-case situation.

To trap and handle such programmatic exceptions, wrap your calls to IBMatlab within a try-catch block, as follows:

try
data = IBMatlab(
'action','query', ... );
catch
% process the exception here
end

Try-catch blocks have negligible performance and memory overheads and are a very effective way to handle programmatic errors. We highly recommend that you use them very liberally within your user program, not just to wrap IBMatlab calls but also for any other processing tasks. I/O sections in particular (reading/writing to files) are prone to errors and are prime candidates for such exception handling. The same applies for processing blocks that handle user inputs (we can never really be too sure what invalid junk a user might enter in there, can we?).

Sometimes it is preferable to silently trap errors, rather than receive a Matlab exception error. This can be done by specifying a 5th output argument in the call to IBMatlab:

[orderId, ibConnector, contract, order, errMsg] = ...
IBMatlab(
'action','BUY',...);
if ~isempty(errMsg)
% process the error here (errMsg is a char array)
end

In most cases we do not need the ibConnector, contract, order output args of IBMatlab (see §9.6 for their usage), so such cases can be simplified to this:

[orderId, ~, ~, ~, errMsg] = IBMatlab('action','BUY',...);
if ~isempty(errMsg)
% process the error here (errMsg is a char array)
end

Programmatic errors may occur in programs that rely on valid account, portfolio or market-data data returned from IB. Unfortunately, sometimes the IB server data feed (or perhaps only the interface) is not as reliable as it could be. IB sometimes returns empty or invalid data field values, typically -1. This issue, together with some workarounds, is discussed in §14.2 and §4. User programs should implement sanity checks on the returned data, and resend the request until valid data is received. Failing to do so may result in applicative errors or bad trading decisions.

A common cause of program errors is due to specifying numeric values as strings or vice versa. For example, specifying 12 rather than “12”, or “0” rather than 0 or false. Numbers should not be enclosed with quote marks when specifying parameter values. For example, specify IBMatlab(…, 'Strike',5.20), not IBMatlab(…, 'Strike','5.20'), otherwise Matlab might get confused when trying to interpret the string '5.20' as a number. Each parameter has a specific data type, which is listed in the parameter tables in this guide. IB-Matlab is often smart enough to automatically convert to the correct data type, but you should not rely on this: it is better to always use the correct data type.

Another common cause of errors when using IB-Matlab is relying on default parameter values (for example, relying on the default SecType ('STK') for non-equity contracts (Forex, future, option etc.); see §3.2 and §14.2 for additional details.

The final type of error is out-of-memory errors, either directly in Matlab or in Java:

Matlab “out of memory” errors might occur when receiving and storing a huge amount of streaming/historic data. These can be fixed by running IB-Matlab on a computer having more memory, or by reducing the amount of stored data.164

Java memory errors are recognized by the message “java.lang.OutOfMemoryError: Java heap space”. They can be solved by increasing Matlab’s pre-allocated Java heap memory using Matlab’s preferences, or via a java.opts file.165

A possible cause of confusion is Matlab’s default use of the “short” format, which rounds numbers in the Matlab console (Command Window) to 4 digits after the decimal. This is not an error or bug: The data actually has higher precision, so when we use it in a calculation the full precision is used; this is simply not displayed in the console.

IB-Matlab does not truncate/round/modify the IB data in any manner!

To display the full numeric precision in the Matlab console, change your Matlab’s Command Window’s Numeric Format from “short” to “long” (or “long g”) in Matlab’s Preferences window, or use the “format long” Matlab command:

>> data = IBMatlab('action','query','localsymbol','EUR.USD',...);

>> data.askPrice % short format
ans =
1.0727

>> format long g % long format
>> data.askPrice
ans =
1.07265

1

14.4 Troubleshooting specific problems/errors

Error

Description / solution

Sections

Cannot connect to IB. Confirm that "Enable ActiveX and Socket Clients" is enabled on the TWS "Configure->API" menu.

Enable ActiveX etc. in TWS/Gateway API settings. Note that IBGateway has a separate set of settings than TWS.

2.0 steps #5-6

failed to connect to IB using Port=7496; retrying to connect using Port=4001

TWS and IBGateway use different default ports for API connections. You can modify their API seettings, specify the Port parameter in your IBMatlab command, or simply ignore this message.

2.0 steps #5-6

13

IBMatlab is not activated on this computer

Your activated computer fingerprint has changed. Revert this change or contact us to modify the activated fingerprint.

2.1, 2.2

Your IBMatlab license has expired on 1-Jun-2014

IB-Matlab’s license is limited in duration. When the license term expires, you can contact us to renew it.

2.1

Cannot connect to undocumentedmatlab.com to validate your IBMatlab license

IB-Matlab validates its license on the UndocumentedMatlab.com server. Your internet connection may be down, or this domain may be blocked by your firewall (your IT admin can unblock it).

2.1

IBMatlab.jar was not found in the static Java classpath

IB-Matlab cannot work properly unless its Java file (IBMatlab.jar) is added to Matlab’s static Java classpath.

2.3

NullPointerException com.mathworks.jmi.bean.MatlabBeanInterface.addCallback

IB-Matlab cannot work properly unless its Java file (IBMatlab.jar) is added to Matlab’s static Java classpath.

2.3

(Commands can be sent to IB, but no data is received from IB)

IB-Matlab cannot receive IB data unless its Java file (IBMatlab.jar) is added to Matlab’s static Java classpath.

2.3

Unknown parameter 'xyz'

The specified parameter in the IBMatlab command is not valid. Refer to the relevant User Guide section for a list of acceptable parameter names, or type “help IBMatlab” in the Matlab console.

3.1

Max rate of messages per second has been exceeded: max=50 rec=55

IB server limits the rate of messages sent to the IB server to 50 msgs/sec. Reduce your requests rate using Matlab’s pause(0.02) command.

3.1, 8

The account code is required for this operation

or:

You must specify an allocation (either a single account, group, or profile)

You manage multiple IB accounts, and IB does not understand which of these accounts relates to your requested action. Specify the AccountName or FAGroup or FAProfile parameter.

3.2, 8.5, 9.7

Historical Market Data Service error message:
No market data permissions for NYSE STK

You are not subscribed to the IB service of fetching historical data for the specified security type or exchange.

5.1

Requested market data is not subscribed

You are not subscribed for IB real-time data for the asset. Sometimes happens when security parameters are incorrect.

5.1, 14.2

Deep market data is not supported for this combination of security type/exchange

The specified exchange does not provide market depth (level 2) information for the requested security type.

5.2

Historical data request pacing violation

Historical and real-time streaming data is subject to IB’s strict pacing limits. Either limit your requests rate, or
ask IB to raise your account limits.

6, 7.1

Historical data bar size setting is invalid

IB only accepts some combinations of barSize/duration in historic data requests

6

Historical Market Data Service error message: No historical market data for EUR/CASH@IDEALPRO Last 1d

The default WhatToShow parameter value is ‘Trades’, which is not supported for Forex. Specify a ‘Midpoint’ parameter value instead.

6

(IB-Matlab stops receiving streaming data from IB)

Streaming data from TWS is sometimes stopped, depending on data rate. Try to set ReconnectEvery, or restart Matlab.

7.1

Symbol "IBM" is not currently streaming

Start the streaming (QuotesNumber>0) before requesting any streamed data.

7.1, 7.2, 7.3

Can't find EID with tickerId

You can safely ignore this message:
It represents a harmless request from IBMatlab to IB, to cancel a streaming data request that was already cancelled.

7.2

The order size cannot be zero

You have either specified Quantity=0, or FAPercentage with invalid direction

8.1, 8.5

Order rejected - reason: Invalid value in field #6159

One of the provided parameter values (e.g., FAMethod) is invalid.

8.5

Invalid ICS spread

You specified incorrect ComboRatios values between the combo-order legs.

9.5

Unable to modify this order as it is still being processed

You tried to modify an order before it was fully registered by the IB server.

9.6

Exercise ignored because option is not in-the-money

You tried to exercise an out-of-money option without specifying Override.

9.7

No unlapsed position exists in this option in account

You tried to exercise an option that does not exist in your account.

9.7

Order rejected - reason: The time-in-force is invalid for IB algorithmic orders

You tried to send an IBAlgo order with an invalid (or default='GTC') value.
Use TIF='Day' instead.

9.8

No security definition has been found for the request

or:

Either Symbol or LocalSymbol (or both) must be specified to create a valid trade order

The requested security’s parameters are not properly (or completely) specified, so IB cannot identify it.
Specify additional contract parameters.

14.2

The contract description specified for TNA is ambiguous; you must specify the multiplier

IB cannot decide which of several possible securities you intended.
Specify additional contract parameters.

14.2

(Missing digits displayed in Matlab Command Window)

Perhaps Matlab’s display format is set to “short” instead of “long”

14.3

Out of memory

or:

Maximum variable size allowed by the program is exceeded

or:

Requested array exceeds maximum array size preference

This Matlab error might occur when receiving huge amounts of streaming/ historic data. Different Matlab releases display different messages with the same basic idea. Run IB-Matlab on a computer with more memory, or reduce the amount of stored/processed data.

14.3

java.lang.OutOfMemoryError: Java heap space

Run Matlab with more allocated Java heap memory than the default value. This can be set in Matlab’s preferences, or via a java.opts file.

14.3


152 The Matlab console is the Desktop Command Window in the case of an interactive Matlab session, or the command-prompt window in the case of a compiled (deployed) program.

153 http://interactivebrokers.github.io/tws-api/interfaceIBApi_1_1EWrapper.html#a7dfc221702ca65195609213c984729b8

154 https://interactivebrokers.github.io/tws-api/message_codes.html

155 See §11 for additional explanations and usage examples of user callback functions for IB messages/events

156 See examples in §14.2 above

157 The setting to create an API message file needs to be selected as well (naturally); see §2, installation step 5d. Also see http://interactivebrokers.github.io/tws-api/support.html#tws_logs. In recent versions of TWS/Gateway, the log files are not saved automatically but are available from the main menu: Account à Diagnostics à API logs.

158 http://interactivebrokers.github.io/tws-api/logs.html

159 Using IB Gateway instead of TWS avoids the need to set the API logging level or to review log files – the API messages log is automatically shown in the IB Gateway window if you click the “Show API messages” checkbox above the tabs.

160 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

161 http://interactivebrokers.com/en/index.php?f=2222&ns=T&exch=ibfxpro

162 OSI specification: http://interactivebrokers.com/download/ociguide.pdf, http://en.wikipedia.org/wiki/Option_symbol

163 http://www.amibroker.com/ib.html (scroll down to the SYMBOLOGY section); Note: DTB exchange is now called EUREX.

164 Also see: http://www.mathworks.com/help/matlab/matlab_prog/resolving-out-of-memory-errors.html

165 https://www.mathworks.com/matlabcentral/answers/92813-how-do-i-increase-the-heap-space-for-the-java-vm-in-matlab