• C#
  • Java
  • VB
  • C++
  • Python
Contact us
Receiving Market Data

Receiving Market Data

After subscribing to the ticker stream, your API client will receive the data supplied by the TWS API server via several methods. In your API client code, you will need to implement these methods to manipulate the data relayed back to the client. Notice how market data callbacks such as IBApi.EWrapper.tickPrice and IBApi.EWrapper.tickSize methods contain the request id with which the response can be mapped to its originating request.

When IBApi::EWrapper::tickPrice and IBApi::EWrapper::tickSize are reported as -1, this indicates that there is no data currently available. Most commonly this occurs when requesting data from markets that are closed. It can also occur for infrequently trading instruments which do not have open bids or offers at that time of the request. To receive frozen quotes (the last available bid/ask recorded by the system) invoke the function IBApi.EClient.reqMarketDataType with argument 2. Frozen data is exclusive to default tick types- Generic Tick Types are not available- and requires market data subscriptions.

Following every IBApi::EWrapper::tickPrice callback there will be a IBApi::EWrapper::tickSize. This is important because with combo contracts, an actively trading contract can have a price of zero. In this case it will have a positive IBApi::EWrapper::tickSize value.

  • public class EWrapperImpl : EWrapper
    {

    ...

    public virtual void tickPrice(int tickerId, int field, double price, TickAttrib attribs)
    {
    Console.WriteLine("Tick Price. Ticker Id:"+tickerId+", Field: "+field+", Price: "+price+", CanAutoExecute: "+attribs.CanAutoExecute + ", PastLimit" + attribs.PastLimit);
    }

    The boolean value canAutoExecute in tickPrice is intended to indicate that a quote is available for immediate execution. The boolean value pastLimit indicates whether the bid price is lower than the day's lowest value or the ask price is higher than the highest ask.

    public virtual void tickSize(int tickerId, int field, int size)
    {
    Console.WriteLine("Tick Size. Ticker Id:" + tickerId + ", Field: " + field + ", Size: " + size);
    }

    ....

    public virtual void tickString(int tickerId, int tickType, string value)
    {
    Console.WriteLine("Tick string. Ticker Id:" + tickerId + ", Type: " + tickType + ", Value: " + value);
    }

    ....

    public virtual void tickGeneric(int tickerId, int field, double value)
    {
    Console.WriteLine("Tick Generic. Ticker Id:" + tickerId + ", Field: " + field + ", Value: " + value);
    }
  • public class EWrapperImpl implements EWrapper {

    ...

    @Override
    public void tickPrice(int tickerId, int field, double price, TickAttr attribs) {
    System.out.println("Tick Price. Ticker Id:"+tickerId+", Field: "+field+", Price: "+price+", CanAutoExecute: "+ attribs.canAutoExecute()
    + ", pastLimit: " + attribs.pastLimit());
    }

    The boolean value canAutoExecute in tickPrice is intended to indicate that a quote is available for immediate execution. The boolean value pastLimit indicates whether the bid price is lower than the day's lowest value or the ask price is higher than the highest ask.

    @Override
    public void tickSize(int tickerId, int field, int size) {
    System.out.println("Tick Size. Ticker Id:" + tickerId + ", Field: " + field + ", Size: " + size);
    }

    ...

    @Override
    public void tickString(int tickerId, int tickType, String value) {
    System.out.println("Tick string. Ticker Id:" + tickerId + ", Type: " + tickType + ", Value: " + value);
    }

    ...

    @Override
    public void tickGeneric(int tickerId, int tickType, double value) {
    System.out.println("Tick Generic. Ticker Id:" + tickerId + ", Field: " + TickType.getField(tickType) + ", Value: " + value);
    }
  • Public Class EWrapperImpl
    Implements EWrapper

    ...

    Public Sub tickPrice(tickerId As Integer, field As Integer, price As Double, attribs As TickAttrib) Implements IBApi.EWrapper.tickPrice
    Console.WriteLine("TickPrice - TickerId [" & CStr(tickerId) & "] Field [" & TickType.getField(field) & "] Price [" & CStr(price) & "]")
    End Sub

    The boolean value canAutoExecute in tickPrice is intended to indicate that a quote is available for immediate execution. The boolean value pastLimit indicates whether the bid price is lower than the day's lowest value or the ask price is higher than the highest ask.

    Public Sub tickSize(tickerId As Integer, field As Integer, size As Integer) Implements IBApi.EWrapper.tickSize
    Console.WriteLine("Tick Size. Ticker Id:" & CStr(tickerId) & ", Field: " & TickType.getField(field) & ", Size: " & CStr(size))
    End Sub

    ....

    Public Sub tickString(tickerId As Integer, field As Integer, value As String) Implements IBApi.EWrapper.tickString
    Console.WriteLine("Tick string. Ticker Id:" & CStr(tickerId) & ", Type: " & TickType.getField(field) & ", Value: " & value)
    End Sub

    ....

    Public Sub tickGeneric(tickerId As Integer, field As Integer, value As Double) Implements IBApi.EWrapper.tickGeneric
    Console.WriteLine("Tick Generic. Ticker Id:" & tickerId & ", Field: " & field & ", Value: " & value)
    End Sub
  • class TestCppClient : public EWrapper
    {

    ...

    void TestCppClient::tickPrice( TickerId tickerId, TickType field, double price, const TickAttrib& attribs) {
    printf( "Tick Price. Ticker Id: %ld, Field: %d, Price: %g, CanAutoExecute: %d\n, PastLimit: %d\n", tickerId, (int)field, price, attribs.canAutoExecute, attribs.pastLimit);
    }

    The boolean value canAutoExecute in tickPrice is intended to indicate that a quote is available for immediate execution. The boolean value pastLimit indicates whether the bid price is lower than the day's lowest value or the ask price is higher than the highest ask.

    void TestCppClient::tickSize( TickerId tickerId, TickType field, int size) {
    printf( "Tick Size. Ticker Id: %ld, Field: %d, Size: %d\n", tickerId, (int)field, size);
    }

    ....

    void TestCppClient::tickString(TickerId tickerId, TickType tickType, const std::string& value) {
    printf( "Tick String. Ticker Id: %ld, Type: %d, Value: %s\n", tickerId, (int)tickType, value.c_str());
    }

    ....

    void TestCppClient::tickGeneric(TickerId tickerId, TickType tickType, double value) {
    printf( "Tick Generic. Ticker Id: %ld, Type: %d, Value: %g\n", tickerId, (int)tickType, value);
    }
  • 1 class TestWrapper(wrapper.EWrapper):

    ...

    1  def tickPrice(self, reqId: TickerId, tickType: TickType, price: float,
    2  attrib: TickAttrib):
    3  super().tickPrice(reqId, tickType, price, attrib)
    4  print("Tick Price. Ticker Id:", reqId, "tickType:", tickType, "Price:",
    5  price, "CanAutoExecute:", attrib.canAutoExecute,
    6  "PastLimit", attrib.pastLimit)
    7 

    The boolean value canAutoExecute in tickPrice is intended to indicate that a quote is available for immediate execution. The boolean value pastLimit indicates whether the bid price is lower than the day's lowest value or the ask price is higher than the highest ask.

    1  def tickSize(self, reqId: TickerId, tickType: TickType, size: int):
    2  super().tickSize(reqId, tickType, size)
    3  print("Tick Size. Ticker Id:", reqId, "tickType:", tickType, "Size:", size)
    4 

    ....

    1  def tickString(self, reqId: TickerId, tickType: TickType, value: str):
    2  super().tickString(reqId, tickType, value)
    3  print("Tick string. Ticker Id:", reqId, "Type:", tickType, "Value:", value)
    4 

    ....

    1  def tickGeneric(self, reqId: TickerId, tickType: TickType, value: float):
    2  super().tickGeneric(reqId, tickType, value)
    3  print("Tick Generic. Ticker Id:", reqId, "tickType:", tickType, "Value:", value)
    4 

Exchange Component Mapping

A market data request is able to return data from multiple exchanges. Beginning in TWS/IBG v963 and API v973.02, after a market data request is made for an instrument covered by market data subscriptions, a message will be sent to function IBApi::EWrapper::tickReqParams with information about 'minTick', BBO exchange mapping, and available snapshot permissions.

  • public void tickReqParams(int tickerId, double minTick, string bboExchange, int snapshotPermissions)
    {
    Console.WriteLine("id={0} minTick = {1} bboExchange = {2} snapshotPermissions = {3}", tickerId, minTick, bboExchange, snapshotPermissions);
    BboExchange = bboExchange;
    }
  • @Override
    public void tickReqParams(int tickerId, double minTick, String bboExchange, int snapshotPermissions) {
    System.out.println("Tick req params. Ticker Id:" + tickerId + ", Min tick: " + minTick + ", bbo exchange: " + bboExchange + ", Snapshot permissions: " + snapshotPermissions);
    }
  • Public Sub tickReqParams(tickerId As Integer, minTick As Double, bboExchange As String, snapshotPermissions As Integer) Implements EWrapper.tickReqParams
    Console.WriteLine("id={0} minTick = {1} bboExchange = {2} snapshotPermissions = {3}", tickerId, minTick, bboExchange, snapshotPermissions)
    Me.BboExchange = bboExchange
    End Sub
  • void TestCppClient::tickReqParams(int tickerId, double minTick, std::string bboExchange, int snapshotPermissions) {
    printf("tickerId: %d, minTick: %g, bboExchange: %s, snapshotPermissions: %u", tickerId, minTick, bboExchange.c_str(), snapshotPermissions);
    m_bboExchange = bboExchange;
    }
  • 1  def tickReqParams(self, tickerId:int, minTick:float, bboExchange:str, snapshotPermissions:int):
    2  super().tickReqParams(tickerId, minTick, bboExchange, snapshotPermissions)
    3  print("tickReqParams: ", tickerId, " minTick: ", minTick, " bboExchange: ", bboExchange, " snapshotPermissions: ", snapshotPermissions)

The exchange mapping identifier bboExchange will be a symbol such as "a6" which can be used to decode the single letter exchange abbreviations returned to the bidExch, askExch, and lastExch fields by invoking the function IBApi::EClient::reqSmartComponents. More information about Component Exchanges.

IBApi::ContractDetails::MinTick will represent the smallest possible minimum increment for the contract on any exchange and at any price. For complicated minimum increment structures, such as is common for European stocks, there might be different minimum increments at different price and size levels, so the 'minTick' of the contract may not necessarily represent the minimum increment at which it is presently trading. For complete information about the minimum increment, it is necessary to consult the IB Contracts and Securities search site.

Re-Routing CFDs

IB does not provide market data for certain types of instruments, such as stock and forex CFDs. If a stock or forex CFD is entered into a TWS watchlist, TWS will automatically display market data for the underlying ticker and show a 'U' icon next to the instrument name to indicate that the data is for an underlying.

From the API, when market data is requested for a stock or forex CFD, a callback is made from TWS to the IBApi::EWrapper::rerouteMktDataReq or IBApi::EWrapper::rerouteMktDepthReq with information about the underlying instrument which has market data in IB's database.

  • public void rerouteMktDataReq(int reqId, int conId, string exchange)
    {
    Console.WriteLine("Re-route market data request. Req Id: {0}, ConId: {1}, Exchange: {2}", reqId, conId, exchange);
    }
  • @Override
    public void rerouteMktDataReq(int reqId, int conId, String exchange) {
    System.out.println(EWrapperMsgGenerator.rerouteMktDataReq(reqId, conId, exchange));
    }
  • Public Sub rerouteMktDataReq(reqId As Integer, conId As Integer, exchange As String) Implements IBApi.EWrapper.rerouteMktDataReq
    Console.WriteLine("Re-route market data request. Req Id: {0}, Con Id: {1}, Exchange: {2}", reqId, conId, exchange)
    End Sub
  • void TestCppClient::rerouteMktDataReq(int reqId, int conid, const std::string& exchange) {
    printf( "Re-route market data request. ReqId: %d, ConId: %d, Exchange: %s\n", reqId, conid, exchange.c_str());
    }
  • public void rerouteMktDepthReq(int reqId, int conId, string exchange)
    {
    Console.WriteLine("Re-route market depth request. Req Id: {0}, ConId: {1}, Exchange: {2}", reqId, conId, exchange);
    }
  • @Override
    public void rerouteMktDepthReq(int reqId, int conId, String exchange) {
    System.out.println(EWrapperMsgGenerator.rerouteMktDepthReq(reqId, conId, exchange));
    }
  • Public Sub rerouteMktDepthReq(reqId As Integer, conId As Integer, exchange As String) Implements IBApi.EWrapper.rerouteMktDepthReq
    Console.WriteLine("Re-route market depth request. Req Id: {0}, Con Id: {1}, Exchange: {2}", reqId, conId, exchange)
    End Sub
  • void TestCppClient::rerouteMktDepthReq(int reqId, int conid, const std::string& exchange) {
    printf( "Re-route market depth request. ReqId: %d, ConId: %d, Exchange: %s\n", reqId, conid, exchange.c_str());
    }