build the buiness and adta layer for this layered achtecutre project in python BASED ON THE DOCUMENTATION SCRAPED BELOW . srs :                 Interactive Brokers Trade Management App
                   Software Requirements Speciﬁcation
Purpose
   - Development of app with GUI for trade entry and management interfacing with Interactive
      Brokers

User Needs
   - App must facilitate basic trade entry functions (stock and futures
   - App should enable trade management capabilities
   - Integration with Interactive Brokers (IB) platform is essential, both TWS and Gateway (v.
      10.23.2a)
   - Ability to select from multiple accounts in IB
   - GUI needs to have several tabs as detailed below
   - It needs to be stable and run 24x7 and include auto-reconnect to IB feature
   - Send notiﬁcation (email and text msg) for different levels of communication (e.g. error,
      disconnection, successful trade entry/exit)
   - Logging (error, warning, information)
   - Import new trades and export closed trades via CSV
   - Six months of support to address any bugs in the system

Functional Requirements
   - Run on Windows 10 and above
   - Use PyQt for GUI development
   - Heartbeat monitor that checks the connection status with IB at regular intervals

GUI Requirements
   - Four tabs for trades (see trade logic below for more details on each tab)
          o Active Orders
          o Active Trades
          o Active Risk Summary
          o Closed Trades
   - Settings options
          o Default setting for trades (see example below)
          o Connection to IB
          o Setup of communication (email and txt)
          o Logs

System Features
   - Below is a trade logic diagram and trade example to explain the steps and math behind the
      logic
   - The last page includes the information for the Active Risk Summary Tab
                                                                Start




                                             Daily CSV entry sheet includes manual
For each ticker API                          entry of:
calculates:                                  +Ticker (Stock or Futures with
+Price range for entry                       Contract date)
(mkt order) based on                   <----  +Long or Short
previous day H/L                             +Initial stop loss to calculate shares
(depending if Short or                       +Full or partial take profit exit
Long)                                        +Manual adjustment stop loss
+Shares to buy based on                                                                     Trade Management includes:
Risk and Initial stop loss                   Constants to apply to all trades:
                                             +Risk $ to calculate position size             +++Active Orders+++
                                             +% to calculate price range for entry          - Ticker, Long/Short, shares, Price range for entry
                                             +Others (see next page)                        - Should have import CSV option and option for manual
                                                                                            entry
|
|

                                                                                            +++Active Trades+++
                                            API to:                                         - Ticker, avg. price entry, shares, short/long, Take Profit
                                            +Adjust or delete conditional                   and %, Stop loss (stop loss can be adjusted manually)
API creates:                                                                                - Date and Days until upcoming earnings report
                                            order based on Entry sheet –
+Conditional order in IB
                                            this is a daily update
                                                                                            +++Active Risk Summary+++
                                                                                            - Overall active trades risk ($)
                                                                                            - Broken down by Indices, Futures, Sectors

                                                         No    -->                             +++Closed Trades+++
                                                                                            -Record of trades including entry price, exit price(s),
  Did order get filled in                                                                   Shares, dates for entry and exit(s), P/L, commissions
           IB?                                                                              - Should have date filter and be exportable in CSV




            Yes
	then full or partial?
                                              API creates:
                                              +Take-Profit and Stop loss for full
                                              order based on fill price and formula
    Full or Partial Take                      using initial stop loss from Entry                 Stop-Loss or Take-
         Profit Exit         Full TP Exit
                                              Sheet.                                            Profit triggered in IB
                                              +Stop loss can be manually adjusted
                                              as trade progresses


       Partial TP Exit


API creates:
+Take-Profit for ½ order
based on fill price and
                                                                                          API creates:
formula using initial stop
                                               Stop-Loss or Take-                         +Trailing Stop for remaining
loss from Entry Sheet.                                                      Take-Profit
                                              Profit triggered in IB                      ½ order based on manual
+Stop loss for full order                        goes to stoploss or tp
                                                                                          adjustment of stop-loss
+Stop loss can be
manually adjusted as trade
progresses
                                                    Stop-Loss

                                       API creates:
                                       +Record of trade including
                                       entry price, exit price(s),
                                       Shares, dates for entry and
                                       exit(s), P/L, commissions




                                                      Stop
EXAMPLE – Trade Long, ﬂip logic for Short

Default settings that are applied to all trades, but can be manually adjusted for a given trade

   •    Risk $ to calculate position size: $2,000 [1]
   •    % to calculate price range for entry 1: 2% [2]
   •    % to calculate price range for entry 2: 25% [3]
   •    Stop loss hours: Regular Trading Hours (RTH)
   •    Take Proﬁt hours: Extended Trading Hours (e.g. outside RTH)
   •    Entry type hours: RTH
   •    Entry Time in Force: Good for day (Day)

Entry criteria (Ticker, Long/Short, SL, TP share%, manual adjustment stop loss, IB account)

   •    SPX [4]
   •    Long [5]
   •    5760 [6]
   •    50% [7]
   •    10% [8]
   •    3429294

API calculates:

    •   Previous day SPX High: $5,850 [9]
    •   Risk per contract (given that [5] is L, then Risk [9]-[6]): $90 [10]
    •   Price for entry 1 ([2]*[10]+[9]): $5,851.80 [11]
    •   Price for entry 2 ([3]*[10]+[9]): $5,872.50 [12]
    •   Contracts to buy (Rounddown([1]/[10])): 21 [13]

API creates Order Ticket in TWS

    •   [4] SPX mkt order
    •   [13] 21 contracts
    •   [11] Conditional entry low price
    •   [11] Conditional entry high price

Order is successful - API creates SL/TP in TWS

    •   Avg. entry at $5855 [14]
    •   Risk ([14]-[6]): $95 [15]
    •   TP (1R): $5,950 for half the position (see [7])
    •   SL ([14]-[8]*[15]): $5,845.50 [16]

Take proﬁt hit – API create SL based on manual input

    •   No TP
    •   SL based on daily manual adjustments
Active Risk Summary Tab

For each active trade calculate:

   •   Risk: Difference between Entry [14] and Stop Loss [16]. Note, if this is positive, then zero risk
   •   Stocks – Sector

Provide Summary Table of Active Risk by

   •   Overall Portfolio
   •   Indices
   •   Futures
   •   Sectors
 DOCUMENTATION:  TWS API Documentation

   (BUTTON) Python (BUTTON) Java (BUTTON) C++ (BUTTON) C# (BUTTON)
   VB
     * [196]Introduction
     * [197]Notes & Limitations
          + [198]Limitations
               o [199]Requests
               o [200]Paper Trading
          + [201]Requirements
          + [202]Unset Values
     * [203]Download TWS or IB Gateway
     * [204]TWS Settings
          + [205]TWS Configuration For API Use
          + [206]Best Practice: Configure TWS / IB Gateway
               o [207]Memory Allocation
               o [208]Daily & Weekly Reauthentication
               o [209]Order Precautions
               o [210]Connected IB Server Location in TWS
               o [211]SMART Algorithm
               o [212]Allocation Setup (For Financial Advisors)
          + [213]Intelligent Order Resubmission
          + [214]Disconnect on Invalid Format
     * [215]Download the TWS API
          + [216]How to install the TWS API Components on Mac /
            Unix
     * [217]TWS API Folder Files & Tools
     * [218]Unique Configurations
          + [219]Implementing the Intel Decimal Library for MacOS
            and Linux
          + [220]Updating The Python Interpreter
               o [221]1. Open Command Prompt or Terminal
               o [222]2. Navigate to Python Source
               o [223]3. Run The setup.py File
               o [224]4. Confirm Updates
               o [225]5. Confirm your installation
          + [226]Implementing Visual Basic .NET
     * [227]Third Party API Platforms
     * [228]Troubleshooting & Support
          + [229]Understanding Order Precautions
               o [230]Disabling Warning Messages
               o [231]Modifying Precautionary Settings
          + [232]Log Files
               o [233]API Logs
               o [234]TWS Log Files
               o [235]Local location of logs
               o [236]Uploading Logs
               o [237]Exporting Logs
               o [238]Reading Exported Logs
               o [239]How To Enable Debug Logging
     * [240]Architecture
          + [241]The Trader Workstation
               o [242]The IB Gateway
     * [243]Connectivity
          + [244]Establishing an API connection
          + [245]The EReader Thread
          + [246]Accepting an API connection from TWS
          + [247]Logging into multiple applications
          + [248]Broken API socket connection
     * [249]Account & Portfolio Data
          + [250]Account Summary
               o [251]Requesting Account Summary
               o [252]Account Summary Tags
               o [253]Receiving Account Summary
               o [254]Cancel Account Summary
          + [255]Account Updates
               o [256]Requesting Account Updates
               o [257]Receiving Account Updates
               o [258]Account Value Keys
               o [259]Cancel Account Updates
          + [260]Account Update by Model
               o [261]Requesting Account Update by Model
               o [262]Receiving Account Updates by Model
               o [263]Cancel Account Updates by Model
          + [264]Family Codes
               o [265]Request Family Codes
               o [266]Receive Family Codes
          + [267]Managed Accounts
               o [268]Request Managed Accounts
               o [269]Receive Managed Accounts
          + [270]Positions
               o [271]Request Positions
               o [272]Receive Positions
               o [273]Cancel Positions Request
          + [274]Positions By Model
               o [275]Request Positions By Model
               o [276]Receive Positions By Model
               o [277]Cancel Positions By Model
          + [278]Profit & Loss (PnL)
               o [279]Request P&L for individual positions
               o [280]Receive P&L for individual positions
               o [281]Cancel P&L request for individual positions
               o [282]Request P&L for accounts
               o [283]Receive P&L for accounts
               o [284]Cancel P&L subscription requests for
                 accounts
          + [285]White Branding User Info
               o [286]Requesting White Branding Info
               o [287]Receiving White Branding Info
     * [288]Bulletins
          + [289]Request IB Bulletins
          + [290]Receive IB Bulletins
          + [291]Cancel Bulletin Request
     * [292]Contracts (Financial Instruments)
          + [293]The Contract Object
          + [294]Finding Contract Details in Trader Workstation
          + [295]Contract Details
               o [296]Request Contract Details
               o [297]Receive Contract Details
               o [298]Receive Bond Details
          + [299]Option Chains
               o [300]Request Option Chains
               o [301]Receive Option Chains
          + [302]Stock Symbol Search
               o [303]Request Stock Contract Search
               o [304]Receive Searched Stock Contract
     * [305]Error Handling
          + [306]Understanding Message Codes
          + [307]System Message Codes
          + [308]Error Codes
          + [309]Receiving Error Messages
     * [310]Financial Advisors
          + [311]Request FA Groups and Profiles
          + [312]Receiving FA Groups and Profiles
          + [313]Replace FA Allocations
          + [314]Allocation Methods and Groups
          + [315]Allocation Method XML Format
               o [316]Available Equity
               o [317]Contracts Or Shares
               o [318]Equal Quantity
               o [319]MonetaryAmount
               o [320]Net Liquidation Value
               o [321]Percentages
               o [322]Ratios
          + [323]Model Portfolios and the API
          + [324]Unification of Groups and Profiles
          + [325]Order Placement
     * [326]Market Data: Delayed
          + [327]Market Data Type Behavior
          + [328]Request Market Data Type
          + [329]Receive Market Data Type
     * [330]Market Data: Historical
          + [331]Historical Data Limitations
               o [332]Historical Data Filtering
               o [333]Pacing Violations for Small Bars (30 secs or
                 less)
               o [334]Unavailable Historical Data
          + [335]Finding the Earliest Available Data Point
               o [336]Requesting the Earliest Data Point
               o [337]Receiving the Earliest Data Point
               o [338]Cancelling Timestamp Requests
          + [339]Historical Bars
               o [340]Requesting Historical Bars
               o [341]Duration
               o [342]Historical Bar Sizes
               o [343]Step Sizes
               o [344]Max Duration Per Bar Size
               o [345]Format Date Received
               o [346]Keep Up To Date
               o [347]Receiving Historical Bars
          + [348]Historical Bar whatToShow
               o [349]AGGTRADES
               o [350]ASK
               o [351]BID
               o [352]BID_ASK
               o [353]FEE_RATE
               o [354]HISTORICAL_VOLATILITY
               o [355]MIDPOINT
               o [356]OPTION_IMPLIED_VOLATILITY
               o [357]SCHEDULE
               o [358]TRADES
               o [359]YIELD_ASK
               o [360]YIELD_BID
               o [361]YIELD_BID_ASK
               o [362]YIELD_LAST
          + [363]Histogram Data
               o [364]Requesting Histogram Data
               o [365]Receiving Histogram Data
               o [366]Cancelling Histogram Data
          + [367]Historical Time & Sales
               o [368]Requesting Time and Sales data
               o [369]Receiving Time and Sales data
               o [370]Historical Halted and Unhalted ticks
          + [371]Historical Date Formatting
               o [372]Operator Time Zone
               o [373]Exchange Time Zone
               o [374]Coordinated Universal Time (UTC)
          + [375]Modifying Returned Date
     * [376]Market Data: Live
          + [377]Live Data Limitations
          + [378]5 Second Bars
               o [379]Request Real Time Bars
               o [380]Receive Real Time Bars
               o [381]Cancel Real Time Bars
          + [382]Component Exchanges
               o [383]Request Component Exchanges
               o [384]Receive Component Exchanges
          + [385]Market Depth Exchanges
               o [386]Requesting Market Depth Exchanges
               o [387]Receive Market Depth Exchanges
          + [388]Market Depth (L2)
               o [389]Request Market Depth
               o [390]Receive Market Depth
               o [391]Cancel Market Depth
          + [392]Option Greeks
               o [393]Request Options Greeks
               o [394]Calculating option prices
               o [395]Calculating historical volatility
               o [396]Receiving Options Data
          + [397]Top of Book (L1)
               o [398]Request Watchlist Data
               o [399]Generic Tick Types
               o [400]Streaming Data Snapshots
               o [401]Regulatory Snapshots
               o [402]Receive Live Data
               o [403]Exchange Component Mapping
               o [404]Re-Routing CFDs
               o [405]Cancel Watchlist Data
          + [406]Available Tick Types
               o [407]Halted
               o [408]Shortable
               o [409]Volume Data
               o [410]RT Volume
               o [411]IB Dividends
          + [412]Tick By Tick Data
               o [413]Request Tick By Tick Data
               o [414]Receive Tick By Tick Data
               o [415]Cancel Tick By Tick Data
               o [416]Halted and Unhalted ticks
     * [417]Market Scanner
          + [418]Market Scanner Parameters
               o [419]Request Market Scanner Parameters
               o [420]Receive Market Scanner Parameters
          + [421]Market Scanner Subscription
               o [422]Request Market Scanner Subscription
               o [423]Receive Market Scanner Subscription
               o [424]Cancel Market Scanner Subscription
     * [425]Order Management
          + [426]Commission Report
          + [427]Execution Details
               o [428]ExecID Behavior
               o [429]The Execution Object
               o [430]Request Execution Details
               o [431]Receive Execution Details
          + [432]Open Orders
          + [433]Order Status
               o [434]Understanding Order Status Message
          + [435]Requesting Currently Active Orders
               o [436]API client's orders
               o [437]All submitted orders
               o [438]Manually Submitted TWS Orders
               o [439]Order Binding Notification
          + [440]Retrieving Completed Orders
               o [441]Requesting Completed Orders
               o [442]Receiving Completed Orders
     * [443]Orders
          + [444]The Order Object
          + [445]Exercise Options
          + [446]Minimum Price Increment
               o [447]Request Market Rule
               o [448]Receive Market Rule
          + [449]Place Order
               o [450]Order Placement Considerations
          + [451]Modifying Orders
          + [452]Cancelling an Order
               o [453]Cancel Individual Order
               o [454]Cancel All Open Orders
          + [455]Test Order Impact (WhatIf)
          + [456]Trigger Methods
          + [457]MiFIR Transaction Reporting Fields
     * [458]News
          + [459]News Providers
               o [460]Request News Providers
               o [461]Receive News Providers
          + [462]Live News Headlines
               o [463]Request Contract Specific News
               o [464]Request BroadTape News
               o [465]Receive Live News Headlines
          + [466]Historical News Headlines
               o [467]Requesting Historical News
               o [468]Receive Historical News
          + [469]News Articles
               o [470]Request News Articles
               o [471]Receive News Articles
     * [472]Next Valid ID
          + [473]Reset Order ID Sequence
          + [474]Request Next Valid ID
          + [475]Receive Next Valid ID
     * [476]TWS UI Display Groups
          + [477]Query Display Groups
               o [478]Request Query Display Groups
               o [479]Receive Query Display Groups
          + [480]Subscribe To Group Events
               o [481]Request Group Events Subscription
               o [482]Receive Group Events Subscription
               o [483]Unsubscribe From Group Events
          + [484]Update Display Group
     * [485]Wall Street Horizon
          + [486]Meta Data
               o [487]Requesting Meta Data
               o [488]Receive Meta Data
               o [489]Cancel Meta Data
          + [490]Event Data
               o [491]WshEventData Object
               o [492]Request Event Data
               o [493]Receive Event Data
               o [494]Cancel Event Data

Introduction

Copy Location
            The TWS API is a TCP Socket Protocol API based on
            connectivity to the Trader Workstation or IB Gateway.
            The API acts as an interface to retrieve and send data
            autonomously to Interactive Brokers. Interactive
            Brokers provides code systems in Python, Java, C++,
            C#, and VisualBasic.
            The TWS API is a message protocol as its core, and any
            library that implements the TWS API, whether created
            by IB or someone else, is a tool to send and receive
            these messages over a TCP socket connection with the
            IB host platform (TWS or IB Gateway). As such the
            system can be tweaked and modified into any language
            of interest given the intention to translate the
            underlying decoder.
            In short, a library written in any other languages
            must be sending and receiving the same data in the
            same format as any other conformant TWS API library,
            so users can look at the documentation for our
            libraries to see what a given request or response
            consists of (what it must include, in what form, etc.)
            and implement them in their own structure.
            Our TWS API components are aimed at experienced
            professional developers willing to enhance the current
            TWS functionality. Before you use TWS API, please make
            sure you fully understand the concepts of OOP
            ([495]https://www.geeksforgeeks.org/introduction-of-ob
            ject-oriented-programming/) and other Computer Science
            Concepts. Regrettably, Interactive Brokers cannot
            offer any programming consulting. Before contacting
            our API support, please always refer to our available
            documentation, sample applications and Recorded
            Webinars
            This guide references the Java, VB, C#, C++ and Python
            Testbed sample projects to demonstrate the TWS API
            functionality. Code snippets are extracted from these
            projects and we suggest all those users new to the TWS
            API to get familiar with them in order to quickly
            understand the fundamentals of our programming
            interface. The Testbed sample projects can be found
            within the samples folder of the TWS API’s
            installation directory.

    [495] https://www.geeksforgeeks.org/introduction-of-object-oriented-programming/

Notes & Limitations

Copy Location

Limitations

Copy Location
            Our programming interface is designed to automate some
            of the operations a user normally performs manually
            within the TWS Software such as placing orders,
            monitoring your account balance and positions, viewing
            an instrument’s live data… etc. There is no logic
            within the API other than to ensure the integrity of
            the exchanged messages. Most validations and checks
            occur in the backend of TWS and our servers. Because
            of this it is highly convenient to familiarize with
            the TWS itself, in order to gain a better
            understanding on how our platform works. Before
            spending precious development time troubleshooting on
            the API side, it is recommended to first experiment
            with the TWS directly.
            Remember: If a certain feature or operation is not
            available in the TWS, it will not be available on the
            API side either!

Requests

Copy Location
            The TWS/ IB Gateway is designed to accept up to 50
            messages per second coming from the client side.
            Anything coming from the client application to the
            TWS/ IB Gateway counts as a message (i.e. requesting
            data, placing orders, requesting your portfolio…
            etc.). This limitation is applied to all connected
            clients in the sense where all connected client
            applications to the same instance of TWS/ IB Gateway
            combined cannot exceed this number. On the other hand,
            there are no limits on the amount of messages the TWS
            can send to the client application.

            In some use cases, if you plan to send more than 50
            requests per second, some orders may be queued and
            delayed. For this scenario, please consider switching
            to FIX API.
            For FIX API users in IB Gateway, the limitation is 250
            messages per second.
            For FIX API users without using IB Gateway or TWS,
            there is no limitation on messages per second, but
            less is better.

Paper Trading

Copy Location
            If your regular trading account has been approved and
            funded, you can use your Account Management page to
            open a [496]Paper Trading Account which lets you use
            the full range of trading facilities in a simulated
            environment using real market conditions. Using a
            Paper Trading Account will allow you not only to get
            familiar with the TWS API but also to test your
            trading strategies without risking your capital. Note
            the paper trading environment has
            inherent [497]limitations.

    [496] https://www.ibkrguides.com/clientportal/papertradingaccount.htm
    [497] https://www.ibkrguides.com/clientportal/aboutpapertradingaccounts.htm

Requirements

Copy Location
               o A funded and opened IBKR Pro account
               o The current Stable or Latest release of the TWS
                 or IB Gateway
               o The current Stable or Latest release of the TWS
                 API
               o A working knowledge of the programming language
                 our Testbed sample projects are developed in.

Unset Values

Copy Location
            Developers may often find a super-massive value
            returned from requests like market data, P&L
            information, and elsewhere. These are known as Unset
            values. Unset values are used throughout programming
            systems to indicate that a value is not available.
            Unset values are used in place of NULL characters to
            prevent any unexpected error be thrown in your code.
            Unset values are also used in place of values like 0
            to avoid confusing viewers to believe they have an
            account balance of 0, or that an equity is worth $0.
            An unset value is the maximum value of a given data
            type. So the Unset Double value will appear like
            1.7976931348623157E308, which contains approximately
            308 digits to intentionally appear extraneous.

Download TWS or IB Gateway

Copy Location
            In order to use the TWS API, all customers must
            install either Trader Workstation or IB Gateway to
            connect the API to. Both downloads maintain the same
            level of usage and support; however, they both have
            equal benefits. For example, IB Gateway will be less
            resource intensive as there is no UI; however, the
            Trader Workstation has access all of the same
            information as the API, if users would like an
            interface to confirm data.

            It is recommended for API users to use offline TWS
            because TWS online version has automatic update.
            Please use same TWS version to make sure the TWS
            version and TWS API version are synced. These will
            help preventing version conflict issue.


            Note:
              1. For IBHK API users, it is commended to use IB
                 Gateway instead of TWS. It is because all IBHK
                 users cannot choose “Never Lock Trader
                 Workstation” in TWS – Global Configuration – Lock
                 and Exit. If there is inactivity, TWS will be
                 locked and there will be API disconnection.
            [498]Download Trader Workstation [499]Download IB
            Gateway

    [498] https://www.interactivebrokers.com/en/trading/tws.php#tws-software
    [499] https://www.interactivebrokers.com/en/trading/ibgateway-stable.php

TWS Settings

Copy Location
            Some TWS Settings affect API.

TWS Configuration For API Use

Copy Location
            In TWS Global Configuration – API – Settings, there
            are many API settings. Please enable/disable some API
            settings based on your use case.
            In this section, only the most important API settings
            for API connection and incident troubleshooting are
            covered.
            Please:
               o Enable “ActiveX and Socket Clients”
               o Disable “Read-Only API”
               o Enable “Create API message log file”
               o Enable “Include market data in API log file”
               o Change “Logging Level” to “Detail”
            If you want to establish localhost API connection,
            please enable “Allow connection from localhost only”.
            if you want to connect TWS/ IB Gateway from a remote
            server, please disable “Allow connection from
            localhost only” and put the IP Address detected in
            “Accept incoming connection attempt from <IP Address>”
            into “Trusted IPs”.
            The IP Address is usually Private IPv4 Address.
            “Trusted IPs” does not accept subnet (e.g. /27, /28).
            It only accepts single IP Addresses. In the following
            example, there is a remote computing cluster /27 which
            has 32 IP Addresses and the remote computing cluster
            will randomly assign one of the computing nodes to
            connect to TWS in every connection.  To make this
            happen, every Private IPv4 Address of the subnet are
            put into the “Trusted IPs” (You can also exclude the
            first IP Network Address and the last IP Broadcast
            Address of the subnet).
            For more details, please visit:
            [500]https://www.interactivebrokers.com/campus/ibkr-ap
            i-page/twsapi-doc/#incoming-api-connections
            Note:
              1. In TWS, if you don’ t put the remote IP Address
                 into the “Trusted IPs” and you try to establish
                 remote API connection, there will be a message
                 “Accept incoming connection attempt from <IP
                 Address>” which requires you to accept the
                 connection or reject the connection. In IB
                 Gateway, it is compulsory for IB Gateway users to
                 put the remote IP Address into the “Trusted IPs”.
                 Otherwise, there will be no connection attempt
                 detected.

    [500] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#incoming-api-connections

Best Practice: Configure TWS / IB Gateway

Copy Location
            The information listed below are not required or
            necessary in order to operate the TWS API. However,
            these steps include many references which can help
            improve the day to day usage of the TWS API that is
            not explicitly offered as a callable method within the
            API itself.

Memory Allocation

Copy Location
            In TWS/ IB Gateway – “Global Configuration” –
            “General”, you can adjust the Memory Allocation (in
            MB)*.
            This feature is to control how much memory your
            computer can assign to the TWS/ IB Gateway
            application. Usually, higher value allows users to
            have faster data returning speed.
            Normally, it is recommended for API users to set 4000.
            However, it depends on your computer memory size
            because setting too high may cause High Memory Usage
            and application not responding.
            For details, please visit:
            [501]https://www.ibkrguides.com/traderworkstation/incr
            ease-tws-memory-size.htm

    [501] https://www.ibkrguides.com/traderworkstation/increase-tws-memory-size.htm

            Note:
              1. In IB Gateway Global Configuration – API –
                 settings, there is no “Compatibility Mode: Send
                 ISLAND for US stocks trading on NASDAQ”.
                 Specifying NASDAQ exchange in contract details
                 may cause error if connecting to IB Gateway. For
                 this error, please specify ISLAND exchange.

Daily & Weekly Reauthentication

Copy Location
            It is compulsory for TWS/ IB Gateway users to auto
            logoff/auto restart TWS/ IB Gateway daily and manually
            login TWS/ IB Gateway weekly (Organizational client
            with 1M+USD in equity or large organizational client
            can request an exception from IB Gateway weekly
            reauthentication).

Daily Reauthentication
            In TWS/ IB Gateway – “Global Configuration” – “Lock
            and Exit”, you can choose the time that your TWS will
            be shut down.
            For API users, it is recommended to choose “Never lock
            Trader Workstation” and “Auto restart”.
            Note:
              1. IBHK users do not have “Never lock Trader
                 Workstation” and “Auto restart” in TWS. It is
                 suggested IBHK users to use IB Gateway for API
                 connection because IB Gateway won’t be locked due
                 to activity and IBHK users can choose “Auto
                 restart” in IB Gateway.

Weekly Reauthentication
            The weekly authentication cycle starts on every
            Monday. If you receive Login failed = Soft token=0
            received instead of expected permanent for
            zdc1.ibllc.com:4001 (SSL),  this means you need to
            manually login again to complete the weekly
            reauthentication task.

Request an exception from IB Gateway weekly reauthentication
            To request an exception from IB Gateway weekly
            reauthentication, please submit a web ticket to
            “Technical Assistance” – “Connectivity”. However, it
            is not guaranteed to accept the IB Gateway weekly
            reauthentication request.
            In the web ticket, you need to provide:
              1. IB Account Number
              2. Username(s) of the IB Account number that need to
                 be excluded from IB Gateway weekly
                 reauthentication.
              3. Is the IB Gateway on a Virtual Machine?
                    # If yes, please provide which data center.
              4. What kind of access is available for the machine
                 (Only Remote Terminal or Physical Access to
                 Console)?
                    # If only physical access is available, which
                      is the access control method?
              5. Who is administering the machine?

Operating System Sleeping
            OS Sleeping Mode also causes TWS/IB Gateway and API
            disconnection. It is strongly suggested to choose
            “Never Sleep“.

            For how to turn off Sleep Mode in Windows, please
            visit:
            [502]https://support.microsoft.com/en-us/windows/how-t
            o-adjust-power-and-sleep-settings-in-windows-26f623b5-
            4fcc-4194-863d-b824e5ea7679
            For how to turn off Sleep Mode in MacOS, please visit:
            [503]https://support.apple.com/en-hk/guide/mac-help/mc
            hle41a6ccd/mac

    [502] https://support.microsoft.com/en-us/windows/how-to-adjust-power-and-sleep-settings-in-windows-26f623b5-4fcc-4194-863d-b824e5ea7679
    [503] https://support.apple.com/en-hk/guide/mac-help/mchle41a6ccd/mac

Order Precautions

Copy Location
            In TWS – “Global Configuration” – “API” –
            “Precautions”, you can enable the following items to
            stop receiving the order submission messages.
               o Enable “Bypass Order Precautions for API orders”.
               o Enable “Bypass Bond warning for API orders”.
               o Enable “Bypass negative yield to worst
                 confirmation for API orders”.
               o Enable “Bypass Called Bond warning for API
                 orders”.
               o Enable “Bypass “same action pair trade” warning
                 for API orders”.
               o Enable “Bypass price-based volatility risk
                 warning for API orders”.
               o Enable “Bypass US Stocks market data in shares
                 warning for API orders”.
               o Enable “Bypass Redirect Order warning for Stock
                 API orders”.
               o Enable “Bypass No Overfill Protection precaution
                 for destinations where implied natively”.

Connected IB Server Location in TWS

Copy Location
            Each IB account has a pre-decided IB server. You can
            visit this link to know our IB servers’ locations:
            [504]https://www.interactivebrokers.com/download/IB-Ho
            st-and-Ports.pdf
            Yet, all IB paper accounts are connected to US server
            by default and its location cannot be changed.
            As IB servers in different regions have different
            scheduled server maintenance time (
            [505]https://www.interactivebrokers.com/en/software/sy
            stemStatus.php ), you may need to change the IB server
            location in order to avoid service downtime.
            For checking your connected IB server location, you
            can go to TWS and click “Data” to see your Primary
            server. In the below image, the pre-decided IB server
            location is: cdc1.ibllc.com
            If you want to change your live IB account server
            location in TWS, please submit a web ticket to
            “Technical Assistance” – “Connectivity” in order to
            request changing the IB server location.
            In the web ticket, you need to provide:
              1. Which account do you want to have IB server
                 location change?
              2. Which IB server location would you like to
                 connect to?
                    # TWS AMERICA – EAST (New York)
                    # TWS AMERICA – CENTRAL (Chicago)
                    # TWS Europe (Zurich)
                    # TWS Asia (Hong Kong)
                    # TWS Asia – CHINA (For mainland China users,
                      if the account server is hosted in Hong
                      Kong, they will automatically connect with
                      the Shenzhen Gateway mcgw1.ibllc.com.cn)
              3. Which IB scheduled maintenance time do you
                 choose? (Recommended to choose the default
                 schedule maintenance time of its own IB server
                 location)
                    # North America
                    # Europe
                    # Asia
            After you submit the ticket, you will receive a web
            ticket reply which require you to confirm and
            understand the migration request.

    [504] https://www.interactivebrokers.com/download/IB-Host-and-Ports.pdf
    [505] https://www.interactivebrokers.com/en/software/systemStatus.php

            Note:
              1. For Internet users, as the connection between IB
                 server and Exchange goes through a dedicated
                 line, it is commonly recommended to choose a IB
                 server location which is closer to your TWS
                 location. For IB connection types, please visit:
                 [506]https://www.interactivebrokers.co.uk/en/soft
                 ware/connectionInterface.php
              2. The pre-decided IB server location connected from
                 TWS is different from the IB Server location
                 connected from IB Client Portal and IBKR Mobile.
                    # IB server location connected from TWS is
                      pre-decided. You can submit a web ticket to
                      request the IB server relocation for the TWS
                      connection.
                    # IB server location connected from Client
                      Portal, IBKR Mobile is based on your nearest
                      IB server location. You cannot request the
                      IB server relocation for Client Portal and
                      IBKR Mobile connections. However, OAuth CP
                      API users can specify which server they want
                      to connect to by themselves. For details,
                      please visit:
                      [507]https://www.interactivebrokers.com/camp
                      us/ibkr-api-page/cpapi-v1/#oauth-base-url

    [506] https://www.interactivebrokers.co.uk/en/software/connectionInterface.php
    [507] https://www.interactivebrokers.com/campus/ibkr-api-page/cpapi-v1/#oauth-base-url

SMART Algorithm

Copy Location
            In TWS Global Configuration – Orders – Smart Routing,
            you can set your SMART order routing algorithm. For
            available SMART Routing via TWS API, please visit:
            [508]https://www.interactivebrokers.com/campus/ibkr-ap
            i-page/contracts/#smart-routing

    [508] https://www.interactivebrokers.com/campus/ibkr-api-page/contracts/#smart-routing

Allocation Setup (For Financial Advisors)

Copy Location
            In TWS Global Configuration – Advisor Setup – Presets,
            you can need to choose Allocation Preference in order
            to avoid wrong allocation result.

Intelligent Order Resubmission

Copy Location
            The TWS Setting listed in the Global Configuration
            under API -> Setting for Maintain and resubmit orders
            when connection is restored, is enabled by default in
            TWS 10.28 and above. When this setting is checked, all
            orders received while connectivity is lost will be
            saved and automatically resubmitted when connectivity
            is restored. Please note, if the Trader Workstation is
            closed during this time, the orders are deleted
            regardless of the setting.

Disconnect on Invalid Format

Copy Location
            The TWS Setting listed in the Global Configuration
            under API -> Setting for Maintain connection upon
            receiving incorrectly formatted fields, is enabled by
            default in TWS 10.28 and above. For clients operating
            on Client Version 100 and above, users will not
            disconnect from fields with invalid value submissions
            when the setting is enabled.

Download the TWS API

Copy Location
            Current LTS API version is 10.16 or above. It is
            STRONGLY RECOMMENDED for 10.16 version below API users
            to upgrade API.

            It is recommended for API users to use same TWS API
            version to make sure the TWS version and TWS API
            version are synced in order to prevent version
            conflict issue.

            Running the Windows version of the API installer
            creates a directory “C:\\TWS API\” for the API source
            code in addition to automatically copying two files
            into the Windows directory for the DDE and C++
            APIs. It is important that the API installs to the C:
            drive, as otherwise API applications may not be able
            to find the associated files. The Windows installer
            also copies compiled dynamic linked libraries (DLL) of
            the ActiveX control TWSLib.dll, C# API CSharpAPI.dll,
            and C++ API TwsSocketClient.dll. Starting in API
            version 973.07, running the API installer is designed
            to install an ActiveX control TWSLib.dll, and
            TwsRtdServer control TwsRTDServer.dll which are
            compatible with both 32 and 64 bit applications.

            It is important to know that the TWS API is only
            available through the interactivebrokers.github.io MSI
            or ZIP file. Any other resource, including pip, NuGet,
            or any other online repository is not hosted,
            endorsed, supported, or connected to Interactive
            Brokers. As such, updates to the installation should
            always be downloaded from the github directly.
            [509]TWS API Download Page

    [509] https://interactivebrokers.github.io/

How to install the TWS API Components on Mac / Unix

Copy Location
              1. Download the IB API Stable for Mac/Unix zip file
                 to your local machine
              2. This will direct you to Interactive Brokers API
                 License Agreement, please review it
              3. Once you have clicked “I Agree“, refer to the Mac
                 / Unix section to download the API Software
                 version of your preference
                 API Software Download List API Software Download
                 List
              4. This will download twsapi_macunix.<Major
                 Version>.<Minor Version>.zip to your computer
                 (where <Major Version> and <Minor Version> are
                 the major and minor version numbers respectively)
              5. Open Terminal (Ctrl+Alt+T on most distributions)
                 (On Mac press Command+Space to launch Spotlight,
                 then type terminal and press Return)
              6. Navigate to the directory where the installer has
                 been downloaded (normally it should be the
                 Download folder within your home folder) and
                 confirm the file is present
                  $  cd ~/Downloads
                  $  ls
              7. Unzip the contents the installer into your home
                 folder with the following command (if prompted,
                 enter your password):
                 NOTE: replace the values ‘n.m’ with the name of
                 your installed file.
                 $  sudo unzip twsapi_macunix.n.m.zip -d $HOME/
                 Installation directions Step 3 and Step 4
                 Installation directions Step 3 and Step 4
              8. To access the sample and source files, navigate
                 to the IBJts directory and confirm the subfolders
                 samples and source are present
                 $  cd ~/IBJts
                 $  ls

            Note:
               o When running “python3 setup.py install“,  you may
                 get “ModuleNotFoundError: No Module named
                 ‘setuptools’“. As “setuptools” is deprecated,
                 please grant the write permission on the target
                 folder (e.g. source/pythonclient) using “sudo
                 chmod -R 777” in order to avoid “error: could not
                 create ‘ibapi.egg-info’: Permission denied“.
                 After that, run “python3 -m pip install .“

TWS API Folder Files & Tools

Copy Location

TWS API Folder Files Explanation:

               o “API_VersionNum.txt”
            File Path: C:\TWS API\API_VersionNum.txt
            You can check your API version in this file.

               o “IBSampleApp.exe”
            File Path: C:\TWS
            API\samples\CSharp\IBSampleApp\bin\Release\IBSampleApp
            .exe
            You can manually use the IBSampleApp to test the API
            functions.

Unique Configurations

Copy Location
            While all of the available Trader Workstation API
            default samples provide equivalent functionality, some
            languages have unique configurations that must be
            implemented in order to use our samples or program
            code with the underlying API.

Implementing the Intel Decimal Library for MacOS and Linux

Copy Location
            Due to the malleability of the many Linux
            distributions including MacOS, Interactive Brokers is
            unable to provide a pre-built binary for the library.
            As such, users programming in C++ on a Linux machine
            must manually build the Intel® Decimal Floating-Point
            Math Library manually.
            As described in the README file from the linked page,
            you can find the library’s build steps within the
            ~/IntelRDFPMathLib20U2/LIBRARY/README file.
            [510]Download the Intel® Decimal Floating-Point Math
            Library

    [510] https://www.intel.com/content/www/us/en/developer/articles/tool/intel-decimal-floating-point-math-library.html

Updating The Python Interpreter

Copy Location
            Python has a unique system for importing libraries
            into it’s IDEs. This extends even further when it
            comes to virtual environments. In order to utilize
            Python code with the TWS API, you must run our setup
            file in order to import the code.

1. Open Command Prompt or Terminal

Copy Location
            In order to update the Python IDE, these steps MUST be
            performed through Command Prompt or Terminal. This can
            not be done through an explorer interface.
            As such, users should begin by launching their
            respective command line interface.
            These samples will display Windows commands, though
            the procedure is identical on Windows, MacOS, and
            Linux.
            Displays the standard cmd Displays the standard cmd

2. Navigate to Python Source

Copy Location
            Customers should then change their directory to  {TWS
            API}\source\pythonclient .
            It is then recommend to display the contents of the
            directory with “ls” for Unix, or “dir” for Windows
            users.
            Displays directory navigation to the python source
            Displays directory navigation to the python source

3. Run The setup.py File

Copy Location
            Customers will now need to run the setup.py steps with
            the installation parameter. This can be done with the
            command: python setup.py install
            Displays the setup.py install command Displays the
            setup.py install command

4. Confirm Updates

Copy Location
            After running the prior command, users should see a
            large block of text describing various values being
            updated and added to their system. It is important to
            confirm that the version installed on your system
            mirrors the build version displayed. This example
            represents 10.25; however, you may have a different
            version.
            Displays the updated packages from setup.py Displays
            the updated packages from setup.py

5. Confirm your installation

Copy Location
            Finally, users should look to confirm their
            installation. The simplest way to do this is to
            confirm their version with pip. Typing this command
            should show the latest installed version on your
            system: python -m pip show ibapi
            Displays the result of pip show ibapi Displays the
            result of pip show ibapi

Implementing Visual Basic .NET

Copy Location
            Our VB.NET code is provided for demonstration purposes
            only; there is no pure, standalone VB.NET-based TWS
            API library. Both our “VB_API_Sample” and the VB.NET
            “Testbed” projects included with our TWS API releases
            call the C# TWS API source. The provided VB.NET code
            only interfaces with the C# source. Please keep in
            mind that these samples are in VB.NET, not Visual
            Basic for Applications.

Third Party API Platforms

Copy Location
            Third party software vendors make use of the TWS’
            programming interface (API) to integrate their
            platforms with Interactive Broker’s. Thanks to the TWS
            API, well known platforms such as Ninja Trader or
            Multicharts can interact with the TWS to fetch market
            data, place orders and/or manage account and portfolio
            information.
            It is important to keep in mind that most third party
            API platforms are not compatible with all IBKR account
            structures. Always check first with the software
            vendor before opening a specific account type or
            converting an IBKR account type. For instance, many
            third party API platforms such as NinjaTrader and
            TradeNavigator are not compatible with IBKR linked
            account structures, so it is highly recommended to
            first check with the third party vendor before linking
            your IBKR accounts.
            An ongoing list of common [511]Third Party Connections
            are available within our documentation. This resource
            will also link out to connection guides detailing how
            a user can connect with a given platform.
            A non-exhaustive list of third party platforms
            implementing our interface can be found in
            our [512]Investor’s Marketplace. As stated in the
            marketplace, the vendors’ list is in no way a
            recommendation from Interactive Brokers. If you are
            interested in a given platform that is not listed,
            please contact the platform’s vendor directly for
            further information.

    [511] https://www.interactivebrokers.com/campus/ibkr-api-page/third-party-connections/
    [512] https://www.interactivebrokers.com/Universal/servlet/MarketPlace.MarketPlaceServlet

Troubleshooting & Support

Copy Location
            The API documentation contains a complete description
            of all API functions. Additionally the source code of
            the API itself is distributed freely and is a great
            resource for more in-depth understanding of how the
            API works. If after reviewing these resources there
            are remaining questions about available API
            functionality, the API Support group is available to
            help.
            -> It is important to keep in mind that IB cannot
            provide programming assistance or give suggestions on
            how to code custom applications. The API group can
            review log files which contain a record of
            communications between API applications and TWS, and
            give details about what the API can provide.
            General suggestions on starting out with the IB
            system:
               o Become familiar with the analogous functionality
                 in TWS before using the API: the TWS API is
                 nothing but a communication channel between your
                 client application and TWS. Each API function has
                 a corresponding tool in TWS. For instance, the
                 market data tick types in the API correspond to
                 watchlist columns in TWS. Any order which can be
                 created in the API can first be created in TWS,
                 and it is recommended to do so. Additionally, if
                 information is not available in TWS, it will not
                 be available in the API. Before using IB Gateway
                 with the API, it is recommended to first become
                 familiar with TWS.
               o Make use of the sample API applications: the
                 sample applications distributed with the API
                 download have examples of essentially every API
                 function in each of the available programming
                 languages. If an issue does not occur in the
                 corresponding sample application, that implies
                 there is a problem with the custom
                 implementation.
               o Upgrade TWS or IB Gateway periodically: TWS and
                 IB Gateway often have new software releases that
                 have enhancements, and that can sometimes have
                 bug fixes. Because of this, we strongly recommend
                 our users to keep their software as up to date as
                 possible. There is no problem with staying with a
                 version of the API and upgrading TWS, as TWS/IB
                 Gateway are designed to be backwards compatible
                 with older API versions. If you are experiencing
                 a specific problem that is occurring in TWS or IB
                 Gateway and not in the API program, it is quite
                 possible it does not occur in the more recent
                 software build.

Understanding Order Precautions

Copy Location
            By default, the Trader Workstation implements several
            precautionary settings that will notify customers of
            potential order risks to make sure users are well
            informed before transmitting orders. As a result,
            customers will typically need to acknowledge a
            precautionary message and manually transmit the orders
            through the Trader Workstation. These precautionary
            messages may be disabled if the user is comfortable
            and aware of the behavior they are disabling.

Disabling Warning Messages

Copy Location
              1. Log in to the Trader Workstation
              2. Open the Global Configuration by selecting the
                 Cog Wheel icon in the top right corner
              3. Navigate to the “Messages” section on the left.
              4. Carefully read each message before disabling it.
                 You can then disable the warning by unchecking
                 the box on the right of the message description.

Modifying Precautionary Settings

Copy Location
              1. Log in to the Trader Workstation
              2. Open the Global Configuration by selecting the
                 Cog Wheel icon in the top right corner
              3. Navigate to the “Presets” section on the left
              4. Select the instrument(s) you are trading
              5. Carefully read each setting before making changes
                 to it. You may modify the values inside the
                 “Precautionary Settings” settings to be more or
                 less restrictive. You may also set the value to
                 ‘0’ to disable the precaution entirely.

Log Files

Copy Location
            The log files are essential to provide detailed
            information about how a custom application may be
            malfunctioning. They are useful tools for direct
            review by an API application programmer, and
            additionally they can be uploaded for review by the
            API Support group.

API Logs

Copy Location
            TWS and IB Gateway can be configured to create a
            separate log file which has a record of just
            communications with API applications. This log is not
            enabled by default; but needs to be enabled by the
            Global Configuration setting “Create API Message Log
            File”(picture below).
               o API logs contain a record of exchanged messages
                 between API applications and TWS/IB Gateway.
                 Since only API messages are recorded, the API
                 logs are more compact and easier to handle.
                 However they do not contain general diagnostic
                 information about TWS/IBG as the TWS/IBG logs.
                 The TWS/IBG settings folder is by
                 default C:\Jts (or IBJts on Mac/Linux). The API
                 logs are named api.[clientId].[day].log, where
                 [clientId] corresponds to the Id the client
                 application used to connect to the TWS and [day]
                 to the week day (i.e. api.123.Thu.log).
               o There is also a setting “Include Market Data in
                 API Log” that will include streaming market data
                 values in the API log file. Historical
                 candlestick data is always recorded in the API
                 log.
            Note: Both the API and TWS logs are encrypted locally.
            The API logs can be decrypted for review from the
            associated TWS or IB Gateway session, just like the
            TWS logs, as shown in the section describing the Local
            location of logs.
            Enabling creation of API logs
            TWS:
              1. Navigate to File/Edit → Global Configuration →
                 API → Settings
              2. Check the box Create API message log file
              3. Click Apply and Ok

            IB Gateway:
              1. Navigate to Configure → Settings → API → Settings
              2. Check the box Create API message log file
              3. Click Apply and Ok

TWS Log Files

Copy Location
            The TWS Logging Level must be set to the ‘Detail’
            level to record information pertinent to the API. By
            default it is at the ‘Error’ level which records a
            minimum of diagnostic information. To capture API
            messages it is necessary to change the Logging Level
            to ‘Detail’. Note the ‘Logging Level’, like all
            TWS/IBG settings, is saved separately for different
            users and for TWS and IBG.
               o Important: The TWS/IB Gateway log file setting
                 has to be set to ‘Detail’ level before an issue
                 occurs so that information recorded correctly
                 when it manifests. However due to the high amount
                 of information that will be generated under this
                 level, the resulting logs can grow considerably
                 in size. It is therefore recommended to use the
                 ‘Detail’ level only when troubleshooting and/or
                 tracking a very specific issue. This can also be
                 done from the API client itself using
                 the IBApi.EClient.setServerLogLevel function.
                 Some third party applications, such as
                 NinjaTrader, are configured to invoke this
                 function to set the TWS Logging Level every time
                 they connect, and so to set the TWS Log to
                 ‘Detail’ this will have to be done from within
                 the API client program.
            TWS:
              1. Navigate to File/Edit → Global Configuration →
                 API → Settings
              2. Set Logging Level to Detail
            IB Gateway:
              1. Navigate to Configure → Settings → API → Settings
              2. Set Logging Level to Detail

Local location of logs

Copy Location
            Logs are stored in the TWS settings directory, C:\Jts\
            by default on a Windows computer (the default can be
            configured differently on the login screen).
            The path to the log file directory can be found from a
            TWS or IB Gateway session by using the
            combination Ctrl-Alt-U. This will reveal path such as
            C:\Jts\detcfsvirl\ (on Windows).
            Due to privacy regulations, logs are encrypted before
            they are saved to disk. They can be decrypted from the
            associated TWS or IB Gateway session.
               o In TWS: Classic TWS  Help -> Troubleshooting ->
                 Diagnostics -> TWS Logs.
               o In IB Gateway, File -> Gateway Logs.

Uploading Logs

Copy Location
            If API logging has been enabled with the setting
            “Create API Message Log” during the time when an issue
            occurs, it can be uploaded to the API group.
            To upload logs as a Windows user:
              1. In TWS or IB Gateway, press CTRL+ALT+H to bring
                 up the Upload Diagnostics window.
              2. In the “reason” text field, please type the
                 reason for your upload.
                    # Alternatively, type “ATTENTION: ” and then
                      the ticket number you are working with, or
                      the name of your customer service
                      representative.
              3. Find the small arrow in the upper right corner,
                 click it and select “Advanced View”
              4. Make sure “Full internal state of the
                 application” is checked
              5. Make sure “Include previous days logs and
                 settings” is unchecked, unless the error happened
                 on a prior day.
              6. Click Submit
            To upload logs as a Mac and Linux user:
              1. In TWS or IB Gateway, press CMD+OPT+H to bring up
                 the Upload Diagnostics window.
              2. In the “reason” text field, please type the
                 reason for your upload.
                    # Alternatively, type “ATTENTION: ” and then
                      the ticket number you are working with, or
                      the name of your customer service
                      representative.
              3. Find the small arrow in the upper right corner,
                 click it and select “Advanced View”
              4. Make sure “Full internal state of the
                 application” is checked
              5. Make sure “Include previous days logs and
                 settings” is unchecked, unless the error happened
                 on a prior day.
              6. Click Submit
            If logs have been uploaded, please let the API Support
            group know by creating a webticket in the Message
            Center in Account Management (under Support)
            indicating the username of the associated TWS session.
            In some cases a TWS log may also be requested at the
            Detailed logging level. The TWS log can grow quite
            large and may not be uploadable by the automatic
            method; in this case an alternative means of upload
            can be found.

Exporting Logs

Copy Location
              1. In TWS, navigate to Help menu >> Troubleshooting
                 >> Diagnostics >> “API Logs” or “TWS Logs”.
              2. In IBG, both “API Logs” and “Gateway Logs” are
                 accessible directly from the File menu.
              3. Click “Export Today Logs…” to decrypt the logs
                 and save them in plaintext (logs are stored
                 encrypted on your local machine)

Reading Exported Logs

Copy Location
            Each supported API language of the API contains a
            message file that translates a given number identifier
            into their corresponding request. The message
            identifier numbers used in the underlying wire
            protocol is the core of the TWS API.
            The information on the right documents where each
            message reader file is located. The {TWS API} listed
            is the path to the primary TWS API or JTS folder
            created from the API installation.
            By default, this will be saved directly on the C:
            drive.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
            Both the Incoming and Outgoing message IDs are listed
            in one file.
            {TWS API}\source\pythonclient\ibapi\messages.py
            Incoming Message IDs:
            {TWS
            API}\source\JavaClient\com\ib\client\EDecoder.java
            Outgoing Message IDs:
            {TWS API}\source\JavaClient\com\ib\client\EClient.java
            Incoming Message IDs:
            {TWS API}\source\CppClient\client\EDecoder.h
            Outgoing Message IDs:
            {TWS API}\source\CppClient\client\EClient.h
            Incoming Message IDs:
            {TWS
            API}\source\CSharpClient\client\IncomingMessage.cs
            Outgoing Message IDs:
            {TWS
            API}\source\CSharpClient\client\OutgoingMessages.cs
            Depending on the Excel structure used, either C# or
            Java file path will be used.
            For ActiveX and RTD, see C#
            For DDE, see Java.
            In our API logs, the direction of the message is
            indicated by the arrow at the beginning:
            -> for incoming messages (TWS to client)
            <- for outgoing messages (client to TWS)
            Thus  <- 3 (outgoing request of type 3) is a
            placeOrder request, and the subsequent incoming
            requests are:
            -> 5 = openOrder response
            -> 11 = executionData response
            -> 59 = commissionReport response
            Also note that the first openOrder response carries
            with it an orderStatus response in the same message.
            If that status were to change later, it would be
            delivered as a standalone message:
            -> 3 = orderStatus response

How To Enable Debug Logging

Copy Location
            Enabling DEBUG-level logging for the host platform
            (TWS or IBG, this does not affect API logs):
              1. Navigate to the root TWS/IBG installation
                 directory
              2. Find jts.ini and open in text editor
              3. Put debug=1 under the [Communication] section
              4. Reboot TWS/IBG
            Setting debug=1 has added benefits in TWS.
              1. Debug=1 also allows you to enter conIds into a
                 watchlist to resolve them into symbols.
                 Type/paste the conId in an empty watchlist row,
                 add |C (vertical bar, capital C) at the end, and
                 press Enter. Example: 265598|C will resolve
                 immediately to AAPL (exchange will be SMART where
                 available, primary otherwise).
                    # If the instrument is already present in the
                      watchlist, nothing will happen.
              2. Additional detail in the “Description” window for
                 an instrument, normally available by
                 right-clicking on an instrument in a watchlist
                 and selecting Financial Instrument Info >>
                 Description from the context menu. Debug=1 will
                 add the conId, min order sizes, market rules
                 (i.e., min price increments and thresholds), all
                 available order types, and all available
                 exchanges to this interface. Changing the
                 behavior of TWS to bring up that Description
                 window on double-click can make it easier to
                 find.
                   1. In TWS, go to Global Configuration >>
                      Display >> Ticker Row
                   2. Change “Double-click on Financial Instrument
                      will” dropdown menu to “Open Contract
                      Details”

Architecture

Copy Location
            The IBApi.EWrapper interface is the mechanism through
            which the TWS delivers information to the API client
            application. By implementing this interface the client
            application will be able to receive and handle the
            information coming from the TWS. For further
            information on how to implement interfaces, refer to
            your programming language’s documentation.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
class TestWrapper(wrapper.EWrapper):

public class EWrapperImpl implements EWrapper {

class TestCppClient : public EWrapper
    {

public class EWrapperImpl : EWrapper
   {

Public Class EWrapperImpl
    Implements EWrapper

            The class used to send messages to TWS is
            IBApi.EClientSocket. Unlike EWrapper, this class is
            not overriden as the provided functions in
            EClientSocket are invoked to send messages to TWS. To
            use EClientSocket, first it may be necessary to
            implement the IBApi.EWrapper interface as part of its
            constructor parameters so that the application can
            handle all returned messages. Messages sent from TWS
            as a response to function calls in IBApi.EClientSocket
            require an EWrapper implementation so they can be
            processed to meet the needs of the API client.
            Another crucial element is the IBApi.EReaderSignal
            object passed to theEClientSocket’s constructor. With
            the exception of Python, this object is used in APIs
            to signal a message is ready for processing in the
            queue. (In Python the Queue class handles this task
            directly). We will discuss this object in more detail
            in the The EReader Thread section.

            In conclusion:
               o EClient functions are for requesting data to IB
                 server.
               o EWrapper functions are for receiving data from IB
                 server.
               o Missing anyone of them cannot let you
                 successfully request/receive data.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
class TestClient(EClient):
     def __init__(self, wrapper):
         EClient.__init__(self, wrapper)
...
class TestApp(TestWrapper, TestClient):
        def __init__(self):
        TestWrapper.__init__(self)
         TestClient.__init__(self, wrapper=self)
            Note: The EReaderSignal class is not used for Python
            API. The Python Queue module is used for inter-thread
            communication and data exchange.
private EReaderSignal readerSignal;
private EClientSocket clientSocket;
protected int currentOrderId = -1;

            …
public EWrapperImpl() {
    readerSignal = new EJavaSignal();
    clientSocket = new EClientSocket(this, readerSignal);
}

EReaderOSSignal m_osSignal;
    EClientSocket * const m_pClient;
            …
TestCppClient::TestCppClient() :
      m_osSignal(2000)//2-seconds timeout
    , m_pClient(new EClientSocket(this, &m_osSignal))
    , m_state(ST_CONNECT)
    , m_sleepDeadline(0)
    , m_orderId(0)
    , m_extraAuth(false)
{
}

EClientSocket clientSocket;
public readonly EReaderSignal Signal;
            …
public EWrapperImpl()
{
    Signal = new EReaderMonitorSignal();
    clientSocket = new EClientSocket(this, Signal);
}

Public eReaderSignal As EReaderSignal
Public socketClient As EClientSocket
            …
Sub New()
    eReaderSignal = New EReaderMonitorSignal
    socketClient = New EClientSocket(Me, eReaderSignal)
End Sub

The Trader Workstation

Copy Location
            Our market maker-designed IBKR Trader Workstation
            (TWS) lets traders, investors, and institutions trade
            stocks, options, futures, forex, bonds, and funds on
            over 100 markets worldwide from a single account. The
            TWS API is a programming interface to TWS, and as
            such, for an application to connect to the API there
            must first be a running instance of TWS or IB Gateway.

The IB Gateway

Copy Location
            As an alternative to TWS for API users, IBKR also
            offers IB Gateway (IBGW). From the perspective of an
            API application, IB Gateway and TWS are identical;
            both represent a server to which an API client
            application can open a socket connection after the
            user has authenticated. With either application (TWS
            or IBGW), the user must manually enter their username
            and password into a login window. For security
            reasons, a headless session of TWS or IBGW without a
            GUI is not supported. From the user’s perspective, IB
            Gateway may be advantageous because it is a lighter
            application which consumes about 40% fewer resources.
            Both TWS and IBGW were designed to be restarted daily.
            This is necessary to perform functions such as
            re-downloading contract definitions in cases where
            contracts have been changed or new contracts have been
            added. Beginning in version 974+ both applications
            offer an autorestart feature that allows the
            application to restart daily without user
            intervention. With this option enabled, TWS or IBGW
            can potentially run from Sunday to Sunday without
            re-authenticating. After the nightly server reset on
            Saturday night it will be necessary to again enter
            security credentials.
            The advantages of TWS over IBGW is that it provides
            the end user with many tools (Risk Navigator,
            OptionTrader, BookTrader, etc) and a graphical user
            interface which can be used to monitor an account or
            place orders. For beginning API users, it is
            recommended to first become acquainted with TWS before
            using IBGW.
            For simplicity, this guide will mostly refer to the
            TWS although the reader should understand that for the
            TWS API’s purposes, TWS and IB Gateway are synonymous.

Connectivity

Copy Location
            A socket connection between the API client application
            and TWS is established with the
            IBApi.EClientSocket.eConnect function. TWS acts as a
            server to receive requests from the API application
            (the client) and responds by taking appropriate
            actions. The first step is for the API client to
            initiate a connection to TWS on a socket port where
            TWS is already listening. It is possible to have
            multiple TWS instances running on the same computer if
            each is configured with a different API socket port
            number. Also, each TWS session can receive up to 32
            different client applications simultaneously. The
            client ID field specified in the API connection is
            used to distinguish different API clients.

Establishing an API connection

Copy Location
            Once our two main objects have been created, EWrapper
            and ESocketClient, the client application can connect
            via the IBApi.EClientSocket object:
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
app.connect("127.0.0.1", args.port, clientId=0)

m_client.eConnect("127.0.0.1", 7497, 2);


bool bRes = m_pClient->eConnect( host, port, clientId, m_extraAuth);

clientSocket.eConnect("127.0.0.1", 7497, 0);

socketClient.eConnect("127.0.0.1", 7497, 0)

            eConnect starts by requesting from the operating
            system that a TCP socket be opened to the specified IP
            address and socket port. If the socket cannot be
            opened, the operating system (not TWS) returns an
            error which is received by the API client as error
            code 502 to IBApi.EWrapper.error (Note: since this
            error is not generated by TWS it is not captured in
            TWS log files). Most commonly error 502 will indicate
            that TWS is not running with the API enabled, or it is
            listening for connections on a different socket port.
            If connecting across a network, the error can also
            occur if there is a firewall or antivirus program
            blocking connections, or if the router’s IP address is
            not listed in the “Trusted IPs” in TWS.
            After the socket has been opened, there must be an
            initial handshake in which information is exchanged
            about the highest version supported by TWS and the
            API. This is important because API messages can have
            different lengths and fields in different versions and
            it is necessary to have a version number to interpret
            received messages correctly.
               o For this reason it is important that the main
                 EReader object is not created until after a
                 connection has been established. The initial
                 connection results in a negotiated common version
                 between TWS and the API client which will be
                 needed by the EReader thread in interpreting
                 subsequent messages.
            After the highest version number which can be used for
            communication is established, TWS will return certain
            pieces of data that correspond specifically to the
            logged-in TWS user’s session. This includes (1) the
            account number(s) accessible in this TWS session, (2)
            the next valid order identifier (ID), and (3) the time
            of connection. In the most common mode of operation
            the EClient.AsyncEConnect field is set to false and
            the initial handshake is taken to completion
            immediately after the socket connection is
            established. TWS will then immediately provides the
            API client with this information.
               o Important:
                 The IBApi.EWrapper.nextValidID callback is
                 commonly used to indicate that the connection is
                 completed and other messages can be sent from the
                 API client to TWS. There is the possibility that
                 function calls made prior to this time could be
                 dropped by TWS.
            There is an alternative, deprecated mode of connection
            used in special cases in which the variable
            AsyncEconnect is set to true, and the call to startAPI
            is only called from the connectAck() function. All IB
            samples use the mode AsyncEconnect = False.

The EReader Thread

Copy Location
            API programs always have at least two threads of
            execution. One thread is used for sending messages to
            TWS, and another thread is used for reading returned
            messages. The second thread uses the API EReader class
            to read from the socket and add messages to a queue.
            Everytime a new message is added to the message queue,
            a notification flag is triggered to let other threads
            now that there is a message waiting to be processed.
            In the two-thread design of an API program, the
            message queue is also processed by the first thread.
            In a three-thread design, an additional thread is
            created to perform this task. The thread responsible
            for the message queue will decode messages and invoke
            the appropriate functions in EWrapper. The
            two-threaded design is used in the IB Python sample
            Program.py and the C++ sample TestCppClient, while the
            ‘Testbed’ samples in the other languages use a
            three-threaded design. Commonly in a Python
            asynchronous network application, the asyncio
            module will be used to create a more sequential
            looking code design.
            The class which has functionality for reading and
            parsing raw messages from TWS is the IBApi.EReader
            class.
            In Python IB API, the code below is included in
            Client::connect(), so the EReader thread is
            automatically started upon connection. There is no
            need for user to start the reader.
            Once the client is connected, a reader thread will be
            automatically created to handle incoming messages and
            put the messages into a message queue for further
            process. User is required to trigger Client::run()
            below, where the message queue is processed in an
            infinite loop and the EWrapper call-back functions are
            automatically triggered.
               o (BUTTON) Python
# You don't need to run this in your code!
self.reader = reader.EReader(self.conn, self.msg_queue)
self.reader.start()   # start thread

app.run()


            For C#, Java, C++, and Visual Basic, we instead
            maintain a triple thread structure which requires the
            creation of a reader thread, a queue thread, and then
            a wrapper thread. The documentation listed here
            further elaborates on the structure for those
            languages.
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
final EReader reader = new EReader(m_client, m_signal);

reader.start();
//An additional thread is created in this program design to empty the me
ssaging queue
new Thread(() -> {
    while (m_client.isConnected()) {
        m_signal.waitForSignal();
        try {
             reader.processMsgs();
        } catch (Exception e) {
            System.out.println("Exception: "+e.getMessage());
        }
    }
}).start();


m_pReader = std::unique_ptr<EReader>( new EReader(m_pClient, &m_osSignal
) );
m_pReader->start();


//Create a reader to consume messages from the TWS. The EReader will con
sume the incoming messages and put them in a queue
var reader = new EReader(clientSocket, readerSignal);
reader.Start();
//Once the messages are in the queue, an additional thread can be create
d to fetch them
new Thread(() => { while (clientSocket.IsConnected()) { readerSignal.wai
tForSignal(); reader.processMsgs(); } }) { IsBackground = true }.Start()
;
'Once the messages are in the queue, an additional thread need to fetch
them
Dim msgThread As Thread = New Thread(AddressOf messageProcessing)
msgThread.IsBackground = True
If (wrapperImpl.serverVersion() > 0) Then Call msgThread.Start()

Private Sub messageProcessing()
    Dim reader As EReader = New EReader(wrapperImpl.socketClient, wrappe
rImpl.eReaderSignal)
    reader.Start()
    While (wrapperImpl.socketClient.IsConnected)
        wrapperImpl.eReaderSignal.waitForSignal()
        reader.processMsgs()
    End While
End Sub


            Now it is time to revisit the role of
            IBApi.EReaderSignal initially introduced in The
            EClientSocket Class. As mentioned in the previous
            paragraph, after the EReader thread places a message
            in the queue, a notification is issued to make known
            that a message is ready for processing. In the (C++,
            C#/.NET, Java) APIs, this is done via the
            IBApi.EReaderSignal object we initiated within the
            IBApi.EWrapper’s implementer. In the Python API, it is
            handled automatically by the Queue class.
            The client application is now ready to work with the
            Trader Workstation! At the completion of the
            connection, the API program will start receiving
            events such as IBApi.EWrapper.nextValidId and
            IBApi.EWrapper.managedAccounts. In TWS (not IB
            Gateway) if there is an active network connection,
            there will also immediately be callbacks to
            IBApi::EWrapper::error with errorId as -1 and
            errorCode=2104,2106, errorMsg = “Market Data Server is
            ok” to indicate there is an active connection to the
            IB market data server. Callbacks to
            IBApi::EWrapper::error with errorId as -1 do not
            represent true ‘errors’ but only notifications that a
            connection has been made successfully to the IB market
            data farms.
            IB Gateway by contrast will not make connections to
            market data farms until a request is made by the IB
            client. Until this time the connection indicator in
            the IB Gateway GUI will show a yellow color of
            ‘inactive’ rather than an ‘active’ green indication.
            When initially making requests from an API application
            it is important that the verifies that a response is
            received rather than proceeding assuming that the
            network connection is ok and the subscription request
            (portfolio updates, account information, etc) was made
            successfully.

Accepting an API connection from TWS

Copy Location
            For security reasons, by default the API is not
            configured to automatically accept connection requests
            from API applications. After a connection attempt, a
            dialogue will appear in TWS asking the user to
            manually confirm that a connection can be made:
            To prevent the TWS from asking the end user to accept
            the connection, it is possible to configure it to
            automatically accept the connection from a trusted IP
            address and/or the local machine. This can easily be
            done via the TWS API settings:
            Note: you have to make sure the connection has been
            fully established before attempting to do any requests
            to the TWS. Failure to do so will result in the TWS
            closing the connection. Typically this can be done by
            waiting for a callback from an event and the end of
            the initial connection handshake, such as
            IBApi.EWrapper.nextValidId or
            IBApi.EWrapper.managedAccounts.
            In rare cases in which IB Gateway or TWS has a
            momentarily delay in establishing connecting to the IB
            servers, messages sent immediately after receiving the
            nextValidId could be dropped and would need to be
            resent. If the API client has not receive the expected
            callbacks from issued requests, it should not proceed
            assumming the connection is ok.

Logging into multiple applications

Copy Location
            It is not possible to login to multiple trading
            applications simultaneously with the same username.
            However, it is possible to create additional usernames
            for an account that can be used in different trading
            applications simultaneously, as long as there is not
            more than a single trading application logged in with
            a given username at a time. There are some additional
            cases in which it is also useful to create additional
            usernames:
               o If TWS or IBGW is logged in with a username that
                 is used to login to Client Portal during that
                 session, that application will not be able to
                 automatically reconnect to the server after the
                 next disconnection (such as the server reset).
               o A TWS or IBGW session logged into a paper trading
                 account will not to receive market data if it is
                 sharing data from a live user which is used to
                 login to Client Portal.
            If a different username is utilized to login to Client
            Portal in either of these cases, then it will not
            affect the TWS/IBGW session.
            [513]How to add additional usernames in Account
            Management
               o It is important to note that market data
                 subscriptions are setup independently for each
                 live username.

    [513] https://www.ibkrguides.com/clientportal/uar/addingauser.htm

Broken API socket connection

Copy Location
            If there is a problem with the socket connection
            between TWS and the API client, for instance if TWS
            suddenly closes, this will trigger an exception in the
            EReader thread which is reading from the socket. This
            exception will also occur if an API client attempts to
            connect with a client ID that is already in use.
            The socket EOF is handled slightly differently in
            different API languages. For instance in Java, it is
            caught and sent to the client application to
            IBApi::EWrapper::error with errorCode 507: “Bad
            Message”. In C# it is caught and sent to
            IBApi::EWrapper::error with errorCode -1. The client
            application needs to handle this error message and use
            it to indicate that an exception has been thrown in
            the socket connection. Associated functions such as
            IBApi::EWrapper::connectionClosed and
            IBApi::EClient::IsConnected functions are not called
            automatically by the API code but need to be handled
            at the API client-level*.

Account & Portfolio Data

Copy Location
            The IBApi.EClient.reqAccountSummary method creates a
            subscription for the account data displayed in the TWS
            Account Summary window. It is commonly used with
            multiple-account structures. Introducing broker
            (IBroker) accounts with more than 50 subaccounts or
            configured for on-demand account lookup cannot use
            reqAccountSummary with group=”All”. A profile name can
            be accepted in place of group. See Unification of
            Groups and Profiles.
            The TWS offers a comprehensive overview of your
            account and portfolio through its Account and
            Portfolio windows. This information can be obtained
            via the TWS API through three different kind of
            requests/operations.

Account Summary

Copy Location
            The initial invocation of reqAccountSummary will
            result in a list of all requested values being
            returned, and then every three minutes those values
            which have changed will be returned. The update
            frequency of 3 minutes is the same as the TWS Account
            Window and cannot be changed.

Requesting Account Summary

Copy Location
            Requests a specific account’s summary. This method
            will subscribe to the account summary as presented in
            the TWS’ Account Summary tab. Customers can specify
            the data received by using a specific tags value. See
            the Account Summary Tags section for available
            options.
            Alternatively, many languages offer the import of
            AccountSummaryTags with a method to retrieve all tag
            values.

EClient.reqAccountSummary (
            reqId: int. The unique request identifier.
            group: String. set to “All” to return account summary
            data for all accounts, or set to a specific Advisor
            Account Group name that has already been created in
            TWS Global Configuration.
            tags: String. A comma separated list with the
            [514]desired tags
            )
            Important: only two active summary subscriptions are
            allowed at a time!
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqAccountSummary(9001, "All", AccountSummaryTags.AllTags)

            Code example:
from ibapi.client import *
from ibapi.wrapper import *
from ibapi.contract import Contract
import time

class TradeApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)

    def accountSummary(self, reqId: int, account: str, tag: str, value:
str,currency: str):
        print("AccountSummary. ReqId:", reqId, "Account:", account,"Tag:
 ", tag, "Value:", value, "Currency:", currency)

    def accountSummaryEnd(self, reqId: int):
        print("AccountSummaryEnd. ReqId:", reqId)

app = TradeApp()
app.connect("127.0.0.1", 7496, clientId=1)

time.sleep(1)

app.reqAccountSummary(9001, "All", 'NetLiquidation')
app.run()

client.reqAccountSummary(9001, "All", "AccountType,NetLiquidation,TotalC
ashValue,SettledCash,AccruedCash,BuyingPower,EquityWithLoanValue,Previou
sEquityWithLoanValue,GrossPositionValue,ReqTEquity,ReqTMargin,SMA,InitMa
rginReq,MaintMarginReq,AvailableFunds,ExcessLiquidity,Cushion,FullInitMa
rginReq,FullMaintMarginReq,FullAvailableFunds,FullExcessLiquidity,LookAh
eadNextChange,LookAheadInitMarginReq ,LookAheadMaintMarginReq,LookAheadA
vailableFunds,LookAheadExcessLiquidity,HighestSeverity,DayTradesRemainin
g,Leverage");

m_pClient->reqAccountSummary(9001, "All", AccountSummaryTags::getAllTags
());

client.reqAccountSummary(9001, "All", AccountSummaryTags.GetAllTags());

client.reqAccountSummary(9001, "All", AccountSummaryTags.GetAllTags())

Account Summary Tags

Copy Location

   AccountType Identifies the IB account structure
   NetLiquidation The basis for determining the price of the
   assets in your account. Total cash value + stock value +
   options value + bond value
   TotalCashValue Total cash balance recognized at the time of
   trade + futures PNL
   SettledCash Cash recognized at the time of settlement –
   purchases at the time of trade – commissions – taxes – fees
   AccruedCash Total accrued cash value of stock, commodities and
   securities
   BuyingPower Buying power serves as a measurement of the dollar
   value of securities that one may purchase in a securities
   account without depositing additional funds
   EquityWithLoanValue Forms the basis for determining whether a
   client has the necessary assets to either initiate or maintain
   security positions. Cash + stocks + bonds + mutual funds
   PreviousEquityWithLoanValue Marginable Equity with Loan value
   as of 16:00 ET the previous day
   GrossPositionValue The sum of the absolute value of all stock
   and equity option positions
   RegTEquity Regulation T equity for universal account
   RegTMargin Regulation T margin for universal account
   SMA Special Memorandum Account: Line of credit created when the
   market value of securities in a Regulation T account increase
   in value
   InitMarginReq Initial Margin requirement of whole portfolio
   MaintMarginReq Maintenance Margin requirement of whole
   portfolio
   AvailableFunds This value tells what you have available for
   trading
   ExcessLiquidity This value shows your margin cushion, before
   liquidation
   Cushion Excess liquidity as a percentage of net liquidation
   value
   FullInitMarginReq Initial Margin of whole portfolio with no
   discounts or intraday credits
   FullMaintMarginReq Maintenance Margin of whole portfolio with
   no discounts or intraday credits
   FullAvailableFunds Available funds of whole portfolio with no
   discounts or intraday credits
   FullExcessLiquidity Excess liquidity of whole portfolio with no
   discounts or intraday credits
   LookAheadNextChange Time when look-ahead values take effect
   LookAheadInitMarginReq Initial Margin requirement of whole
   portfolio as of next period’s margin change
   LookAheadMaintMarginReq Maintenance Margin requirement of whole
   portfolio as of next period’s margin change
   LookAheadAvailableFunds This value reflects your available
   funds at the next margin change
   LookAheadExcessLiquidity This value reflects your excess
   liquidity at the next margin change
   HighestSeverity A measure of how close the account is to
   liquidation
   DayTradesRemaining The Number of Open/Close trades a user could
   put on before Pattern Day Trading is detected. A value of “-1”
   means that the user can put on unlimited day trades.
   Leverage GrossPositionValue / NetLiquidation
   $LEDGER Single flag to relay all cash balance tags*, only in
   base currency.
   $LEDGER:CURRENCY Single flag to relay all cash balance tags*,
   only in the specified currency.
   $LEDGER:ALL Single flag to relay all cash balance tags* in all
   currencies.

Receiving Account Summary

Copy Location

EWrapper.accountSummary (
            reqId: int. the request’s unique identifier.
            account: String. the account id
            tag: String. the account’s attribute being received.
            value: String. the account’s attribute’s value.
            currency: String. the currency on which the value is
            expressed.
            )
            Receives the account information. This method will
            receive the account information just as it appears in
            the TWS’ Account Summary Window.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def accountSummary(self, reqId: int, account: str, tag: str, value: str,
currency: str):
  print("AccountSummary. ReqId:", reqId, "Account:", account,"Tag: ", ta
g, "Value:", value, "Currency:", currency)
@Override
public void accountSummary(int reqId, String account, String tag, String
 value, String currency) {
    System.out.println(EWrapperMsgGenerator.accountSummary(reqId, accoun
t, tag, value, currency));
}

void TestCppClient::accountSummary( int reqId, const std::string& accoun
t, const std::string& tag, const std::string& value, const std::string&
currency) {
    printf( "Acct Summary. ReqId: %d, Account: %s, Tag: %s, Value: %s, C
urrency: %s\n", reqId, account.c_str(), tag.c_str(), value.c_str(), curr
ency.c_str());
}
public virtual void accountSummary(int reqId, string account, string tag
, string value, string currency)
{
    Console.WriteLine("Acct Summary. ReqId: " + reqId + ", Acct: " + acc
ount + ", Tag: " + tag + ", Value: " + value + ", Currency: " + currency
);
}
Public Sub accountSummary(reqId As Integer, account As String, tag As St
ring, value As String, currency As String) Implements IBApi.EWrapper.acc
ountSummary
    Console.WriteLine("AccountSummary - ReqId [" & reqId & "] Account ["
 & account & "] Tag [" & tag & "] Value [" & value & "] Currency [" & cu
rrency & "]")
End Sub

EWrapper.accountSummaryEnd(
            reqId: String. The request’s identifier.
            )
            Notifies when all the accounts’ information has ben
            received. Requires TWS 967+ to receive
            accountSummaryEnd in linked account structures.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def accountSummaryEnd(self, reqId: int):
    print("AccountSummaryEnd. ReqId:", reqId)

@Override
public void accountSummaryEnd(int reqId) {
    System.out.println("Account Summary End. Req Id: " + EWrapperMsgGene
rator.accountSummaryEnd(reqId));
}
void TestCppClient::accountSummaryEnd( int reqId) {
    printf( "AccountSummaryEnd. Req Id: %d\n", reqId);
}

public virtual void accountSummaryEnd(int reqId)
{
    Console.WriteLine("AccountSummaryEnd. Req Id: "+reqId+"\n");
}
Public Sub accountSummaryEnd(reqId As Integer) Implements IBApi.EWrapper
.accountSummaryEnd
    Console.WriteLine("AccountSummaryEnd - ReqId [" & reqId & "]")
End Sub

Cancel Account Summary

Copy Location
            Once the subscription to account summary is no longer
            needed, it can be cancelled via the
            IBApi::EClient::cancelAccountSummary method:

EClient.cancelAccountSummary (
            reqId: int. The identifier of the previously performed
            account request
            )
               o (BUTTON) Python
               o (BUTTON) C++
self.cancelAccountSummary(9001)

m_pClient->cancelAccountSummary(9001);

Account Updates

Copy Location
            The IBApi.EClient.reqAccountUpdates function creates a
            subscription to the TWS through which account and
            portfolio information is delivered. This information
            is the exact same as the one displayed within the TWS’
            Account Window. Just as with the TWS’ Account Window,
            unless there is a position change this information is
            updated at a fixed interval of three minutes.
            Unrealized and Realized P&L is sent to the API
            function IBApi.EWrapper.updateAccountValue function
            after a subscription request is made with
            IBApi.EClient.reqAccountUpdates. This information
            corresponds to the data in the TWS Account Window, and
            has a different source of information, a different
            update frequency, and different reset schedule than
            PnL data in the TWS Portfolio Window and associated
            API functions (below). In particular, the unrealized
            P&L information shown in the TWS Account Window which
            is sent to updatePortfolioValue will update either (1)
            when a trade for that particular instrument occurs or
            (2) every 3 minutes. The realized P&L data in the TWS
            Account Window is reset to 0 once per day.
            It is important to keep in mind that the P&L data
            shown in the Account Window and Portfolio Window will
            sometimes differ because there is a different source
            of information and a different reset schedule.
            See [515]Profit & Loss for alternative PnL data

Requesting Account Updates

Copy Location
            Subscribes to a specific account’s information and
            portfolio. Through this method, a single account’s
            subscription can be started/stopped. As a result from
            the subscription, the account’s information, portfolio
            and last update time will be received at
            EWrapper::updateAccountValue,
            EWrapper::updateAccountPortfolio,
            EWrapper::updateAccountTime respectively. All account
            values and positions will be returned initially, and
            then there will only be updates when there is a change
            in a position, or to an account value every 3 minutes
            if it has changed. Only one account can be subscribed
            at a time. A second subscription request for another
            account when the previous one is still active will
            cause the first one to be canceled in favor of the
            second one.

EClient.reqAccountUpdates (
            subscribe: bool. Set to true to start the subscription
            and to false to stop it.
            acctCode: String. The account id (i.e. U123456) for
            which the information is requested.
            )
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqAccountUpdates(True, self.account)

            Code example:
from ibapi.client import *
from ibapi.wrapper import *
from ibapi.contract import Contract
import time

class TradeApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)

    def updateAccountValue(self, key: str, val: str, currency: str,accou
ntName: str):
        print("UpdateAccountValue. Key:", key, "Value:", val, "Currency:
", currency, "AccountName:", accountName)

    def updatePortfolio(self, contract: Contract, position: Decimal,mark
etPrice: float, marketValue: float, averageCost: float, unrealizedPNL: f
loat, realizedPNL: float, accountName: str):
        print("UpdatePortfolio.", "Symbol:", contract.symbol, "SecType:"
, contract.secType, "Exchange:",contract.exchange, "Position:", decimalM
axString(position), "MarketPrice:", floatMaxString(marketPrice),"MarketV
alue:", floatMaxString(marketValue), "AverageCost:", floatMaxString(aver
ageCost), "UnrealizedPNL:", floatMaxString(unrealizedPNL), "RealizedPNL:
", floatMaxString(realizedPNL), "AccountName:", accountName)

    def updateAccountTime(self, timeStamp: str):
        print("UpdateAccountTime. Time:", timeStamp)

    def accountDownloadEnd(self, accountName: str):
        print("AccountDownloadEnd. Account:", accountName)

app = TradeApp()
app.connect("127.0.0.1", 7496, clientId=1)

time.sleep(1)

app.reqAccountUpdates(True, 'U123456')
app.run()

client.reqAccountUpdates(true, "U1234567");

m_pClient->reqAccountUpdates(true, "U150462");

client.reqAccountUpdates(true, "U1234567");

client.reqAccountUpdates(True, "U1234567")

Receiving Account Updates

Copy Location
            Resulting account and portfolio information will be
            delivered via the IBApi.EWrapper.updateAccountValue,
            IBApi.EWrapper.updatePortfolio,
            IBApi.EWrapper.updateAccountTime and
            IBApi.EWrapper.accountDownloadEnd

EWrapper.updateAccountValue (
            key: String. The value being updated.
            value: String. up-to-date value
            currency: String. The currency on which the value is
            expressed.
            accountName: String. The account identifier.
            )
            Receives the subscribed account’s information. Only
            one account can be subscribed at a time. After the
            initial callback to updateAccountValue, callbacks only
            occur for values which have changed. This occurs at
            the time of a position change, or every 3 minutes at
            most. This frequency cannot be adjusted.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def updateAccountValue(self, key: str, val: str, currency: str,accountNa
me: str):
    print("UpdateAccountValue. Key:", key, "Value:", val, "Currency:", c
urrency, "AccountName:", accountName)

@Override
public void updateAccountValue(String key, String value, String currency
, String accountName) {
    System.out.println(EWrapperMsgGenerator.updateAccountValue( key, val
ue, currency, accountName));
}

void TestCppClient::updateAccountValue(const std::string& key, const std
::string& val, const std::string& currency, const std::string& accountNa
me) {
    printf("UpdateAccountValue. Key: %s, Value: %s, Currency: %s, Accoun
t Name: %s\n", key.c_str(), val.c_str(), currency.c_str(), accountName.c
_str());
}

public virtual void updateAccountValue(string key, string value, string
currency, string accountName)
{
    Console.WriteLine("UpdateAccountValue. Key: " + key + ", Value: " +
value + ", Currency: " + currency + ", AccountName: " + accountName);
}

Public Sub updateAccountValue(key As String, value As String, currency A
s String, accountName As String) Implements IBApi.EWrapper.updateAccount
Value
        Console.WriteLine("UpdateAccountValue. Key: " & key & ", Value:
" & value & ", Currency: " & currency & ", AccountName: " & accountName)
End Sub

EWrapper.updatePortfolio (
            contract: Contract. The Contract for which a position
            is held.
            position: Decimal. The number of positions held.
            marketPrice: Double. The instrument’s unitary price
            marketValue: Double. Total market value of the
            instrument.
            averageCost: Double. Average cost of the overall
            position.
            unrealizedPNL: Double. Daily unrealized profit and
            loss on the position.
            realizedPNL: Double. Daily realized profit and loss on
            the position.
            accountName: String. Account ID for the update.
            )
            Receives the subscribed account’s portfolio. This
            function will receive only the portfolio of the
            subscribed account. After the initial callback to
            updatePortfolio, callbacks only occur for positions
            which have changed.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def updatePortfolio(self, contract: Contract, position: Decimal,marketPr
ice: float, marketValue: float, averageCost: float, unrealizedPNL: float
, realizedPNL: float, accountName: str):
    print("UpdatePortfolio.", "Symbol:", contract.symbol, "SecType:", co
ntract.secType, "Exchange:",contract.exchange, "Position:", decimalMaxSt
ring(position), "MarketPrice:", floatMaxString(marketPrice),"MarketValue
:", floatMaxString(marketValue), "AverageCost:", floatMaxString(averageC
ost), "UnrealizedPNL:", floatMaxString(unrealizedPNL), "RealizedPNL:", f
loatMaxString(realizedPNL), "AccountName:", accountName)

@Override
public void updatePortfolio(Contract contract, Decimal position, double
marketPrice, double marketValue, double averageCost, double unrealizedPN
L, double realizedPNL, String accountName) {
    System.out.println(EWrapperMsgGenerator.updatePortfolio( contract, p
osition, marketPrice, marketValue, averageCost, unrealizedPNL, realizedP
NL, accountName));
}

void TestCppClient::updatePortfolio(const Contract& contract, Decimal po
sition, double marketPrice, double marketValue, double averageCost, doub
le unrealizedPNL, double realizedPNL, const std::string& accountName){
    printf("UpdatePortfolio. %s, %s @ %s: Position: %s, MarketPrice: %s,
 MarketValue: %s, AverageCost: %s, UnrealizedPNL: %s, RealizedPNL: %s, A
ccountName: %s\n", (contract.symbol).c_str(), (contract.secType).c_str()
, (contract.primaryExchange).c_str(), decimalStringToDisplay(position).c
_str(), Utils::doubleMaxString(marketPrice).c_str(), Utils::doubleMaxStr
ing(marketValue).c_str(), Utils::doubleMaxString(averageCost).c_str(), U
tils::doubleMaxString(unrealizedPNL).c_str(), Utils::doubleMaxString(rea
lizedPNL).c_str(), accountName.c_str());
}

public virtual void updatePortfolio(Contract contract, decimal position,
 double marketPrice, double marketValue, double averageCost, double unre
alizedPNL, double realizedPNL, string accountName)
{
    Console.WriteLine("UpdatePortfolio. " + contract.Symbol + ", " + con
tract.SecType + " @ " + contract.Exchange + ": Position: " + Util.Decima
lMaxString(position) + ", MarketPrice: " + Util.DoubleMaxString(marketPr
ice) + ", MarketValue: " + Util.DoubleMaxString(marketValue) +  ", Avera
geCost: " + Util.DoubleMaxString(averageCost) + ", UnrealizedPNL: " + Ut
il.DoubleMaxString(unrealizedPNL) + ", RealizedPNL: " + Util.DoubleMaxSt
ring(realizedPNL) +  ", AccountName: " + accountName);
}

Public Sub updatePortfolio(contract As IBApi.Contract, position As Decim
al, marketPrice As Double, marketValue As Double, averageCost As Double,
 unrealizedPNL As Double, realizedPNL As Double, accountName As String)
Implements IBApi.EWrapper.updatePortfolio
        Console.WriteLine("UpdatePortfolio. " & contract.Symbol & ", " &
 contract.SecType & " @ " & contract.Exchange & ": Position: " & Util.De
cimalMaxString(position) & ", MarketPrice: " & Util.DoubleMaxString(mark
etPrice) & ", MarketValue: " & Util.DoubleMaxString(marketValue) & ", Av
erageCost: " & Util.DoubleMaxString(averageCost) & ", UnrealizedPNL: " &
 Util.DoubleMaxString(unrealizedPNL) & ", RealizedPNL: " & Util.DoubleMa
xString(realizedPNL) & ", AccountName: " & accountName)
End Sub

EWrapper.updateAccountTime (
            timestamp: String. the last update system time.
            )
            Receives the last time on which the account was
            updated.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def updateAccountTime(self, timeStamp: str):
     print("UpdateAccountTime. Time:", timeStamp)

@Override
public void updateAccountTime(String timeStamp) {
    System.out.println(EWrapperMsgGenerator.updateAccountTime( timeStamp
));
}

void TestCppClient::updateAccountTime(const std::string& timeStamp) {
    printf( "UpdateAccountTime. Time: %s\n", timeStamp.c_str());
}

public virtual void updateAccountTime(string timestamp)
{
        Console.WriteLine("UpdateAccountTime. Time: " + timestamp+"\n");
}

Public Sub updateAccountTime(timestamp As String) Implements IBApi.EWrap
per.updateAccountTime
    Console.WriteLine("UpdateAccountTime. Time: " & timestamp)
End Sub

EWrapper.accountDownloadEnd (
            account: String. The account identifier.
            )
            Notifies when all the account’s information has
            finished.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def accountDownloadEnd(self, accountName: str):
    print("AccountDownloadEnd. Account:", accountName)

@Override
public void accountDownloadEnd(String accountName) {
    System.out.println(EWrapperMsgGenerator.accountDownloadEnd(accountNa
me));
}

void TestCppClient::accountDownloadEnd(const std::string& accountName) {
    printf( "Account download finished: %s\n", accountName.c_str());
}

public virtual void accountDownloadEnd(string account)
{
    Console.WriteLine("Account download finished: "+account+"\n");
}

Public Sub accountDownloadEnd(account As String) Implements IBApi.EWrapp
er.accountDownloadEnd
    Console.WriteLine("accountDownloadEnd - Account[" & account & "]")
End Sub

Account Value Keys

Copy Location
            When requesting [516]reqAccountUpdates customers will
            receive values corresponding to various account
            key/value pairs. The table below documents potential
            responses and what they mean.
            Account values delivered
            via [517]IBApi.EWrapper.updateAccountValue can be
            classified in the following way:
               o Commodities: suffixed by a “-C”
               o Securities: suffixed by a “-S”
               o Totals: no suffix

    [516] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#request-account-updates
    [517] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#receive-account-updates

   Key Description
   AccountCode The account ID number
   AccountOrGroup “All” to return account summary data for all
   accounts, or set to a specific Advisor Account Group name that
   has already been created in TWS Global Configuration
   AccountReady For internal use only
   AccountType Identifies the IB account structure
   AccruedCash Total accrued cash value of stock, commodities and
   securities
   AccruedCash-C Reflects the current’s month accrued debit and
   credit interest to date, updated daily in commodity segment
   AccruedCash-S Reflects the current’s month accrued debit and
   credit interest to date, updated daily in security segment
   AccruedDividend Total portfolio value of dividends accrued
   AccruedDividend-C Dividends accrued but not paid in commodity
   segment
   AccruedDividend-S Dividends accrued but not paid in security
   segment
   AvailableFunds This value tells what you have available for
   trading
   AvailableFunds-C Net Liquidation Value – Initial Margin
   AvailableFunds-S Equity with Loan Value – Initial Margin
   Billable Total portfolio value of treasury bills
   Billable-C Value of treasury bills in commodity segment
   Billable-S Value of treasury bills in security segment
   BuyingPower Cash Account: Minimum (Equity with Loan Value,
   Previous Day Equity with Loan Value)-Initial Margin, Standard
   Margin Account: Minimum (Equity with Loan Value, Previous Day
   Equity with Loan Value) – Initial Margin *4
   CashBalance Cash recognized at the time of trade + futures PNL
   CorporateBondValue Value of non-Government bonds such as
   corporate bonds and municipal bonds
   Currency Open positions are grouped by currency
   Cushion Excess liquidity as a percentage of net liquidation
   value
   DayTradesRemaining Number of Open/Close trades one could do
   before Pattern Day Trading is detected
   DayTradesRemainingT+1 Number of Open/Close trades one could do
   tomorrow before Pattern Day Trading is detected
   DayTradesRemainingT+2 Number of Open/Close trades one could do
   two days from today before Pattern Day Trading is detected
   DayTradesRemainingT+3 Number of Open/Close trades one could do
   three days from today before Pattern Day Trading is detected
   DayTradesRemainingT+4 Number of Open/Close trades one could do
   four days from today before Pattern Day Trading is detected
   EquityWithLoanValue Forms the basis for determining whether a
   client has the necessary assets to either initiate or maintain
   security positions
   EquityWithLoanValue-C Cash account: Total cash value +
   commodities option value – futures maintenance margin
   requirement + minimum (0, futures PNL) Margin account: Total
   cash value + commodities option value – futures maintenance
   margin requirement
   EquityWithLoanValue-S Cash account: Settled Cash Margin
   Account: Total cash value + stock value + bond value +
   (non-U.S. & Canada securities options value)
   ExcessLiquidity This value shows your margin cushion, before
   liquidation
   ExcessLiquidity-C Equity with Loan Value – Maintenance Margin
   ExcessLiquidity-S Net Liquidation Value – Maintenance Margin
   ExchangeRate The exchange rate of the currency to your base
   currency
   FullAvailableFunds Available funds of whole portfolio with no
   discounts or intraday credits
   FullAvailableFunds-C Net Liquidation Value – Full Initial
   Margin
   FullAvailableFunds-S Equity with Loan Value – Full Initial
   Margin
   FullExcessLiquidity Excess liquidity of whole portfolio with no
   discounts or intraday credits
   FullExcessLiquidity-C Net Liquidation Value – Full Maintenance
   Margin
   FullExcessLiquidity-S Equity with Loan Value – Full Maintenance
   Margin
   FullInitMarginReq Initial Margin of whole portfolio with no
   discounts or intraday credits
   FullInitMarginReq-C Initial Margin of commodity segment’s
   portfolio with no discounts or intraday credits
   FullInitMarginReq-S Initial Margin of security segment’s
   portfolio with no discounts or intraday credits
   FullMaintMarginReq Maintenance Margin of whole portfolio with
   no discounts or intraday credits
   FullMaintMarginReq-C Maintenance Margin of commodity segment’s
   portfolio with no discounts or intraday credits
   FullMaintMarginReq-S Maintenance Margin of security segment’s
   portfolio with no discounts or intraday credits
   FundValue Value of funds value (money market funds + mutual
   funds)
   FutureOptionValue Real-time market-to-market value of futures
   options
   FuturesPNL Real-time changes in futures value since last
   settlement
   FxCashBalance Cash balance in related IB-UKL account
   GrossPositionValue Gross Position Value in securities segment
   GrossPositionValue-S Long Stock Value + Short Stock Value +
   Long Option Value + Short Option Value
   IndianStockHaircut Margin rule for IB-IN accounts
   InitMarginReq Initial Margin requirement of whole portfolio
   InitMarginReq-C Initial Margin of the commodity segment in base
   currency
   InitMarginReq-S Initial Margin of the security segment in base
   currency
   IssuerOptionValue Real-time mark-to-market value of Issued
   Option
   Leverage-S GrossPositionValue / NetLiquidation in security
   segment
   LookAheadNextChange Time when look-ahead values take effect
   LookAheadAvailableFunds This value reflects your available
   funds at the next margin change
   LookAheadAvailableFunds-C Net Liquidation Value – look ahead
   Initial Margin
   LookAheadAvailableFunds-S Equity with Loan Value – look ahead
   Initial Margin
   LookAheadExcessLiquidity This value reflects your excess
   liquidity at the next margin change
   LookAheadExcessLiquidity-C Net Liquidation Value – look ahead
   Maintenance Margin
   LookAheadExcessLiquidity-S Equity with Loan Value – look ahead
   Maintenance Margin
   LookAheadInitMarginReq Initial margin requirement of whole
   portfolio as of next period’s margin change
   LookAheadInitMarginReq-C Initial margin requirement as of next
   period’s margin change in the base currency of the account
   LookAheadInitMarginReq-S Initial margin requirement as of next
   period’s margin change in the base currency of the account
   LookAheadMaintMarginReq Maintenance margin requirement of whole
   portfolio as of next period’s margin change
   LookAheadMaintMarginReq-C Maintenance margin requirement as of
   next period’s margin change in the base currency of the account
   LookAheadMaintMarginReq-S Maintenance margin requirement as of
   next period’s margin change in the base currency of the account
   MaintMarginReq Maintenance Margin requirement of whole
   portfolio
   MaintMarginReq-C Maintenance Margin for the commodity segment
   MaintMarginReq-S Maintenance Margin for the security segment
   MoneyMarketFundValue Market value of money market funds
   excluding mutual funds
   MutualFundValue Market value of mutual funds excluding money
   market funds
   NetDividend The sum of the Dividend Payable/Receivable Values
   for the securities and commodities segments of the account
   NetLiquidation The basis for determining the price of the
   assets in your account
   NetLiquidation-C Total cash value + futures PNL + commodities
   options value
   NetLiquidation-S Total cash value + stock value + securities
   options value + bond value
   NetLiquidationByCurrency Net liquidation for individual
   currencies
   OptionMarketValue Real-time mark-to-market value of options
   PASharesValue Personal Account shares value of whole portfolio
   PASharesValue-C Personal Account shares value in commodity
   segment
   PASharesValue-S Personal Account shares value in security
   segment
   PostExpirationExcess Total projected “at expiration” excess
   liquidity
   PostExpirationExcess-C Provides a projected “at expiration”
   excess liquidity based on the soon-to expire contracts in your
   portfolio in commodity segment
   PostExpirationExcess-S Provides a projected “at expiration”
   excess liquidity based on the soon-to expire contracts in your
   portfolio in security segment
   PostExpirationMargin Total projected “at expiration” margin
   PostExpirationMargin-C Provides a projected “at expiration”
   margin value based on the soon-to expire contracts in your
   portfolio in commodity segment
   PostExpirationMargin-S Provides a projected “at expiration”
   margin value based on the soon-to expire contracts in your
   portfolio in security segment
   PreviousDayEquityWithLoanValue Marginable Equity with Loan
   value as of 16:00 ET the previous day in securities segment
   PreviousDayEquityWithLoanValue-S IMarginable Equity with Loan
   value as of 16:00 ET the previous day
   RealCurrency Open positions are grouped by currency
   RealizedPnL Shows your profit on closed positions, which is the
   difference between your entry execution cost and exit execution
   costs, or (execution price + commissions to open the positions)
   – (execution price + commissions to close the position)
   RegTEquity Regulation T equity for universal account
   RegTEquity-S Regulation T equity for security segment
   RegTMargin Regulation T margin for universal account
   RegTMargin-S Regulation T margin for security segment
   SMA Line of credit created when the market value of securities
   in a Regulation T account increase in value
   SMA-S Regulation T Special Memorandum Account balance for
   security segment
   SegmentTitle Account segment name
   StockMarketValue Real-time mark-to-market value of stock
   TBondValue Value of treasury bonds
   TBillValue Value of treasury bills
   TotalCashBalance Total Cash Balance including Future PNL
   TotalCashValue Total cash value of stock, commodities and
   securities
   TotalCashValue-C CashBalance in commodity segment
   TotalCashValue-S CashBalance in security segment
   TradingType-S Account Type
   UnrealizedPnL The difference between the current market value
   of your open positions and the average cost, or Value – Average
   Cost
   WarrantValue Value of warrants
   WhatIfPMEnabled To check projected margin requirements under
   Portfolio Margin model

Cancel Account Updates

Copy Location
            Once the subscription to account updates is no longer
            needed, it can be cancelled by invoking the
            IBApi.EClient.reqAccountUpdates method while
            specifying the susbcription flag to be False.
            Note: An important key passed back in
            IBApi.EWrapper.updateAccountValue after a call to
            IBApi.EClient.reqAccountUpdates is a boolean value
            ‘accountReady’. If an accountReady value of false is
            returned that means that the IB server is in the
            process of resetting at that moment, i.e. the account
            is ‘not ready’. When this occurs subsequent key values
            returned to IBApi::EWrapper::updateAccountValue in the
            current update can be out of date or incorrect.
            Important: only one account at a time can be
            subscribed at a time. Attempting a second subscription
            without previously cancelling an active one will not
            yield any error message although it will override the
            already subscribed account with the new one. With
            Financial Advisory (FA) account structures there is an
            alternative way of specifying the account code such
            that information is returned for ‘All’ sub accounts-
            this is done by appending the letter ‘A’ to the end of
            the account number, i.e. reqAccountUpdates(true,
            “F123456A”)

EClient.reqAccountUpdates (
            subscribe: bool. Set to true to start the subscription
            and to false to stop it.
            acctCode: String. The account id (i.e. U123456) for
            which the information is requested.
            )
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqAccountUpdates(False, self.account)

client.reqAccountUpdates(false, "U1234567");

m_pClient->reqAccountUpdates(true, "U150462");

client.reqAccountUpdates(true, "U1234567");

client.reqAccountUpdates(True, "U1234567")

Account Update by Model

Copy Location

Requesting Account Update by Model

Copy Location
            The IBApi.EClient.reqAccountUpdatesMulti can be used
            in any account structure to create simultaneous
            account value subscriptions from one or multiple
            accounts and/or models. As with
            IBApi.EClient.reqAccountUpdates the data returned will
            match that displayed within the TWS Account Window.

EClient.reqAccountUpdatesMulti (
            reqId: int. Identifier to label the request
            account: String. Account values can be requested for a
            particular account
            modelCode: String. Values can also be requested for a
            model
            ledgerAndNLV: bool. returns light-weight request; only
            currency positions as opposed to account values and
            currency positions
            )
            Requests account updates for account and/or model.
            IBApi.EClient.reqAccountUpdatesMulti cannot be used
            with Account=”All” in IBroker accounts with more than
            50 subaccounts.
            A profile name can be accepted in place of group in
            the account parameter for [518]Financial Advisors
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqAccountUpdatesMulti(reqId, self.account, "", True)

    [518] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#financial-advisors

            Code example:
from ibapi.client import *
from ibapi.wrapper import *
import time

class TradeApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)

    def accountUpdateMulti(self, reqId: int, account: str, modelCode: st
r, key: str, value: str, currency: str):
        print("AccountUpdateMulti. RequestId:", reqId, "Account:", accou
nt, "ModelCode:", modelCode, "Key:", key, "Value:", value, "Currency:",
currency)

    def accountUpdateMultiEnd(self, reqId: int):
        print("AccountUpdateMultiEnd. RequestId:", reqId)

app = TradeApp()
app.connect("127.0.0.1", 7496, clientId=1)

time.sleep(1)

app.reqAccountUpdatesMulti(103, 'U123456', "", True)

app.run()

client.reqAccountUpdatesMulti(reqId, "U1234567", "", true);

m_pClient->reqAccountUpdatesMulti(reqId, "U1234567", "", true);

client.reqAccountUpdatesMulti(reqId, "U1234567", "", true);

client.reqAccountUpdatesMulti(reqId, "U1234567", "", True)

Receiving Account Updates by Model

Copy Location
            The resulting account and portfolio information will
            be delivered via the IBApi.EWrapper.accountUpdateMulti
            and IBApi.EWrapper.accountUpdateMultiEnd

EWrapper.accountUpdateMulti (
            requestId: int. The id of request.
            account: String. The account with updates.
            modelCode: String. The model code with updates.
            key: String. The name of parameter.
            value: String. The value of parameter.
            currency: String. The currency of parameter.
            )
            Provides the account updates.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def accountUpdateMulti(self, reqId: int, account: str, modelCode: str, k
ey: str, value: str, currency: str):
  print("AccountUpdateMulti. RequestId:", reqId, "Account:", account, "M
odelCode:", modelCode, "Key:", key, "Value:", value, "Currency:", curren
cy)

@Override
public void accountUpdateMulti(int reqId, String account, String modelCo
de, String key, String value, String currency) {
    System.out.println("Account Update Multi: " + EWrapperMsgGenerator.a
ccountUpdateMulti(reqId, account, modelCode, key, value, currency));
}

void TestCppClient::accountUpdateMulti( int reqId, const std::string& ac
count, const std::string& modelCode, const std::string& key, const std::
string& value, const std::string& currency) {
    printf("AccountUpdate Multi. Request: %d, Account: %s, ModelCode: %s
, Key, %s, Value: %s, Currency: %s\n", reqId, account.c_str(), modelCode
.c_str(), key.c_str(), value.c_str(), currency.c_str());
}

public virtual void accountUpdateMulti(int reqId, string account, string
 modelCode, string key, string value, string currency)
{
    Console.WriteLine("Account Update Multi. Request: " + reqId + ", Acc
ount: " + account + ", ModelCode: " + modelCode + ", Key: " + key + ", V
alue: " + value + ", Currency: " + currency + "\n");
}

Public Sub accountUpdateMulti(requestId As Integer, account As String, m
odelCode As String, key As String, value As String, currency As String)
Implements IBApi.EWrapper.accountUpdateMulti
    Console.WriteLine("accountUpdateMulti. Id: " & requestId & ", Accoun
t: " & account & ", modelCode: " & modelCode & ", key: " & key & ", valu
e: " & value & ", currency: " & currency)
End Sub

EWrapper.accountUpdateMultiEnd (
            requestId: int. The id of request
            )
            Indicates all the account updates have been
            transmitted.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def accountUpdateMultiEnd(self, reqId: int):
    print("AccountUpdateMultiEnd. RequestId:", reqId)

@Override
public void accountUpdateMultiEnd(int reqId, ) {
    System.out.println( "Account Update Multi End: " + EWrapperMsgGenera
tor.accountUpdateMultiEnd(reqId));
}

void TestCppClient::accountUpdateMultiEnd( int reqId) {
    printf("Account Update Multi End. Request: %d\n", reqId);
}

public virtual void accountUpdateMultiEnd(int reqId)
{
    Console.WriteLine("Account Update Multi End. Request: " + reqId + "\
n");
}

Public Sub accountUpdateMultiEnd(requestId As Integer) Implements IBApi.
EWrapper.accountUpdateMultiEnd
    Console.WriteLine("accountUpdateMultiEnd. id: " & requestId)
End Sub

Cancel Account Updates by Model

Copy Location

EClient.reqAccountUpdatesMulti (
            reqId: int. Identifier to label the request
            account: String. Account values can be requested for a
            particular account
            modelCode: String. Values can also be requested for a
            model
            ledgerAndNLV: bool. Specify false to cancel your
            subscription.
            )
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqAccountUpdatesMulti(reqId, self.account, "", False)

client.reqAccountUpdatesMulti(reqId, "U1234567", "", false);

m_pClient->reqAccountUpdatesMulti(reqId, "U1234567", "", true);

client.reqAccountUpdatesMulti(reqId, "U1234567", "", false);

client.reqAccountUpdatesMulti(reqId, "U1234567", "", False)

Family Codes

Copy Location
            It is possible to determine from the API whether an
            account exists under an account family, and find the
            family code using the function reqFamilyCodes.
            For instance, if individual account U112233 is under a
            financial advisor with account number F445566, if the
            function reqFamilyCodes is invoked for the user of
            account U112233, the family code “F445566A” will be
            returned, indicating that it belongs within that
            account family.

Request Family Codes

Copy Location

EClient.reqFamilyCodes()
            Requests family codes for an account, for instance if
            it is a FA, IBroker, or associated account.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqFamilyCodes()

client.reqFamilyCodes();

m_pClient->reqFamilyCodes();

client.reqFamilyCodes()

client.reqFamilyCodes()

Receive Family Codes

Copy Location

EWrapper.familyCodes(
            familyCodes: FamilyCodes[]. Unique family codes array
            of accountIds.
            )
            Returns array of family codes.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def familyCodes(self, familyCodes: ListOfFamilyCode):
    print("Family Codes:", familyCode)

@Override
public void familyCodes(FamilyCode[] familyCodes) {
    System.out.print(EWrapperMsgGenerator.familyCodes(familyCodes));
}

void TestCppClient::familyCodes(const std::vector<FamilyCode> &familyCod
es) {
    printf("Family codes (%lu):\n", familyCodes.size());
    for (unsigned int i = 0; i < familyCodes.size(); i++) {
        printf("Family code [%d] - accountID: %s familyCodeStr: %s\n", i
, familyCodes[i].accountID.c_str(), familyCodes[i].familyCodeStr.c_str()
);
    }
}

public void familyCodes(FamilyCode[] familyCodes)
{
  Console.WriteLine("Family Codes:");
  foreach (var familyCode in familyCodes)
  {
    Console.WriteLine("Account ID: {0}, Family Code Str: {1}", familyCod
e.AccountID, familyCode.FamilyCodeStr);
  }
}

Public Sub familyCodes(familyCodes As FamilyCode()) Implements EWrapper.
familyCodes
  Console.WriteLine("Family Codes:")
  For Each familyCode In familyCodes
    Console.WriteLine("Account ID: " & familyCode.AccountID & " Family C
ode Str: " & familyCode.FamilyCodeStr)
  Next
End Sub

Managed Accounts

Copy Location
            A single user name can handle more than one account.
            As mentioned in the [519]Connectivity section, the TWS
            will automatically send a list of managed accounts
            once the connection is established. The list can also
            be fetched via the IBApi.EClient.reqManagedAccts
            method.

    [519] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#connectivity

Request Managed Accounts

Copy Location

EClient.reqManagedAccts()
            Requests the accounts to which the logged user has
            access to.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqManagedAccts()

client.reqManagedAccts();

m_pClient->reqManagedAccts();

client.reqManagedAccts();

client.reqManagedAccts()

Receive Managed Accounts

Copy Location

EWrapper.managedAccounts (
            accountsList: String. A comma-separated string with
            the managed account ids.
            )
            Returns a string of all available accounts for the
            logged in user. Occurs automatically on initial API
            client connection.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def managedAccounts(self, accountsList: str):
    print("Account list:", accountsList)

@Override
public void managedAccounts(String accountsList) {
        System.out.println("Account list: " + accountsList);
}

void TestCppClient::managedAccounts( const std::string& accountsList) {
    printf( "Account List: %s\n", accountsList.c_str());
}

public virtual void managedAccounts(string accountsList)
{
        Console.WriteLine("Account list: "+accountsList);
}

Public Sub managedAccounts(accountsList As String) Implements IBApi.EWra
pper.managedAccounts
        Console.WriteLine("ManagedAccounts - AccountsList [" & accountsL
ist & "]")
End Sub

Positions

Copy Location
            A limitation of the function
            IBApi.EClient.reqAccountUpdates is that it can only be
            used with a single account at a time. To create a
            subscription for position updates from multiple
            accounts, the function IBApi.EClient.reqPositions is
            available.
            Note: The reqPositions function is not available in
            Introducing Broker or Financial Advisor master
            accounts that have very large numbers of subaccounts
            (> 50) to optimize the performance of TWS/IB Gateway.
            Instead the function reqPositionsMulti can be used to
            subscribe to updates from individual subaccounts. Also
            not available with IBroker accounts configured for
            on-demand account lookup.
            After initially invoking reqPositions, information
            about all positions in all associated accounts will be
            returned, followed by the IBApi::EWrapper::positionEnd
            callback. Thereafter, when a position has changed an
            update will be returned to the
            IBApi::EWrapper::position function. To cancel a
            reqPositions subscription, invoke
            IBApi::EClient::cancelPositions.

Request Positions

Copy Location

EClient.reqPositions()
            Subscribes to position updates for all accessible
            accounts. All positions sent initially, and then only
            updates as positions change.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqPositions()

            Code example:
from ibapi.client import *
from ibapi.wrapper import *
import threading
import time

class TradingApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self,self)

    def position(self, account: str, contract: Contract, position: Decim
al, avgCost: float):
        print("Position.", "Account:", account, "Contract:", contract, "
Position:", position, "Avg cost:", avgCost)

    def positionEnd(self):
       print("PositionEnd")

def websocket_con():
    app.run()

app = TradingApp()
app.connect("127.0.0.1", 7496, clientId=1)

con_thread = threading.Thread(target=websocket_con, daemon=True)
con_thread.start()
time.sleep(1)

app.reqPositions()
time.sleep(1)

client.reqPositions();


m_pClient->reqPositions();


client.reqPositions();


client.reqPositions()


Receive Positions

Copy Location

EWrapper.position(
            account: String. The account holding the position.
            contract: Contract. The position’s Contract
            pos: decimal. The number of positions held. avgCost
            the average cost of the position.
            avgCost: double. The total average cost of all trades
            for the currently held position.
            )
            Provides the portfolio’s open positions. After the
            initial callback (only) of all positions, the
            IBApi.EWrapper.positionEnd function will be triggered.
            For futures, the exchange field will not be populated
            in the position callback as some futures trade on
            multiple exchanges
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def position(self, account: str, contract: Contract, position: Decimal,
avgCost: float):
  print("Position.", "Account:", account, "Contract:", contract, "Positi
on:", position, "Avg cost:", avgCost)

@Override
public void position(String account, Contract contract, Decimal pos, dou
ble avgCost) {
    System.out.println(EWrapperMsgGenerator.position(account, contract,
pos, avgCost));
}

@Override
public void position(String account, Contract contract, Decimal pos, dou
ble avgCost) {
    System.out.println(EWrapperMsgGenerator.position(account, contract,
pos, avgCost));
}

public virtual void position(string account, Contract contract, decimal
pos, double avgCost)
{
Console.WriteLine("Position. " + account + " - Symbol: " + contract.Symb
ol + ", SecType: " + contract.SecType + ", Currency: " + contract.Curren
cy + ", Position: " + Util.DecimalMaxString(pos) + ", Avg cost: " + Util
.DoubleMaxString(avgCost));
}

Public Sub position(account As String, contract As IBApi.Contract, pos A
s Decimal, avgCost As Double) Implements IBApi.EWrapper.position
  Console.WriteLine("Position. " & account & " - Symbol: " & contract.Sy
mbol & ", SecType: " & contract.SecType & ", Currency: " &  contract.Cur
rency & ", Position: " & Util.DecimalMaxString(pos) & ", Avg cost: " & U
til.DoubleMaxString(avgCost))
End Sub

Ewrapper.positionEnd()
            Indicates all the positions have been transmitted.
            Only returned after the initial callback of
            EWrapper.position.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def positionEnd(self):
  print("PositionEnd")

@Override
public void positionEnd() {
        System.out.println("Position End: " + EWrapperMsgGenerator.posit
ionEnd());
}

void TestCppClient::positionEnd() {
    printf( "PositionEnd\n");
}

public virtual void positionEnd()
{
        Console.WriteLine("PositionEnd \n");
}

Public Sub positionEnd() Implements IBApi.EWrapper.positionEnd
        Console.WriteLine("PositionEnd")
End Sub

Cancel Positions Request

Copy Location

EClient.cancelPositions()
            Cancels a previous position subscription request made
            with EClient.reqPositions().
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.cancelPositions()

client.cancelPositions();

m_pClient->cancelPositions();

client.cancelPositions()


client.cancelPositions()


Positions By Model

Copy Location
            The function IBApi.EClient.reqPositionsMulti can be
            used with any account structure to subscribe to
            positions updates for multiple accounts and/or models.
            The account and model parameters are optional if there
            are not multiple accounts or models available. It is
            more efficient to use this function for a specific
            subset of accounts than using
            IBApi.EClient.reqPositions. A profile name can be
            accepted in place of group in the account parameter.

Request Positions By Model

Copy Location

EClient.reqPositionsMulti(
            requestId: int. Request’s identifier.
            account: String. If an account Id is provided, only
            the account’s positions belonging to the specified
            model will be delivered.
            modelCode: String. The code of the model’s positions
            we are interested in.
            )
            Requests position subscription for account and/or
            model Initially all positions are returned, and then
            updates are returned for any position changes in real
            time.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqPositionsMulti(requestid, "U1234567", "")

            Code example:
from ibapi.client import *
from ibapi.wrapper import *
import threading
import time

class TradingApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self,self)

    def positionMulti(self, reqId: int, account: str, modelCode: str, co
ntract: Contract, pos: Decimal, avgCost: float):
       print("PositionMulti. RequestId:", reqId, "Account:", account, "M
odelCode:", modelCode, "Contract:", contract, ",Position:", pos, "AvgCos
t:", avgCost)

    def positionMultiEnd(self, reqId: int):
        print("")
        print("PositionMultiEnd. RequestId:", reqId)

def websocket_con():
    app.run()

app = TradingApp()
app.connect("127.0.0.1", 7497, clientId=1)

con_thread = threading.Thread(target=websocket_con, daemon=True)
con_thread.start()
time.sleep(1)

app.reqPositionsMulti(2, "DU1234567", "")  #To specify a U-account numbe
r
time.sleep(1)

app.reqPositionsMulti(3, "Group1", "")     #To specify a Financial Advis
or Group / Profile
time.sleep(1)

client.reqPositionsMulti(requestid, "U1234567", "");

m_pClient->reqPositionsMulti(requestid, "U1234567", "");

client.reqPositionsMulti(requestid, "U1234567", "");

client.reqPositionsMulti(requestid, "U1234567", "")

Receive Positions By Model

Copy Location

EWrapper.positionMulti(
            requestId: int. The id of request
            account: String. The account holding the position.
            modelCode: String. The model code holding the
            position.
            contract: Contract. The position’s Contract
            pos: decimal. The number of positions held.
            avgCost: double. The average cost of the position.
            )
            Provides the portfolio’s open positions.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def positionMulti(self, reqId: int, account: str, modelCode: str, contra
ct: Contract, pos: Decimal, avgCost: float):
  print("PositionMulti. RequestId:", reqId, "Account:", account, "ModelC
ode:", modelCode, "Contract:", contract, ",Position:", pos, "AvgCost:",
avgCost)

@Override
public void positionMulti(int reqId, String account, String modelCode, C
ontract contract, Decimal pos, double avgCost) {
        System.out.println(EWrapperMsgGenerator.positionMulti(reqId, acc
ount, modelCode, contract, pos, avgCost));
}

void TestCppClient::positionMulti( int reqId, const std::string& account
,const std::string& modelCode, const Contract& contract, Decimal pos, do
uble avgCost) {
    printf("Position Multi. Request: %d, Account: %s, ModelCode: %s, Sym
bol: %s, SecType: %s, Currency: %s, Position: %s, Avg Cost: %s\n", reqId
, account.c_str(), modelCode.c_str(), contract.symbol.c_str(), contract.
secType.c_str(), contract.currency.c_str(), decimalStringToDisplay(pos).
c_str(), Utils::doubleMaxString(avgCost).c_str());
}

public virtual void positionMulti(int reqId, string account, string mode
lCode, Contract contract, decimal pos, double avgCost)
{
        Console.WriteLine("Position Multi. Request: " + reqId + ", Accou
nt: " + account + ", ModelCode: " + modelCode + ", contract: " + contrac
t + ", Position: " + Util.DecimalMaxString(pos) + ", Avg cost: " + Util.
DoubleMaxString(avgCost) + "\n");
}

Public Sub positionMulti(requestId As Integer, account As String, modelC
ode As String, contract As Contract, pos As Decimal, avgCost As Double)
Implements IBApi.EWrapper.positionMulti
        Console.WriteLine("PositionMulti. Id: " & requestId & ", Account
: " & account & ", ModelCode: " & modelCode & ", Contract: " & contract.
Symbol & ", pos: " & Util.DecimalMaxString(pos) & ", avgCost: " & Util.D
oubleMaxString(avgCost))
End Sub

EWrapper.positionMultiEnd(
            requestId: int. The id of request
            )
            Indicates all the positions have been transmitted.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def positionMultiEnd(self, reqId: int):
        print("PositionMultiEnd. RequestId:", reqId)

@Override
public void positionMultiEnd(int reqId) {
        System.out.println("Position Multi End: " + EWrapperMsgGenerator
.positionMultiEnd(reqId));
}

void TestCppClient::positionMultiEnd( int reqId) {
    printf("Position Multi End. Request: %d\n", reqId);
}

public virtual void positionMultiEnd(int reqId)
{
        Console.WriteLine("Position Multi End. Request: " + reqId + "\n"
);
}

Public Sub positionMultiEnd(requestId As Integer) Implements IBApi.EWrap
per.positionMultiEnd
        Console.WriteLine("PositionMultiEnd")
End Sub

Cancel Positions By Model

Copy Location

EClient.cancelPositionsMulti (
            requestId: int. The identifier of the request to be
            canceled.
            )
            Cancels positions request for account and/or model.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.cancelPositionsMulti(requestid)

client.cancelPositionsMulti(requestid);

m_pClient->cancelPositionsMulti(requestid);

client.cancelPositionsMulti(requestid);

client.cancelPositionsMulti(requestid)

Profit & Loss (PnL)

Copy Location
            Requests can be made to receive real time updates
            about the daily P&L and unrealized P&L for an account,
            or for individual positions. Financial Advisors can
            also request P&L figures for ‘All’ subaccounts, or for
            a portfolio model. This is further extended to include
            realized P&L information at the account or individual
            position level.
            The P&L API functions demonstrated below return the
            data which is displayed in the TWS Portfolio Window in
            current versions of TWS. As such, the P&L values are
            calculated based on the reset schedule specified in
            TWS Global Configuration (by default an
            instrument-specific reset schedule) and this setting
            affects values sent to the associated API functions as
            well. Also in TWS, P&L data from virtual forex
            positions will be included in the account P&L if and
            only if the Virtual Fx section of the Account Window
            is expanded.
            See [520]Account Updates for alternative PnL data.

Request P&L for individual positions

Copy Location
            Subscribe using the IBApi::EClient::reqPnLSingle
            function Cannot be used with IBroker accounts
            configured for on-demand lookup with account = ‘All’.
            Currently updates are returned to
            IBApi.EWrapper.pnlSingle approximately once per
            second*.
               o If a P&L subscription request is made for an
                 invalid conId or contract not in the account,
                 there will not be a response.
               o As elsewhere in the API, a max double value will
                 indicate an ‘unset’ value. This corresponds to an
                 empty cell in TWS.
               o Introducing broker accounts without a large
                 number of subaccounts (<50) can receive aggregate
                 data by specifying the account as “All”.
               o *Cannot be used with IBroker accounts configured
                 for on-demand lookup with account = ‘All’
            *subject to change in the future.

EClient.reqPnLSingle (
            reqId: int. Request identifier for to track the data.
            account: String. Account in which position exists
            modelCode: String. Model in which position exists
            conId: int. Contract ID (conId) of contract to receive
            daily PnL updates for. Note: does not return message
            if invalid conId is entered
            )
            Requests real time updates for daily PnL of individual
            positions.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqPnLSingle(requestId, "U1234567", "", 265598)

            Code example:
from ibapi.client import *
from ibapi.wrapper import *
import time

class TradeApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)

    def pnlSingle(self, reqId: int, pos: Decimal, dailyPnL: float, unrea
lizedPnL: float, realizedPnL: float, value: float):
        print("Daily PnL Single. ReqId:", reqId, "Position:", pos, "Dail
yPnL:", dailyPnL, "UnrealizedPnL:", unrealizedPnL, "RealizedPnL:", reali
zedPnL, "Value:", value)

app = TradeApp()
app.connect("127.0.0.1", 7496, clientId=1)

time.sleep(1)
app.reqPnLSingle(101, "U123456", "", 8314) #IBM conId: 8314

app.run()

client.reqPnLSingle(requestId, "U1234567", "", 265598);

m_pClient->reqPnLSingle(requestId, "U1234567", "", 265598);

client.reqPnLSingle(requestId, "U1234567", "", 265598);

client.reqPnLSingle(requestId, "U1234567", "", 265598)

Receive P&L for individual positions

Copy Location

EWrapper.pnlSingle (
            reqId: int. Request identifier used for tracking.
            pos: decimal. Current size of the position
            dailyPnL: double. DailyPnL for the position
            unrealizedPnL: double. Total unrealized PnL for the
            position (since inception) updating in real time
            realizedPnL: double. Total realized PnL for the
            position (since inception) updating in real time
            value: double. Current market value of the position.
            )
            Receives real time updates for single position daily
            PnL values
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def pnlSingle(self, reqId: int, pos: Decimal, dailyPnL: float, unrealize
dPnL: float, realizedPnL: float, value: float):
  print("Daily PnL Single. ReqId:", reqId, "Position:", pos, "DailyPnL:"
, dailyPnL, "UnrealizedPnL:", unrealizedPnL, "RealizedPnL:", realizedPnL
, "Value:", value)

@Override
public void pnlSingle(int reqId, Decimal pos, double dailyPnL, double un
realizedPnL, double realizedPnL, double value) {
  System.out.println(EWrapperMsgGenerator.pnlSingle(reqId, pos, dailyPnL
, unrealizedPnL, realizedPnL, value));
}

void TestCppClient::pnlSingle(int reqId, Decimal pos, double dailyPnL, d
ouble unrealizedPnL, double realizedPnL, double value) {
    printf("PnL Single. ReqId: %d, pos: %s, daily PnL: %s, unrealized Pn
L: %s, realized PnL: %s, value: %s\n", reqId, decimalStringToDisplay(pos
).c_str(), Utils::doubleMaxString(dailyPnL).c_str(), Utils::doubleMaxStr
ing(unrealizedPnL).c_str(), Utils::doubleMaxString(realizedPnL).c_str(),
 Utils::doubleMaxString(value).c_str());
}

public void pnlSingle(int reqId, decimal pos, double dailyPnL, double un
realizedPnL, double realizedPnL, double value)
{
        Console.WriteLine("PnL Single. Request Id: {0}, Pos {1}, Daily P
nL {2}, Unrealized PnL {3}, Realized PnL: {4}, Value: {5}", reqId, Util.
DecimalMaxString(pos), Util.DoubleMaxString(dailyPnL), Util.DoubleMaxStr
ing(unrealizedPnL),
                Util.DoubleMaxString(realizedPnL), Util.DoubleMaxString(
value));
}

Public Sub pnlSingle(reqId As Integer, pos As Decimal, dailyPnL As Doubl
e, unrealizedPnL As Double, realizedPnL As Double, value As Double) Impl
ements EWrapper.pnlSingle
        Console.WriteLine("PnL Single. Request Id: {0}, pos: {1}, daily
PnL: {2}, unrealized PnL: {3}, realized PnL: {4}, value: {5}", reqId, Ut
il.DecimalMaxString(pos), Util.DoubleMaxString(dailyPnL), Util.DoubleMax
String(unrealizedPnL), Util.DoubleMaxString(realizedPnL), Util.DoubleMax
String(value))
End Sub

Cancel P&L request for individual positions

Copy Location

EClient.cancelPnLSingle (
            reqId: int. Request identifier to cancel the P&L
            subscription for.
            )
            Cancels real time subscription for a positions daily
            PnL information.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.cancelPnLSingle(requestId);

client.cancelPnLSingle(reqId);

m_pClient->cancelPnLSingle(reqId);

client.cancelPnLSingle(reqId);

client.cancelPnLSingle(reqId);

Request P&L for accounts

Copy Location
            Subscribe using the IBApi::EClient::reqPnL function.
            Updates are sent to IBApi.EWrapper.pnl.
               o Introducing broker accounts with less than 50
                 subaccounts can receive aggregate PnL for all
                 subaccounts by specifying ‘All’ as the account
                 code.
               o With requests for advisor accounts with many
                 subaccounts and/or positions can take several
                 seconds for aggregated P&L to be computed and
                 returned.
               o For account P&L data the TWS setting “Prepare
                 portfolio PnL data when downloading positions”
                 must be checked.

EClient.reqPnL (
            reqId: int. Request ID to track the data.
            account: String. Account for which to receive PnL
            updates
            modelCode: String. Specify to request PnL updates for
            a specific model.
            )
            Creates subscription for real time daily PnL and
            unrealized PnL updates.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqPnL(reqId, "U1234567", "")

            Code example:
from ibapi.client import *
from ibapi.wrapper import *
import time

class TradeApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)

    def pnl(self, reqId: int, dailyPnL: float, unrealizedPnL: float, rea
lizedPnL: float):
        print("Daily PnL. ReqId:", reqId, "DailyPnL:", dailyPnL, "Unreal
izedPnL:", unrealizedPnL, "RealizedPnL:", realizedPnL)

app = TradeApp()
app.connect("127.0.0.1", 7496, clientId=1)

time.sleep(1)
app.reqPnL(102, "U123456", "")

app.run()

client.reqPnL(reqId, "U1234567", "");

m_pClient->reqPnL(reqId, "U1234567", "");

client.reqPnL(reqId, "U1234567", "");

client.reqPnL(reqId, "U1234567", "")

Receive P&L for accounts

Copy Location

EWrapper.pnl (
            reqId: int. Request identifier for tracking data.
            dailyPnL: double. DailyPnL updates for the account in
            real time
            unrealizedPnL: double. Total Unrealized PnL updates
            for the account in real time
            realizedPnL: double. Total Realized PnL updates for
            the account in real time
            )
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def pnl(self, reqId: int, dailyPnL: float, unrealizedPnL: float, realize
dPnL: float):
  print("Daily PnL. ReqId:", reqId, "DailyPnL:", dailyPnL, "UnrealizedPn
L:", unrealizedPnL, "RealizedPnL:", realizedPnL)

@Override
public void pnl(int reqId, double dailyPnL, double unrealizedPnL, double
 realizedPnL) {
        System.out.println(EWrapperMsgGenerator.pnl(reqId, dailyPnL, unr
ealizedPnL, realizedPnL));
}

void TestCppClient::pnl(int reqId, double dailyPnL, double unrealizedPnL
, double realizedPnL) {
    printf("PnL. ReqId: %d, daily PnL: %s, unrealized PnL: %s, realized
PnL: %s\n", reqId, Utils::doubleMaxString(dailyPnL).c_str(), Utils::doub
leMaxString(unrealizedPnL).c_str(),
        Utils::doubleMaxString(realizedPnL).c_str());
}

public void pnl(int reqId, double dailyPnL, double unrealizedPnL, double
 realizedPnL)
{
        Console.WriteLine("PnL. Request Id: {0}, Daily PnL: {1}, Unreali
zed PnL: {2}, Realized PnL: {3}", reqId, Util.DoubleMaxString(dailyPnL),
 Util.DoubleMaxString(unrealizedPnL), Util.DoubleMaxString(realizedPnL))
;
}

 Public Sub pnl(reqId As Integer, dailyPnL As Double, unrealizedPnL As D
ouble, realizedPnL As Double) Implements EWrapper.pnl
        Console.WriteLine("PnL. Request Id: {0}, daily PnL: {1}, unreali
zed PnL: {2}, realized PnL: {3}", reqId, Util.DoubleMaxString(dailyPnL),
 Util.DoubleMaxString(unrealizedPnL), Util.DoubleMaxString(realizedPnL))
End Sub

Cancel P&L subscription requests for accounts

Copy Location

EClient.cancelPnL (
            reqId: int. Request identifier for tracking data.
            )
            Cancels subscription for real time updated daily PnL
            params reqId
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.cancelPnL(reqId)

client.cancelPnL(reqId);

m_pClient->cancelPnL(7001);

client.cancelPnL(reqId);

client.cancelPnL(reqId)

White Branding User Info

Copy Location
            This function will return [521]White Branding
            ID associated with the user.
            Please note, that nothing will be returned if
            requesting username is not associated with any White
            Branding entity.

    [521] https://www.interactivebrokers.com/en/trading/white-branding.php

Requesting White Branding Info

Copy Location

EClient.reqUserInfo(
            reqId: int. Request ID
            )
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqUserInfo(reqId)

client.reqUserInfo(reqId);

m_pClient->reqUserInfo(0);

client.reqUserInfo(reqId);

client.reqUserInfo(reqId)

Receiving White Branding Info

Copy Location

EWrapper.userInfo (
            reqId: int. Identifier for the given request.
            whiteBrandingId: String. Identifier for the white
            branded entity.
            )
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def userInfo(self, reqId: int, whiteBrandingId: str):
        print("UserInfo.", "ReqId:", reqId, "WhiteBrandingId:", whiteBra
ndingId)

@Override
public void userInfo(int reqId, String whiteBrandingId) {
        System.out.println(EWrapperMsgGenerator.userInfo(reqId, whiteBra
ndingId));
}

void TestCppClient::userInfo(int reqId, const std::string& whiteBranding
Id) {
    printf("User Info. ReqId: %d, WhiteBrandingId: %s\n", reqId, whiteBr
andingId.c_str());
}

public void userInfo(int reqId, string whiteBrandingId)
{
        Console.WriteLine($"User Info. ReqId: {reqId}, WhiteBrandingId:
{whiteBrandingId}");
}

Public Sub userInfo(reqId As Integer, whiteBrandingId As String) Impleme
nts EWrapper.userInfo
  Console.WriteLine($"User Info. ReqId: {reqId}, WhiteBrandingId: {white
BrandingId}")
End Sub

Bulletins

Copy Location
            From time to time, IB sends out important [522]News
            Bulletins, which can be accessed via the TWS API
            through the EClient.reqNewsBulletins. Bulletins are
            delivered via IBApi.EWrapper.updateNewsBulletin
            whenever there is a new bulletin. In order to stop
            receiving bulletins you need to cancel the
            subscription.

    [522] https://ibkrguides.com/tws/usersguidebook/realtimeactivitymonitoring/bulletins and system status.htm

Request IB Bulletins

Copy Location

EClient.reqNewsBulletins (
            allMessages: bool. If set to true, will return all the
            existing bulletins for the current day, set to false
            to receive only the new bulletins.
            )
            Subscribes to IB’s News Bulletins.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqNewsBulletins(True)

client.reqNewsBulletins(true);

m_pClient->reqNewsBulletins(true);

client.reqNewsBulletins(true);

client.reqNewsBulletins(True)

Receive IB Bulletins

Copy Location

EWrapper.updateNewsBulletin (
            msgId: int. The bulletin’s identifier.
            msgType: int. 1: Regular news bulletin; 2: Exchange no
            longer available for trading; 3: Exchange is available
            for trading.
            message: String. The news bulletin context.
            origExchange: String. The exchange where the message
            comes from.
            )
            Provides IB’s bulletins
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def updateNewsBulletin(self, msgId: int, msgType: int, newsMessage: str,
 originExch: str):
  print("News Bulletins. MsgId:", msgId, "Type:", msgType, "Message:", n
ewsMessage, "Exchange of Origin: ", originExch)

@Override
public void updateNewsBulletin(int msgId, int msgType, String message, S
tring origExchange) {
        System.out.println("News Bulletin: " + EWrapperMsgGenerator.upda
teNewsBulletin( msgId, msgType, message, origExchange));
}

void TestCppClient::updateNewsBulletin(int msgId, int msgType, const std
::string& newsMessage, const std::string& originExch) {
    printf( "News Bulletins. %d - Type: %d, Message: %s, Exchange of Ori
gin: %s\n", msgId, msgType, newsMessage.c_str(), originExch.c_str());
}

public virtual void updateNewsBulletin(int msgId, int msgType, String me
ssage, String origExchange)
{
        Console.WriteLine("News Bulletins. "+msgId+" - Type: "+msgType+"
, Message: "+message+", Exchange of Origin: "+origExchange+"\n");
}

Public Sub updateNewsBulletin(msgId As Integer, msgType As Integer, mess
age As String, origExchange As String) Implements IBApi.EWrapper.updateN
ewsBulletin
        Console.WriteLine("News Bulletins. " & msgId & " - Type: " & msg
Type & ", Message: " & message & ", Exchange of Origin: " & origExchange
)
End Sub

Cancel Bulletin Request

Copy Location

EClient.cancelNewsBulletin ()
            Cancels IB’s news bulletin subscription.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.cancelNewsBulletins()


client.cancelNewsBulletins();

m_pClient->cancelNewsBulletins();

client.cancelNewsBulletin();


client.cancelNewsBulletin()

Contracts (Financial Instruments)

Copy Location
            An IBApi.Contract object represents trading
            instruments such as a stocks, futures or options.
            Every time a new request that requires a contract
            (i.e. market data, order placing, etc.) is sent to
            TWS, the platform will try to match the provided
            contract object with a single candidate.

The Contract Object

Copy Location
            The Contract object is an object used throughout the
            TWS API to define the target of your requests.
            Contract objects will be used for market data,
            portfolios, orders, executions, and even some news
            request. This is the staple structure used for all of
            the TWS API.
            In all contracts, the minimum viable structure
            requires at least a conId and exchange, or a symbol,
            secType, exchange, primaryExchange, and currency.
            Derivatives will require additional fields, such as
            lastTradeDateOrExpiration, tradingClass, multiplier,
            strikes, and so on.
            The values to the right represent the most common
            Contract values to pass for complete contracts. For a
            more comprehensive list of contract structures, please
            see [523]the Contracts page.

    [523] https://www.interactivebrokers.com/campus/ibkr-api-page/contracts/

Contract()
            ConId: int. Identifier to specify an exact contract.
            Symbol: String. Ticker symbol of the underlying
            instrument.
            SecType: String. Security type of the traded
            instrument.
            Exchange: String. Exchange for which data or trades
            should be routed.
            PrimaryExchange: String. Primary listing exchange of
            the instrument.
            Currency: String. Base currency the instrument is
            traded on.
            LastTradeDateOrContractMonth: String. For derivatives,
            the expiration date of the contract.
            Strike: double. For derivatives, the strike price of
            the instrument.
            Right: String. For derivatives, the right (P/C) of the
            instrument.
            TradingClass: String. For derivatives, the trading
            class of the instrument.
            May be used to indicate between a monthly or a weekly
            contract.
            Given additional structures for contracts are ever
            evolving, it is recommended to review the relevant
            Contract class in your programming language for a
            comprehensive review of what fields are available.
            [524]Contract Class Reference

    [524] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-ref/#contract-ref

Finding Contract Details in Trader Workstation

Copy Location
            If there is more than one contract matching the same
            description, TWS will return an error notifying you
            there is an ambiguity. In these cases the TWS needs
            further information to narrow down the list of
            contracts matching the provided description to a
            single element.
            The best way of finding a contract’s description is
            within the TWS itself. Within the TWS, you can easily
            check a contract’s description either by double
            clicking it or through the Contract Info ->
            Description menu, which you access by right-clicking a
            contract in TWS:
            The description will then appear:
            Note: you can see the extended contract details by
            choosing Contract Info -> Details. This option will
            open a web page showing all available information on
            the contract.
            Whenever a contract description is provided via the
            TWS API, the TWS will try to match the given
            description to a single contract. This mechanism
            allows for great flexibility since it gives the
            possibility to define the same contract in multiple
            ways.
            The simplest way to define a contract is by providing
            its symbol, security type, currency and exchange. The
            vast majority of stocks, CFDs, Indexes or FX pairs can
            be uniquely defined through these four attributes.
            More complex contracts such as options and futures
            require some extra information due to their nature.
            Below are several examples for different types of
            instruments.

Contract Details

Copy Location
            Complete details about a contract in IB’s database can
            be retrieved using the function
            [525]IBApi.EClient.reqContractDetails. This includes
            information about a contract’s conID, symbol, local
            symbol, currency, etc. which is returned in a
            IBApi.ContractDetails object. reqContractDetails takes
            as an argument a Contract object which may uniquely
            match one contract, and unlike other API functions it
            can also take a Contract object which matches multiple
            contracts in IB’s database. When there are multiple
            matches, they will each be returned individually to
            the function[526] IBApi::EWrapper::contractDetails.
            Request for Bond details will be returned to
            [527]IBApi::EWrapper::bondContractDetails instead.
            Because of bond market data license restrictions,
            there are only a few available fields to be returned
            in a bond contract description, namely the minTick,
            exchange, and short name.
            Note: Invoking reqContractDetails with a Contract
            object which has currency = USD will only return US
            contracts, even if there are non-US instruments which
            have the USD currency.
            Another function of IBApi::EClient::reqContractDetails
            is to request the trading schedule of an instrument
            via the TradingHours and LiquidHours fields. The
            corresponding timeZoneId field will then indicate the
            time zone for the trading schedule of the instrument.
            TWS sends these timeZoneId strings to the API from the
            schedule responses as-is, and may not exactly match
            the time zones displayed in the TWS contract
            description.
            Possible timeZoneId values are:
               o Europe/Riga
               o Australia/NSW
               o Europe/Warsaw
               o US/Pacific
               o Europe/Tallinn
               o Japan
               o US/Eastern
               o GB-Eire
               o Africa/Johannesburg
               o Israel
               o Europe/Vilnius
               o MET
               o Europe/Helsinki
               o US/Central
               o Europe/Budapest
               o Asia/Calcutta
               o Hongkong
               o Europe/Moscow
               o GMT

Request Contract Details

Copy Location

EClient.reqContractDetails (
            reqId: int. Request identifier to track data.
            contract: ContractDetails. the contract used as sample
            to query the available contracts.
            Typically contains at least the Symbol, SecType,
            Exchange, and Currency.
            )
            Receives the full contract’s definitions This method
            will return all contracts matching the requested via
            EClientSocket::reqContractDetails. For example, one
            can obtain the whole option chain with it.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqContractDetails(reqId, contract)
client.reqContractDetails(reqId, contract)

m_pClient->reqContractDetails(reqId, contract);

client.reqContractDetails(reqId, contract);

client.reqContractDetails(reqId, contract)

Receive Contract Details

Copy Location

EWrapper.contractDetails (
            reqId: int. Request identifier to track data.
            contract: ContractDetails. Contains the full contract
            object contents including all information about a
            specific traded instrument.
            )
            Receives the full contract’s definitions This method
            will return all contracts matching the requested via
            EClientSocket::reqContractDetails. For example, one
            can obtain the whole option chain with it.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def contractDetails(self, reqId: int, contractDetails: ContractDetails):
  print(reqId, contractDetails)

@Override
public void contractDetails(int reqId, ContractDetails contractDetails)
{
        System.out.println(EWrapperMsgGenerator.contractDetails(reqId, c
ontractDetails));
}

void TestCppClient::contractDetails( int reqId, const ContractDetails& c
ontractDetails) {
    printf( "ContractDetails. ReqId: %d\n", reqId);
    printContractDetailsMsg(contractDetails);
}

public virtual void contractDetails(int reqId, ContractDetails contractD
etails)
{
        Console.WriteLine("ContractDetails. ReqId: " + reqId);
        printContractDetailsMsg(contractDetails);
}

Public Sub contractDetails(reqId As Integer, contractDetails As IBApi.Co
ntractDetails) Implements IBApi.EWrapper.contractDetails
        Console.WriteLine("ContractDetails. ReqId: " & reqId)
        printContractDetailsMsg(contractDetails)
End Sub

EWrapper.contractDetailsEnd (
            reqId: int. Request identifier to track data.
            )
            After all contracts matching the request were
            returned, this method will mark the end of their
            reception.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def contractDetailsEnd(self, reqId: int):
        print("ContractDetailsEnd. ReqId:", reqId)

@Override
public void contractDetailsEnd(int reqId) {
        System.out.println("Contract Details End: " + EWrapperMsgGenerat
or.contractDetailsEnd(reqId));
}

void TestCppClient::contractDetailsEnd( int reqId) {
    printf( "ContractDetailsEnd. %d\n", reqId);
}

public virtual void contractDetailsEnd(int reqId)
{
        Console.WriteLine("ContractDetailsEnd. "+reqId+"\n");
}

 Public Sub contractDetailsEnd(reqId As Integer) Implements IBApi.EWrapp
er.contractDetailsEnd
            Console.WriteLine("ContractDetailsEnd - ReqId [" & reqId & "
]")
        End Sub

Receive Bond Details

Copy Location

EWrapper.bondContractDetails (
            reqId: int. Request identifier to track data.
            contract: ContractDetails. Contains the full contract
            object contents including all information about a
            specific traded instrument.
            )
            Delivers the Bond contract data after this has been
            requested via reqContractDetails.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def bondContractDetails(self, reqId: int, contractDetails: ContractDetai
ls):
  printinstance(reqId, contractDetails)

@Override
public void bondContractDetails(int reqId, ContractDetails contractDetai
ls) {
        System.out.println(EWrapperMsgGenerator.contractDetails(reqId, c
ontractDetails));
}

void TestCppClient::bondContractDetails( int reqId, const ContractDetail
s& contractDetails) {
    printf( "BondContractDetails. ReqId: %d\n", reqId);
    printContractDetailsMsg(contractDetails);
}

public virtual void bondContractDetails(int reqId, ContractDetails contr
actDetails)
{
        Console.WriteLine("BondContractDetails. ReqId: " + reqId);
        printContractDetailsMsg(contractDetails);
}

Public Sub bondContractDetails(reqId As Integer, contractDetails As IBAp
i.ContractDetails) Implements IBApi.EWrapper.contractDetails
        Console.WriteLine("BondContractDetails. ReqId: " & reqId)
        printContractDetailsMsg(contractDetails)
End Sub

Option Chains

Copy Location
            The option chain for a given security can be returned
            using the function [528]EClient.reqContractDetails. If
            an option contract is incompletely defined (for
            instance with the strike undefined) and used as an
            argument to [529]EClient.reqContractDetails, a list of
            all matching option contracts will be returned.
            One limitation of this technique is that the return of
            option chains will be throttled and take a longer time
            the more ambiguous the contract definition. The
            function [530]EClient.reqSecDefOptParams was
            introduced that does not have the throttling
            limitation.
               o It is not recommended to use
                 [531]EClient.reqContractDetails to receive
                 complete option chains on an underlying, e.g. all
                 combinations of strikes/rights/expiries.
               o For very large option chains returned from
                 [532]EClient.reqContractDetails, unchecking the
                 setting in TWS Global Configuration at API ->
                 Settings -> “Expose entire trading schedule to
                 the API” will decrease the amount of data
                 returned per option and help to return the
                 contract list more quickly.
            [533]EClient.reqSecDefOptParams returns a list of
            expiries and a list of strike prices. In some cases,
            it is possible there are combinations of strike and
            expiry that would not give a valid option contract.

    [528] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#request-contract-details
    [529] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#request-contract-details
    [530] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#request-opt-chain
    [531] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#request-contract-details
    [532] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#request-contract-details
    [533] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#request-opt-chain

Request Option Chains

Copy Location

EClient.reqSecDefOptParams (
            reqId: int. The ID chosen for the request
            underlyingSymbol: String. Contract symbol of the
            underlying.
            futFopExchange: String. The exchange on which the
            returned options are trading. Can be set to the empty
            string “” for all exchanges.
            underlyingSecType: String. The type of the underlying
            security, i.e. STK
            underlyingConId: int. The contract ID of the
            underlying security.
            )
            Requests security definition option parameters for
            viewing a contract’s option chain.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqSecDefOptParams(0, "IBM", "", "STK", 8314)

client.reqSecDefOptParams(0, "IBM", "", "STK", 8314);

m_pClient->reqSecDefOptParams(0, "IBM", "", "STK", 8314);

client.reqSecDefOptParams(0, "IBM", "", "STK", 8314);

client.reqSecDefOptParams(0, "IBM", "", "STK", 8314)

Receive Option Chains

Copy Location

EWrapper.securityDefinitionOptionParameter (
            reqId: int. ID of the request initiating the callback.
            underlyingConId: int. The conID of the underlying
            security.
            tradingClass: String. The option trading class.
            multiplier: String. The option multiplier.
            exchange: String. Exchange for which the derivative is
            hosted.
            expirations: HashSet. A list of the expiries for the
            options of this underlying on this exchange.
            strikes: HashSet. A list of the possible strikes for
            options of this underlying on this exchange.
            )
            Returns the option chain for an underlying on an
            exchange specified in reqSecDefOptParams There will be
            multiple callbacks to
            securityDefinitionOptionParameter if multiple
            exchanges are specified in reqSecDefOptParams
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def securityDefinitionOptionParameter(self, reqId: int, exchange: str, u
nderlyingConId: int, tradingClass: str, multiplier: str, expirations: Se
tOfString, strikes: SetOfFloat):
  print("SecurityDefinitionOptionParameter.", "ReqId:", reqId, "Exchange
:", exchange, "Underlying conId:", underlyingConId, "TradingClass:", tra
dingClass, "Multiplier:", multiplier, "Expirations:", expirations, "Stri
kes:", strikes)

@Override
public void securityDefinitionOptionalParameter(int reqId, String exchan
ge, int underlyingConId, String tradingClass, String multiplier, Set exp
irations, Set strikes) {
        System.out.println("Security Definition Optional Parameter: " +
EWrapperMsgGenerator.securityDefinitionOptionalParameter(reqId, exchange
, underlyingConId, tradingClass, multiplier, expirations, strikes));
}

void TestCppClient::securityDefinitionOptionalParameter(int reqId, const
 std::string& exchange, int underlyingConId, const std::string& tradingC
lass,
                                                        const std::strin
g& multiplier, const std::set& expirations, const std::set& strikes) {
    printf("Security Definition Optional Parameter. Request: %d, Trading
 Class: %s, Multiplier: %s\n", reqId, tradingClass.c_str(), multiplier.c
_str());
}

public void securityDefinitionOptionParameter(int reqId, string exchange
, int underlyingConId, string tradingClass, string multiplier, HashSet e
xpirations, HashSet strikes)
{
        Console.WriteLine("Security Definition Option Parameter. Reqest:
 {0}, Exchange: {1}, Undrelying contract id: {2}, Trading class: {3}, Mu
ltiplier: {4}, Expirations: {5}, Strikes: {6}", reqId, exchange, Util.In
tMaxString(underlyingConId), tradingClass, multiplier, string.Join(", ",
 expirations), string.Join(", ", strikes));
}

Public Sub securityDefinitionOptionParameter(reqId As Integer, exchange
As String, underlyingConId As Integer, tradingClass As String, multiplie
r As String, expirations As HashSet(Of String), strikes As HashSet(Of Do
uble)) Implements EWrapper.securityDefinitionOptionParameter
            Console.WriteLine("securityDefinitionOptionParameter: " & re
qId & " tradingClass: " & tradingClass & " multiplier: ")
End Sub

Stock Symbol Search

Copy Location
            The function IBApi::EClient::reqMatchingSymbols is
            available to search for stock contracts. The input can
            be either the first few letters of the ticker symbol,
            or for longer strings, a character sequence matching a
            word in the security name. For instance to search for
            the stock symbol ‘IBKR’, the input ‘I’ or ‘IB’ can be
            used, as well as the word ‘Interactive’. Up to 16
            matching results are returned.
            There must be an interval of at least 1 second between
            successive calls to reqMatchingSymbols
            Matching stock contracts are returned to
            IBApi::EWrapper::symbolSamples with information about
            types of derivative contracts which exist (warrants,
            options, dutch warrants, futures).

Request Stock Contract Search

Copy Location

EClient.reqMatchingSymbols (
            reqId: int. Request identifier used to track data.
            pattern: String. Either start of ticker symbol or (for
            larger strings) company name.
            )
            Requests matching stock symbols.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqMatchingSymbols(reqId, "IBM")

client.reqMatchingSymbols(reqId, "IB");

m_pClient->reqMatchingSymbols(reqId, "IBM");

client.reqMatchingSymbols(reqId, "IBM");

client.reqMatchingSymbols(reqId, "IBM")

Receive Searched Stock Contract

Copy Location

EWrapper.symbolSamples (
            reqID: int. Request identifier used to track data.
            contractDescription: ContractDescription[]. Provide an
            array of contract objects matching the requested
            descriptoin.
            )
            Returns array of sample contract descriptions
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def symbolSamples(self, reqId: int, contractDescriptions: ListOfContract
Description):
        print("Symbol Samples. Request Id: ", reqId)
        for contractDescription in contractDescriptions:
                derivSecTypes = ""
                for derivSecType in contractDescription.derivativeSecTyp
es:
                        derivSecTypes += " "
                        derivSecTypes += derivSecType
                        print("Contract: conId:%s, symbol:%s, secType:%s
 primExchange:%s, "
                                "currency:%s, derivativeSecTypes:%s, des
cription:%s, issuerId:%s" % (
                                contractDescription.contract.conId,
                                contractDescription.contract.symbol,
                                contractDescription.contract.secType,
                                contractDescription.contract.primaryExch
ange,
                                contractDescription.contract.currency, d
erivSecTypes,
                                contractDescription.contract.description
,
                                contractDescription.contract.issuerId))

@Override
public void symbolSamples(int reqId, ContractDescription[] contractDescr
iptions) {
        System.out.println(EWrapperMsgGenerator.symbolSamples(reqId, con
tractDescriptions));
}

void TestCppClient::symbolSamples(int reqId, const std::vector &contract
Descriptions) {
    printf("Symbol Samples (total=%lu) reqId: %d\n", contractDescription
s.size(), reqId);
    for (unsigned int i = 0; i < contractDescriptions.size(); i++) {
        Contract contract = contractDescriptions[i].contract;
        std::vector derivativeSecTypes = contractDescriptions[i].derivat
iveSecTypes;
        printf("Contract (%u): conId: %ld, symbol: %s, secType: %s, prim
aryExchange: %s, currency: %s, ", i, contract.conId, contract.symbol.c_s
tr(), contract.secType.c_str(), contract.primaryExchange.c_str(), contra
ct.currency.c_str());
        printf("Derivative Sec-types (%lu):", derivativeSecTypes.size())
;
        for (unsigned int j = 0; j < derivativeSecTypes.size(); j++) {
            printf(" %s", derivativeSecTypes[j].c_str());
        }
        printf(", description: %s, issuerId: %s", contract.description.c
_str(), contract.issuerId.c_str());
        printf("\n");
    }
}

public void symbolSamples(int reqId, ContractDescription[] contractDescr
iptions)
{
        string derivSecTypes;
        Console.WriteLine("Symbol Samples. Request Id: {0}", reqId);
        foreach (var contractDescription in contractDescriptions)
        {
                derivSecTypes = "";
                foreach (var derivSecType in contractDescription.Derivat
iveSecTypes)
                {
                        derivSecTypes += derivSecType;
                        derivSecTypes += " ";
                }
                Console.WriteLine("Contract: conId - {0}, symbol - {1},
secType - {2}, primExchange - {3}, currency - {4}, derivativeSecTypes -
{5}, description - {6}, issuerId - {7}",
                        contractDescription.Contract.ConId, contractDesc
ription.Contract.Symbol, contractDescription.Contract.SecType,
                        contractDescription.Contract.PrimaryExch, contra
ctDescription.Contract.Currency, derivSecTypes, contractDescription.Cont
ract.Description, contractDescription.Contract.IssuerId);
        }
}

Public Sub symbolSamples(reqId As Integer, contractDescriptions As Contr
actDescription()) Implements EWrapper.symbolSamples
        Dim derivSecTypes As String
        Console.WriteLine("Symbol Samples. Request Id: " & reqId)
        For Each contractDescription In contractDescriptions
                derivSecTypes = ""
                For Each derivSecType In contractDescription.DerivativeS
ecTypes
                        derivSecTypes += derivSecType
                        derivSecTypes += " "
                Next
                Console.WriteLine("Contract conId: " & contractDescripti
on.Contract.ConId & ", symbol: " & contractDescription.Contract.Symbol &
                                                  ", secType: " & contra
ctDescription.Contract.SecType & ", primExchange: " & contractDescriptio
n.Contract.PrimaryExch &
                                                  ", currency: " & contr
actDescription.Contract.Currency & ", derivativeSecTypes: " & derivSecTy
pes &
                                                  ", description: " & co
ntractDescription.Contract.Description & ", issuerId: " & contractDescri
ption.Contract.IssuerId)
        Next
End Sub

Error Handling

Copy Location
            When a client application sends a message to TWS which
            requires a response which has an expected response
            (i.e. placing an order, requesting market data,
            subscribing to account updates, etc.), TWS will almost
            either always 1) respond with the relevant data or 2)
            send an error message to [534]EWrapper.error().
               o Exceptions when no response can occur: Also, if a
                 request is made prior to full establishment of
                 connection (denoted by a returned 2104 or 2106
                 error code “Data Server is Ok”), there may not be
                 a response from the request.
            Error messages sent by the TWS are handled by the
            [535]EWrapper.error() method. The
            [536]EWrapper.error() event contains the originating
            request Id (or the orderId in case the error was
            raised when placing an order), a numeric error code
            and a brief description. It is important to keep in
            mind that this function is used for true error
            messages as well as notifications that do not mean
            anything is wrong.
            API Error Messages when TWS is not set to the English
            Language
               o Currently on the Windows platform, error messages
                 are sent using Latin1 encoding. If TWS is
                 launched in a non-Western language, it is
                 recommended to enable the setting at Global
                 Configuration -> API -> Settings to “Show API
                 error messages in English”.

    [534] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#error
    [535] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#error
    [536] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#error

Understanding Message Codes

Copy Location
            The TWS uses the [537]EWrapper.error method not only
            to deliver errors but also warnings or informative
            messages. This is done mostly for simplicity’s sake.
            Below is a table with all the messages which can be
            sent by the TWS/IB Gateway. All messages delivered by
            the TWS are usually accompanied by a brief but
            meaningful description pointing in the direction of
            the problem.
            Remember that the TWS API simply connects to a running
            TWS/IB Gateway which most of times will be running on
            your local network if not in the same host as the
            client application. It is your responsibility to
            provide reliable connectivity between the TWS and your
            client application.

    [537] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#error

System Message Codes

Copy Location
            The messages in the table below are not a consequence
            of any action performed by the client application.
            They are notifications about the connectivity status
            between the TWS and our servers. Your client
            application must pay special attention to them and
            handle the situation accordingly. You are very likely
            to lose connectivity to our servers at least once a
            day due to our daily server maintenance downtime as
            clearly detailed in our Current System Status page.
            Note that after the system reset, the TWS/IB Gateway
            will automatically reconnect to our servers and you
            can resume your operations normally.

            Note:
              1. During a reset period, there may be an
                 interruption in the ability to log in or manage
                 orders. Existing orders (native types) will
                 operate normally although execution reports and
                 simulated orders will be delayed until the reset
                 is complete. It is not recommended to operate
                 during the scheduled reset times.

   Code TWS message Additional notes
   1100 Connectivity between IB and the TWS has been lost. Your
   TWS/IB Gateway has been disconnected from IB servers. This can
   occur because of an internet connectivity issue, a nightly
   reset of the IB servers, or a competing session.
   1101 Connectivity between IB and TWS has been restored- data
   lost.* The TWS/IB Gateway has successfully reconnected to IB’s
   servers. Your market data requests have been lost and need to
   be re-submitted.
   1102 Connectivity between IB and TWS has been restored- data
   maintained. The TWS/IB Gateway has successfully reconnected to
   IB’s servers. Your market data requests have been recovered and
   there is no need for you to re-submit them.
   1300 TWS socket port has been reset and this connection is
   being dropped. Please reconnect on the new port – <port_num>
   The port number in the TWS/IBG settings has been changed during
   an active API connection.

Error Codes

Copy Location
            Error codes in different ranges have different
            indications.

   Code TWS message Additional notes
   100 Max rate of messages per second has been exceeded. The
   client application has exceeded the rate of 50 messages/second.
   The TWS will likely disconnect the client application after
   this message.
   101 Max number of tickers has been reached. “The current number
   of active market data subscriptions in TWS and the API
   altogether has been exceeded. This number is calculated based
   on a formula which is based on the equity, commissions, and
   quote booster packs in an account. Active lines can be checked
   in Tws using the Ctrl-Alt-= combination”
   102 Duplicate ticker ID. A market data request used a ticker ID
   which is already in use by an active request.
   103 Duplicate order ID. An order was placed with an order ID
   that is less than or equal to the order ID of a previous order
   from this client
   104 Can’t modify a filled order. An attempt was made to modify
   an order which has already been filled by the system.
   105 Order being modified does not match original order. An
   order was placed with an order ID of a currently open order but
   basic parameters differed (aside from quantity or price fields)
   106 Can’t transmit order ID:
   107 Cannot transmit incomplete order. Order is missing a
   required field.
   109 Price is out of the range defined by the Percentage setting
   at order defaults frame. The order will not be transmitted.
   Price entered is outside the range of prices set in TWS or IB
   Gateway Order Precautionary Settings
   110 The price does not conform to the minimum price variation
   for this contract. An entered price field has more digits of
   precision than is allowed for this particular contract. Minimum
   increment information can be found on the IB Contracts and
   Securities Search page.
   111 The TIF (Tif type) and the order type are incompatible. The
   time in force specified cannot be used with this order type.
   Please refer to order tickets in TWS for allowable
   combinations.
   113 The Tif option should be set to DAY for MOC and LOC orders.
   Market-on-close or Limit-on-close orders should be sent with
   time in force set to ‘DAY’
   114 Relative orders are valid for stocks only. This error is
   deprecated.
   115 “Relative orders for US stocks can only be submitted to
   SMART, SMART_ECN, INSTINET, or PRIMEX.” This error is
   deprecated.
   116 The order cannot be transmitted to a dead exchange.
   Exchange field is invalid.
   117 The block order size must be at least 50.
   118 VWAP orders must be routed through the VWAP exchange.
   119 Only VWAP orders may be placed on the VWAP exchange. “When
   an order is routed to the VWAP exchange, the type of the order
   must be defined as ‘VWAP’.”
   120 It is too late to place a VWAP order for today. The cutoff
   has passed for the current day to place VWAP orders.
   121 “Invalid BD flag for the order. Check “”Destination”” and
   “”BD”” flag.” This error is deprecated.
   122 No request tag has been found for order:
   123 No record is available for conid: The specified contract ID
   cannot be found. This error is deprecated.
   124 No market rule is available for conid:
   125 Buy price must be the same as the best asking price.
   126 Sell price must be the same as the best bidding price.
   129 VWAP orders must be submitted at least three minutes before
   the start time. The start time specified in the VWAP order is
   less than 3 minutes after when it is placed.
   131 “The sweep-to-fill flag and display size are only valid for
   US stocks routed through SMART, and will be ignored.”
   132 This order cannot be transmitted without a clearing
   account.
   133 Submit new order failed.
   134 Modify order failed.
   135 Can’t find order with ID = An attempt was made to cancel an
   order not currently in the system.
   136 This order cannot be cancelled. “An attempt was made to
   cancel an order than cannot be cancelled, for instance because”
   137 VWAP orders can only be cancelled up to three minutes
   before the start time.
   138 Could not parse ticker request:
   139 Parsing error: Error in command syntax generated parsing
   error.
   140 The size value should be an integer: The size field in the
   Order class has an invalid type.
   141 The price value should be a double: A price field in the
   Order type has an invalid type.
   142 Institutional customer account does not have account info
   143 Requested ID is not an integer number. The IDs used in API
   requests must be integer values.
   144 “Order size does not match total share allocation. To
   adjust the share allocation, right-click on the order and
   select â€œModify > Share Allocation.â€?”
   145 Error in validating entry fields – An error occurred with
   the syntax of a request field.
   146 Invalid trigger method. The trigger method specified for a
   method such as stop or trail stop was not one of the allowable
   methods.
   147 The conditional contract info is incomplete.
   148 Conditional submission of orders is supported for Limit,
   Market, MidPrice, Relative and Snap order types only.
   Conditional cancelation of orders is supported for Limit and
   MidPrice order types only.
   151 This order cannot be transmitted without a user name. In
   DDE the user name is a required field in the place order
   command.
   152 “The “”hidden”” order attribute may not be specified for
   this order.” The order in question cannot be placed as a hidden
   order.
   See- https://www.interactivebrokers.com/en/index.php?f=596
   153 EFPs can only be limit orders. This error is deprecated.
   154 Orders cannot be transmitted for a halted security. A
   security was halted for trading when an order was placed.
   155 A sizeOp order must have a user name and account. This
   error is deprecated.
   156 A SizeOp order must go to IBSX This error is deprecated.
   157 An order can be EITHER Iceberg or Discretionary. Please
   remove either the Discretionary amount or the Display size. In
   the Order class extended attributes the fields ‘Iceberg’ and
   ‘Discretionary’ cannot
   158 You must specify an offset amount or a percent offset
   value. TRAIL and TRAIL STOP orders must have an absolute offset
   amount or offset percentage specified.
   159 The percent offset value must be between 0% and 100%. A
   percent offset value was specified outside the allowable range
   of 0% and 100%.
   160 The size value cannot be zero. The size of an order must be
   a positive quantity.
   161 Cancel attempted when order is not in a cancellable state.
   Order permId = An attempt was made to cancel an order not
   active at the time.
   162 Historical market data Service error message.
   163 The price specified would violate the percentage constraint
   specified in the default order settings. The order price
   entered is outside the allowable range specified in the Order
   Precautionary Settings of TWS or IB Gateway
   164 There is no market data to check price percent violations.
   No market data is available for the specified contract to
   determine whether the specified price is outside the price
   percent precautionary order setting.
   165 Historical market Data Service query message. “There was an
   issue with a historical data request, such is no such data in
   IB’s database. Note this message is not specific to the API.”
   166 HMDS Expired Contract Violation. Historical data is not
   available for the specified expired contract.
   167 VWAP order time must be in the future. The start time of a
   VWAP order has already passed.
   168 Discretionary amount does not conform to the minimum price
   variation for this contract. The discretionary field is
   specified with a number of degrees of precision higher than
   what is allowed for a specified contract.
   200 No security definition has been found for the request. “The
   specified contract does not match any in IB’s database, usually
   because of an incorrect or missing parameter.”
   200 The contract description specified for is ambiguous
   Ambiguity may occur when the contract definition provided is
   not unique.
   200 “For some stocks that has the same Symbol, Currency and
   Exchange, you need to specify
   the IBApi.Contract.PrimaryExch attribute to avoid ambiguity.
   Please refer to a sample stock contract here.”
   200 “For futures that has multiple multipliers for the same
   expiration, You need to specify
   the IBApi.Contract.Multiplier attribute to avoid ambiguity.
   Please refer to a sample futures contract here.”
   201 Order rejected – Reason: An attempted order was rejected by
   the IB servers. See Order Placement Considerations for
   additional information/considerations for these errors.
   202 Order cancelled – Reason: An active order on the IB server
   was cancelled. See Order Placement Considerations for
   additional information/considerations for these errors.
   203 The security is not available or allowed for this account.
   The specified security has a trading restriction with a
   specific account.
   300 Can’t find EId with ticker Id: An attempt was made to
   cancel market data for a ticker ID that was not associated with
   a current subscription. With the DDE API this occurs by
   clearing the spreadsheet cell.
   301 Invalid ticker action:
   302 Error parsing stop ticker string:
   303 Invalid action: An action field was specified that is not
   available for the account. For most accounts this is only BUY
   or SELL. Some institutional accounts also have the options
   SSHORT or SLONG available.
   304 Invalid account value action:
   305 “Request parsing error, the request has been ignored.” The
   syntax of a DDE request is invalid.
   306 Error processing DDE request: An issue with a DDE request
   prevented it from processing.
   307 Invalid request topic: The ‘topic’ field in a DDE request
   is invalid.
   308 Unable to create the ‘API’ page in TWS as the maximum
   number of pages already exists. “An order placed from the API
   will automatically open a new page in classic TWS, however
   there are already the maximum number of pages open.”
   309 “Max number (3) of market depth requests has been reached.
   Note: TWS currently limits users to a maximum of 3 distinct
   market depth requests. This same restriction applies to API
   clients, however API clients may make multiple market depth
   requests for the same security.”
   310 Can’t find the subscribed market depth with tickerId: An
   attempt was made to cancel market depth for a ticker not
   currently active.
   311 The origin is invalid. The origin field specified in the
   Order class is invalid.
   312 The combo details are invalid. Combination contract
   specified has invalid parameters.
   313 The combo details for leg ” are invalid. A combo leg was
   not defined correctly.
   314 Security type ‘BAG’ requires combo leg details. When
   specifying security type as ‘BAG’ make sure to also add combo
   legs with details.
   315 Stock combo legs are restricted to SMART order routing.
   Make sure to specify ‘SMART’ as an exchange when using stock
   combo contracts.
   316 Market depth data has been HALTED. Please re-subscribe. You
   need to re-subscribe to start receiving market depth data
   again.
   317 Market depth data has been RESET. Please empty deep book
   contents before applying any new entries.
   319 Invalid log level Make sure that you are setting a log
   level to a value in range of 1 to 5.
   320 Server error when reading an API client request.
   321 Server error when validating an API client request.
   322 Server error when processing an API client request.
   323 Server error: cause – s
   324 Server error when reading a DDE client request (missing
   information). Make sure that you have specified all the needed
   information for your request.
   325 Discretionary orders are not supported for this combination
   of exchange and order type. Make sure that you are specifying a
   valid combination of exchange and order type for the
   discretionary order.
   326 Unable to connect as the client id is already in use. Retry
   with a unique client id. Another client application is already
   connected with the specified client id.
   327 Only API connections with clientId set to 0 can set the
   auto bind TWS orders property.
   328 Trailing stop orders can be attached to limit or stop-limit
   orders only. Indicates attempt to attach trail stop to order
   which was not a limit or stop-limit.
   329 Order modify failed. Cannot change to the new order type.
   You are not allowed to modify initial order type to the
   specific order type you are using.
   330 Only FA or STL customers can request managed accounts list.
   Make sure that your account type is either FA or STL.
   331 Internal error. FA or STL does not have any managed
   accounts. You do not have any managed accounts.
   332 The account codes for the order profile are invalid. You
   need to check that the account codes you specified for your
   request are valid.
   333 Invalid share allocation syntax.
   334 Invalid Good Till Date order Check you order settings.
   335 Invalid delta: The delta must be between 0 and 100.
   336 “The time or time zone is invalid. The correct format is
   hh:mm:ss xxx where xxx is an optionally specified time-zone.
   E.g.: 15:59:00 EST Note that there is a space between the time
   and the time zone. If no time zone is specified, local time is
   assumed.”
   337 “The date, time, or time-zone entered is invalid. The
   correct format is yyyymmdd hh:mm:ss xxx where yyyymmdd and xxx
   are optional. E.g.: 20031126 15:59:00 ESTNote that there is a
   space between the date and time, and between the time and
   time-zone.”
   338 Good After Time orders are currently disabled on this
   exchange.
   339 Futures spread are no longer supported. Please use combos
   instead.
   340 Invalid improvement amount for box auction strategy.
   341 “Invalid delta. Valid values are from 1 to 100. You can set
   the delta from the “”Pegged to Stock”” section of the Order
   Ticket Panel, or by selecting Page/Layout from the main menu
   and adding the Delta column.”
   342 Pegged order is not supported on this exchange. You can
   review all order types and supported exchanges on the Order
   Types and Algos page.
   343 “The date, time, or time-zone entered is invalid. The
   correct format is yyyymmdd hh:mm:ss xxx”
   344 The account logged into is not a financial advisor account.
   You are trying to perform an action that is only available for
   the financial advisor account.
   345 Generic combo is not supported for FA advisor account.
   346 Not an institutional account or an away clearing account.
   347 Short sale slot value must be 1 (broker holds shares) or 2
   (delivered from elsewhere). Make sure that your slot value is
   either 1 or 2.
   348 Order not a short sale – type must be SSHORT to specify
   short sale slot. Make sure that the action you specified is
   ‘SSHORT’.
   349 “Generic combo does not support “”Good After”” attribute.”
   350 Minimum quantity is not supported for best combo order.
   351 “The “”Regular Trading Hours only”” flag is not valid for
   this order.”
   352 Short sale slot value of 2 (delivered from elsewhere)
   requires location. You need to specify designatedLocation for
   your order.
   353 Short sale slot value of 1 requires no location be
   specified. You do not need to specify designatedLocation for
   your order.
   354 Not subscribed to requested market data. You do not have
   live market data available in your account for the specified
   instruments. For further details please refer to Streaming
   Market Data.
   355 Order size does not conform to market rule. Check order
   size parameters for the specified contract from the TWS
   Contract Details.
   356 Smart-combo order does not support OCA group. Remove OCA
   group from your order.
   357 Your client version is out of date.
   358 Smart combo child order not supported.
   359 Combo order only supports reduce on fill without
   block(OCA).
   360 No whatif check support for smart combo order. Pre-trade
   commissions and margin information is not available for this
   type of order.
   361 Invalid trigger price.
   362 Invalid adjusted stop price.
   363 Invalid adjusted stop limit price.
   364 Invalid adjusted trailing amount.
   365 No scanner subscription found for ticker id: Scanner market
   data subscription request with this ticker id has either been
   cancelled or is not found.
   366 No historical data query found for ticker id: Historical
   market data request with this ticker id has either been
   cancelled or is not found.
   367 Volatility type if set must be 1 or 2 for VOL orders. Do
   not set it for other order types.
   368 Reference Price Type must be 1 or 2 for dynamic volatility
   management. Do not set it for non-VOL orders.
   369 Volatility orders are only valid for US options. Make sure
   that you are placing an order for US OPT contract.
   370 “Dynamic Volatility orders must be SMART routed, or trade
   on a Price Improvement Exchange.”
   371 VOL order requires positive floating point value for
   volatility. Do not set it for other order types.
   372 Cannot set dynamic VOL attribute on non-VOL order. Make
   sure that your order type is ‘VOL’.
   373 Can only set stock range attribute on VOL or RELATIVE TO
   STOCK order.
   374 “If both are set, the lower stock range attribute must be
   less than the upper stock range attribute.”
   375 Stock range attributes cannot be negative.
   376 The order is not eligible for continuous update. The option
   must trade on a cheap-to-reroute exchange.
   377 Must specify valid delta hedge order aux. price.
   378 Delta hedge order type requires delta hedge aux. price to
   be specified. Make sure your order has delta attribute.
   379 Delta hedge order type requires that no delta hedge aux.
   price be specified. Make sure you do not specify aux. delta
   hedge price.
   380 This order type is not allowed for delta hedge orders.
   “Limit, Market or Relative orders are supported.”
   381 Your DDE.dll needs to be upgraded.
   382 The price specified violates the number of ticks constraint
   specified in the default order settings.
   383 The size specified violates the size constraint specified
   in the default order settings.
   384 Invalid DDE array request.
   385 Duplicate ticker ID for API scanner subscription. Make sure
   you are using a unique ticker ID for your new scanner
   subscription.
   386 Duplicate ticker ID for API historical data query. Make
   sure you are using a unique ticker ID for your new historical
   market data query.
   387 Unsupported order type for this exchange and security type.
   You can review all order types and supported exchanges on
   the Order Types and Algos page.
   388 Order size is smaller than the minimum requirement. Check
   order size parameters for the specified contract from the TWS
   Contract Details.
   389 Supplied routed order ID is not unique.
   390 Supplied routed order ID is invalid.
   391 The time or time-zone entered is invalid. The correct
   format is hh:mm:ss xxx
   392 Invalid order: contract expired. You can not place an order
   for the expired contract.
   393 Short sale slot may be specified for delta hedge orders
   only.
   394 Invalid Process Time: must be integer number of
   milliseconds between 100 and 2000. Found:
   395 “Due to system problems, orders with OCA groups are
   currently not being accepted.” Check TWS bulletins for more
   information.
   396 “Due to system problems, application is currently accepting
   only Market and Limit orders for this contract.” Check TWS
   bulletins for more information.
   397 “Due to system problems, application is currently accepting
   only Market and Limit orders for this contract.”
   398 cannot be used as a condition trigger. Please make sure
   that you specify a valid condition
   399 Order message error
   400 Algo order error.
   401 Length restriction.
   402 Conditions are not allowed for this contract. Condition
   order type does not support for this contract
   403 Invalid stop price. The Stop Price you specified for the
   order is invalid for the contract
   404 Shares for this order are not immediately available for
   short sale. The order will be held while we attempt to locate
   the shares. You order is held by the TWS because you are trying
   to sell a contract but you do not have any long position and
   the market does not have short sale available. You order will
   be transmitted once there is short sale available on the market
   405 The child order quantity should be equivalent to the parent
   order size. This error is deprecated.
   406 The currency is not allowed. Please specify a valid
   currency
   407 The symbol should contain valid non-unicode characters
   only. Please check your contract Symbol
   408 Invalid scale order increment.
   409 Invalid scale order. You must specify order component size.
   ScaleInitLevelSize specified is invalid
   410 Invalid subsequent component size for scale order.
   ScaleSubsLevelSize specified is invalid
   411 “The “”Outside Regular Trading Hours”” flag is not valid
   for this order.” Trading outside of regular trading hours is
   not available for this security
   412 The contract is not available for trading.
   413 What-if order should have the transmit flag set to true.
   You need to set IBApi.Order.Transmit to TRUE
   414 Snapshot market data subscription is not applicable to
   generic ticks. You must leave Generic Tick List to be empty
   when requesting snapshot market data
   415 Wait until previous RFQ finishes and try again.
   416 RFQ is not applicable for the contract. Order ID:
   417 Invalid initial component size for scale order.
   ScaleInitLevelSize specified is invalid
   418 Invalid scale order profit offset. ScaleProfitOffset
   specified is invalid
   419 Missing initial component size for scale order. You need to
   specify the ScaleInitLevelSize
   420 Invalid real-time query. [538]Information about pacing
   violations
   421 Invalid route. This error is deprecated.
   422 The account and clearing attributes on this order may not
   be changed.
   423 Cross order RFQ has been expired. THI committed size is no
   longer available. Please open order dialog and verify liquidity
   allocation.
   424 FA Order requires allocation to be specified. This error is
   deprecated.
   425 FA Order requires per-account manual allocations because
   there is no common clearing instruction. Please use order
   dialog Adviser tab to enter the allocation. This error is
   deprecated.
   426 None of the accounts have enough shares. You are not able
   to enter short position with Cash Account
   427 Mutual Fund order requires monetary value to be specified.
   This error is deprecated.
   428 Mutual Fund Sell order requires shares to be specified.
   This error is deprecated.
   429 Delta neutral orders are only supported for combos (BAG
   security type).
   430 “We are sorry, but fundamentals data for the security
   specified is not available.”
   431 What to show field is missing or incorrect. This error is
   deprecated.
   432 Commission must not be negative. This error is deprecated.
   433 “Invalid “”Restore size after taking profit”” for multiple
   account allocation scale order.”
   434 The order size cannot be zero.
   435 You must specify an account. The function you invoked only
   works on a single account
   436 “You must specify an allocation (either a single account,
   group, or profile).” “When you try to place an order with a
   Financial Advisor account, you must specify the order to be
   routed to either a single account, a group, or a profile.”
   437 Order can have only one flag Outside RTH or Allow PreOpen.
   This error is deprecated.
   438 The application is now locked. This error is deprecated.
   439 Order processing failed. Algorithm definition not found.
   Please double check your specification
   for IBApi.Order.AlgoStrategy and IBApi.Order.AlgoParams
   440 Order modify failed. Algorithm cannot be modified.
   441 Algo attributes validation failed: Please double check your
   specification
   for IBApi.Order.AlgoStrategy and IBApi.Order.AlgoParams
   442 Specified algorithm is not allowed for this order.
   443 Order processing failed. Unknown algo attribute.
   Specification for IBApi.Order.AlgoParams is incorrect
   444 Volatility Combo order is not yet acknowledged. Cannot
   submit changes at this time. The order is not in a state that
   is able to be modified
   445 The RFQ for this order is no longer valid.
   446 Missing scale order profit offset. ScaleProfitOffset is not
   properly specified
   447 Missing scale price adjustment amount or interval.
   ScalePriceAdjustValue or ScalePriceAdjustInterval is not
   specified properly
   448 Invalid scale price adjustment interval.
   ScalePriceAdjustInterval specified is invalid
   449 Unexpected scale price adjustment amount or interval.
   ScalePriceAdjustValue or ScalePriceAdjustInterval specified is
   invalid
   481 Order size reduced.
   501 Already Connected. Your client application is already
   connected to the TWS.
   502 “Couldn’t connect to TWS. Confirm that “”Enable ActiveX and
   Socket Clients”” is enabled and connection port is the same as
   “”Socket Port”” on the TWS “”Edit->Global
   Configuration…->API->Settings”” menu.” When you receive this
   error message it is either because you have not enabled API
   connectivity in the TWS and/or you are trying to connect on the
   wrong port. Refer to the TWS’ API Settings as explained in the
   error message. See also Connectivity
   503 The TWS is out of date and must be upgraded. Indicates TWS
   or IBG is too old for use with the current API version. Can
   also be triggered if the TWS version does not support a
   specific API function.
   504 Not connected. You are trying to perform a request without
   properly connecting and/or after connection to the TWS has been
   broken probably due to an unhandled exception within your
   client application.
   505 Fatal Error: Unknown message id.
   507 Bad Message Length (Java-only) “Indicates EOF exception was
   caught while reading from the socket. This can occur if there
   is an attempt to connect to TWS with a client ID that is
   already in use, or if TWS is locked, closes, or breaks the
   connection. It should be handled by the client application and
   used to indicate that the socket connection is not valid.”
   585 FA Profile is not supported anymore, use FA Group instead
   “Indicates FaDataTypeEnum.PROFILES is deprecated. Use
   FaDataTypeEnum.GROUPS or 1 instead”
   2100 New account data requested from TWS. API client has been
   unsubscribed from account data. “The TWS only allows
   one IBApi.EClient.reqAccountUpdates request at a time. If the
   client application attempts to subscribe to a second account
   without canceling the previous subscription, the new request
   will override the old one and the TWS will send this message
   notifying so.”
   2101 Unable to subscribe to account as the following clients
   are subscribed to a different account. “If a client application
   invokes IBApi.EClient.reqAccountUpdates when there is an active
   subscription started by a different client, the TWS will reject
   the new subscription request with this message.”
   2102 Unable to modify this order as it is still being
   processed. “If you attempt to modify an order before it gets
   processed by the system, the modification will be rejected.
   Wait until the order has been fully processed before modifying
   it. See Placing Orders for further details.”
   2103 A market data farm is disconnected. “Indicates a
   connectivity problem to an IB server. Outside of the nightly IB
   server reset, this typically indicates an underlying ISP
   connectivity issue.”
   2104 Market data farm connection is OK “A notification that
   connection to the market data server is ok. This is a
   notification and not a true error condition, and is expected on
   first establishing connection.”
   2105 A historical data farm is disconnected. “Indicates a
   connectivity problem to an IB server. Outside of the nightly IB
   server reset, this typically indicates an underlying ISP
   connectivity issue.”
   2106 A historical data farm is connected. “A notification that
   connection to the market data server is ok. This is a
   notification and not a true error condition, and is expected on
   first establishing connection.”
   2107 A historical data farm connection has become inactive but
   should be available upon demand. “Whenever a connection to the
   historical data farm is not being used because there is not an
   active historical data request, the connection will go inactive
   in IB Gateway. This does not indicate any connectivity issue or
   problem with IB Gateway. As soon as a historical data request
   is made the status will change back to active.”
   2108 A market data farm connection has become inactive but
   should be available upon demand. “Whenever a connection to our
   data farms is not needed, it will become dormant. There is
   nothing abnormal nor wrong with your client application nor
   with the TWS. You can safely ignore this message.”
   2109 “Order Event Warning: Attribute “”Outside Regular Trading
   Hours”” is ignored based on the order type and destination.
   PlaceOrder is now processed.” Indicates the outsideRth flag was
   set for an order for which there is not a regular vs outside
   regular trading hour distinction
   2110 Connectivity between TWS and server is broken. It will be
   restored automatically. Indicates a connectivity problem
   between TWS or IBG and the IB server. This will usually only
   occur during the IB nightly server reset; cases at other times
   indicate a problem in the local ISP connectivity.
   2111 The Start and/or End Time for algo order BUY/SELL a
   contract was adjusted to use the next trading date. To modify
   this setting, use the Auto-adjust algo order date item on the
   Orders configuration page Please go to TWS Global Configuration
   – “Orders” – “Settings” to correct the configuration.
   2119 Market data farm is connecting.
   2130 Warning: products are trading on the basis of currency
   price with factor.
   2137 Cross Side Warning “This warning message occurs in TWS
   version 955 and higher. It occurs when an order will change the
   position in an account from long to short or from short to
   long. To bypass the warning, a new feature has been added to IB
   Gateway 956 (or higher) and TWS 957 (or higher) so that once
   can go to Global Configuration > Messages and disable the
   “”Cross Side Warning””.”
   2152 Market depth smart depth exchanges.
   2158 Sec-def data farm connection is OK “A notification that
   connection to the Security definition data server is ok. This
   is a notification and not a true error condition, and is
   expected on first establishing connection.”
   2168 Etrade Only Not Supported Warning The
   EtradeOnly IBApi.Order attribute is no longer supported. Error
   received with TWS versions 983+. Remove attribute to place
   order.
   2169 Firm Quote Only Not Supported Warning The
   firmQuoteOnly IBApi.Order attribute is no longer supported.
   Error received with TWS versions 983+. Remove attribute to
   place order.
   10000 Cross currency combo error.
   10001 Cross currency vol error.
   10002 Invalid non-guaranteed legs.
   10003 IBSX not allowed.
   10005 Read-only models.
   10006 Missing parent order. The parent order ID specified
   cannot be found. In some cases this can occur with bracket
   orders if the child order is placed immediately after the
   parent order; a brief pause of 50 ms or less will be necessary
   before the child order is transmitted to TWS/IBG.
   10007 Invalid hedge type.
   10008 Invalid beta value.
   10009 Invalid hedge ratio.
   10010 Invalid delta hedge order.
   10011 Currency is not supported for Smart combo.
   10012 Invalid allocation percentage FaPercentage specified is
   not valid
   10013 Smart routing API error (Smart routing opt-out required).
   10014 PctChange limits. This error is deprecated
   10015 Trading is not allowed in the API.
   10016 Contract is not visible. This error is deprecated
   10017 Contracts are not visible. This error is deprecated
   10018 Orders use EV warning.
   10019 Trades use EV warning.
   10020 Display size should be smaller than order size./td> The
   display size should be smaller than the total quantity
   10021 Invalid leg2 to Mkt Offset API. This error is deprecated
   10022 Invalid Leg Prio API. This error is deprecated
   10023 Invalid combo display size API. This error is deprecated
   10024 Invalid don’t start next legin API. This error is
   deprecated
   10025 Invalid leg2 to Mkt time1 API. This error is deprecated
   10026 Invalid leg2 to Mkt time2 API. This error is deprecated
   10027 Invalid combo routing tag API. This error is deprecated
   10090 Part of requested market data is not subscribed.
   “Indicates that some tick types requested require additional
   market data subscriptions not held in the account. This
   commonly occurs for instance if a user has options
   subscriptions but not the underlying stock so the system cannot
   calculate the real time greek values (other default ticks will
   be returned). Or alternatively, if generic tick types are
   specified in a market data request without the associated
   subscriptions.”
   10147 Order to be canceled was not found.
   10148 “OrderId that needs to be cancelled can not be cancelled,
   state:” An attempt was made to cancel an order that had already
   been filled by the system.
   10186 Requested market data is not subscribed. Delayed market
   data is not enabled See Market Data Types on how to enable
   delayed data.
   10187 Failed to request historical ticks:No market data
   permissions
   10189 Failed to request tick-by-tick data. Invalid Real-time
   Query Trading TWS session is connected from a different IP
   address. Or, No market data permissions
   10197 No market data during competing session “Indicates that
   the user is logged into the paper account and live account
   simultaneously trying to request live market data using both
   the accounts. In such a scenario preference would be given to
   the live account, for more details please
   refer: https://ibkr.info/node/1719”
   10225 “Bust event occurred, current subscription is
   deactivated. Please resubscribe real-time bars immediately”
   10230 “You have unsaved FA changes. Please retry ‘request FA’
   operation later, when ‘replace FA’ operation is complete” There
   are pending Financial Advisor configuration changes.
   See Financial Advisors
   10231 The following Groups and/or Profiles contain invalid
   accounts: “If the account(s) inside Groups or Profiles is/are
   incorrect in xml-formatted configuration string of replaceFA
   request, then the error shows list of such Groups and/or
   Profiles.”
   10233 Defaults were inherited from CASH preset during the
   creation of this order.
   10234 The Decision Maker field is required and not set for this
   order (non-desktop).
   10235 The Decision Maker field is required and not set for this
   order (ibbot).
   10236 Child has to be AON if parent order is AON
   10237 All or None ticket can route entire unfilled size only
   10238 Some error occured during communication with Advisor
   Setup web-app
   10239 This order will affect one or more accounts that are
   flagged because they do not fit the required risk score
   criteria prescribed by the group/profile/model allocation.
   10240 You must enter a valid Price Cap.
   10241 Order Quantity is expressed in monetary terms.
   Modification is not supported via API. Please use desktop
   version to revise this order.
   10242 Fractional-sized order cannot be modified via API. Please
   use desktop version to revise this order.
   10243 Fractional-sized order cannot be placed via API. Please
   use desktop version to place this order.
   10244 Cash Quantity cannot be used for this order
   10245 This financial instrument does not support fractional
   shares trading
   10246 This order doesn’t support fractional shares trading
   10247 Only IB SmartRouting supports fractional shares
   10248 doesn’t have permission to trade fractional shares
   10249 “=””””> order doesn’t support fractional shares”
   10250 The size does not conform to the minimum variation of for
   this contract
   10251 Fractional shares are not supported for allocation orders
   10252 This non-close-position order doesn’t support fractional
   shares trading
   10253 Clear Away orders are not supported for multi-leg combo
   with attached hedge.
   10254 Invalid Order: bond expired
   10268 The ‘EtradeOnly’ order attribute is not supported The
   EtradeOnly IBApi.Order attribute is no longer supported. Error
   received with TWS versions 983+
   10269 The ‘firmQuoteOnly’ order attribute is not supported The
   firmQuoteOnly IBApi.Order attribute is no longer supported.
   Error received with TWS versions 983+
   10270 The ‘nbboPriceCap’ order attribute is not supported The
   nbboPriceCap IBApi.Order attribute is no longer supported.
   Error received with TWS versions 983+
   10276 News feed is not allowed The API client is not
   permissioned for receiving WSH news feed.
   10277 News feed permissions required The API client is not
   subscribed to receive WSH news feed
   10278 Duplicate WSH metadata request A request is already
   pending for the same API client.
   10279 Failed request WSH metadata A general error occurred when
   processing the request.
   10280 Failed cancel WSH metadata A general error occurred when
   processing the request.
   10281 Duplicate WSH event data request A request is already
   pending for the same API client.
   10282 WSH metadata not requested WSH metadata was not requested
   by first sending a reqWshMetaData request.
   10283 Fail request WSH event data A general error occurred when
   processing the request.
   10284 Fail cancel WSH event data A general error occurred when
   processing the request.
   10285 Your API version does not support fractional sizing
   rules. Please upgrade to at least version 163
   WinError 10038 An operation was attempted on something that is
   not a socket. This indicates socket connection was closed
   improperly. Typically for Python clients. You may refer
   : https://stackoverflow.com/questions/15210178/python-socket-pr
   ogramming-oserror-winerror-10038-an-operation-was-attempted-o

    [538] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#historical-pacing-limitations

Receiving Error Messages

Copy Location

EWrapper.error(
            reqId: int. The request identifier corresponding to
            the most recent reqId that maintained the error
            stream.
            This does not pertain to the orderId from placeOrder,
            but whatever the most recent requestId is.
            errorCode: int. The code identifying the error.
            errorMsg: String. The error’s description.
            advancedOrderRejectJson: String. Advanced order reject
            description in json format.
            )
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def error(self, reqId: TickerId, errorCode: int, errorString: str, advan
cedOrderRejectJson = ""):
  print("Error. Id:", reqId, "Code:", errorCode, "Msg:", errorString, "A
dvancedOrderRejectJson:", advancedOrderRejectJson)

@Override
public void error(int id, int errorCode, String errorMsg, String advance
dOrderRejectJson) {
  String str = "Error. Id: " + id + ", Code: " + errorCode + ", Msg: " +
 errorMsg;
  if (advancedOrderRejectJson != null) {
    str += (", AdvancedOrderRejectJson: " + advancedOrderRejectJson);
  }
  System.out.println(str + "\n");
}

void TestCppClient::error(int id, int errorCode, const std::string& erro
rString, const std::string& advancedOrderRejectJson)
{
    printf("Error. Id: %d, Code: %d, Msg: %s, AdvancedOrderRejectJson: %
s\n", id, errorCode, errorString.c_str(), advancedOrderRejectJson.c_str(
));
}

public virtual void error(int id, int errorCode, string errorMsg, string
 advancedOrderRejectJson)
{
  Console.WriteLine("Error. Id: " + id + ", Code: " + errorCode + ", Msg
: " + errorMsg + ", AdvancedOrderRejectJson: " + advancedOrderRejectJson
 + "\n");
}

Public Sub [error](id As Integer, errorCode As Integer, errorMsg As Stri
ng, advancedOrderRejectJson As String) Implements IBApi.EWrapper.error
            Console.WriteLine("Error - Id [" & id & "] ErrorCode [" & er
rorCode & "] ErrorMsg [" & errorMsg & "] AdvancedOrderRejectJson [" & ad
vancedOrderRejectJson & "]")
End Sub

Financial Advisors

Copy Location
            Financial Advisors are able to manage their allocation
            groups from the TWS API.
            Note: Modifications made through the API will effect
            orders placed through TWS, the TWS API, Client Portal,
            and the Client Portal API.

Request FA Groups and Profiles

Copy Location

EClient.requestFA (
            faDataType: int. The configuration to change. Set to 1
            or 3 as defined in the table below.
            )
            Requests the FA configuration as set in TWS for the
            given FA Group or Profile.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.requestFA(1)

client.requestFA(1);

m_pClient->requestFA(1);

client.requestFA(1);

client.requestFA(1)


requestFA FA Data Types

   Type Code Type Name Description
   1 Groups offer traders a way to create a group of accounts and
   apply a single allocation method to all accounts in the group.
   3 Account Aliases let you easily identify the accounts by
   meaningful names rather than account numbers.

Receiving FA Groups and Profiles

Copy Location

EWrapper.receiveFA (
            faDataType: int. Receive the faDataType value
            specified in the requestFA. See [539]FA Data Types
            faXmlData: String. The xml-formatted configuration.
            )
            Receives the Financial Advisor’s configuration
            available in the TWS.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def receiveFA(self, faData: FaDataType, cxml: str):
        print("Receiving FA: ", faData)
        open('log/fa.xml', 'w').write(cxml)

@Override
public void receiveFA(int faDataType, String xml) {
        System.out.println("Receiving FA: " + faDataType + " - " + xml);
}

void TestCppClient::receiveFA(faDataType pFaDataType, const std::string&
 cxml) {
    std::cout << "Receiving FA: " << (int)pFaDataType << std::endl << cx
ml << std::endl;
}

public virtual void receiveFA(int faDataType, string faXmlData)
{
        Console.WriteLine("Receing FA: "+faDataType+" - "+faXmlData);
}

Public Sub receiveFA(faDataType As Integer, faXmlData As String) Impleme
nts IBApi.EWrapper.receiveFA
  Console.WriteLine("Receing FA: " & faDataType & " - " & faXmlData)
End Sub

Replace FA Allocations

Copy Location

EClient.replaceFA (
            reqId: int. Request identifier used to track data.
            faDataType: int. The configuration structure to
            change. Set to 1 or 3 as defined above.
            xml: String. XML configuration for allocation profiles
            or group. See [540]Allocation Method XML Format for
            more details.
            )
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.replaceFa(reqId, 1, xml)

    [540] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#allocation-format

client.replaceFa(reqId, 1, xml);

m_pClient->replaceFa(reqId, 1, xml);

client.replaceFa(reqId, 1, xml);

client.replaceFa(reqId, 1, xml)


replaceFA FA Data Types

   replaceFA Type Code Type Name Description
   1 Groups offer traders a way to create a group of accounts and
   apply a single allocation method to all accounts in the group.
   2 Account Aliases let you easily identify the accounts by
   meaningful names rather than account numbers.

            Note:
            In order to confirm that your FA changes were saved,
            you may wait for the [541]EWrapper.replaceFAEnd
            callback, which provides the corresponding reqId. In
            addition, after saving changes, it is advised to
            verify the new FA setup via [542]EClient.requestFA. If
            it is called before changes are fully saved, you may
            receive an error, such as [543]error 10230. See
            [544]Message Codes.

    [541] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-methods-e-f/#receive-fa
    [542] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-methods-e-f/#request-fa
    [543] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-ref/#api-error-codes
    [544] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-ref/#api-error-codes

            [545]EClient.replaceFA only accepts faDataType 1
            now. Otherwise, it may trigger [546]error 585.

    [545] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#replace-fa
    [546] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#api-error-codes

EWrapper.replaceFAEnd (
            reqId: int. Request identifier used to track data.
            text: String. the message text.
            )
            Marks the ending of the replaceFA reception.

               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def replaceFAEnd(self, reqId: int, text: str):
    super().replaceFAEnd(reqId, text)
    print("ReplaceFAEnd.", "ReqId:", reqId, "Text:", text)

@Override
public void replaceFAEnd(int reqId, String text) {
        System.out.println(EWrapperMsgGenerator.replaceFAEnd(reqId, text
));
}
void TestCppClient::replaceFAEnd(int reqId, const std::string& text) {
    printf("Replace FA End. Request: %d, Text:%s\n", reqId, text.c_str()
);
}

public virtual void replaceFAEnd(int reqId, string text)
{
    Console.WriteLine("Replace FA End. ReqId: " + reqId + ", Text: " + t
ext + "\n");
}

Public Sub replaceFAEnd(reqId As Integer, text As String) Implements IBA
pi.EWrapper.replaceFAEnd
    Console.WriteLine("replaceFAEnd. ReqId: {0}, Text: {1}", reqId, text
)
End Sub

Allocation Methods and Groups

Copy Location
            A number of methods for account allocations are
            available with Financial Advisor and IBroker account
            structures to specify how trades should be distributed
            across multiple accounts.
            Allocation Groups can be created or modified in the
            Trader Workstation directly as described in [547]TWS:
            Allocations and Transfers.
            Alternatively, allocation groups can be created or
            modified through the [548]EClient.replaceFA() method
            in the API.
            Interactive Brokers supports two forms of allocation
            methods. Allocation methods that have calculations
            completed by Interactive Brokers, and a set of
            allocation methods calculated by the user and then
            specified.

    [547] https://www.ibkrguides.com/tws/usersguidebook/financialadvisors/create an account group for share allocation.htm
    [548] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#replace-fa

IB-computed allocation methods
               o [549]Available Equity
               o [550]Equal Quantity
               o [551]Net Liquidation Value

    [549] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#available-equity-xml
    [550] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#equal-quantity-xml
    [551] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#nlv-xml

User-specified allocation methods

Formerly known as Allocation Profiles
               o [552]Cash Quantity
               o [553]Percentages
               o [554]Ratios
               o [555]Shares

    [552] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#cash-xml
    [553] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#percentage-xml
    [554] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#ratio-xml
    [555] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#shares-xml

Allocation Method XML Format

Copy Location
            Allocation methods for financial advisor’s allocation
            groups are created using an XML format. The content
            below signifies the supported allocation groups and
            how to format them in their respective XML.

Available Equity

Copy Location
            Requires you to specify an order size. This method
            distributes shares based on the amount of available
            equity in each account. The system calculates ratios
            based on the Available Equity in each account and
            allocates shares based on these ratios.

            Example: You transmit an order for 700 shares of stock
            XYZ. The account group includes three accounts, A, B
            and C with available equity in the amounts of $25,000,
            $50,000 and $100,000 respectively. The system
            calculates a ratio of 1:2:4 and allocates 100 shares
            to Client A, 200 shares to Client B, and 400 shares to
            Client C.
<?xml version="1.0" encoding="UTF-8"?>
<ListOfGroups>
  <Group>
    <name>MyTestProfile2</name>
    <defaultMethod>AvailableEquity</defaultMethod>
    <ListOfAccts varName="list">
      <Account>
        <acct>DU6202167</acct>
      </Account>
      <Account>
        <acct>DU6202168</acct>
      </Account>
    </ListOfAccts>
  </Group>
</ListOfGroups>

Contracts Or Shares

Copy Location
            This method allocates the absolute number of shares
            you enter to each account listed. If you use this
            method, the order size is calculated by adding
            together the number of shares allocated to each
            account in the profile.

            Example:
            Assume an order for 300 shares of stock ABC is
            transmitted.
            In the example code shown in the right side, you can
            see that:
              1. Account A is set to receive 100.0 shares while
                 Account B is set to receive 200.0 shares. Account
                 A should receive 100 shares and Account B should
                 receive 200 shares.
<?xml version="1.0" encoding="UTF-8"?>
<ListOfGroups>
  <Group>
  <name>MyTestProfile2</name>
  <defaultMethod>ContractsOrShares</defaultMethod>

  <ListOfAccts varName="list">
  <Account>
    <acct>DU6202167</acct>
    <amount>100.0</amount>
  </Account>
  <Account>
    <acct>DU6202168</acct>
    <amount>200.0</amount>
  </Account>
  </ListOfAccts>
  </Group>
</ListOfGroups>

Equal Quantity

Copy Location
            Requires you to specify an order size. This method
            distributes shares equally between all accounts in the
            group.

            Example: You transmit an order for 400 shares of stock
            ABC. If your Account Group includes four accounts,
            each account receives 100 shares. If your Account
            Group includes six accounts, each account receives 66
            shares, and then 1 share is allocated to each account
            until all are distributed.
<?xml version="1.0" encoding="UTF-8"?>
<ListOfGroups>
  <Group>
    <name>MyTestProfile2</name>
    <defaultMethod>Equal</defaultMethod>
    <ListOfAccts varName="list">
      <Account>
        <acct>DU6202167</acct>
      </Account>
      <Account>
        <acct>DU6202168</acct>
      </Account>
    </ListOfAccts>
  </Group>
</ListOfGroups>

MonetaryAmount

Copy Location
            The Monetary Amount method calculates the number of
            units to be allocated based on the monetary value
            assigned to each account.
<?xml version="1.0" encoding="UTF-8"?>
<ListOfGroups>
  <Group>
  <name>MyTestProfile2</name>
  <defaultMethod>MonetaryAmount</defaultMethod>

  <ListOfAccts varName="list">
  <Account>
    <acct>DU6202167</acct>
    <amount>1000.0</amount>
  </Account>
  <Account>
    <acct>DU6202168</acct>
    <amount>2000.0</amount>
  </Account>
  </ListOfAccts>
  </Group>
</ListOfGroups>

Net Liquidation Value

Copy Location
            Requires you to specify an order size. This method
            distributes shares based on the net liquidation value
            of each account. The system calculates ratios based on
            the Net Liquidation value in each account and
            allocates shares based on these ratios.

            Example: You transmit an order for 700 shares of stock
            XYZ. The account group includes three accounts, A, B
            and C with Net Liquidation values of $25,000, $50,000
            and $100,000 respectively. The system calculates a
            ratio of 1:2:4 and allocates 100 shares to Client A,
            200 shares to Client B, and 400 shares to Client C.
<?xml version="1.0" encoding="UTF-8"?>
<ListOfGroups>
  <Group>
    <name>MyTestProfile2</name>
    <defaultMethod>NetLiq</defaultMethod>
    <ListOfAccts varName="list">
      <Account>
        <acct>DU6202167</acct>
      </Account>
      <Account>
        <acct>DU6202168</acct>
      </Account>
    </ListOfAccts>
  </Group>
</ListOfGroups>

Percentages

Copy Location
            This method will split the total number of shares in
            the order between listed accounts based on the
            percentages you indicate.

            Example:
            Assume an order for 300 shares of stock ABC is
            transmitted.
            In the example code shown in the right side, you can
            see that:
              1. Account A is set to have 60.0 percentage while
                 Account B is set to have 40.0 percentage. Account
                 A should receive 180 shares and Account B should
                 receive 120 shares.

            While making modifications to allocations for
            profiles, the method uses an enumerated value. The
            number shown below demonstrates precisely what profile
            corresponds to which value.

              BUY ORDER    Positive Percent   Negative Percent
            Long Position  Increases position No effect
            Short Position No effect          Decreases position

              SELL ORDER   Positive Percent   Negative Percent
            Long Position  No effect          Decreases position
            Short Position Increases position No effect

            Note:
            Do not specify an order size. Since the quantity is
            calculated by the system, the order size is displayed
            in the Quantity field after the order is acknowledged.
            This method increases or decreases an already existing
            position. Positive percents will increase a position,
            negative percents will decrease a position. For
            exmaple, to fully close out a position, you just need
            to specify percentage to be -100.

<?xml version="1.0" encoding="UTF-8"?>
<ListOfGroups>
  <Group>
  <name>MyTestProfile2</name>
  <defaultMethod>Percent</defaultMethod>
  <ListOfAccts varName="list">
  <Account>
    <acct>DU6202167</acct>
    <amount>60.0</amount>
  </Account>
  <Account>
    <acct>DU6202168</acct>
    <amount>40.0</amount>
  </Account>
  </ListOfAccts>
  </Group>
</ListOfGroups>

Ratios

Copy Location
            This method calculates the allocation of shares based
            on the ratios you enter.
            Example:
            Assume an order for 300 shares of stock ABC is
            transmitted.
            In the example code shown in the right side, you can
            see that:
              1. A ratio of 1.0 and 2.0 is set to Account A and
                 Account B. Account A should receive 100 shares
                 and Account B should receive 200 shares.
<?xml version="1.0" encoding="UTF-8"?>
<ListOfGroups>
  <Group>
  <name>MyTestProfile2</name>
  <defaultMethod>Ratio</defaultMethod>

  <ListOfAccts varName="list">
  <Account>
    <acct>DU6202167</acct>
    <amount>1.0</amount>
  </Account>
  <Account>
    <acct>DU6202168</acct>
    <amount>2.0</amount>
  </Account>
  </ListOfAccts>
  </Group>
</ListOfGroups>

Model Portfolios and the API

Copy Location
            Advisors can use Model Portfolios to easily invest
            some or all of a client’s assets into one or multiple
            custom-created portfolios, rather than tediously
            managing individual investments in single instruments.
            [556]More about Model Portfolios
            The TWS API can access model portfolios in accounts
            where this functionality is available and a specific
            model has previously been setup in TWS. API
            functionality allows the client application to request
            model position update subscriptions, request model
            account update subscriptions, or place orders to a
            specific model.
            Model Portfolio functionality not available in the TWS
            API:
               o Portfolio Model Creation
               o Portfolio Model Rebalancing
               o Portfolio Model Position or Cash Transfer
            To request position updates from a specific model, the
            function [557]IBApi::EClient::reqPositionsMulti can be
            used: [558]Position Update Subscription by Model
            To request model account updates, there is the
            function [559]IBApi::EClient::reqAccountUpdatesMulti,
            see: [560]Account Value Update Subscriptions by Model
            To place an order to a model, the
            IBApi.Order.ModelCode field must be set accordingly,
            for example:
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
modelOrder = Order()
modelOrder.account = "DF12345"
modelOrder.modelCode = "Technology" # model for tech stocks first create
d in TWS
self.placeOrder(self.nextOrderId(), contract, modelOrder)

    [556] https://www.interactivebrokers.com/en/index.php?f=20917
    [557] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#request-positions-multi
    [558] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#positions-multi
    [559] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#request-model-account-update
    [560] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#model-account-update

Order modelOrder = Order();
modelOrder.account("DF12345");  // master FA account number
modelOrder.modelCode("Technology"); // model for tech stocks first creat
ed in TWS
client.placeOrder(nextOrderId++, contract, modelOrder);

Order modelOrder = Order();
modelOrder.account = "DF12345";
modelOrder.modelCode = "Technology";
m_pClient->placeOrder(m_orderId++, contract, modelOrder);

Order modelOrder = Order();
modelOrder.Account = "DF12345";  // master FA account number
modelOrder.ModelCode = "Technology"; // model for tech stocks first crea
ted in TWS
client.placeOrder(nextOrderId++, contract, modelOrder);

Dim modelOrder As Order = Order()
modelOrder.Account = "DF12345" 'master FA account number
modelOrder.ModelCode = "Technology" 'model for tech stocks first created
 in TWS
client.placeOrder(increment(nextOrderId), contract, modelOrder)

Unification of Groups and Profiles

Copy Location
            With TWS/IBGW build 983+, the API settings will have a
            new flag/checkbox, “Use Account Groups with Allocation
            Methods” (enabled by default for new users). If not
            enabled, groups and profiles would behave the same as
            before. If it is checked, group and profile
            functionality will be merged.
            With TWS/IBGW Build 10.20+, this setting is now
            enabled by default, and moving forward into new
            versions, the two systems can be deemed as
            interchangeable for modifying allocation groups,
            placing orders, requesting account or portfolio
            summaries, or requesting multiple positions.

Order Placement

Copy Location
            For advisors to place orders to their [561]allocation
            groups users would simply declare their allocation
            group name in the order object. This would be done
            with the Order’s faGroup field. The example to the
            right references a standard market order placed to our
            allocation group, MyTestProfile.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
order = Order()
order.action = "BUY"
order.orderType = "MKT"
order.totalQuantity = 50
order.faGroup = "MyTestProfile"

    [561] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#replace-fa

Order order = new Order();
order.action("BUY");
order.orderType("MKT");
order.totalQuantity(50);
order.faGroup("MyTestProfile");


Order order;
order.action = "BUY";
order.orderType = "MKT";
order.totalQuantity = 50;
order.faGroup = "MyTestProfile";



Order order = new Order();
order.Action = "BUY";
order.OrderType = "MKT";
order.TotalQuantity = 50;
order.FaGroup = "MyTestProfile";


Dim order As Order = New Order
order.Action = "BUY"
order.OrderType = "MKT"
order.TotalQuantity = 50
order.FaGroup = "MyTestProfile"


Market Data: Delayed

Copy Location
            Delayed market data can only used with
            [562]EClient.reqMktData and
            [563]EClient.reqHistoricalData. This does not function
            for tick data.
            The API can request Live, Frozen, Delayed and Delayed
            Frozen market data from Trader Workstation by
            switching market data type via the
            [564]EClient.reqMarketDataType before making a market
            data request. A successful switch to a different
            (non-live) market data type for a particular market
            data request will be indicated by a callback to
            [565]EWrapper.marketDataType with the ticker ID of the
            market data request which is returning a different
            type of data.
               o A [566]EClient.reqMarketDataType callback
                 of 1 will occur automatically after invoking
                 reqMktData if the user has live data permissions
                 for the instrument.

    [562] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#watchlist-data
    [563] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#historical-bars

   Market Data Type ID Description
   Live 1 Live market data is streaming data relayed back in real
   time. Market data subscriptions are required to receive live
   market data.
   Frozen 2 Frozen market data is the last data recorded at market
   close. In TWS, Frozen data is displayed in gray numbers. When
   you set the market data type to Frozen, you are asking TWS to
   send the last available quote when there is not one currently
   available. For instance, if a market is currently closed and
   real time data is requested, -1 values will commonly be
   returned for the bid and ask prices to indicate there is no
   current bid/ask data available. TWS will often show a ‘frozen’
   bid/ask which represents the last value recorded by the system.
   To receive the last know bid/ask price before the market close,
   switch to market data type 2 from the API before requesting
   market data. API frozen data requires TWS/IBG v.962 or higher
   and the same market data subscriptions necessary for real time
   streaming data.
   Delayed 3

   Free, delayed data is 15 – 20 minutes delayed. In TWS, delayed
   data is displayed in brown background. When you set market data
   type to delayed, you are telling TWS to automatically switch to
   delayed market data if the user does not have the necessary
   real time data subscription. If live data is available a
   request for delayed data would be ignored by TWS. Delayed
   market data is returned with delayed [567]Tick Types (Tick ID
   66~76).
   Delayed Frozen 4 Requests delayed “frozen” data for a user
   without market data subscriptions.

Market Data Type Behavior

Copy Location
            1) If user sends reqMarketDataType(1) – TWS will start
            sending only regular (1) market data.
            2) If user sends reqMarketDataType(2) – frozen, TWS
            will start sending regular (1) as default and frozen
            (2) market data. TWS sends marketDataType callback (1
            or 2) indicating what market data will be sent after
            this callback. It can be regular or frozen.
            3) If user sends reqMarketDataType(3) – delayed, TWS
            will start sending regular (1) as default and delayed
            (3) market data.
            4) If user sends reqMarketDataType(4) –
            delayed-frozen, TWS will start sending regular (1) as
            default, delayed (3) and delayed-frozen (4) market
            data.
            Interactive Brokers data will always try to provide
            the most up to date market data possible, but will
            permit additional delayed or frozen data if available
            upon request.

Request Market Data Type

Copy Location

EClient.reqMarketDataType (
            marketDataType: int. Type of market data to retrieve.
            )
            Switches data type returned from reqMktData request to
            Live (1), Frozen (2), Delayed (3), or Frozen-Delayed
            (4).
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqMarketDataType(3)

client.reqMarketDataType(2);

m_pClient->reqMarketDataType(3);

client.reqMarketDataType(3);

client.reqMarketDataType(4)

Receive Market Data Type

Copy Location

EWrapper.marketDataType (
            reqId: int. Request identifier used to track data.
            marketDataType: int. Type of market data to retrieve.
            )
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def marketDataType(self, reqId: TickerId, marketDataType: int):
        print("MarketDataType. ReqId:", reqId, "Type:", marketDataType)

@Override
public void marketDataType(int reqId, int marketDataType) {
        System.out.println("MarketDataType: " + EWrapperMsgGenerator.mar
ketDataType(reqId, marketDataType));
}

void TestCppClient::marketDataType(TickerId reqId, int marketDataType) {
    printf( "MarketDataType. ReqId: %ld, Type: %d\n", reqId, marketDataT
ype);
}

public virtual void marketDataType(int reqId, int marketDataType)
{
        Console.WriteLine("MarketDataType. "+reqId+", Type: "+marketData
Type+"\n");
}

Public Sub marketDataType(reqId As Integer, marketDataType As Integer) I
mplements IBApi.EWrapper.marketDataType
        Console.WriteLine("MarketDataType - ReqId [" & reqId & "] Market
DataType [" & marketDataType & "]")
End Sub

Market Data: Historical

Copy Location
            Historical Market data is available for Interactive
            Brokers market data subscribers in a range of methods
            and structures. This includes requests for historical
            bars, identical to the Trader Workstation, historical
            Time & Sales, as well as Histogram data.

Historical Data Limitations

Copy Location
            Historical market data has it’s own set of market data
            limitations unique to other requests such as real time
            market data. This section will cover all limitations
            that effect historical market data in the Trader
            Workstation API.

Historical Data Filtering

Copy Location
            Historical data at IB is filtered for trade types
            which occur away from the NBBO such as combo legs,
            block trades, and derivative trades. For that reason
            the daily volume from the (unfiltered) real time data
            functionality will generally be larger than the
            (filtered) historical volume reported by historical
            data functionality. Also, differences are expected in
            other fields such as the VWAP between the real time
            and historical data feeds.

            As historical data at IB gets adjusted, compressed and
            filtered by default, there may be historical data
            differences if you request historical data at
            different time points.

Pacing Violations for Small Bars (30 secs or less)

Copy Location
            Although Interactive Brokers offers our clients high
            quality market data, IB is not a specialised market
            data provider and as such it is forced to put in place
            restrictions to limit traffic which is not directly
            associated to trading. A Pacing Violation occurs
            whenever one or more of the following restrictions is
            not observed:
            Important: these limitations apply to all our clients
            and it is not possible to overcome them. If your
            trading strategy’s market data requirements are not
            met by our market data services please consider
            contacting a specialized provider.

               o Making identical historical data requests within
                 15 seconds.
               o Making six or more historical data requests for
                 the same Contract, Exchange and Tick Type within
                 two seconds.
               o Making more than 60 requests within any ten
                 minute period.
               o Note that when BID_ASK historical data is
                 requested, each request is counted twice. In a
                 nutshell, the information above can simply be put
                 as “do not request too much data too quick”.

Unavailable Historical Data

Copy Location
            The other historical data limitations listed are
            general limitations for all trading platforms:
               o Bars whose size is 30 seconds or less older than
                 six months
               o Expired futures data older than two years
                 counting from the future’s expiration date.
               o Expired options, FOPs, warrants and structured
                 products.
               o End of Day (EOD) data for options, FOPs, warrants
                 and structured products.
               o Data for expired future spreads
               o Data for securities which are no longer trading.
               o Native historical data for combos. Historical
                 data is not stored in the IB database separately
                 for combos.; combo historical data in TWS or the
                 API is the sum of data from the legs.
               o Historical data for securities which move to a
                 new exchange will often not be available prior to
                 the time of the move. For example, SOXX stock
                 moved to NASDAQ exchange on 15 Oct 2010, so no
                 SOXX data before 15 Oct 2010 can be retrieved
                 despite SOXX was listed in 2001. This limitation
                 also applied to contract which specifies SMART as
                 the exchange.
               o Studies and indicators such as Weighted Moving
                 Averages or Bollinger Bands are not available
                 from the API.

Finding the Earliest Available Data Point

Copy Location
            For many functions, such as EClient.reqHistoricalData,
            you will need to request market data for a contract.
            Given that you may not know how long a symbol has been
            available, you can use EClient.reqHeadTimestamp to
            find the first available point of data for a given
            whatToShow value.
            ReqHeadTimeStamp counts as an ongoing historical data
            request, similar to using EClient.reqHistoricalData’s
            keepUpToDate=True flag. As a result, users should
            always:
               o Cancel timestamp requests using
                 [568]EClient.cancelHeadTimeStamp.
               o All EClient.reqHeadTimestamp requests follow the
                 [569]30 second bar limitations, regardless of
                 which bar size value has been requested.

    [568] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#cancelling-earliest-data
    [569] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#historical-pacing-limitations

Requesting the Earliest Data Point

Copy Location

EClient.reqHeadTimestamp (
            tickerId: int., A unique identifier which will serve
            to identify the incoming data.
            contract: Contract. The IBApi.Contract you are
            interested in.
            whatToShow: String. The type of data to retrieve.
            See Historical Data Types
            useRTH: int. Whether (1) or not (0) to retrieve data
            generated only within Regular Trading Hours (RTH)
            formatDate: int. Using 1 will return UTC time in
            YYYYMMDD-hh:mm:ss format. Using 2 will return epoch
            time.
            )
            Returns the timestamp of earliest available historical
            data for a contract and data type.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqHeadTimeStamp(1, ContractSamples.USStockAtSmart(), "TRADES", 1,
1)

client.reqHeadTimestamp(4003, contract, "TRADES", 1, 1);

m_pClient->reqHeadTimestamp(14001, contract, "MIDPOINT", 1, 1);

client.reqHeadTimestamp(14001, contract, "TRADES", 1, 1);


client.reqHeadTimestamp(14001, ContractSamples.USStock(), "TRADES", 1, 1
)

Receiving the Earliest Data Point

Copy Location

EWrapper.headTimestamp (
            requestId: int. Request identifier used to track data.
            headTimestamp: String. Value identifying earliest data
            date
            )
            The data requested will be returned to
            EWrapper.headTimeStamp.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def headTimestamp(self, reqId, headTimestamp):
        print(reqId, headTimestamp)

@Override
public void headTimestamp(int reqId, String headTimestamp) {
        System.out.println(EWrapperMsgGenerator.headTimestamp(reqId, hea
dTimestamp));
}

void TestCppClient::headTimestamp(int reqId, const std::string& headTime
stamp) {
    printf( "Head time stamp. ReqId: %d - Head time stamp: %s,\n", reqId
, headTimestamp.c_str());
}

public void headTimestamp(int reqId, string headTimestamp)
{
        Console.WriteLine("Head time stamp. Request Id: {0}, Head time s
tamp: {1}", reqId, headTimestamp);
}

Public Sub headTimestamp(requestId As Integer, timeStamp As String) Impl
ements IBApi.EWrapper.headTimestamp
        Console.WriteLine("Head time stamp. Request Id: {0}, Head time s
tamp: {1}", requestId, timeStamp)
End Sub

Cancelling Timestamp Requests

Copy Location

EWrapper.cancelHistogramData (
            tickerId: int. Request identifier used to track data.
            )
            A reqHeadTimeStamp request can be cancelled with
            EClient.cancelHeadTimestamp
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.cancelHeadTimeStamp(reqId)

client.cancelHeadTimestamp(4003);

m_pClient->cancelHeadTimestamp(14001);

client.cancelHeadTimestamp(14001);

client.cancelHeadTimestamp(14001)

Historical Bars

Copy Location
            Historical Bar data returns a candlestick value based
            on the requested duration and bar size. This will
            always return an open, high, low, and close values.
            Based on which whatToShow value is used, you may also
            receive volume data. See the [570]whatToShow section
            for more details.

Requesting Historical Bars

Copy Location

EClient.reqHistoricalData(
            tickerId: int, A unique identifier which will serve to
            identify the incoming data.
            contract: Contract, The IBApi.Contract object you are
            working with.
            endDateTime: String, The request’s end date and time.
            This should be formatted as “YYYYMMDD HH:mm:ss TMZ” or
            an empty string indicates current present moment).
            Please be aware that endDateTime must be left as an
            empty string when requesting continuous futures
            contracts.
            [571]durationString: String, The amount of time
            (or Valid Duration String units) to go back from the
            request’s given end date and time.
            [572]barSizeSetting: String, The data’s granularity
            or Valid Bar Sizes
            [573]whatToShow: String, The type of data to retrieve.
            See Historical Data Types
            useRTH: bool, Whether (1) or not (0) to retrieve data
            generated only within Regular Trading Hours (RTH)
            [574]formatDate: bool, The format in which the
            incoming bars’ date should be presented. Note that for
            day bars, only yyyyMMdd format is available.
            [575]keepUpToDate: bool, Whether a subscription is
            made to return updates of unfinished real time bars as
            they are available (True), or all data is returned on
            a one-time basis (False). If True, and endDateTime
            cannot be specified.
            Supported whatToShow values: Trades, Midpoint, Bid,
            Ask.
            mktDataOptions: TagValueList, This is a field used
            exclusively for internal use.
            )
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqHistoricalData(4102, contract, queryTime, "1 M", "1 day", "MIDPO
INT", 1, 1, False, [])

    [571] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#hist-duration
    [572] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#hist-bar-size
    [573] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#historical-whattoshow
    [574] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#hist-format-date
    [575] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#hist-keepUp-date

client.reqHistoricalData(4002, contract, formatted, "10 D", "1 min", "TR
ADES", 1, 1, false, null);

m_pClient->reqHistoricalData(4001, contract, queryTime, "1 M", "1 day",
"MIDPOINT", 1, 1, false, TagValueListSPtr());

client.reqHistoricalData(4001, contract, queryTime, "1 M", "1 day", "MID
POINT", 1, 1, false, null);

client.reqHistoricalData(4001, contract, queryTime, "1 M", "1 day", "MID
POINT", 1, 1, False, Nothing)

Duration

Copy Location
            The Interactive Brokers Historical Market Data
            maintains a duration parameter which specifies the
            overall length of time that data can be collected. The
            duration specified will derive the bars of data that
            can then be collected.

Valid Duration String Units:

            Unit Description
            S    Seconds
            D    Day
            W    Week
            M    Month
            Y    Year

Historical Bar Sizes

Copy Location
            Bar sizes dictate the data returned by historical bar
            requests. The bar size will dictate the scale over
            which the OHLC/V is returned to the API.

Valid Bar Sizes:

            Bar Unit         Bar Sizes
            secs     1, 5, 10, 15, 30
            mins     1, 2, 3, 5, 10, 15, 20, 30
            hrs      1, 2, 3, 4, 8
            days     1
            weeks    1
            months   1

Step Sizes

Copy Location
            The functionality of market data requests are
            predicated on preset step sizes. As such, not all bar
            sizes will work with all duration values. The table
            listed here will discuss the smallest to largest bar
            size value for each duration string.

            Duration Unit Bar units allowed Bar size Interval (Min/Max)
            S             secs | mins       1 secs -> 1mins
            D             secs | mins | hrs 5 secs -> 1 hours
            W             sec | mins | hrs  10 secs -> 4 hrs
            M             sec | mins | hrs  30 secs -> 8 hrs
            Y             mins | hrs   | d  1 mins-> 1 day

Max Duration Per Bar Size

Copy Location
            The table below displays the maximum duration values
            allowed for a given bar.
            As an example, the maximum duration for Seconds values
            supported for 5 seconds bars are 86400 S. This means
            that if I want to retrieve more than 1 day’s worth of
            5 second bars, I will then need to request data in
            increments of D (days).

   Bar Size Max Second Duration Max Day Duration Max Week Duration
   Max Month Duration Max Year Duration
   1 secs 2000 S {Not Supported} {Not Supported} {Not Supported}
   {Not Supported}
   5 secs 86400 S 365 D 52 W 12 M 68 Y
   10 secs 86400 S 365 D 52 W 12 M 68 Y
   15 secs 86400 S 365 D 52 W 12 M 68 Y
   30 secs 86400 S 365 D 52 W 12 M 68 Y
   1 min 86400 S 365 D 52 W 12 M 68 Y
   2 mins 86400 S 365 D 52 W 12 M 68 Y
   3 mins 86400 S 365 D 52 W 12 M 68 Y
   5 mins 86400 S 365 D 52 W 12 M 68 Y
   10 mins 86400 S 365 D 52 W 12 M 68 Y
   15 mins 86400 S 365 D 52 W 12 M 68 Y
   20 mins 86400 S 365 D 52 W 12 M 68 Y
   30 mins 86400 S 365 D 52 W 12 M 68 Y
   1 hour 86400 S 365 D 52 W 12 M 68 Y
   2 hours 86400 S 365 D 52 W 12 M 68 Y
   3 hours 86400 S 365 D 52 W 12 M 68 Y
   4 hours 86400 S 365 D 52 W 12 M 68 Y
   8 hours 86400 S 365 D 52 W 12 M 68 Y
   1 day 86400 S 365 D 52 W 12 M 68 Y
   1M 86400 S 365 D 52 W 12 M 68 Y
   1W 86400 S 365 D 52 W 12 M 68 Y

Format Date Received

Copy Location
            Interactive Brokers will return historical market data
            based on the format set from the request. The
            formatDate parameter can be provided an integer value
            to indicate how data should be returned.
            Note: Day bars will only return dates in the yyyyMMdd
            format. Time data is not available.

        Value      Description                    Example
        1     String Time Zone Date “20231019 16:11:48 America/New_York”
        2     Epoch Date            1697746308
        3     Day & Time Date       “1019 16:11:48 America/New_York”

Keep Up To Date

Copy Location
            When using keepUpToDate=True for historical data
            requests, you will see several bars returned with the
            same timestamp. This is because data is updated
            approximately every 1-2 seconds. These updates
            compound until the end of the specified bar size.
            In our example to the below, 15 second bars are
            requested, and we can see the 30 second bar built out
            incrementally until 20231204 13:30:30 is completed. At
            which point, we move on to the 45th second bars. This
            same logic extends into minute, hourly, or daily bars.

Note:
            keepUpToDate is only available for whatToShow: Trades,
            Midpoint, Bid, Ask
Date: 20231204 13:30:30 US/Eastern, Open: 188.56, High: 188.56, Low: 188
.54, Close: 188.55
Date: 20231204 13:30:30 US/Eastern, Open: 188.56, High: 188.56, Low: 188
.54, Close: 188.55
Date: 20231204 13:30:30 US/Eastern, Open: 188.56, High: 188.56, Low: 188
.54, Close: 188.55
Date: 20231204 13:30:30 US/Eastern, Open: 188.56, High: 188.56, Low: 188
.54, Close: 188.55
Date: 20231204 13:30:30 US/Eastern, Open: 188.56, High: 188.56, Low: 188
.54, Close: 188.55
Date: 20231204 13:30:30 US/Eastern, Open: 188.56, High: 188.56, Low: 188
.54, Close: 188.56
Date: 20231204 13:30:30 US/Eastern, Open: 188.56, High: 188.56, Low: 188
.54, Close: 188.56
Date: 20231204 13:30:30 US/Eastern, Open: 188.56, High: 188.57, Low: 188
.54, Close: 188.55
Date: 20231204 13:30:45 US/Eastern, Open: 188.54, High: 188.54, Low: 188
.54, Close: 188.54

Receiving Historical Bars

Copy Location

EWrapper.historicalData (
            reqId: int. Request identifier used to track data.
            bar: Bar. The OHLC historical data Bar. The time zone
            of the bar is the time zone chosen on the TWS login
            screen. Smallest bar size is 1 second.
            )
            The historical data will be delivered via the
            EWrapper.historicalData method in the form of
            candlesticks. The time zone of returned bars is the
            time zone chosen in TWS on the login screen.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def historicalData(self, reqId:int, bar: BarData):
        print("HistoricalData. ReqId:", reqId, "BarData.", bar)

@Override
public void historicalData(int reqId, Bar bar) {
        System.out.println("HistoricalData:  " + EWrapperMsgGenerator.hi
storicalData(reqId, bar.time(), bar.open(), bar.high(), bar.low(), bar.c
lose(), bar.volume(), bar.count(), bar.wap()));
}

void TestCppClient::historicalData(TickerId reqId, const Bar& bar) {
    printf( "HistoricalData. ReqId: %ld - Date: %s, Open: %s, High: %s,
Low: %s, Close: %s, Volume: %s, Count: %s, WAP: %s\n", reqId, bar.time.c
_str(),
        Utils::doubleMaxString(bar.open).c_str(), Utils::doubleMaxString
(bar.high).c_str(), Utils::doubleMaxString(bar.low).c_str(), Utils::doub
leMaxString(bar.close).c_str(),
        decimalStringToDisplay(bar.volume).c_str(), Utils::intMaxString(
bar.count).c_str(), decimalStringToDisplay(bar.wap).c_str());
}

public virtual void historicalData(int reqId, Bar bar)
{
        Console.WriteLine("HistoricalData. " + reqId + " - Time: " + bar
.Time + ", Open: " + Util.DoubleMaxString(bar.Open) + ", High: " + Util.
DoubleMaxString(bar.High) + ", Low: " + Util.DoubleMaxString(bar.Low) +
", Close: " + Util.DoubleMaxString(bar.Close) + ", Volume: " + Util.Deci
malMaxString(bar.Volume) + ", Count: " + Util.IntMaxString(bar.Count) +
", WAP: " + Util.DecimalMaxString(bar.WAP));
}

public virtual void historicalData(int reqId, Bar bar)
{
        Console.WriteLine("HistoricalData. " + reqId + " - Time: " + bar
.Time + ", Open: " + Util.DoubleMaxString(bar.Open) + ", High: " + Util.
DoubleMaxString(bar.High) + ", Low: " + Util.DoubleMaxString(bar.Low) +
", Close: " + Util.DoubleMaxString(bar.Close) + ", Volume: " + Util.Deci
malMaxString(bar.Volume) + ", Count: " + Util.IntMaxString(bar.Count) +
", WAP: " + Util.DecimalMaxString(bar.WAP));
}

Default Return Format
            The text on the right is the default formatting for
            returning data.
            The datetime value here was [576]modified to return
            UTC datetime formatting.
            Note: The datetime value indicates the beginning of
            the request range rather than the end. The last bar on
            the right would then indicate data that took place
            between 20241111-16:53:15 to 20241111-16:53:20.
Date: 20241111-16:53:00, Open: 222.97, High: 222.97, Low: 222.96, Close:
 222.97, Volume: 300, WAP: 222.965, BarCount: 2
Date: 20241111-16:53:05, Open: 222.97, High: 223.01, Low: 222.96, Close:
 223.01, Volume: 5378, WAP: 222.981, BarCount: 38
Date: 20241111-16:53:10, Open: 223.02, High: 223.02, Low: 222.98, Close:
 222.98, Volume: 3659, WAP: 222.997, BarCount: 24
Date: 20241111-16:53:15, Open: 222.98, High: 222.98, Low: 222.96, Close:
 222.97, Volume: 2585, WAP: 222.963, BarCount: 24

    [576] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#modify-return-date

EWrapper.historicalSchedule (
            reqId: int. Request identifier used to track data.
            startDateTime: String. Returns the start date and time
            of the historical schedule range.
            endDateTime: String. Returns the end date and time of
            the historical schedule range.
            timeZone: String. Returns the time zone referenced by
            the schedule.
            sessions: HistoricalSession[]. Returns the full block
            of historical schedule data for the duration.
            )
            In the case of whatToShow=”schedule”, you will need to
            also define the EWrapper.historicalSchedule value.
            This is a unique method that will only be called in
            the case of the unique whatToShow value to display
            calendar information.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def historicalSchedule(self, reqId: int, startDateTime: str, endDateTime
: str, timeZone: str, sessions: ListOfHistoricalSessions):
        print("HistoricalSchedule. ReqId:", reqId, "Start:", startDateTi
me, "End:", endDateTime, "TimeZone:", timeZone)
        for session in sessions:
                print("\tSession. Start:", session.startDateTime, "End:"
, session.endDateTime, "Ref Date:", session.refDate)

@Override
public void historicalSchedule(int reqId, String startDateTime, String e
ndDateTime, String timeZone, List sessions) {
        System.out.println(EWrapperMsgGenerator.historicalSchedule(reqId
, startDateTime, endDateTime, timeZone, sessions));
}

void TestCppClient::historicalSchedule(int reqId, const std::string& sta
rtDateTime, const std::string& endDateTime, const std::string& timeZone,
 const std::vector& sessions) {
    printf("Historical Schedule. ReqId: %d, Start: %s, End: %s, TimeZone
: %s\n", reqId, startDateTime.c_str(), endDateTime.c_str(), timeZone.c_s
tr());
    for (unsigned int i = 0; i < sessions.size(); i++) {
        printf("\tSession. Start: %s, End: %s, RefDate: %s\n", sessions
i].startDateTime.c_str(), sessions[i].endDateTime.c_str(), sessions[i].r
efDate.c_str());
    }
}

public void historicalSchedule(int reqId, string startDateTime, string e
ndDateTime, string timeZone, HistoricalSession[] sessions)
{
        Console.WriteLine($"Historical Schedule. ReqId: {reqId}, Start:
{startDateTime}, End: {endDateTime}, Time Zone: {timeZone}");
        foreach (var session in sessions)
        {
                Console.WriteLine($"\tSession. Start: {session.StartDate
Time}, End: {session.EndDateTime}, Ref Date: {session.RefDate}");
        }
}

public void historicalSchedule(int reqId, string startDateTime, string e
ndDateTime, string timeZone, HistoricalSession[] sessions)
{
        Console.WriteLine($"Historical Schedule. ReqId: {reqId}, Start:
{startDateTime}, End: {endDateTime}, Time Zone: {timeZone}");
        foreach (var session in sessions)
        {
                Console.WriteLine($"\tSession. Start: {session.StartDate
Time}, End: {session.EndDateTime}, Ref Date: {session.RefDate}");
        }
}

EWrapper.historicalDataUpdate (
            reqId: int. Request identifier used to track data.
            bar: Bar. The OHLC historical data Bar. The time zone
            of the bar is the time zone chosen on the TWS login
            screen. Smallest bar size is 1 second.
            )
            Receives bars in real time if keepUpToDate is set as
            True in reqHistoricalData. Similar to realTimeBars
            function, except returned data is a composite of
            historical data and real time data that is equivalent
            to TWS chart functionality to keep charts up to date.
            Returned bars are successfully updated using real time
            data.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def historicalDataUpdate(self, reqId: int, bar: BarData):
        print("HistoricalDataUpdate. ReqId:", reqId, "BarData.", bar)

@Override
public void historicalDataUpdate(int reqId, Bar bar) {
        System.out.println("HistoricalDataUpdate. " + EWrapperMsgGenerat
or.historicalData(reqId, bar.time(), bar.open(), bar.high(), bar.low(),
bar.close(), bar.volume(), bar.count(), bar.wap()));
}

void TestCppClient::historicalDataUpdate(TickerId reqId, const Bar& bar)
 {
    printf( "HistoricalDataUpdate. ReqId: %ld - Date: %s, Open: %s, High
: %s, Low: %s, Close: %s, Volume: %s, Count: %s, WAP: %s\n", reqId, bar.
time.c_str(),
        Utils::doubleMaxString(bar.open).c_str(), Utils::doubleMaxString
(bar.high).c_str(), Utils::doubleMaxString(bar.low).c_str(), Utils::doub
leMaxString(bar.close).c_str(),
        decimalStringToDisplay(bar.volume).c_str(), Utils::intMaxString(
bar.count).c_str(), decimalStringToDisplay(bar.wap).c_str());
}

public void historicalDataUpdate(int reqId, Bar bar)
{
        Console.WriteLine("HistoricalDataUpdate. " + reqId + " - Time: "
 + bar.Time + ", Open: " + Util.DoubleMaxString(bar.Open) + ", High: " +
 Util.DoubleMaxString(bar.High) +
                ", Low: " + Util.DoubleMaxString(bar.Low) + ", Close: "
+ Util.DoubleMaxString(bar.Close) + ", Volume: " + Util.DecimalMaxString
(bar.Volume) +
                ", Count: " + Util.IntMaxString(bar.Count) + ", WAP: " +
 Util.DecimalMaxString(bar.WAP));
}

public void historicalDataUpdate(int reqId, Bar bar)
{
        Console.WriteLine("HistoricalDataUpdate. " + reqId + " - Time: "
 + bar.Time + ", Open: " + Util.DoubleMaxString(bar.Open) + ", High: " +
 Util.DoubleMaxString(bar.High) + ", Low: " + Util.DoubleMaxString(bar.L
ow) + ", Close: " + Util.DoubleMaxString(bar.Close) + ", Volume: " + Uti
l.DecimalMaxString(bar.Volume) + ", Count: " + Util.IntMaxString(bar.Cou
nt) + ", WAP: " + Util.DecimalMaxString(bar.WAP));
}

EWrapper.historicalDataEnd (
            reqId: int. Request identifier used to track data.
            start: String. Returns the starting time of the first
            historical data bar.
            end: String. Returns the end time of the last
            historical data bar.
            )
            Marks the ending of the historical bars reception.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def historicalDataEnd(self, reqId: int, start: str, end: str):
        print("HistoricalDataEnd. ReqId:", reqId, "from", start, "to", e
nd)

@Override
public void historicalDataEnd(int reqId, String startDateStr, String end
DateStr) {
        System.out.println("HistoricalDataEnd. " + EWrapperMsgGenerator.
historicalDataEnd(reqId, startDateStr, endDateStr));
}

void TestCppClient::historicalDataEnd(int reqId, const std::string& star
tDateStr, const std::string& endDateStr) {
    std::cout << "HistoricalDataEnd. ReqId: " << reqId << " - Start Date
: " << startDateStr << ", End Date: " << endDateStr << std::endl;
}

public virtual void historicalDataEnd(int reqId, string startDate, strin
g endDate)
{
        Console.WriteLine("HistoricalDataEnd - "+reqId+" from "+startDat
e+" to "+endDate);
}

public virtual void historicalDataEnd(int reqId, string startDate, strin
g endDate)
        {
            Console.WriteLine("HistoricalDataEnd - "+reqId+" from "+star
tDate+" to "+endDate);
        }

Historical Bar whatToShow

Copy Location
            The historical bar types listed below can be used as
            the whatToShow value for historical bars. These values
            are used to request different data such as Trades,
            Midpoint, Bid_Ask data and more. Some bar types
            support more products than others. Please note the
            Supported Products section for each bar type below.

AGGTRADES

Copy Location
            Bar Values:

   Open High Low Close Volume
   First traded price Highest traded price Lowest traded price
   Last traded price Total traded volume
            Supported Products: Cryptocurrency

ASK

Copy Location
            Bar Values:

           Open              High              Low         Close  Volume
    Starting ask price Highest ask price Lowest ask price Last ask
                                                          price   N/A
            Supported Products: Bonds, CFDs, Commodities,
            Cryptocurrencies, ETFs, FOPs, Forex, Funds, Futures,
            Metals, Options, SSFs, Stocks, Structured Products,
            Warrants

BID

Copy Location
            Bar Values:

           Open              High              Low         Close  Volume
    Starting bid price Highest bid price Lowest bid price Last bid
                                                          price   N/A
            Supported Products: Bonds, CFDs, Commodities,
            Cryptocurrencies, ETFs, FOPs, Forex, Funds, Futures,
            Metals, Options, SSFs, Stocks, Structured Products,
            Warrants

BID_ASK

Copy Location
            Bar Values:

                  Open        High     Low        Close       Volume
            Time average bid Max Ask Min Bid Time average ask N/A
            Supported Products: Bonds, CFDs, Commodities,
            Cryptocurrencies, ETFs, FOPs, Forex, Funds,
            Futures, Metals, Options, SSFs, Stocks, Structured
            Products, Warrants

FEE_RATE

Copy Location
            Bar Values:

             Open              High             Low        Close  Volume
       Starting Fee Rate Highest fee rate Lowest fee rate Last fee
                                                          rate    N/A
            Supported Products: Stocks, ETFs,

HISTORICAL_VOLATILITY

Copy Location
            Bar Values:

   Open High Low Close Volume
   Starting volatility Highest volatility Lowest volatility Last
   volatility N/A
            Supported Products: ETFs, Indices, Stocks

MIDPOINT

Copy Location
            Bar Values:

   Open High Low Close Volume
   Starting midpoint price Highest midpoint price Lowest midpoint
   price Last midpoint price N/A
            Supported Products: Bonds, CFDs, Commodities,
            Cryptocurrencies, ETFs, FOPs, Forex, Funds, Futures,
            Metals, Options, SSFs, Stocks, Structured Products,
            Warrants

OPTION_IMPLIED_VOLATILITY

Copy Location
            Bar Values:

   Open High Low Close Volume
   Starting implied volatility Highest implied volatility Lowest
   implied volatility Last implied volatility N/A
            Supported Products: ETFs, Indices, Stocks

SCHEDULE

Copy Location
            Bar Values:

           Open              High              Low         Close  Volume
    Starting ask price Highest ask price Lowest ask price Last ask
                                                          price   N/A
            Supported Products: Bonds, CFDs, Commodities,
            Cryptocurrencies, ETFs, Forex, Funds, Futures,
            Indices, Metals,  SSFs, Stocks, Structured Products,
            Warrants
            NOTE: SCHEDULE data returns only on 1 day bars but
            returns historical trading schedule only with no
            information about OHLCV.

TRADES

Copy Location
            Bar Values:

   Open High Low Close Volume
   First traded price Highest traded price Lowest traded price
   Last traded price Total traded volume
            Supported Products: Bonds, ETFs, FOPs, Futures,
            Indices, Metals, Options, SSFs, Stocks, Structured
            Products, Warrants
            NOTES: TRADES data is adjusted for splits, but not
            dividends.

YIELD_ASK

Copy Location
            Bar Values:

           Open              High              Low         Close  Volume
    Starting ask yield Highest ask yield Lowest ask yield Last ask
                                                          yield   N/A
            Supported Products: Indices
            Note: Yield historical data only available for
            corporate bonds.

YIELD_BID

Copy Location
            Bar Values:

           Open              High              Low         Close  Volume
    Starting bid yield Highest bid yield Lowest bid yield Last bid
                                                          yield   N/A
            Supported Products: Indices
            Note: Yield historical data only available for
            corporate bonds.

YIELD_BID_ASK

Copy Location
            Bar Values:

   Open High Low Close Volume
   Time average bid yield Highest ask yield Lowest bid yield Time
   average ask yield N/A
            Supported Products: Indices
            Note: Yield historical data only available for
            corporate bonds.

YIELD_LAST

Copy Location
            Bar Values:

   Open High Low Close Volume
   Starting last yield Highest last yield Lowest last yield Last
   last yield N/A
            Supported Products: Indices
            Note: Yield historical data only available for
            corporate bonds.

Histogram Data

Copy Location
            Instead of returned data points as a function of time
            as with the function
            IBApi::EClient::reqHistoricalData, histograms return
            data as a function of price level with function
            IBApi::EClient::reqHistogramData

Requesting Histogram Data

Copy Location

EClient.reqHistogramData (
            requestId: int, id of the request
            contract: Contract, Contract object that is subject of
            query.
            useRth: bool, Data from regular trading hours (1), or
            all available hours (0).
            period: String, string value of requested date range.
            This will be tied to the same bar size strings as the
            [577]historical bar sizes
            )
            Returns data histogram of specified contract.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqHistogramData(4004, contract, false, "3 days")

    [577] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#hist-bar-size

client.reqHistogramData(4004, contract, false, "3 days");

m_pClient->reqHistogramData(15001, contract, false, "1 weeks");

client.reqHistogramData(15001, contract, false, "1 week");

client.reqHistogramData(15001, contract, False, "1 week")

Receiving Histogram Data

Copy Location

EWrapper.histogramData (
            requestId: int. Request identifier used to track data.
            data: HistogramEntry[]. Returned Tuple of histogram
            data, number of trades at specified price level.
            )
            Returns relevant histogram data.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def histogramData(self, reqId:int, items:HistogramDataList):
        print("HistogramData. reqid, items)

@Override
public void histogramData(int reqId, List items) {
        System.out.println(EWrapperMsgGenerator.histogramData(reqId, ite
ms));
}

void TestCppClient::histogramData(int reqId, const HistogramDataVector&
data) {
    printf("Histogram. ReqId: %d, data length: %lu\n", reqId, data.size(
));
    for (const HistogramEntry& entry : data) {
        printf("\t price: %s, size: %s\n", Utils::doubleMaxString(entry.
price).c_str(), decimalStringToDisplay(entry.size).c_str());
    }
}

public void histogramData(int reqId, HistogramEntry[] data)
{
        Console.WriteLine("Histogram data. Request Id: {0}, data size: {
1}", reqId, data.Length);
        data.ToList().ForEach(i => Console.WriteLine("\tPrice: {0}, Size
: {1}", Util.DoubleMaxString(i.Price), Util.DecimalMaxString(i.Size)));
}

Public Sub histogramData(reqId As Integer, data As HistogramEntry()) Imp
lements EWrapper.histogramData
        Console.WriteLine("Histogram data. Request Id: {0}, data size: {
1}", reqId, data.Length)
        data.ToList().ForEach(Sub(i) Console.WriteLine(vbTab & "Price: {
0}, Size: {1}", Util.DoubleMaxString(i.Price), Util.DecimalMaxString(i.S
ize)))
End Sub

Cancelling Histogram Data

Copy Location

EClient.cancelHistogramData (
            tickerId: int. Request identifier used to track data.
            )
            An active histogram request which has not returned
            data can be cancelled with EClient.cancelHistogramData
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqHistogramData(4004)

client.cancelHistogramData(4004);

m_pClient->cancelHistogramData(15001);

client.cancelHistogramData(15001);

client.cancelHistogramData(15001)

Historical Time & Sales

Copy Location
            The highest granularity of historical data from IB’s
            database can be retrieved using the API function
            [578]EClient.reqHistoricalTicks for historical time
            and sales values. Historical Time & Sales will return
            the same data as what is available in Trader
            Workstation under the Time and Sales window. This is a
            series of ticks indicating each trade based on the
            requested values.
               o Historical Tick-By-Tick data is not available for
                 combos.
               o Data will not be returned from multiple trading
                 sessions in a single request; Multiple requests
                 must be used.
               o To complete a full second, more ticks may be
                 returned than requested.
               o Time & Sales data requires a Level 1, Top Of Book
                 market data subscription. This would be the same
                 subscription as [579]EClient.reqMktData() or
                 [580]EClient.reqHistoricalData().

    [578] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#requesting-time-and-sales
    [579] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#watchlist-data
    [580] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#historical-bars

Requesting Time and Sales data

Copy Location

EClient.reqHistoricalTicks (
            requestId: int, id of the request
            contract: Contract, Contract object that is subject of
            query.
            startDateTime: String, i.e. “20170701 12:01:00”. Uses
            TWS timezone specified at login.
            endDateTime: String, i.e. “20170701 13:01:00”. In TWS
            timezone. Exactly one of startDateTime or endDateTime
            must be defined.
            numberOfTicks: int, Number of distinct data points.
            Max is 1000 per request.
            whatToShow: String, (Bid_Ask, Midpoint, or Trades)
            Type of data requested.
            useRth: bool, Data from regular trading hours (1), or
            all available hours (0).
            ignoreSize: bool, Omit updates that reflect only
            changes in size, and not price. Applicable to Bid_Ask
            data requests.
            Note: Options and Future Options will only display a
            value of 1, unless to indicate a removed bid/ask,
            which will instead return a price and size value of 0.
            miscOptions: list, Should be defined as null; reserved
            for internal use.
            )
            Requests historical Time & Sales data for an
            instrument.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqHistoricalTicks(18001, contract, "20170712 21:39:33 US/Eastern",
 "", 10, "TRADES", 1, True, [])

client.reqHistoricalTicks(18001, contract, "20220808 10:00:00 US/Eastern
", null, 10, "TRADES", 1, true, null);

m_pClient->reqHistoricalTicks(19001, contract, "20170621 09:38:33 US/Eas
tern", "", 10, "BID_ASK", 1, true, TagValueListSPtr());

client.reqHistoricalTicks(18001, contract, "20170712 21:39:33 US/Eastern
", null, 10, "TRADES", 1, true, null);

client.reqHistoricalTicks(18001, contact, "20170712 21:39:33 US/Eastern"
, Nothing, 10, "TRADES", 1, True, Nothing)

Receiving Time and Sales data

Copy Location
            Data is returned to unique functions based on what is
            requested in the whatToShow field.
               o IBApi.EWrapper.historicalTicks for
                 whatToShow=MIDPOINT
               o IBApi.EWrapper.historicalTicksBidAsk for
                 whatToShow=BID_ASK
               o IBApi.EWrapper.historicalTicksLast for for
                 whatToShow=TRADES

EWrapper.historicalTicks (
            reqId: int, id of the request
            ticks: ListOfHistoricalTick, object containing a list
            of tick values for the requested timeframe.
            done: bool, return whether or not this is the end of
            the historical ticks requested.
            )
            For whatToShow=MIDPOINT
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def historicalTicks(self, reqId: int, ticks: ListOfHistoricalTickLast, d
one: bool):
        for tick in ticks:
                print("historicalTicks. ReqId:", reqId, tick)

@Override
public void historicalTicks(int reqId, List ticks, boolean done) {
        for (HistoricalTick tick : ticks) {
                System.out.println(EWrapperMsgGenerator.historicalTick(r
eqId, tick.time(), tick.price(), tick.size()));
        }
}

void TestCppClient::historicalTicks(int reqId, const std::vector& ticks,
 bool done) {
    for (const HistoricalTick& tick : ticks) {
    std::time_t t = tick.time;
        std::cout << "Historical tick. ReqId: " << reqId << ", time: " <
< ctime(&t) << ", price: "<< Utils::doubleMaxString(tick.price).c_str()
<< ", size: " << decimalStringToDisplay(tick.size).c_str() << std::endl;
    }
}

public void historicalTicks(int reqId, HistoricalTick[] ticks, bool done
)
{
        foreach (var tick in ticks)
        {
                Console.WriteLine("Historical Tick. Request Id: {0}, Tim
e: {1}, Price: {2}, Size: {3}", reqId, Util.UnixSecondsToString(tick.Tim
e, "yyyyMMdd-HH:mm:ss"), Util.DoubleMaxString(tick.Price), Util.DecimalM
axString(tick.Size));
        }
}

Public Sub historicalTick(reqId As Integer, ticks As HistoricalTick(), d
one As Boolean) Implements EWrapper.historicalTicks
        For Each tick In ticks
                Console.WriteLine("Historical Tick. Request Id: {0}, Tim
e: {1}, Price: {2}, Size: {3}", reqId, Util.UnixSecondsToString(tick.Tim
e, "yyyyMMdd-HH:mm:ss"), Util.DoubleMaxString(tick.Price), Util.DecimalM
axString(tick.Size))
        Next
End Sub

EWrapper.historicalTicksBidAsk (
            reqId: int, id of the request
            ticks: ListOfHistoricalTick, object containing a list
            of tick values for the requested timeframe.
            done: bool, return whether or not this is the end of
            the historical ticks requested.
            )
            For whatToShow=BidAsk
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def historicalTicksBidAsk(self, reqId: int, ticks: ListOfHistoricalTickL
ast, done: bool):
        for tick in ticks:
                print("historicalTicksBidAsk. ReqId:", reqId, tick)

@Override
public void historicalTicksBidAsk(int reqId, List ticks, boolean done) {
        for (HistoricalTickBidAsk tick : ticks) {
                System.out.println(EWrapperMsgGenerator.historicalTickBi
dAsk(reqId, tick.time(), tick.tickAttribBidAsk(), tick.priceBid(), tick.
priceAsk(), tick.sizeBid(),
                                tick.sizeAsk()));
        }
}

void TestCppClient::historicalTicksBidAsk(int reqId, const std::vector&
ticks, bool done) {
    for (const HistoricalTickBidAsk& tick : ticks) {
                std::time_t t = tick.time;
        std::cout << "Historical tick bid/ask. ReqId: " << reqId << ", t
ime: " << ctime(&t) << ", price bid: "<< Utils::doubleMaxString(tick.pri
ceBid).c_str()  << ", price ask: "<< Utils::doubleMaxString(tick.priceAs
k).c_str() << ", size bid: " << decimalStringToDisplay(tick.sizeBid).c_s
tr() << ", size ask: " << decimalStringToDisplay(tick.sizeAsk).c_str() <
< ", bidPastLow: " << tick.tickAttribBidAsk.bidPastLow << ", askPastHigh
: " << tick.tickAttribBidAsk.askPastHigh << std::endl;
    }
}

public void historicalTicksBidAsk(int reqId, HistoricalTickBidAsk[] tick
s, bool done)
{
        foreach (var tick in ticks)
        {
                Console.WriteLine("Historical Tick Bid/Ask. Request Id:
{0}, Time: {1}, Price Bid: {2}, Price Ask: {3}, Size Bid: {4}, Size Ask:
 {5}, Bid/Ask Tick Attribs: {6} ", reqId, Util.UnixSecondsToString(tick.
Time, "yyyyMMdd-HH:mm:ss"), Util.DoubleMaxString(tick.PriceBid), Util.Do
ubleMaxString(tick.PriceAsk), Util.DecimalMaxString(tick.SizeBid), Util.
DecimalMaxString(tick.SizeAsk), tick.TickAttribBidAsk);
        }
}

Public Sub historicalTickBidAsk(reqId As Integer, ticks As HistoricalTic
kBidAsk(), done As Boolean) Implements EWrapper.historicalTicksBidAsk
        For Each tick In ticks
                Console.WriteLine("Historical Tick Bid/Ask. Request Id:
{0}, Time: {1}, Price Bid: {2}, Price Ask: {3}, Size Bid: {4}, Size Ask:
 {5}, Bid/Ask Tick Attribs: {6}", reqId, Util.UnixSecondsToString(tick.T
ime, "yyyyMMdd-HH:mm:ss"), Util.DoubleMaxString(tick.PriceBid), Util.Dou
bleMaxString(tick.PriceAsk), Util.DecimalMaxString(tick.SizeBid), Util.D
ecimalMaxString(tick.SizeAsk), tick.TickAttribBidAsk.ToString())
        Next
End Sub

EWrapper.historicalTicksLast (
            reqId: int, id of the request
            ticks: ListOfHistoricalTick, object containing a list
            of tick values for the requested timeframe.
            done: bool, return whether or not this is the end of
            the historical ticks requested.
            )
            For whatToShow=Last & AllLast
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def historicalTicksLast(self, reqId: int, ticks: ListOfHistoricalTickLas
t, done: bool):
        for tick in ticks:
                print("HistoricalTickLast. ReqId:", reqId, tick)

public void historicalTicksLast(int reqId, List ticks, boolean done) {
        for (HistoricalTickLast tick : ticks) {
                System.out.println(EWrapperMsgGenerator.historicalTickLa
st(reqId, tick.time(), tick.tickAttribLast(), tick.price(), tick.size(),
 tick.exchange(),
                        tick.specialConditions()));
        }
}

void TestCppClient::historicalTicksLast(int reqId, const std::vector& ti
cks, bool done) {
    for (HistoricalTickLast tick : ticks) {
                std::time_t t = tick.time;
        std::cout << "Historical tick last. ReqId: " << reqId << ", time
: " << ctime(&t) << ", price: "<< Utils::doubleMaxString(tick.price).c_s
tr() << ", size: " << decimalStringToDisplay(tick.size).c_str() << ", ex
change: " << tick.exchange << ", special conditions: " << tick.specialCo
nditions << ", unreported: " << tick.tickAttribLast.unreported << ", pas
tLimit: " << tick.tickAttribLast.pastLimit << std::endl;
    }
}

public void historicalTicksLast(int reqId, HistoricalTickLast[] ticks, b
ool done)
{
        foreach (var tick in ticks)
        {
                Console.WriteLine("Historical Tick Last. Request Id: {0}
, Time: {1}, Price: {2}, Size: {3}, Exchange: {4}, Special Conditions: {
5}, Last Tick Attribs: {6} ", reqId, Util.UnixSecondsToString(tick.Time,
 "yyyyMMdd-HH:mm:ss"), Util.DoubleMaxString(tick.Price), Util.DecimalMax
String(tick.Size), tick.Exchange, tick.SpecialConditions, tick.TickAttri
bLast);
        }
}

Public Sub historicalTickLast(reqId As Integer, ticks As HistoricalTickL
ast(), done As Boolean) Implements EWrapper.historicalTicksLast
        For Each tick In ticks
                Console.WriteLine("Historical Tick Last. Request Id: {0}
, Time: {1}, Price: {2}, Size: {3}, Exchange: {4}, Special Conditions: {
5}, Last Tick Attribs: {6}", reqId, Util.UnixSecondsToString(tick.Time,
"yyyyMMdd-HH:mm:ss"), Util.DoubleMaxString(tick.Price), Util.DecimalMaxS
tring(tick.Size), tick.Exchange, tick.SpecialConditions, tick.TickAttrib
Last.ToString())
        Next
End Sub

Historical Halted and Unhalted ticks

Copy Location
            The tick attribute pastLimit is also returned with
            streaming Tick-By-Tick responses. Check Halted and
            Unhalted ticks section.
               o If tick has zero price, zero size and pastLimit
                 flag is set – this is “Halted” tick.
               o If tick has zero price, zero size and followed
                 immediately after “Halted” tick – this is
                 “Unhalted” tick.

Historical Date Formatting

Copy Location
            When creating dates in the TWS API, Interactive
            Brokers typically supports three methods:
              1. [581]Operator Time Zone
              2. [582]Exchange Time Zone
              3. [583]Coordinated Universal Time (UTC)

    [581] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#operator-tz
    [582] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#exchange-tz
    [583] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#utc-tz

Operator Time Zone

Copy Location
            Operator Time Zone is the local time set by the user
            in Trader Workstation. The Operator Time Zone
            typically maintains a unique formatting structure
            separate from Exchange Time Zones; however, they can
            match.
            A user can confirm their Operator Time Zone by
            launching Trader Workstation then, before logging in,
            click “More Options >”.
            tws login screen highlighting More Options button. tws
            login screen highlighting More Options button.
            Users can then confirm their active Operator Time Zone
            by referencing the “Time Zone” field.
            For US residents, this will typically appear as
            “America/New_York”, “America/Chicago”, or
            “America/Los_Angeles”. It is essential to note the
            Time Zone formatting here, as “America/Chicago” is
            treated differently than “US/Central” as a time zone.
            All requests made can now be sent as “YYYYMMDD
            hh:mm:ss America/Chicago” to always send dates in
            Central time. This same rule goes for any alternative
            Time Zones, such as “America/Los_Angeles” or
            “America/New_York”.

Exchange Time Zone

Copy Location
            The exchange Time Zone is the value the exchange
            itself uses to calculate time. This value is typically
            unique to the Operator Time Zone, but these values can
            overlap.
            As an example, the New York Stock Exchange operates on
            “US/Eastern”. However, the CME operates on
            “US/Central”. This values can be programmatically
            requested using the EClient.reqContractDetails method,
            and then received from EWrapper.contractDetails in
            contractDetails.Time ZoneId.
            Note that this will be interpreted differently from
            “America/Chicago”.
            code Time Zone Display code Time Zone Display

Coordinated Universal Time (UTC)

Copy Location
            UTC is a time standard centered around Greenwich Mean
            Time (GMT). UTC historical data can be formatted as
            “YYYYMMDD-hh:mm:ss”. Please keep in mind this is based
            on UTC+0, and as a reference, US/Eastern time is
            approximately UTC-4 or UTC-5 depending on U.S.
            Daylight savings.
            Please note GMT is unaffected by Daylight savings, and
            so 09:00:00 will be the same time of day year round
            regardless of the exchange’s or your local daylight
            savings observation.

Modifying Returned Date

Copy Location
            You may also log in to the Trader Workstation and
            modify this in the Global Configuration under API and
            then Settings. Here, you will find a modifiable
            setting labeled “Send instrument-specific attributes
            for dual-mode API client in” Here you can select one
            of the following:
               o operator timezone: refers to the local timezone
                 you have set in the Trader Workstation or IB
                 Gateway
               o instrument timezone: refers to the timezone of
                 the requested exchange. If “SMART” is used, this
                 will use the instrument’s primary exchange.
               o UTC format: refers to a standardized return using
                 UTC as the timezone. This will be returned in the
                 format YYYYMMDD-hh:mm:ss

Market Data: Live

Copy Location

Live Data Limitations

Copy Location
            For all data, besides [584]Delayed Watchlist Data, a
            paid data subscription is required to receive market
            data through the API. See the [585]Market Data
            Subscriptions page for more information.
               o Live market data and historical bars are
                 currently not available from the API for the
                 exchange OSE. Only 15 minute delayed streaming
                 data will be available for this exchange.
               o Some [586]Available Tick Types may not be
                 provided due to the contract details, the time
                 that you run the code…… ,etc. To verify whether
                 the specific Available Tick Type is provided, it
                 is suggested to manually check the data in TWS.
               o Different [587]Available Tick Types have
                 different updating frequency.
            The bid, ask, and last size quotes are displayed in
            shares instead of lots.
            API users have the option to configure the TWS API to
            work in compatibility mode for older programs, but we
            recommend migrating to “quotes in shares” at your
            earliest convenience.
            To display quotes as lots, from the Global
            Configuration > API > Settings page, check “Bypass US
            Stocks market data in shares warning for API orders.”

    [585] https://www.interactivebrokers.com/campus/ibkr-api-page/market-data-subscriptions/
    [586] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#available-tick-types
    [587] https://www.interactivebrokers.com/campus/ibkr-api-page/twsapi-doc/#available-tick-types

5 Second Bars

Copy Location
            Real time and historical data functionality is
            combined through the EClient.reqRealTimeBars request.
            reqRealTimeBars will create an active subscription
            that will return a single bar in real time every five
            seconds that has the OHLC values over that period.
            reqRealTimeBars can only be used with a bar size of 5
            seconds.
            Important: real time bars subscriptions combine the
            limitations of both, top and historical market data.
            Make sure you observe Market Data
            Lines and [588]Pacing Violations for Small Bars (30
            secs or less). For example, no more than
            60 *new* requests for real time bars can be made in 10
            minutes, and the total number of active active
            subscriptions of all types cannot exceed the maximum
            allowed market data lines for the user.

    [588] https://www.interactivebrokers.com/campus/ibkr-api-page/trader-workstation-api/#historical-pacing-limitations

Request Real Time Bars

Copy Location

EClient.reqRealTimeBars (
            tickerId: int. Request identifier used to track data.
            contract: Contract. The Contract object for which the
            depth is being requested
            barSize: int. Currently being ignored
            whatToShow: String. The nature of the data being
            retrieved:
            Available Values: TRADES, MIDPOINT, BID, ASK
            useRTH: int. Set to 0 to obtain the data which was
            also generated outside of the Regular Trading Hours,
            set to 1 to obtain only the RTH data
            )
            realTimeBarOptions: List<TagValue>. Internal use only.

            Requests real time bars.
            Only 5 seconds bars are provided. This request is
            subject to the same pacing as any historical data
            request: no more than 60 API queries in more than 600
            seconds.
            Real time bars subscriptions are also included in the
            calculation of the number of Level 1 market data
            subscriptions allowed in an account.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqRealTimeBars(3001, contract, 5, "MIDPOINT", 0, [])

            Code example:
from ibapi.client import *
from ibapi.wrapper import *
from ibapi.contract import Contract
import time

class TradeApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)

    def realtimeBar(self, reqId: TickerId, time:int, open_: float, high:
 float, low: float, close: float, volume: Decimal, wap: Decimal, count:
int):
        print("RealTimeBar. TickerId:", reqId, RealTimeBar(time, -1, ope
n_, high, low, close, volume, wap, count))

app = TradeApp()
app.connect("127.0.0.1", 7496, clientId=1)

contract = Contract()
contract.symbol = "AAPL"
contract.secType = "STK"
contract.currency = "USD"
contract.exchange = "SMART"

app.reqRealTimeBars(3001, contract, 5, "TRADES", 0, [])

app.run()

client.reqRealTimeBars(3001, contract, 5, "MIDPOINT", true, null);

m_pClient->reqRealTimeBars(3001, contract, 5, "MIDPOINT", true, TagValue
ListSPtr());

client.reqRealTimeBars(3001, contract, 5, "MIDPOINT", true, null);

client.reqRealTimeBars(3001, contract, 5, "MIDPOINT", True, Nothing)

Receive Real Time Bars

Copy Location

EWrapper.realtimeBar (
            reqId: int. Request identifier used to track data.
            time: long. The bar’s start date and time (Epoch/Unix
            time)
            open: double. The bar’s open point
            high: double. The bar’s high point
            low: double. The bar’s low point
            close: double. The bar’s closing point
            volume: decimal. The bar’s traded volume (only
            returned for TRADES data)
            WAP: decimal. The bar’s Weighted Average Price rounded
            to minimum increment (only available for TRADES).
            count: int. The number of trades during the bar’s
            timespan (only available for TRADES).
            )
            Receives the real time 5 second bars.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def realtimeBar(self, reqId: TickerId, time:int, open_: float, high: flo
at, low: float, close: float, volume: Decimal, wap: Decimal, count: int)
:
        print("RealTimeBar. TickerId:", reqId, RealTimeBar(time, -1, ope
n_, high, low, close, volume, wap, count))

@Override
public void realtimeBar(int reqId, long time, double open, double high,
double low, double close, Decimal volume, Decimal wap, int count) {
        System.out.println("RealTimeBar: " + EWrapperMsgGenerator.realti
meBar(reqId, time, open, high, low, close, volume, wap, count));
}

void TestCppClient::realtimeBar(TickerId reqId, long time, double open,
double high, double low, double close, Decimal volume, Decimal wap, int
count) {
    printf( "RealTimeBars. %ld - Time: %s, Open: %s, High: %s, Low: %s,
Close: %s, Volume: %s, Count: %s, WAP: %s\n", reqId, Utils::longMaxStrin
g(time).c_str(), Utils::doubleMaxString(open).c_str(), Utils::doubleMaxS
tring(high).c_str(), Utils::doubleMaxString(low).c_str(), Utils::doubleM
axString(close).c_str(), decimalStringToDisplay(volume).c_str(), Utils::
intMaxString(count).c_str(), decimalStringToDisplay(wap).c_str());
}

public virtual void realtimeBar(int reqId, long time, double open, doubl
e high, double low, double close, decimal volume, decimal WAP, int count
)
{
        Console.WriteLine("RealTimeBars. " + reqId + " - Time: " + Util.
LongMaxString(time) + ", Open: " + Util.DoubleMaxString(open) + ", High:
 " + Util.DoubleMaxString(high) +  ", Low: " + Util.DoubleMaxString(low)
 + ", Close: " + Util.DoubleMaxString(close) + ", Volume: " + Util.Decim
alMaxString(volume) + ", Count: " + Util.IntMaxString(count) + ", WAP: "
 + Util.DecimalMaxString(WAP));
}

Public Sub realtimeBar(reqId As Integer, time As Long, open As Double, h
igh As Double, low As Double, close As Double, volume As Decimal, WAP As
 Decimal, count As Integer) Implements IBApi.EWrapper.realtimeBar
        Console.WriteLine("RealTimeBars. " & reqId & " - Time: " & Util.
LongMaxString(time) & ", Open: " & Util.DoubleMaxString(open) & ", High:
 " & Util.DoubleMaxString(high) & ", Low: " & Util.DoubleMaxString(low)
& ", Close: " & Util.DoubleMaxString(close) & ", Volume: " & Util.Decima
lMaxString(volume) & ", Count: " & Util.IntMaxString(count) & ", WAP: "
& Util.DecimalMaxString(WAP))
End Sub

Cancel Real Time Bars

Copy Location

EClient.cancelRealTimeBars (
            tickerId: int. Request identifier used to track data.
            )
            Cancels Real Time Bars’ subscription.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.cancelRealTimeBars(3001)

client.cancelRealTimeBars(3001);


m_pClient->cancelRealTimeBars(3001);

client.cancelRealTimeBars(3001);

client.cancelRealTimeBars(3001)


Component Exchanges

Copy Location
            A single data request from the API can receive
            aggregate quotes from multiple exchanges. The tick
            types ‘bidExch’ (tick type 32), ‘askExch’ (tick type
            33), ‘lastExch’ (tick type 84) are used to identify
            the source of a quote. To preserve bandwidth, the data
            returned to these tick types consists of a sequence of
            capital letters rather than a long list of exchange
            names for every returned exchange name field. To find
            the full exchange name corresponding to a single
            letter code returned in tick types 32, 33, or 84, and
            API function IBApi::[589]EClient::reqSmartComponents
            is available. Note: This function can only be used
            when the exchange is open.
            Different IB contracts have a different exchange map
            containing the set of exchanges on which they trade.
            Each exchange map has a different code, such as “a6”
            or “a9”. This exchange mapping code is returned to
            [590]EWrapper.tickReqParams immediately after a market
            data request is made by a user with market data
            subscriptions. To find a particular map of single
            letter codes to full exchange names, the function
            reqSmartComponents is invoked with the exchange
            mapping code returned to tickReqParams.
            For instance, a market data request for the IBKR US
            contract may return the exchange mapping identifier
            “a6” to [591]EWrapper.tickReqParams . Invoking the
            function [592]EClient.reqSmartComponents with the
            symbol “a9” will reveal the list of exchanges offering
            market data for the IBKR US contract, and their single
            letter codes. The code for “ARCA” may be “P”. In that
            case if “P” is returned to the exchange tick types,
            that would indicate the quote was provided by ARCA.

Request Component Exchanges

Copy Location

EClient.reqSmartComponents (
            reqId: int. Request identifier used to track data.
            bboExchange: String. Mapping identifier received from
            EWrapper.tickReqParams
            )
            Returns the mapping of single letter codes to exchange
            names given the mapping identifier.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqSmartComponents(1018, "a6")

client.reqSmartComponents(1013, "a6");

m_pClient->reqSmartComponents(13002, m_bboExchange);

client.reqSmartComponents(13002, testImpl.BboExchange);

client.reqSmartComponents(13002, wrapperImpl.BboExchange)

Receive Component Exchanges

Copy Location

EWrapper.smartComponents (
            reqId: int. Request identifier used to track data.
            smartComponentMap: SmartComponentMap. Unique object
            containing a map of all key-value pairs
            )
            Containing a bit number to exchange + exchange
            abbreviation dictionary. All IDs can be initially
            retrieved using [593]reqTickParams.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def smartComponents(self, reqId:int, smartComponentMap:SmartComponentMap
):
        print("SmartComponents:")
        for smartComponent in smartComponentMap:
                print("SmartComponent.", smartComponent)

@Override
public void smartComponents(int reqId, Map<Integer, Entry> theMap) {
        System.out.println(EWrapperMsgGenerator.smartComponents(reqId, t
heMap));
}

void TestCppClient::smartComponents(int reqId, const SmartComponentsMap&
 theMap) {
    printf("Smart components: (%lu):\n", theMap.size());
    for (SmartComponentsMap::const_iterator i = theMap.begin(); i != the
Map.end(); i++) {
        printf(" bit number: %d exchange: %s exchange letter: %c\n", i->
first, std::get(i->second).c_str(), std::get(i->second));
    }
}

public void smartComponents(int reqId, Dictionary<int, KeyValuePair> the
Map)
{
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("==== Smart Components Begin (total={0}) reqId =
 {1} ====\n", theMap.Count, reqId);
        foreach (var item in theMap)
        {
                sb.AppendFormat("bit number: {0}, exchange: {1}, exchang
e letter: {2}\n", item.Key, item.Value.Key, item.Value.Value);
        }
        sb.AppendFormat("==== Smart Components Begin (total={0}) reqId =
 {1} ====\n", theMap.Count, reqId);
        Console.WriteLine(sb);
}

Public Sub smartComponents(reqId As Integer, theMap As Dictionary(Of Int
eger, KeyValuePair(Of String, Char))) Implements EWrapper.smartComponent
s
        Dim sb As New StringBuilder
        sb.AppendFormat("==== Smart Components Begin (total={0}) reqId =
 {1} ===={2}", theMap.Count, reqId, Environment.NewLine)
        For Each item In theMap
                sb.AppendFormat("bit number: {0}, exchange: {1}, exchang
e letter: {2}{3}", item.Key, item.Value.Key, item.Value.Value, Environme
nt.NewLine)
        Next
        sb.AppendFormat("==== Smart Components Begin (total={0}) reqId =
 {1} ===={2}", theMap.Count, reqId, Environment.NewLine)
        Console.WriteLine(sb)
End Sub


Market Depth Exchanges

Copy Location
            To check which exchanges offer deep book data, the
            function EClient.reqMktDepthExchanges can be invoked.
            It will return a list of exchanges from where market
            depth is available if the user has the appropriate
            market data subscription.
            API ‘Exchange’ fields for which a market depth request
            would return market maker information and result in a
            callback to EWrapper.updateMktDepthL2 will be
            indicated in the results from the
            EWrapper.mktDepthExchanges field by a ‘True’ value in
            the ‘isL2’ field:

Requesting Market Depth Exchanges

Copy Location

EClient.reqMktDepthExchanges ()
            Requests venues for which market data is returned to
            updateMktDepthL2 (those with market makers).
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqMktDepthExchanges()

client.reqMktDepthExchanges();

m_pClient->reqMktDepthExchanges();

client.reqMktDepthExchanges();

client.reqMktDepthExchanges()

Receive Market Depth Exchanges

Copy Location

EWrapper.mktDepthExchanges (
            depthMktDataDescriptions: DepthMktDataDescription[]. A
            list containing all available exchanges offering
            market depth.
            )
            Called when receives Depth Market Data Descriptions.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def mktDepthExchanges(self, depthMktDataDescriptions:ListOfDepthExchange
s):
        print("MktDepthExchanges:")
        for desc in depthMktDataDescriptions:
                print("DepthMktDataDescription.", desc)

@Override
public void mktDepthExchanges(DepthMktDataDescription[] depthMktDataDesc
riptions) {
        System.out.println(EWrapperMsgGenerator.mktDepthExchanges(depthM
ktDataDescriptions));
}

void TestCppClient::mktDepthExchanges(const std::vector &depthMktDataDes
criptions) {
        printf("Mkt Depth Exchanges (%lu):\n", depthMktDataDescriptions.
size());
        for (unsigned int i = 0; i < depthMktDataDescriptions.size(); i+
+) {
                printf("Depth Mkt Data Description [%d] - exchange: %s s
ecType: %s listingExch: %s serviceDataType: %s aggGroup: %s\n", i, depth
MktDataDescriptions[i].exchange.c_str(), depthMktDataDescriptions[i].sec
Type.c_str(), depthMktDataDescriptions[i].listingExch.c_str(), depthMktD
ataDescriptions[i].serviceDataType.c_str(), Utils::intMaxString(depthMkt
DataDescriptions[i].aggGroup).c_str());
        }
}

public void mktDepthExchanges(DepthMktDataDescription[] depthMktDataDesc
riptions)
{
        Console.WriteLine("Market Depth Exchanges:");
        foreach (var depthMktDataDescription in depthMktDataDescriptions
)
        {
                Console.WriteLine("Depth Market Data Description: Exchan
ge: {0}, Security Type: {1}, Listing Exch: {2}, Service Data Type: {3},
Agg Group: {4}", depthMktDataDescription.Exchange, depthMktDataDescripti
on.SecType, depthMktDataDescription.ListingExch, depthMktDataDescription
.ServiceDataType, Util.IntMaxString(depthMktDataDescription.AggGroup));
        }
}

Public Sub mktDepthExchanges(depthMktDataDescriptions As DepthMktDataDes
cription()) Implements EWrapper.mktDepthExchanges
        Console.WriteLine("Market Depth Exchanges:")
        For Each depthMktDataDescription In depthMktDataDescriptions
                Console.WriteLine("Depth Market Data Descriprion. Exchan
ge: " & depthMktDataDescription.Exchange & " Security Type: " & depthMkt
DataDescription.SecType & " Listing Exch: " & depthMktDataDescription.Li
stingExch & " Service Data Type: " & depthMktDataDescription.ServiceData
Type & "  Agg Group: " & Util.IntMaxString(depthMktDataDescription.AggGr
oup))
        Next
End Sub

Market Depth (L2)

Copy Location
            Market depth data, also known as level II, represents
            an instrument’s order book. Via the TWS API it is
            possible to obtain this information with the
            [594]EClient.reqMarketDepth function. Unlike [595]Top
            Market Data (Level I), market depth data is sent
            without sampling nor filtering, however we cannot
            guarantee that every price quoted for a particular
            security will be displayed when you invoke
            [596]EClient.reqMarketDepth.
            In particular, odd lot orders are not included.
            It is possible to Smart-route a
            [597]EClient.reqMarketDepth request to receive
            aggregated data from all available exchanges, similar
            to the TWS BookTrader display.
            An integral part of processing the incoming data is
            monitoring EWrapper::error for message 317 “Market
            depth data has been RESET. Please empty deep book
            contents before applying any new entries.” and
            handling it appropriately, otherwise the update
            process would be corrupted.
            Market Depth is not support for Calendar Spreads or
            Combos.

Request Market Depth

Copy Location
            Important: Please note that the languages use
            different method names for requesting market depth.
            The C# and Visual Basic APIs use reqMarketDepth().
            The Python, Java, and C++ APIs use reqMktDepth().

EClient.reqMarketDepth (
            tickerId: int. Request identifier used to track data.
            contract: Contract. The Contract for which the depth
            is being requested.
            numRows: int. The number of rows on each side of the
            order book.
            isSmartDepth: bool. Flag indicates that this is smart
            depth request.
            mktDepthOptions: List. Internal use only. Leave an
            empty array.
            )
            Requests the contract’s market depth (order book).
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.reqMktDepth(2001, contract, 5, False, [])

client.reqMktDepth(2001, contract, 5, false, null);

m_pClient->reqMktDepth(2001, contract, 5, false, TagValueListSPtr());

client.reqMarketDepth(2001, contract, 5, false, null);

client.reqMarketDepth(2001, contract, 5, False, Nothing)

Receive Market Depth

Copy Location

EWrapper.updateMktDepth (
            tickerId: int. Request identifier used to track data.
            position: int. The order book’s row being updated
            operation: int. Indicates a change in the row’s
            value.:
               o 0 = insert (insert this new order into the row
                 identified by ‘position’)·
               o 1 = update (update the existing order in the row
                 identified by
                 ‘position’)·
               o 2 = delete (delete the existing order at the row
                 identified by ‘position’).
            side: int. 0 for ask, 1 for bid
            price: double. The order’s price
            size: decimal. The order’s size
            )
            Returns the order book. Used for direct routed
            requests only.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def updateMktDepth(self, reqId: TickerId, position: int, operation: int,
 side: int, price: float, size: Decimal):
                print("UpdateMarketDepth. ReqId:", reqId, "Position:", p
osition, "Operation:", operation, "Side:", side, "Price:", floatMaxStrin
g(price), "Size:", decimalMaxString(size))

@Override
public void updateMktDepth(int tickerId, int position, int operation, in
t side, double price, Decimal size) {
        System.out.println(EWrapperMsgGenerator.updateMktDepth(tickerId,
 position, operation, side, price, size));
}

void TestCppClient::updateMktDepth(TickerId id, int position, int operat
ion, int side, double price, Decimal size) {
    printf( "UpdateMarketDepth. %ld - Position: %s, Operation: %d, Side:
 %d, Price: %s, Size: %s\n", id, Utils::intMaxString(position).c_str(),
operation, side, Utils::doubleMaxString(price).c_str(), decimalStringToD
isplay(size).c_str());
}

public virtual void updateMktDepth(int tickerId, int position, int opera
tion, int side, double price, decimal size)
{
        Console.WriteLine("UpdateMarketDepth. " + tickerId + " - Positio
n: " + position + ", Operation: " + operation + ", Side: " + side + ", P
rice: " + Util.DoubleMaxString(price) + ", Size: " + Util.DecimalMaxStri
ng(size));
}

Public Sub updateMktDepth(tickerId As Integer, position As Integer, oper
ation As Integer, side As Integer, price As Double, size As Decimal) Imp
lements IBApi.EWrapper.updateMktDepth
        Console.WriteLine("UpdateMarketDepth. " & CStr(tickerId) & " - P
osition: " & CStr(position) & ", Operation: " & CStr(operation) & ", Sid
e: " & CStr(side) & ", Price: " & Util.DoubleMaxString(price) & ", Size:
 " & Util.DecimalMaxString(size))
End Sub

EWrapper.updateMktDepthL2 (
            tickerId: int. Request identifier used to track data.
            position: int. The order book’s row being updated.
            marketMaker: String. The exchange holding the order if
            isSmartDepth is True, otherwise the MPID of the market
            maker.
            operation: int. Indicates a change in the row’s
            value.:
               o 0 = insert (insert this new order into the row
                 identified by ‘position’)·
               o 1 = update (update the existing order in the row
                 identified by
                 ‘position’)·
               o 2 = delete (delete the existing order at the row
                 identified by ‘position’).
            side: int. 0 for ask, 1 for bid
            price: double. The order’s price
            size: decimal. The order’s size
            isSmartDepth: bool. Flag indicating if this is smart
            depth response
            )
            Returns the order book. Used for direct routed
            requests only.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
def updateMktDepthL2(self, reqId: TickerId, position: int, marketMaker:
str, operation: int, side: int, price: float, size: Decimal, isSmartDept
h: bool):
        print("UpdateMarketDepthL2. ReqId:", reqId, "Position:", positio
n, "MarketMaker:", marketMaker, "Operation:", operation, "Side:", side,
"Price:", floatMaxString(price), "Size:", decimalMaxString(size), "isSma
rtDepth:", isSmartDepth)

@Override
public void updateMktDepthL2(int tickerId, int position, String marketMa
ker, int operation, int side, double price, Decimal size, boolean isSmar
tDepth) {
        System.out.println(EWrapperMsgGenerator.updateMktDepthL2( ticker
Id, position, marketMaker, operation, side, price, size, isSmartDepth));
}

void TestCppClient::updateMktDepthL2(TickerId id, int position, const st
d::string& marketMaker, int operation, int side, double price, Decimal s
ize, bool isSmartDepth) {
    printf( "UpdateMarketDepthL2. %ld - Position: %s, Operation: %d, Sid
e: %d, Price: %s, Size: %s, isSmartDepth: %d\n", id, Utils::intMaxString
(position).c_str(), operation, side, Utils::doubleMaxString(price).c_str
(), decimalStringToDisplay(size).c_str(), isSmartDepth);
}

public virtual void updateMktDepthL2(int tickerId, int position, string
marketMaker, int operation, int side, double price, decimal size, bool i
sSmartDepth)
{
        Console.WriteLine("UpdateMarketDepthL2. " + tickerId + " - Posit
ion: " + position + ", Operation: " + operation + ", Side: " + side + ",
 Price: " + Util.DoubleMaxString(price) + ", Size: " + Util.DecimalMaxSt
ring(size) + ", isSmartDepth: " + isSmartDepth);
}

Public Sub updateMktDepthL2(tickerId As Integer, position As Integer, ma
rketMaker As String, operation As Integer, side As Integer, price As Dou
ble, size As Decimal, isSmartDepth As Boolean) Implements IBApi.EWrapper
.updateMktDepthL2
        Console.WriteLine("UpdateMarketDepthL2. " & CStr(tickerId) & " M
arketMaker: " & marketMaker & ", Position: " & CStr(position) & ", Opera
tion: " & CStr(operation) & ", Side: " & CStr(side) & ", Price: " & Util
.DoubleMaxString(price) & ", Size: " & Util.DecimalMaxString(size) & ",
isSmartDepth: " & CStr(isSmartDepth))
End Sub

Cancel Market Depth

Copy Location

EClient.cancelMarketDepth (
            tickerId: int. Request identifier used to track data.
            isSmartDepth: bool. Flag indicates that this is smart
            depth request.
            )
            Cancel’s market depth’s request.
               o (BUTTON) Python
               o (BUTTON) Java
               o (BUTTON) C++
               o (BUTTON) C#
               o (BUTTON) VB.NET
self.cancelMktDepth(2001, False)

client.cancelMktDepth(2001, false);

m_pClient->cancelMktDepth(2001, false);

client.cancelMktDepth(2001, false);

client.cancelMktDepth(2001, False)

Option Greeks

Copy Location
            The option greek values- delta, gamma, theta, vega-
            are returned by default following a reqMktData()
            request for the option. See Available Tick Types
            Tick types “Bid Option Computation” (#10), “Ask Option
            Computation” (#11), “Last Option Computation” (#12),
            and “Model Option Computation” (#13) return all Greeks
            (delta, gamma, vega, theta), the underlying price and
            the stock and option reference price when requested.
            MODEL_OPTION_COMPUTATION also returns model implied
            volatility.
            Note that to receive live greek values it is necessary
            to have market data subscriptions for both the option
            and the underlying contract.
            The implied volatility for an option given its price
            and the price of the underlying can be calculated with
            the function EClient.calculateImpliedVolatility.
            Alternatively, given the price of the underlying and
            an implied volatility it is possible to calculate the
            option price using the function
            EClient.calculateOptionPrice.
            After the request, the option specific information
            will be delivered via the
            EWrapper.tickOptionComputation method.

Request Options Greeks

Copy Location

EClient.reqMktData (
            reqId: int. Request identifier for tracking data.
            contract: Contract. Contract object used for
            specifying an instrument.
            genericTickList: String. Comma separated ids of the
            available generic ticks.
            snapshot: bool. Set to True for snapshot data with a
            relevant subscription or False for live data.
            regulatorySnapshot: bool. Set to True for a paid,
            regulator