Updated on March 26th, 2024.  API v10.28

TIABSocket component help file.

https://www.hhssoftware.com/iabsocketapi/

This component set is built to work with the API for both of the InteractiveBrokers TradeWorkStation and the InteractiveBrokers IBGateway. It allows Delphi, BCB and FPC programmers to build apps that send orders directly to the TWS. This TIABSocket component links directly to the sockets on your computer to communicate directly with the TWS API.

There are no dll, ActiveX or DDE files required. This direct connection makes for a fast reliable interaction and response time.

The TIABSocket is the main component in the set. Install this component into your Delphi component library, and then drop it on a form. The properties and events will appear in the Object Inspector. Other objects in this set are the TIABOrder, TIABOrders, TIABPortfolio, TIABInstrumentSpec, TIABBondSpec, TIABScanner, TIABScan. The component manages all interactions with the TWS, including all order activity, portfolio and account details.

Effective with API v10.10 onwards, the ability to handle BigDecimal values was added for use with bitcoin trading. This requires the addition of third party code from DelphiBigNumbers

This help file should be read in conjunction with TWS API help located here
  https://ibkrcampus.com/ibkr-api-page/trader-workstation-api/

The discussion groups for the API here cover many programming tasks for the IAB API in general.
  https://groups.io/g/twsapi

Getting started

  1. Install the TIABSocket component into the library.
    In Delphi XE, 10 and 11 era IDE's; Menu select Components -> Select IABSocketAPI.pas, IABSocketAPI_const.pas, IABSocketAPI_tcpclient.pas and the .dcr files, select existing (dclextras), or new bpl file, Build, Install, save and close. It will appear on the Samples page by default. Amend the IDE's Library and Browing paths to include the above location (Tools -> Options -> Enviroment -> Delphi -> Library).

    In older Delphi 7 era IDE's; Menu select Components -> Install component into dclextras, or other new bpl file, then add the IABSocketAPI.pas, IABSocketAPI_const.pas, IABSocketAPI_tcpclient.pas and the .dcr file, then Build, Install, save and close. It will appear on the Samples page by default.

    For Updating: Replace the IABSocketAPI.pas, IABSocketAPI_const.pas, IABSocketAPI_tcpclient.pas files, open the .dpk package built above, and Build / Install it again.

    If bitcoin trading is needed, then enable USE_BIGDECIMAL (see the Bigdecimal.txt for procedures.)

  2. Start a project, and drop the component on the form.

  3. Set the various properties including the Default Order settings.

  4. Set the events for (as required):
  5. Set connected property to true to start a connection to the TWS.

  6. Call these Methods to (example):
  7. Check the various properties for values such as:
  8. See the "Code-notes.txt" file in the demo project folder for further details on program structure.



This help file applies to API version 10.28 (March 2024)


TIABSocket component

This component is the main interface, which is used for placing and checking on orders, receiving events and calling all methods of the API.


TIABSocket properties


property AccountValues: TStringList

This property requires the GetAccountUpdates method to be called first to populate the string list. The Account Values property maintains a String List of current account values from the TWS. Each string is a combination of the Key, Data, Currency values separated by one space between each element. New changes from the TWS are included as they arrive. Each change from TWS generates an OnAccountValue event. (read and write).

These values below are defined, and the zero based Index will refer to these in order.


property Portfolio: TIABPortfolio


This property requires the GetAccountUpdates method to be called first to populate the list. The Portfolio property maintains a list of all TPortfolioItem updates or adjustments sent by the TWS. Any changes to the list will generate an OnPortfolioUpdate event. (read and write). Access each item in the same manner as Lines property in a TMemo. i.e. Portfolio[2].MarketPrice

The fields of a TIABPortfolioItem are:

  Symbol: string;
  Local: string;
  SecurityType: TIABSecurityType;
  Expiry: string;
  Strike: Double;
  Right: TIABRight;
  Currency: string;
  Position: BigDecimal;//Double;
  MarketPrice: Double;
  MarketValue: Double;
  AverageCost: Double;
  UnrealizedPNL: Double;
  RealizedPNL: Double;
  AccountName: string;
  InstrumentId: Integer;
  Multiplier: string;
  PrimaryExchange: string;
  TradingClass: string;



property Connected: Boolean

Read the Connected property to determine if connected to the TWS. Write false / true to set the connection to the TWS. Monitor the OnConnectionState event for changes in connection status. Do not communicate with TWS until the OnConnectionState signals twsReady. (read and write).



property ClientID: Integer

Set a value for the TWS to identify this Client application. This value may be changed whilst disconnected. Each new ClientId distinguishes each running API process to the TWS. Each running client must have a unique ID. (read and write).

A value of 0 to cause this client to become part of the TWS. See BindTWSOrdersToClient.



property Scanner: TIABScanner;

This property provides access to the TIABScanner object. This controls the scans in the same manner as the TWS. See the TIABScanner for details.

These events are related to the TIABScanner; OnScannerParam and OnScannerData.



property DefOrder: TIABOrder

The DefOrder is the default order. Use the default order to set many of the basic values that will not change between separate orders. This order can be passed to the PlaceOrder method, changing only the values that are different from last order. (read and write).

See the TIABOrder object for details on the properties of DefOrder.



property InstrumentSpecs: TIABInstrumentSpec

This property requires the GetInstrumentSpecs method to be called first. The InstrumentSpecs property maintains a list of TIABInstrumentSpecItem requested from the TWS. (read and write). Access each item in the same manner as Lines property in a TMemo. i.e. InstrumentSpecs[2].MinimumTick

The fields of a TIABInstrumentSpecItem are:

  MarketName: string;
  TradingClass: string;
  ContractId: Integer;
  Multiplier: string;
  MinimumTick: Double;
  OrderTypes: TIABOrderTypesSet;
  ValidExchanges: string;
  Symbol: string;
  SecurityType: TIABSecurityType;
  Expiry: string;
  Strike: Double;
  Right: TIABRight;
  Exchange: string;
  Currency: string;
  LocalSymbol: string;
  PriceMagnifier: Integer;
  DataID: Integer;
  UnderConId: Integer;
  LongName: string;
  PrimaryExchange: string;
  ContractMonth: string;
  Industry: string;
  Category: string;
  SubCategory: string;
  TimeZoneID: string;
  TradingHours: string;
  LiquidHours: string;
  EVRule: string;
  EVMultiplier: Double;
  SecIdList: TIABTagValueArray;
  AggGroup: Integer;
  UnderSymbol: string;
  UnderSecType: string;
  MarketRuleIds: string;
  DerivativeSecTypes: string;
  LastTradeTime: string;
  MinSize: BigDecimal;// Double;
  SizeIncrement: BigDecimal;// Double;
  SuggestedSizeIncrement: BigDecimal;// Double;
  FundValues: TIABFundValues;
  LastTradeDate: string;



property BondSpecs: TIABBondSpec

This property requires the GetInstrumentSpecs method to be called first, using a valid bond CUSIP or ISIN number in the Symbol field.. The BondSpecs property maintains a list of TIABBondSpecItem requested from the TWS. (read and write). Access each item in the same manner as Lines property in a TMemo. i.e. BondSpecs[2].Cusip

The fields of a TIABBondSpecItem are:

  MarketName: string
  TradingClass: string
  ContractId: Integer
  MinimumTick: Double
  OrderTypes: TIABOrderTypesSet
  ValidExchanges: string
  Symbol: string
  SecurityType: TIABSecurityType
  Cusip: string
  Ratings: string
  DescAppend: string
  BondType: string
  CouponType: string
  Callable: Boolean
  Putable: Boolean
  Coupon: Double
  Convertible: Boolean
  Maturity: string
  IssueDate: string
  Exchange: string
  Currency: string
  NextOptionDate: string
  NextOptionType: string
  NextOptionPartial: Boolean
  Notes: string
  LongName: string
  DataId: Integer
  EVRule: string;
  EVMultiplier: Double;
  SecIdList: TIABTagValueArray;
  AggGroup: Integer;
  MarketRuleIds: string;
  TimeZoneID: string;
  LastTradeTime: string;
  MinSize: BigDecimal;// Double;
  SizeIncrement: BigDecimal;// Double;
  SuggestedSizeIncrement: BigDecimal;// Double;



property ReserveIDs: Integer

Set the required number of TempId's required. Advises the TWS to reserve a block of TempId's. (read and write).

Note: Old requirement for old API - no longer needed.



property TWSHostAddress: string

The default value is localhost (read and write). This property sets the connection IP Address or host name where the TWS Server / IAB gateway is listening and located. The TWS works on both IPv4 and IPv6. This property accepts values in most formats (127.0.0.1, localhost, www.somewhere.com, ::1, fe80::a142:a611:f46b:4b5e). Do not use quotes or braces.

While the TWS will accept connections from any IPv4 or IPv6 address, it also limits automatic access through the settings: Edit -> Global config -> API -> Settings -> Allowed / trusted IP's.



property TWSPort: Integer

This value is the port that the TWS server listens. The default TWS port is 7496 for live TWS API connection, and 7497 for Paper trading TWS connections. For the IB Gateway, defualt ports are 4001 live accounts and 4002 paper accounts. This value must correspond the value set in the TWS configuration - Edit - Settings - API. (read and write).



property ConnectAtServerTime: string

Read only. This property is set after a good connection. Read this value in the OnConnectionState event when a Ready state exists.
The format is The TWS connection time is provided as a string with the format "yyyymmdd{space}hh:nn:ss{space}" followed by the local time zone. Use the IABDateTimeStrToDateTime function to convert to a TDateTime value.



property SecurityID: string property SecurityIDType: string

Use these fields when querying contract details (reqContractDetails) or when placing orders (placeOrder).



property Orders: TIABOrders

Orders property is an array component of all singular Orders. The array is populated automatically, each time a new order is placed, and when TWS sends notification of previous executions or OpenOrders. Each Order fill / price is amended automatically as changes occur.
Access this property in the same manner as a Lines property of a TMemo. i.e. Orders[2].FillPrice

See the TIABOrders object for details on its properties / methods / events.



property VerifiedOrders: TIABOrders

This property operates in the same manner as Orders property - see above for descriptions.

The VerifiedOrders property contains only orders that have been sucessfully processed by the VerifyOrder method. See the VerifyOrder method for a description of the purpose and meaning of verified Orders.



property v100plusAPICalls: Boolean;
property ClientMaxVerOverride: Integer;

In mid 2016, the TWS API made a large change to a newer format with better data size tracking. Then they changed the updates to smaller increamental ones, but within each version releases.

These properties allow you to go back to the old API, or control the current version to communicate to TWS with.

v100plusAPICalls: Boolean default true; Setting false puts the API back to v63 (late 2015): update - No longer supported in TWS!

ClientMaxVerOverride: Integer; Set the maximum API version to use (972, 973, 976, 1010, etc). This will be handy if some new TWS API change is made but causes crashes. Default is 0 which uses the latest defined version per the API code.



property SmartDepthMarketData: Boolean;

Applies to Level 2 market depth requests in GetMarketDepth. Set this to recieve combined Smart exchange data values.




property StoredHistoricalData: Boolean;
property HistoricalDataStore: TIABHistoricalData;


These properties apply to the optional addon object, TIABHistoricalData that can automatically save incoming history and tick data. See the TIABHistoricalData topic below on how to install, and utilize this feature.

The StoredHistoricalData property turns on / off the inbuilt use of HistoricalDataStore, per each individual GetHistorical..() method call.
The HistoricalDataStore property accesses the the TIABHistoricalData object and the saved history and its methods.




TIABSocket Methods



procedure CancelAccountUpdates;

This method cancels a previous request for Account updates via GetAccountUpdates.



procedure CancelOrder(TempID: Integer);
This method cancels an existing open order. The TempId is the value that was returned by the PlaceOrder method. Confirm that the cancel was processed correctly by the OnOrderStatus event and an Order. The Completed property will be set to true.



procedure CancelOrderAtTime(TempID: Integer; CancelDateTime: TDateTime);
Like CancelOrder, this cancels an existing order, but at a specified time. Probably only available to Financial adviser accounts. Seems to be related to the property ManualOrderTime and only available to orders placed with this.




procedure CancelMarketData(DataId: Integer);

Cancels the flow of OnMarketDepth and OnMarketLevel2 events. The DataId value is the value supplied to the GetMarketDepth method used to identify and start the flow of data.




procedure CancelMarketDepth(DataId: Integer);

Cancels the flow of OnTickPrice and OnTickSize and TickSizeAndPrice events. The DataId value is the value supplied to the GetMarketData method used to identify and start the flow of data.



procedure GetAccountUpdates(AccountCode: string);

Starts the flow of account status and amendment updates. The AccountCode parameter applies to FA (financial adviser) accounts only. All other account types - pass an empty string. The TWS will send about 20 initial values. The values are received and processed through the OnAccountValue event.

The TWS will continue to amend the account every minute when values change, and when order executions occur. The OnAccountDetailsReady event will fire at the completion of the *initial only* call to this method and not the updates in the later minutes. The flow of data is stopped with CancelAccountUpdates.

This method starts the OnAccountValue and OnAccountTime events.



function GetExecutions(Filter: TIABExecutionFilter): Integer;

Requests from the TWS executions based on the filter conditions. Setting a field to null or 0 will remove that condition. Time is based on exchange time. The function returns a sequential request number that will be in the OnExecutionDetailsReady event parameter. The return values of the execution are received through the OnExecution event. The Orders property will be populated for each new or old order received.

  TIABExecutionFilter = record
    ClientId: Integer;
    AccountCode: string;
    FromTime: TDateTime;
    TimeZone: string;
    Symbol: string;
    SecurityType: TIABSecurityType;
    Exchange: string;
    Action: TIABActionFilter;
  end;

  TIABActionFilter = (afNone,afBuy,afSell,afShort,afExercise,afLapse);


Timezone can be left blank and then the API will convert the time to UTC according to the computers system time. Or specify one of many badly worded time zones texts like America/New_York. Time zones texts like US/Central as supposed to work too (but not yet).

See also RebuildFromTWS.



procedure GetInstrumentSpecs(DataId: Integer; Order: TIABOrder; IncludeExpired: Boolean = false);

Call this function to download all details for a particular underlying instrument, contract or Bond. The return values for instrument or contract are received through the OnInstrumentSpecDetails event. Bond details are returned via the OnBondSpecDetails event.

IncludeExpired parameter (default = false). If it is true, historical data queries can be done on expired contracts, those queries being limited to the last year of the contracts life.
The DataId value is a unique value used to identify this set of data, and is used for identifying the response later.

This method is the same as the API GetContractDetails.




procedure GetMarketData(DataId: Integer; Symbol, Local, Exchange, Expiry, Currency, PrimaryExchange: string;
      SecurityType: TIABSecurityType; Right: TIABRight; Strike: Double; ComboLegs: TIABComboLegArray;
      TradingClass: string = ''; ExMarketData: TIABExMktDataSet = []; Multiplier: string = ''); overload;

procedure GetMarketData(DataId: Integer; Order: TIABOrder; ExMarketData: TIABExMktDataSet = []); overload;

procedure GetMarketData(DataId: Integer; Order: TIABOrder; ExMarketDataString: string); overload;


GetMarketData is an overload method, and may be called three different ways. These methods start the flow of data to the OnTickPrice and OnTickSize and TickSizeAndPrice events. The DataId value is a unique value used to identify this set of data, and is used for canceling later via CancelMarketdata method.

In the first version of this method, we specify each of the individual parameters.

In the second method, the Order parameter is an existing TIABOrder, and GetMarketData will use the symbol and Exchange information contained there. (Pass the DefOrder or create a new TIABOrder, and pass it).

The ExMarketData parameter is to specify an Extended Market Data values. This is a parameter set. Normal (basic) market data requests do not need this parameter. This parameter is defaulted to an empty set [].
The values of TIABExMktDataSet comprise of:

TIABExMktData = (emdOptionVolume, emdOptionOpenInterest, emdHistoricalVolatility, emdOptionImpliedVolatility, emdIndexFuturePremium, emdMiscellaneous, emdMarkPricePnL, emdMarkPricePnLAuction);

Each of these values will generate additional OnTickPrice and OnTickSize events. Not all the requests apply to all instrument types. See the beta notes, or regular help for a table of events from each specific ExMktData value.

The third version of GetMarketData, is for passing special ID strings directly into the TWS. The ExMarketDataString parameter is a comma separated string of Integer ID's (eg. '234,123,'). Use this function to retrieve the Shortable state of an instrument - set the ExMktDataString to '236'. The result is delivered in the OnTickGeneric event.

To cancel the data flow, call CancelMarketData using the same DataId value.

The full list of available tick types, and which event they return through, is here: TWS tick types and responses.

See also GetMarketSnapShot method to retrieve a one time only set of data for an instrument.




procedure GetMarketSnapShot(DataId: Integer; Symbol, Local, Exchange, Expiry, Currency, PrimaryExchange: string; SecurityType: TIABSecurityType; Right: TIABRight; Strike: Double);


GetMarketSnapShot is much like the GetMarketData method, except that a snapshot will give just a single set of data through the OnTick events only. See GetMarketData for parameter details. See the OnSnapShotDataEnd event as well.



procedure GetMarketDepth(DataId: Integer; Order: TIABOrder; nRows: Integer); overload;

procedure GetMarketDepth(DataId: Integer; Symbol, Local, Exchange, PrimaryExchange, Expiry, Currency: string; SecurityType: TIABSecurityType; Right: TIABRight; Strike: Double; nRows: Integer; Multiplier: string = ''); overload;

procedure GetMarketDepth(DataId: Integer; Symbol, Local, Exchange, PrimaryExchange, Expiry, Currency, TradingClass, MktDataOptions, Multiplier: string; SecurityType: TIABSecurityType; Right: TIABRight; Strike: Double; nRows, ConId: Integer); overload;


GetMarketDepth is an overload method, and may be called three different ways. These methods start the flow of data to the OnMarketLevel2 and OnMarketDepth events. The TWS will send data to one Event only, depending on the type of data available for the instrument requested. The DataId value is a unique value used to identify the data for this instrument.

In the first method, the Order parameter is an existing TIABOrder, and GetMarketDepth will use the symbol and Exchange information contained there. (Pass the DefOrder or create a new TIABOrder, and pass it). OR you may specify the individual details in the second GetMarketDepth method.

To cancel the data flow, call CancelMarketDepth using the same DataId value.

See also SmartDepthMarketData setting for Level2 data.



procedure GetOpenOrdersClient;

This method requests from the TWS all open orders - for this Client Id only. The results arrive via the OnOpenOrder and OnOrderStatus events. The TIABSocket will locate the matching Order and amend it, or generate a new TIABOrder in the Orders property, for each value returned. At the end of each data set for this method, the OnOpenOrderDetailsReady event fires.

See also RebuildFromTWS.



procedure GetOpenOrdersAccount;

This method requests from the TWS all open orders - for the entire account. i.e via other Clients or Id's, including TWS generated orders. The results arrive via the OnOpenOrder and OnOrderStatus events. The TIABSocket will locate the matching Order and amend it, or generate a new TIABOrder in the Orders property, for each value returned. At the end of each data set for this method, the OnOpenOrderDetailsReady event fires.

Note: The TWS generated orders are currently excluded from the output, as these all have identical Id's (ClientId=0, OrderId=0), and they cannot be distinguished from each other. Awaiting a fix from IAB (PermId inclusion in OpenOrder event).

See also RebuildFromTWS.



procedure BindTWSOrdersToClient(AutoBind: Boolean);

Call this method to request that newly created TWS orders be implicitly associated with the client. When a new TWS order is created, the order will be associated with the client, and fed back through the OnOpenOrder and OnOrderStatus events. At the end of each data set for this method, the OnOpenOrderDetailsReady event fires.

AutoBind - If set to TRUE, newly created TWS orders will be implicitly associated with the client. If set to FALSE, no association will be made.

Note: This request can only be made from a client with ClientId of 0.



function ModifyOrder(TempId, ClientId: Integer; Quantity: BigDecimal; OrderType: TIABOrderType; Price, AuxPrice: Double): Boolean;

Modify an existing open order. A return value of true indicates only that the order was sent to TWS. It does not indicate a successful change to the order. The TWS will generate a new OnOrderStatus event if successful (usually a Submitted status).

TempId = existing order identity - must be open (not Completed). ClientID = associated with this order.

The TWS allows only these parameters to be changed in an existing order. This method may be called using only the parameters requiring change to be set, and the remaining parameters set to 0 to keep the existing values. i.e.

  ModifyOrder(OrderId, ClientID, 0, otNoChange, 25.75, 0.0); will change only the Price field in the submitted order.

Partial fill procedure
The TWS manages partial fills. That is... no need to adjust quantity for a modified partial filled order. i.e. if half the order was filled, then use the quantity value of zero (0) to have the balance filled. When adjusting the quantity of an order, do the change based on the total of the original order. Adjusting a partial filled order to otMarket type, will fill the balance.



function PlaceOrder(Order: TIABOrder): Integer;

Places an order into the TWS. The Order parameter is a TIABOrder object. The return vale is the TempId of this order. The TempId is used to identify this order at all times.

Order parameter may be set to nil, and PlaceOrder will use the DefOrder values. OR Create a new TIABOrder object, set its values, and pass it as the Order parameter. In this case, you will free the TIABOrder just created.

Each PlaceOrder method call will add the order to the Orders property and maintained by the TIABOrders object. This new order may be found using method of the TIABOrders object through the Orders property.



function ExerciseOptions(Order: TIABOrder; OverridePos: Boolean; ManualOrderTime: TDateTime): Integer;

Places an ExerciseOptions order into the TWS. The Order parameter is a TIABOrder object. The return vale is the TempId of this order. The TempId is used to identify this order at all times.

Order parameter may be set to nil, and PlaceOrder will use the DefOrder values. OR Create a new TIABOrder object, set its values, and pass it as the Order parameter. In this case, you will free the TIABOrder just created.

Each ExerciseOptions method call will add the order to the Orders property and maintained by the TIABOrders object. This new order may be found using method of the TIABOrders object through the Orders property.

The Order.Action poperty can have two values: iabExercise for exercise, and iabLapse for lapse. If no multiplier is specified, a default of 100 is assumed. If the OverridePos parameter is true, exercise instructions will be processed even if the option is out-of-the-money, and lapse instructions will be processed even if the option is in-the-money. Please note that SMART is not an allowed exchange in ExerciseOptions method, and that TWS does a moneyness request for the position in question whenever any API initiated exercise or lapse is attempted.



procedure RebuildFromTWS;

This method will initialize, or rebuild the Orders property, so it corresponds with the TWS. Use this method if you hold positions, or open orders, and have restarted your application or the TWS.

The OnRebuildFromTWS event will be called for each element update. Note that this method, once completed, should set the Orders property to reflect the TWS version of trades to this client.




procedure GetNewsBulletins(AllMessages: Boolean);

This method will start the flow of Flash news Bulletins, and messages concerning Exchange avialability. News / bulletins arrive in the OnNewsBulletin Event. Changes in exchange avialability arrive in the OnExchangeStatus Event. The AllMessages parameter set to TRUE, returns all the existing bulletins for the current day and any new ones. If set to FALSE, will only return new bulletins.

Cancel with CancelNewsBulletins.



procedure CancelNewsBulletins;

Cancels the flow of Flash news Bulletins, and messages concerning Exchange avialability.

Start the flow with GetNewsBulletins.


procedure SetServerLogLevel(LogLevel: Integer);

This method controls the details the TWS will log (log.txt) when communicating with an API Client. This setting has no affect on this API's functionality or the component set. See the IAB help files for details.

1 = SYSTEM (least detailed)
2 = ERROR (default, if no level is specified)
3 = WARNING
4 = INFORMATION
5 = DETAIL (most detailed)

NOTE: Setting the log level to 5 will have a performance overhead, and should only be used when trying to resolve an issue.

UPDATE: somewhere along the way, the TWS shifted to encrypted logs, and reduced the available details to API connections.
Now to access the API log, it must be decrypted from within the TWS, and log level 5 is required to record any API data. This instruction below shows how to setup TWS to log and then convert API logs.

api-logs


An alternative is to use our API Debug capture files. See the message near the top of IABSocketAPI.pas and {$DEFINE CAPTURE_TWS_STREAM}



procedure GetManagedAccounts;

Call this method to request the list of managed accounts. The list will be returned by the OnManagedAccounts event. Note: This request can only be made when connected to a FA managed account.



procedure RequestFA(FADataType: TIABFADataType);

TIABFADataType = (faGroups,faProfiles,faAliases);
TIABFADataTypeStr: array [TIABFADataType] of string = ('GROUPS','PROFILES','ALIASES');

Call this method to request the details of managed accounts. The list will be returned by the OnReceiveFADetail event. Note: This request can only be made when connected to a FA managed account.



procedure ReplaceFA(FADataType: TIABFADataType; XmlValue: string);

TIABFADataType = (faGroups,faProfiles,faAliases);
TIABFADataTypeStr: array [TIABFADataType] of string = ('GROUPS','PROFILES','ALIASES');
Call this method to request the deatils of managed accounts. The list will be returned by the OnReceiveFADetail event and the OnReplaceFAEnd event. Note: This request can only be made when connected to a FA managed account.



procedure GetHistoricalData(DataId: Integer; Symbol, Local, Exchange, Expiry, Currency, PrimaryExchange, Multiplier: string; SecurityType: TIABSecurityType; Right: TIABRight; Strike: Double; DataEndDateTime: string; DataDuration, DurationTimeUnits: Integer; BarSize: TIABChartBarSize; DataBasis: TIABHistoricalDataType; ExtendedHours, IncludeExpired, KeepUpdated: Boolean; DateFormat: Integer; ContractId: Integer; TradingClass: string; ChartOptions: TIABTagValueArray);


Associated data types for this method:

  TIABHistoricalDataType = (cdTrades,cdMidPoint,cdBid,cdAsk,cdBidAsk,
        cdAdjustedLast,cdHistoricalVolatility,cdOptionImpVolatility,cdRebateRate,cdFeeRate,
        cdYeildBid,cdYeildAsk,cdYeildBidAsk,cdYeildLast,cdSchedule,cdUnknown);

  TIABChartBarSize = (bs1sec,bs5sec,bs15sec,bs30sec,bs1min,bs2min,bs3min,bs5min,bs15min,bs30min,
        bs1Hour,bs1Day,bs1Week,bs1Month,bs3Month,bs1Year,bsUnknown);

  IAB_TIME_UNIT_YEAR = 4; IAB_TIME_UNIT_MONTH = 3; IAB_TIME_UNIT_WEEK = 2; IAB_TIME_UNIT_DAY = 1; IAB_TIME_UNIT_SEC = 0;
  IAB_GETHISTORY_DATEFORMAT_TEXT = 1; IAB_GETHISTORY_DATEFORMAT_INTEGER = 2;

  TIABTagValue = record
    Tag, Value: string;
  end;
  PTIABTagValue = ^TIABTagValue;
  TIABTagValueArray = array of TIABTagValue;


Call this method to request the details of Historical Chart data. The data will be returned by the OnHistoricalData event. This method and event is cancelled with the CancelHistoricalData method;

The IAB has limits on the available data sizes, data sets, durations and numbers of concurrent data calls. Please see the current limit details at historical_limitations

A client can extract historical data of up to one year in duration, which can end at any date and time during the past six months for any valid contract or combo. The time span covered by the request is specified in the DataDuration parameter. Use the Constants IAB_TIME_UNIT_xx in the DurationTimeUnits parameter to specify the meaning of DataDuration. The DataEndDateTime parameter accepts a string in the form "yyyymmdd{space}hh:mm:ss{space}time zone". Timezone is now required. A typical value is "20210701 18:26:44 UTC". The timezone has many formats, such as "US/Central", "US/Eastern", "UTC". The API includes a helper function
function DateTimeToIABDateTimeStr(Value: TDateTime; Timezone: string = ''): string;

The BarSize specifies the size of the bars that will be returned (within limits imposed by IB's servers and TWS). The values range from 1 second to 1 day. Use a TIABChartBarSize value here.

Data is returned in bars of a nature very similar to the bars in TWS charts, each bar containing the start time, open, high, low, close, volume, and weighted average price during the time slice in question.

The final time slice has a Date value of "finished," allowing an API application to know when its query has completed. API 882: This also has a time stamp appended showing the request start-finish times eg:
'finished-20060406 12:19:16-20060406 12:24:16'

The nature of the data extracted is governed by setting the value in DataBasis (cdTrades,cdMidPoint,cdBid,cdAsk,cdBidAsk). Bars of the first 5 types contain the start time, open, high, low, close, volume, and weighted average price during the time slice in question. The contents of bars returned in response to a BID_ASK query differ from those returned by the other query types, in that the open and close values are actually the time weighted average bid, and time weighted average offer, respectively. This makes these bars identical in nature to TWS's BID_ASK candlestick chart bars.

The other values of DataBasis (cdAdjustedLast .. cdSchedule) are explained at Databasis - "what_to_show". The cdSchedule value will trigger a second event OnHistoricalSession

The ExtendedHours parameter exists to specify regular or extended trading sessions. All data available during the time span requested is returned, even data bars covering time intervals where the market in question was il-liquid. If ExtendedHours is set false, only data within the "Regular Trading Hours" of the product in question is returned, even if the time span requested falls partially or completely outside of them.

IncludeExpired parameter. If it is true, historical data queries can be done on expired contracts, those queries being limited to the last year of the contracts life.

KeepUpdated parameter when set true, will cause the TWS to keep appending new data bars as they occur, i.e. a new line of data every 5 mins on a 5min bar request. The additional lines of data come through the OnHistoricalDataUpdate event. Note that this parameter conflicts with DataEndDateTime parameter. You can specify an endtime, or KeepUpdated, but not both.

DateFormat parameter: If formatDate = 1, dates applying to bars are returned in a format "yyyymmdd{space}hh:mm:dd," which is the same format already used in EXECUTION_DATA messages. If formatDate = 2, those dates are returned as a text of Integer (Unix epoch / POSIX time) specifying the number of seconds since 1/1/1970 GMT.

ContractID: unknown - set to 0.

TradingClass: unknown - set to an empty string ''.

ChartOptions: Additional tag=value options, but unknown at this time - set to nil.

For details on time frames and allowable requests - see this discussion.

** Stored Historical data **

This API includes an add-on unit and object called TIABHistoricalData, that when active, will capture and store the incomming historical data and ticks. This can be saved and searched and more. See the TIABHistoricalData topic below.



procedure CancelRealTimeData(DataId: Integer);

procedure GetRealTimeData(DataId: Integer; Symbol, Local, Exchange, Expiry, Currency, PrimaryExchange, Multiplier: string;
      SecurityType: TIABSecurityType; Right: TIABRight; Strike: Double;
      BarSize: TIABChartBarSize;
      DataBasis: TIABHistoricalDataType; ExtendedHours: Boolean; DateFormat: Integer;
      ContractId: Integer; TradingClass: string; RealtimeBarOptions: TIABTagValueArray);


Note: some parts of this procedure can now be replaced with the newer GetHistoricalTicks. This old method here will deliver tick "samples" (max 3 samples per second usually). The new method is a full "time and sales" stream with all data points included.

Associated data types for this method:

  TIABHistoricalDataType = (cdTrades,cdMidPoint,cdBid,cdAsk,cdBidAsk);

  TIABChartBarSize = (bs1sec,bs5sec,bs15sec,bs30sec,bs1min,bs2min,bs3min,bs5min,bs15min,bs30min, bs1Hour,bs1Day,bs1Week,bs1Month,bs3Month,bs1Year);


Call this method to request the details of RealTime data. The data will be returned by the OnRealTimeData event. This method and event is cancelled with the CancelRealTimeData method;

NOTE: the current Barsize value is limited by the TWS to a 5 second period ONLY.

Data is returned in bars of a nature very similar to the bars in TWS charts, each bar containing the start time, open, high, low, close, volume, and weighted average price during the time slice in question.

The nature of the data extracted is governed by setting the value in DataBasis ("TRADES", "MIDPOINT", "BID", "ASK", "BID_ASK" ).

The ExtendedHours parameter exists to specify regular or extended trading sessions. All data available during the time span requested is returned, even data bars covering time

ContractID: unknown - set to 0.

TradingClass: unknown - set to an empty string ''.

RealtimeBarOptions: Additional tag=value options, but unknown at this time - set to nil.




procedure RequestHistogramData(DataId: Integer; InstrumentSpec: TIABInstrumentSpecItem; UseRTH, IncludeExpired: Boolean; TimePeriod: string);

procedure CancelHistogramData(DataId: Integer);


Instead of returned data points as a function of time as with the function GetHistoricalData, histograms return data as a function of price level.

The fields of InstrumentSpec are of record type TIABInstrumentSpecItem




procedure CancelHistoricalData(DataId: Integer);


Cancels a previous call to GetHistoricalData. This applies when the initial GetHistoricalData request included the KeepUpdated paramater was set to true, or when a data request was made but not fulfilled after some time.




procedure GetHistoricalTicks(DataId: Integer; Contract: TIABContract; StartDateTime, EndDateTime, WhatToShow: string; NumberOfTicks, UseRTH: Integer;
      IgnoreSize: Boolean; MiscOptions: TIABTagValueArray);

procedure GetTickByTickData(DataId: Integer; Contract: TIABContract; TickType: TIABTickType; NumberOfTicks: Integer; IgnoreSize: Boolean);

procedure CancelTickByTickData(DataId: Integer);

For receiving a Time and Sales stream, both historical data (max 1000) and current stream. Note that this new version (2019) of tick data, delivers a full and complete stream of Time and Sales. The older tick methods gave the summarized version.

The GetHistoricalTicks method will return the history and then continue with the live stream. The GetTickByTickData method goes straight to live stream data. Only 1 stream at any point is accepted, and you must call CancelTickByTickData to terminate the current stream before requesting another.


The MiscOptions param is not used (set to nil).

The stream is returned in the OnHistoricalTickData event, and the OnTickByTickData event.
  TIABContract = record
    ContractId: Integer;
    Symbol: string;
    SecurityType: TIABSecurityType;
    LastTradeDateOrContractMonth: string;
    Strike: Double;
    Right: TIABRight;
    Multiplier: string;
    Exchange: string;
    PrimaryExchange: string; // pick an actual (ie non-aggregate) exchange that the contract trades on. DO NOT SET TO SMART.
    Currency: string;
    LocalSymbol: string;
    TradingClass: string;
    IncludeExpired: Boolean;
    SecIdType: string; // CUSIP;SEDOL;ISIN;RIC
    SecId: string;
    ComboLegsDescrip: string;
    ComboLegList: TIABComboLegArray;
    DeltaNeutralContract: TIABDeltaNeutralContract;
  end;



Two helper methods are available for TIABContracts:

  InitIABContract(var contract: TIABContract); and
  FillContractFromOrder(Order: TIABOrder; var Contract: TIABContract);






procedure GetFundamentalData(DataId: Integer; Order: TIABOrder; ReportType: string);


For receiving Reuters global fundamental market data. Please note that you must set up a subscription to Reuters Fundamentals through the Market Data section of Account Management before you can receive data.

You can receive data via three reports: Estimates (estimates), Financial Statements (finstat) and Summary (snapshot). Reports are sent via XML.

You can also request fundamental ratios using the tickType ttFundamentRatios. Ratios will be sent as a form of TAG=VALUE;TAG2=VALUE2 ...." string in the the OnTickGeneric event. TAGs include: (long list - see the TWS help for specifics);

Data is returned in the OnFundamentalData event. The event is stopped with a call to CancelFundamentalData



procedure CancelFundamentalData(DataId: Integer);


Cancels a previous call to GetFundamentalData




procedure RequestHeadTimestamp(TickerId: Integer; InstrumentSpec: TIABInstrumentSpecItem; WhatToShow: string; UseRTH, IncludeExpired, FormatDate: Boolean);

procedure CancelHeadTimestamp(TickerId: Integer);


Returns the timestamp of earliest available historical data for a contract and data type.

Generates an event OnHeadTimestamp




procedure GetCurrentTime;


Request the current time from the TWS. Result is returned in the OnCurrentTime event.




function VerifyOrder(Order: TIABOrder): Integer;

This method and associated events and properties include the functionality of the TWS API "What-If" features, and extend that capability to the testing of orders validity. VerifyOrder is a method that allows a test order to be placed and run through the TWS API, but it will not execute or affect the account. Verified orders do not form any part of the trading on the account - they are simply a test of the parameters, and a successful result will provide commission and margin requirements information.

A successful VerifyOrder will generate an OnVerifiedOrder event.

A Verified Order will be placed into the special VerifiedOrders property list (like the Orders property for Live orders).

A successful verification will set the read only TIABOrder.Verified property set to true, and the fields of the TIABOrder.GetQueryResult method record will contain valid data (commissions and margins information). A failed verification will generate regular API error messages, and the event will not fire.

An order on the VerifiedOrders list can be submitted for placement to regular live status as follows: PlaceOrder( VerifiedOrders[2] );

Verified Orders will remain on the VerifiedOrders List, and the VerifiedOrders list can be used as a place to store inactive Order type templates.



procedure GetImpliedVolatility(DataID: Integer; Order: TIABOrder; OptionPrice, UnderPrice: Double);
procedure GetOptionPrice(DataID: Integer; Order: TIABOrder; Volatility, UnderPrice: Double);
procedure CancelImpliedVolatility(DataId: Integer);
procedure CancelOptionPrice(DataId: Integer);


GetImpliedVolatility calculates the Implied Volatility based on the user-supplied option and underlying prices. Order is the option contract, optionPrice is the price of the option, underPrice is the price of the underlying of the option. The calculated implied volatility is returned by OnTickOptionComputation event with tick type ttCustomOptionComp. This request is cancelled with the CancelImpliedVolatility method.
The following tick types return values for the Greeks (delta, gamma, vega, theta), the underlying price, pvDividend and the stock and option reference price when requested: ttBidOptionComp, ttAskOptionComp, ttLastOptionComp, ttModelOption.

GetOptionPrice calculates the option price and greek values based on a user-supplied implied volatility and underlying prices. Order is the option contract, Volatility is the user-supplied implied volatility value, underPrice is the price of the underlying of the option. The calculated option price and greek values are returned by OnTickOptionComputation in the new tick type ttCustomOptionComp. This request is cancelled with the CancelOptionPrice method.




procedure RequestGlobalCancel;
Does a global order cancel request.



procedure RequestMarketDataType(DataType: TIABMarketDataType);


TWS sends a marketDataType(type) callback to the API, where type is set to Frozen or RealTime, to announce that market data has been switched between frozen and real-time. This notification occurs only when market data switches between real-time and frozen. The marketDataType( ) callback accepts a reqId parameter and is sent per every subscription because different contracts can generally trade on a different schedule.

During normal trading hours, the API receives real-time market data. If you use the reqMarketDataType(frozen) call, you are telling TWS to automatically switch to frozen market data after the close. Then, before the opening of the next trading day, market data will automatically switch back to real-time market data.

Response is delivered in the OnMarketDataType event.

TIABMarketDataType = (mdtUnset, mdtRealTime, mdtfrozen, mdtDelayed, mdtNone);



procedure RequestMarketDepthExchanges;


Response is delivered in the OnDepthMarketDataDescripItem event.



procedure RequestMarketRule(MarketRuleId: Integer);


Response is delivered in the OnMarketRule event.



procedure RequestMatchingSymbols(DataId: Integer; Pattern: string);


Response is delivered in the OnSymbolSample event.



procedure RequestNewsArticle(DataId: Integer; ProviderCode, ArticleId, NewsArticleOptions: string);


Response is delivered in the OnNewsArticle event.



procedure RequestNewsProviders;


Response is delivered in the OnNewsProvider event.



procedure RequestHistoricalNews(DataId, conId: Integer; ProviderCodes, StartDateTime, EndDateTime: string; TotalResults: Integer; HistoricalNewsOptions: string);


ProviderCodes is a '+' separated list of provider codes. StartDateTime marks the (exclusive) start of the date range. The EndDateTime marks the (inclusive) end of the date range. TotalResults is the maximum number of headlines to fetch (1 - 300). HistoricalNewsOptions is reserved for internal use, and should be a '';

Response is delivered in the OnHistoricalNews event.



procedure RequestPnL(DataId: Integer; Account, ModelCode: string);

procedure CancelPnL(DataId: Integer);

Response is delivered in the OnProfitLoss event.



procedure RequestPnLSingle(DataId: Integer; Account, ModelCode: string; ConId: Integer);

procedure CancelPnLSingle(DataId: Integer);

Response is delivered in the OnProfitLossSingle event.



procedure RequestScan(ScanId: Integer; Criteria: TIABScanCriteria);


This is handled internally by the TIABScan object;



procedure RequestSecDefOptParams(DataId: Integer; UnderlyingSymbol, FutFopExchange: string; UnderlyingSecType: TIABSecurityType; UnderlyingConId: Integer);


Response is delivered in the OnSecurityDefinitionOptionalParameter event.
Response is delivered in the OnSecurityDefinitionOptionalParameterEnd event.



procedure RequestSoftDollarTiers(DataId: Integer);


Response is delivered in the OnSoftDollarTiers event.



procedure RequestSmartComponents(DataId: Integer; bboExchange: string);


Response is delivered in the OnSmartComponent event.



procedure RequestUserInfo(DataID: Integer);

Requests the user info ?? what ever that is??

Response is delivered in the OnUserInfo event.



procedure RequestWSHorizonEventsData(DataID: Integer; WSHRequestSpecs: TIABWSHorizonEventData);

Response is delivered in the OnWsHorizonEvents event. The specifics of the TIABWSHorizonEventData record fields are shown in the IAB API help at

  TIABWSHorizonEventData = record
    ConID: Integer;
    Filter: string;
    FillWatchList: Boolean;
    FillPortfolio: Boolean;
    FillCompetitors: Boolean;
    StartDate: string;
    EndDate: string;
    TotalLimit: Integer;
  end;




procedure RequestWSHorizonMetaData(DataID: Integer);

Requires a subscription to the Wall Street Horizon service.

Response is delivered in the OnWsHorizonMeta event.



TIABSocket Events



property OnAccountTime = procedure(Sender: TObject; TimeStamp: string) of object;

This event has the account time from the TWS. It updates each minute or so. To start this event, call the GetAccountUpdates method. To stop the flow of data, call CancelAccountUpdates.



property OnAccountValue = procedure(Sender: TObject; Index: Integer) of object;

This event has the Index of the value updated in the AccountValue property. Use the Index value in the AccountValues property like so;

  AccountString := AccountValue[Index];

The value returned is in the format Key Data Currency string, separated by a single space between elements. See the AccountValue property for the defined Keys.

See the GetAccountUpdates and CancelAccountUpdates methods.



property OnConnectionState = procedure(Sender: TObject; State: TIABConnection) of object;

  TIABConnection = (twsClosed,twsConnecting,twsReady,twsFailed);

This event updates as the state of the connection to TWS changes. States are Note: This reflects the connection state between your app and the TWS only. In most cases, this will be across the local host, and not likely to encounter many errors. But you may also run your app and the TWS remotely, and net errors will be more prevelant.
The connection from TWS to IAB's server is something completely different. We are not able to have direct knowledge of this connection, however its where the real failures will occur. The TWS does send us some error messages after a time out period though.


property OnEndOfStreamRead: TNotifyEvent;

** This is the most important event in the API. **

Your application will run much better when using this event to process data and the trading logic.

This event fires at the end of each successful stream read. Note that each stream chunk from the socket can be fragmented, or a truncation of several pieces of data. i.e. the stream may contain several changes to a market data's bid price and size, and the OnTickPrice & OnTickSize & OnTickPrceAndSize events will fire several times accordingly. Using this event, you can collect the changes to market data, and then process the final changes from here.

The TWS API can only operate using asynchronous code design for function / procedure calls and events. Any attempt at synchronous code, will cause the TWS API to block or loose its state and fail to operate correctly. This is most relevant with code that automatically generates new commands from data received - getting itself into a nested or circular state.

For best results: On the complex events, like history, or place where you might want to add complex code, you should instead do this: Capture the data only in the other events. Then use this event to process the data and decide trading logic.

If your code logic is to generate new orders automatically based on bid/ask and price changes, or automatically placing closing orders after a fill, then you CANNOT do those new orders in this event here. Instead you must use this event to save the required actions to local variables, and post yourself a message. That allows this event to complete and return, so the TWS API goes into an idle state and ready to accept the next command. In that message handler, make the commands for new orders. The purpose here is to allow the data thread and message queues from the TWS to finish and complete its tasks, and return to idle state, before issuing the TWS with new tasks. You cannot have code that compounds commands within events from the TWS - it will lock up. See the Sample app code for a PostMessage example.

There is a sample of this procedure in the IABSocket demo program - see the UM_DOIT and associated code.



property OnError = procedure(Sender: TObject; TempId, ErrorCode: Integer; ErrorMsg: string) of object;

TempId will be the Order's TempId when known. See the TWS help for a description of codes and messages. Codes above 500 apply to the API.

With the use of TIABOrder AdvancedErrorOverride property, the ErrorMsg will include an appended JSON string. The appended second error message string is seperated with ">>>". It is reported to be a JSON text, so expect embedded LF & CR characters.



property OnInstrumentSpecDetails = procedure(Sender: TObject; Index: Integer) of object;

property OnInstrumentSpecDetailsReady = procedure(Sender: TObject; DataID: Integer) of object;
The OnInstrumentSpecDetails event fires after a call to GetInstrumentSpecs. The Index refers to the TIABInstrumentSpecItem in the InstrumentSpecs property. The event will fire in repetition to each item. After the last item, the OnInstrumentSpecDetailsReady event will fire, and signifies all data has been received.



property OnBondSpecDetails = procedure(Sender: TObject; Index: Integer) of object;

This event fires after a call to GetInstrumentSpecs, using the bonds Cusip or ISIN in the symbol field. The Index refers to the TIABBondSpecItem in the BondSpecs property.



property OnMarketDepth = procedure(Sender: TObject; DataId, Index, Operation, Side: Integer; Size: BigDecimal; Price: Double) of object;

This event occurs in response to the GetMarketDepth method. The TWS decides if this event, or the OnMarketLevel2 gets the data, depending on the symbol requested.
These constants are defined for use in OnMarketDepth / OnMarketLevel2

OPERATION_INSERT = 0; OPERATION_UPDATE = 1; OPERATION_DELETE = 2; SIDE_ASK = 0; SIDE_BID = 1;

DataId is the value of DataId passed in the GetMarketDepth method.
Index is the row that is to altered. Index is 0 based.
Operation as per above.
Side as per above.
Size is the quantity. Note: This will be of type Double, or BigDecimal, depending on your compiler choices.
Price is just that.



property OnMarketLevel2 = procedure(Sender: TObject; DataId, Index, Operation, Side: Integer; Size: BigDecimal; Price: Double; MMId: string; SmartDepth: Boolean) of object;

This event occurs in response to the GetMarketDepth method. The TWS decides if this event, or the OnMarketDepth gets the data, depending on the symbol requested.
These constants are defined for use in OnMarketDepth / OnMarketLevel2

OPERATION_INSERT = 0; OPERATION_UPDATE = 1; OPERATION_DELETE = 2; SIDE_ASK = 0; SIDE_BID = 1;

DataId is the value of DataId passed in the GetMarketDepth method.
Index is the row that is to altered. Index is 0 based.
Operation as per above.
Side as per above.
Size is the quantity. Note: This will be of type Double, or BigDecimal, depending on your compiler choices.
Price is just that.
MMid is the string abbreviation for the Market Maker.
SmartDepth is if the data is from a combining Smart exchange data. Set this on/off with SmartDepthMarketData



property OnOpenOrder = procedure(Sender: TObject; Order: TIABOrder) of object;

This event occurs in response to the GetOpenOrdersClient, GetOpenOrdersAccount, GetExecutions methods. Each order sent from the TWS is added to the Orders property automatically. See also the OnExecutionDetailsReady event.



property OnOrderStatus = procedure(Sender: TObject; Order: TIABOrder; Status: TIABOrderState) of object;

Notify any change to an order's state. Values of State are

  TIABOrderState = (osPendSubmit,osPendCancel,osPreSubmit,osSubmitted,osCancelled,osFilled);

Note: An orders state may change - without any change in the filled quantity. And an Order may fill in any state. Do not rely on the State as an indication of an orders fill progress. i.e. A partial fill can be pending, submitted or filled. The Cancelled and Filled states indicate that the Order is Completed, and these are the only reliable means to determine state.

The filled quantity on an order can be found by checking the properties of the Order parameter. These include

  property Changed: Boolean;
  property Completed: Boolean;
  property TempId: Integer;
  property PermId: Integer;
  property Filled: BigDecimal; // Double;
  property Remaining: BigDecimal; // Double;
  property FillPrice: Double;
  property LatestFillQty: BigDecimal; // Double;
  property LatestFillPrice: Double;
See the TIABOrder object for a complete list and description.

The data types of Filled, Remaining, Latestfill properties: BigDecimal or Double, depend on your compiler choices.



property OnPortfolioUpdate = procedure(Sender: TObject; Index: Integer) of object;

This event is fired for each change or addition the TWS makes to the Portfolio. The Index parameter is used in the Portfolio property. Check the fields of each TIABPortfolioItem to read the values. i.e. NewHoldings := Portfolio[Index].Quantity;

The fields of a TIABPortfolioItem are:

  Symbol: string;
  Local: string;
  SecurityType: TIABSecurityType;
  Expiry: string;
  Strike: Double;
  Right: TIABRight;
  Currency: string;
  Position: BigDecimal;//Double;
  MarketPrice: Double;
  MarketValue: Double;
  AverageCost: Double;
  UnrealizedPNL: Double;
  RealizedPNL: Double;
  AccountName: string;
  InstrumentId: Integer;
  Multiplier: string;
  PrimaryExchange: string;
  TradingClass: string;



property OnRebuildFromTWS = TNotifyEvent;

This event will fire after a call to RebuildFromTWS. It will be called for each new element being updated, and may include several calls per order when a partial fill occurred. The OnExecution and OnOpenOrder events are disabled whilst the rebuild is happening.

Note that there is no end of rebuild marker or event, and this event may be called many times before a full rebuild is complete. After all data has been recieved, the TIABSocket.Orders property will reflect the TWS version of orders for this client.


property OnTickPrice = procedure(Sender: TObject; DataId: Integer; TickType: TIABTickType; Price: Double; TickAttrib: TIABTickAttrib) of object;



This event is started by a call to GetMarketData method. DataId is the value used to identify this stream. TickType identifies the type of tick data to amend, and Price is the new value.
When running against TWS version 835.0 or higher, API version 8.2 and above (client version 17 and above) supports the reporting of whether a market data price tick is eligible for automatic execution. On occasion, a bid or offer price tick is not available for automatic execution, which means that the market maker may or may not fill an order against it. TWS displays such price ticks in a light purple color to distinguish them, and the AutoExecute field passes this detail into the API. When tick type is either a ttBid or ttAsk, a AutoExecute will be a 1 when this price is eligible for automatic execution and a value of 0 when is not eligible. ttClose and ttLast price ticks will always have a value of 0.

TIABTickType = (ttBidSize,ttBid,ttAsk,ttAskSize,ttLast,ttLastSize,ttHigh,ttLow,ttVolume,ttClose,ttBidOptionComp,ttAskOptionComp,ttLastOptionComp,ttModelOption, ttOpen,ttLow13Week,ttHigh13Week,ttLow26Week,ttHigh26Week,ttLow52Week,ttHigh52Week,ttAvgVolume,ttOpenInterest,ttOptionHistoricalVol,ttOptionImpliedVol, ttOptionBidExch,ttOptionAskExch,ttOptionCallOpenInterest,ttOptionPutOpenInterest,ttOptionCallVolume,ttOptionPutVolume,ttIndexFuturePremium,ttBidExch, ttAskExch,ttAuctionVolume,ttAuctionPrice,ttAuctionImbalance,ttMarkPrice, ttBidEFPComp,ttAskEFPComp,ttLastEFPComp,ttOpenEFPComp,ttHighEFPComp,ttLowEFPComp,ttCloseEFPComp, ttLastTimeStamp, ttShortable, ttFundamentalRatios, ttRtVolume, ttHalted, ttBidYeild, ttAskYeild, ttLastYeild, ttCustomOptionComp, ttTradeCount, ttTradeRate, ttVolumeRate, ttLastRTHTrade, ttRtHistoricalVol,ttIbDividends,ttBondFactorMultiplier,ttRegulatoryImbalance,ttNewsTick, ttShortTermVolume3Min,ttShortTermVolume5Min,ttShortTermVolume10Min, ttDelayedBid,ttDelayedAsk,ttDelayedLast,ttDelayedBidSize,ttDelayedAskSize,ttDelayedLastSize,ttDelayedHigh,ttDelayedLow,ttDelayedVolume,ttDelayedClose,ttDelayedOpen, ttRtTrdVolume,ttCreditmanMarkPrice,ttCreditmanSlowMarkPrice, ttDelayedBidOptionComputation,ttDelayedAskOptionComputation,ttDelayedLastOptionComputation,ttDelayedModelOptionComputation, ttLastExch,ttLastRegTime,ttFuturesOpenInterest, ttAvgOptVolume,ttDelayedLastTimestamp,ttShortableShares, ttDelayedHalted, ttReuters2MutualFunds, ttETFNavClose, ttETFNavPrior, ttETFNavBid, ttETFNavAsk, ttETFNavLast, ttETFNavFrozenLast, ttETFNavHigh, ttETFNavLow, ttNotSet);

TIABTickAttrib = record
  CanAutoExecute, PastLimit: Boolean;
end;



property OnTickSize = procedure(Sender: TObject; DataId: Integer; TickType: TIABTickType; Size: BigDecimal) of object;

This event is started by a call to GetMarketData method. DataId is the value used to identify this stream. TickType identifies the type of tick data to amend, and Size is the new value.
The ttLastTimeStamp value is delivered here also, and the Size value represents a ctime in seconds. To change a ctime to a TDateTime value with
  TimeStamp := Size / 86400 + 25569;

Size will be of type Double, or BigDecimal, depending on your compiler choices.

See TIABTickType above.



property OnTickPriceAndSize = procedure(Sender: TObject; DataId: Integer; TickType: TIABTickType; Price: Double; Size: BigDecimal) of object;
This event is started by a call to GetMarketData method. DataId is the value used to identify this stream. TickType identifies the type of tick data to amend, and Size is the new value.

Note: This event fires in addition to the individual OnTickPrice & OnTickSize events. It is best to select either this combination event, or the two seperated events. Otherwise information will become duplicated. Also experience shows that collecting the data from each of the seperate Price and Size events, and then acting on it in the OnEndOfStreamRead event will achieve the same result as this combination event.

Size will be of type Double, or BigDecimal, depending on your compiler choices.

See TIABTickType above.



property OnTickOptionComputation = procedure(Sender: TObject; DataId: Integer; TickType: TIABTickType; ImpliedVol, Delta, OptPrice, pvDividend, Gamma, Vega, Theta, undPrice: Double) of object;

This event is started by a call to GetMarketData method and applies to Option orders and the resulting computed values. Also the methods GetImpliedVolatility and GetOptionPrice will return data in this event. DataId is the value used to identify this stream. Any of the values of ImpliedVol or Delta and Greek values may also return a null value (defined as UNSET_DOUBLE). The TWS may send these place holder UNSET_ x if a value is "not yet computed". This condition should to be checked for in code with each event.
The following tick types return values for the Greeks (delta, gamma, vega, theta), the underlying price, pvDividend and the stock and option reference price when requested: ttBidOptionComp, ttAskOptionComp, ttLastOptionComp, ttModelOption.

See TIABTickType above.



property OnTickGeneric = procedure(Sender: TObject; DataId: Integer; TickType: TIABTickType; Value: Double) of object;

This is a multipurpose event, for a variety of special ticks and values. Some are related to optional extended Market Data parameters (see GetMarketData).
The Tick type ttShortable returns through here. See GetMarketData on details of calling this. This code will give details of a shortable item and the available shares for shorting.

  if TickType = ttShortable then
    begin
      if Value > 2.5 then  // 3.0
        // There are at least 1000 shares available for a short sale
      else if Value > 1.5 then  // 2.0
        // This contract will be available for short sale if shares can be located
      else if Value > 0.5 then  // 1.0
        // Not available for short sale
      else
        // unknown value
    end;



property OnTickString = procedure(Sender: TObject; DataId: Integer; TickType: TIABTickType; Value: string) of object;

This works with the other tick type events above (see GetMarketData). Some tick details are returned as strings. The full list of available tick types, and which event they return through, is here: TWS tick types and responses.



property OnTickEFP = procedure(Sender: TObject; DataId: Integer; TickType: TIABTickType;
      BasisPoints, TotalDividends, DividendImpact, DividendsToExpiry: Double;
      HoldDays: Integer; FutureExpiry, BasisPointsString: string) of object;

This event fires in response to a request for GetMarketData method, with a TIABTickType in this range:
ttBidEFPComp,ttAskEFPComp,ttLastEFPComp,ttOpenEFPComp,ttHighEFPComp,ttLowEFPComp,ttCloseEFPComp



property OnTickReqParams = procedure(Sender: TObject; TickerId: Integer; MinTick: Double; bboExchange: string; SnapshotPermissions: Integer) of object;

Described as: tick with BOO exchange and snapshot permissions.

This event fires in response to a request for GetMarketData. Not certian exactly what is needed to get a response here.



property OnCurrentTime = procedure(Sender: TObject; DateTime: TDateTime) of object;

This event is created by a call to GetCurrentTime method. The DateTime is the current TWS date and time.



property OnNewsBulletin = procedure(Sender: TObject; MsgID: Integer; Bulletin, NewsSource: string) of object;

This event is started by a call to GetNewsBulletins method. MsgId is used to identify the message. Bulletin is the actual message, and NewsSource will usually be an exchange name.



property OnExchangeStatus = procedure(Sender: TObject; MsgID: Integer; Status: TIABExchangeStatus; Bulletin, NewsSource: string) of object;

This event is started by a call to GetNewsBulletins method. MsgId is used to identify the message. Status is the condition of the particuliar exchange. Bulletin is the actual message, and NewsSource will usually be an exchange name.

TIABExchangeStatus = (esUnknown,esAvailable,esUnAvailable);



property OnExecution = procedure(Sender: TObject; Order: TIABOrder) of object;

This event is fire for calls to GetExecutions, GetOpenOrdersAccount, GetOpenOrdersClient. The Order parameter is the affected order. The Executions property of the Order has this execution attached, and will be the highest of the ExecutionsCount.



property OnManagedAccounts = procedure(Sender: TObject; Details: string) of object;

Event for a call to GetManagedAccounts.



property OnReceiveFADetail = procedure(Sender: TObject; FADataType: TIABFADataType; XmlDetails: string) of object;

property OnReplaceFAEnd = procedure(Sender: TObject; DataID: Integer; DataStr: string) of object;

TIABFADataType = (faGroups,faProfiles,faAliases);
TIABFADataTypeStr: array [TIABFADataType] of string = ('GROUPS','PROFILES','ALIASES');

Event for a call in response to RequestFA and ReplaceFA methods.



property OnRerouteMktDataReq = procedure(Sender: TObject; DataId, ConId: Integer; Exchange: string) of object;

property OnRerouteMktDepthReq = procedure(Sender: TObject; DataId, ConId: Integer; Exchange: string) of object;

These two are described as events in the API, but the initiating method calls described in the help (below), are missing and not defined as functions of the API.

void rerouteMktDataReq(int reqId, int conId, string exchange);
void rerouteMktDepthReq(int reqId, int conId, string exchange);




property OnHeadTimestamp = procedure(Sender: TObject; DataId: Integer; HeadTimestamp: string) of object;

HeadTimestamp is the beginning of data for contract for specified data type - a date and time in string format. This event is for a call in response to RequestHeadTimestamp method.



property OnHistoricalData = procedure(Sender: TObject; DataId, Item, Count: Integer; HistoricalChartDataElement: TIABHistoricalChartData) of object;
property OnHistoricalDataUpdate = procedure(Sender: TObject; DataId: Integer; HistoricalChartDataElement: TIABHistoricalChartData) of object;

  TIABHistoricalChartData = record
    Date: string;
    Open, High, Low, Close: Double;
    WAP, Volume: BigDecimal; // Double;
    TradeCount: Integer;
    HasGaps: Boolean;
  end;


Event for a call in response to
GetHistoricalData methods. See the GetHistoricalData for details. The IAB will deliver the entire data request in one blob of data via OnHistoricalData, but it often takes many seconds of idle waiting before the IAB delivers this. This event will fire once for every line of data, and the Item (n) and total Count will reveal the size of the data blob. The final line in the datablob has a Date set to the word 'finished', and other values set to -1;

The OnHistoricalDataUpdate only fires to append a new line of data onto the initial blob. This is dependent on the KeepUpdated parameter in the initial GetHistoricalData request.

WAP and Volume will be of type Double, or BigDecimal, depending on your compiler choices.

NOTE: if the TIABHistoricalData object is utilized and active, then it overrides these two events described here, and the OnStoredHistoryItemUpdated event takes thier place.



property OnHistoricalSession = procedure(Sender: TObject; DataId, Item, Count: Integer; StartDateTime, EndDateTime, TimeZone: string; HistoricalSessionElement: TIABHistoricalSession) of object;

  TIABHistoricalSession = record
    StartDateTime: string;
    EndDateTime: string;
    RefDate: string;
  end;


This event is controlled through the DataBasis: TIABHistoricalDataType parameter in the GetHistoricalData method. Set it to cdShedule.
This event is expected to return multiple times, and each sequential event is numbered with the Item (n) of total Count.



property OnHistogramData = procedure(Sender: TObject; DataId, Item, Count: Integer; Price: Double; Size: BigDecimal) of object;

This event is a response to the RequestHistogramData method. This event is expected to return multiple times, and each sequential event is numbered with the Item (n) of total Count.



property OnHistoricalNews = procedure(Sender: TObject; DataId: Integer; Time, ProviderCode, ArticleId, Headline: string) of object;

property OnHistoricalNewsEnd = procedure(Sender: TObject; DataId: Integer; HasMore: Boolean) of object;

Event for a call in response to RequestHistoricalNews methods. News articles are delivered one at a time OnHistoricalNews, while the OnHistoricalNewsEnd, HasMore value will indicate if the last item has been delivered.




property OnRealTimeData = procedure(Sender: TObject; DataId: Integer; RealTimeDataElement: TIABRealTimeChartData) of object;

  TIABRealTimeData = record
    DateTime: TDateTime
    Open, High, Low, Close: Double;
    WAP, Volume: BigDecimal; // Double;
    TradeCount: Integer;
  end;


Event for a call in response to GetRealTimeData methods. See the GetRealTimeData for details.

WAP and Volume will be of type Double, or BigDecimal, depending on your compiler choices.



property OnHistoricalTickData = procedure(Sender: TObject; DataID: Integer; TickData: TIABTickData) of object;

property OnTickByTickData = procedure(Sender: TObject; DataID: Integer; TickData: TIABTickData) of object;

The record type TIABTickData holds the tick history and live data. The TIABTickData is a composite record of all types of returned data, so check the TickType field to identify which fields apply.


Associated data types for this method:

  TIABTickDataType = (tdNone, tdLast, tdAllLast, tdBidAsk, tdMidPoint);

  TIABTickData = record
    TickType: TIABTickDataType;
    Time: TDateTime;
    // tdLast, tdAllLast
    PastLimit: Boolean;
    Unreported: Boolean;
    Price: Double;
    Size: BigDecimal; // Double; Integer;
    Exchange: string;
    SpecialConditions: string;
    // tdBidAsk
    BidPrice: Double;
    AskPrice: Double;
    BidSize: BigDecimal; // Double; Integer;
    AskSize: BigDecimal; // Double; Integer;
    BidPastLow: Boolean;
    AskPastHigh: Boolean;
    // tdMidPoint
    MidPoint: Double;
  end;





property OnFundamentalData = procedureSender: TObject; DataID: Integer; xmlStrData: string) of object;
Event for a call in response to GetFundamentalData methods. See the GetFundamentalData for details. Cancel this event with CancelFundamentalData

The report is in an XML format in the xmlStrData parameter.



property OnOpenOrderDetailsReady = procedureSender: TObject) of object;
The event will fire at the completion of a successful call of the following methods. GetOpenOrdersClient, GetOpenOrdersAccount, BindTWSOrdersToClient.



property OnAccountDetailsReady = procedureSender: TObject; AccountName: string) of object;
Event for a call in response to GetAccountUpdates method. Note that this event triggers just once per application run, only after the initial call to GetAccountUpdates.



property OnExecutionDetailsReady = procedureSender: TObject; RequestID: Integer) of object;
Event at the completion of the GetExecutions method.



property OnCommissionReport = procedure(Sender: TObject; CommissionReport: PTIABCommissionReport) of object;

Event for incoming Commision reports. The Commission report is a pointer type to the record type TIABCommissionReport.

  TIABCommissionReport = record
    ExecID: string;
    Commission: Double;
    Currency: string;
    RealizedPNL: Double;
    Yield: Double;
    YieldRedemptionDate: Integer; // YYYYMMDD format
  end;



property OnMarketDataType = procedure(Sender: TObject; DataID: Integer; MarketDataType: TIABMarketDataType) of object;

Event for incoming response to the RequestMarketDataType.




property OnDepthMarketDataDescripItem = procedure(Sender: TObject; DataID, Item, Count: Integer; DepthMarketDataDescrip: TIABDepthMarketDataDescripItem) of object;

Event for incoming response to the RequestMarketDepthExchanges.




property OnMarketRule = procedure(Sender: TObject; RuleId, Item, Count: Integer; LowEdge, Increament: Double) of object;

Event for incoming response to the RequestMarketRule.




property OnSymbolSample = procedure(Sender: TObject; DataID, Item, Count: Integer; SymbolDerivative: TIABSymbolDerivativeSpecItem) of object;

Event for incoming response to the RequestMatchingSymbols.

  TIABSymbolDerivativeSpecItem = record
    ContractId: Integer;
    Symbol: string;
    SecurityType: TIABSecurityType;
    Currency: string;
    PrimaryExchange: string;
    DerivativeSecCount: Integer;
    DerivativeSecTypes: string;
    Description: string;
    IssuerID: string;
  end;


DerivativeSecTypes will be a space delimited string, if any.



property OnNewsArticle = procedure(Sender: TObject; DataId, ArticleType: Integer; ArticleText: string) of object;

Event for incoming response to the RequestNewsArticle.




property OnNewsProvider = procedure(Sender: TObject; Item, Count: Integer; ProviderCode, ProviderName: string) of object;

Event for incoming response to the RequestNewsProviders.




property OnProfitLoss = procedure(Sender: TObject; DataId: Integer; DailyPnL, UnrealizedPnL: Double) of object;

Event for incoming response to the RequestPnL.




property OnProfitLossSingle = procedure(Sender: TObject; DataId, Pos: BigDecimal; DailyPnL, UnrealizedPnL, Value: Double) of object;

Event for incoming response to the RequestPnLSingle.

Pos parameter will be of type Double, or BigDecimal, depending on your compiler choices.




property OnSecurityDefinitionOptionalParameter = procedure(Sender: TObject; DataId: Integer; Exchange:string; UnderlyingConId: Integer; tradingClass, multiplier, expirations, strikes: string) of object;

property OnSecurityDefinitionOptionalParameterEnd = procedure(Sender: TObject; DataId: Integer;) of object;

Event for incoming response to the RequestSecDefOptParams.





property OnSoftDollarTiers = procedure(Sender: TObject; DataID, Item, Count: Integer; Name, Value, DisplayName: string) of object;

Event for incoming response to the RequestSoftDollarTiers.




property OnNewsTick = procedure(Sender: TObject; TickerID: Integer; TimeStamp: TDatetime; ProviderCode, ArticleId, Headline, ExtraData: string) of object;

Event for incoming response to the GetNewsBulletins.




property OnSecurityDefinitionOptionalParameter = procedure(Sender: TObject; DataId: Integer; Exchange:string; UnderlyingConId: Integer; tradingClass, multiplier, expirations, strikes: string) of object;

property OnSecurityDefinitionOptionalParameterEnd = procedure(Sender: TObject; DataId: Integer) of object;

Event for incoming response to the RequestSecDefOptParams.




property OnSmartComponent = procedure(Sender: TObject; DataId: DataId, Item, Count, BitNumber: Integer; Exchange, ExchangeLetter: string) of object;

Event for incoming response to the RequestSmartComponents.




property OnWsHorizonEvents = procedure(Sender: TObject; DataID: Integer; DataStr: string) of object;

property OnWsHorizonMetaEvent = procedure(Sender: TObject; DataID: Integer; DataStr: string) of object;

Event for incoming response to the RequestWSHorizonEventsData procedure.



property OnStoredHistoryItemUpdated = procedure(Sender: TObject; ItemIndex, Offset, Count: Integer>) of object;

This event is for the arrival of new and updated data when the TIABHistoricalData object is installed and the StoredHistoricalData property is set true.
*NOTE* This event (when StoredHistoricalData property is set true) will replace the existing OnHistoricalData and OnHistoricalDataUpdate events.

ItemIndex parameter is the array value used within the TIABHistoricalData object.

Offset is the index (zero based) at which the new history line data (a single set of open, high, low, close, etc data) was added. When the Count is 0, the Offset value is the index of the updated line data (normally the last line in the array).

Count is the number of new lines. This will also report zero when a dataline has been updated - usually the newest data line as new trades occur or price changes.


This event prototype is not included in the VCL and Object inspector (is declared public, not published). Instead the event must be assigned manually as follows. Create and add the event procedure to the main form: Under the private or public section add this procedure:

procedure StoredHistoryItemUpdated(Sender: TObject; ItemIndex, Offset, Count: Integer);

In the OnFormCreate event, add the line: IABSocket1.OnStoredHistoryItemUpdated := StoredHistoryItemUpdated;




TIABPortfolio object


The TIABPortfolio object is the Portfolio property of TIABSocket. It maintains an array of TPortfolioItem records. New additions are made as they arrive from the TWS. The TWS will send updates as the account holdings change, and each TIABPortfolioItem will be adjusted accordingly. A call to GetAccountUpdates starts the flow from TWS. Flow is stopped with CancelAccountUpdates.

TIABPortfolio has these methods and properties to work with TIABPortfolioItem(s).

  TIABPortfolio = class(TPersistent)
    function Add(IABPortfolioItem: TIABPortfolioItem): Integer;
    procedure Insert(Index: Integer; IABPortfolioItem: TIABPortfolioItem);
    procedure Delete(Index: Integer);
    function Find(IABPortfolioItem: TIABPortfolioItem): Integer;
    property Count: Integer;
    property Items[Index: Integer]: TIABPortfolioItem;
  end;


The Items property is a zero based index of each TIABPortfolioItem. Use Add, Delete, Insert, Find to manipulate the items.

Each TIABPortfolioItem has this structure

    TIABPortfolioItem = record
    Symbol: string;
    Local: string;
    SecurityType: TIABSecurityType;
    Expiry: string;
    Strike: Double;
    Right: TIABRight;
    Currency: string;
    Position: BigDecimal;//Double;
    MarketPrice: Double;
    MarketValue: Double;
    AverageCost: Double;
    UnrealizedPNL: Double;
    RealizedPNL: Double;
    AccountName: string;
    InstrumentId: Integer;
    Multiplier: string;
    PrimaryExchange: string;
    TradingClass: string;
  end;




property OnScannerParam = procedure(Sender: TObject; Parameters: string) of object;

Event for a call to GetScannerParameters of the TIABScanner object.

The Parameters is a string of XML formatted text. You will need to parse this to get the data from it. The format is as follows
<?xmlVersion="1.0" encoding="UTF-8"?>
<ScanParameterResponse>
<InstrumentList>
  list of instruments, including STK
</InstrumentList>
<LocationTree>
  list of locations with their own trees, including STK.NYSE
</LocationTree>
<ScanTypeList>
  list of scan types with columns, including TOP_PERC_GAIN
</ScanTypeList>
</ScanParameterResponse>
These are described in more detail at TIABScanner.



property OnScannerData = procedure(Sender: TObject; Scan: TIABScan) of object;

Event for a call to NewScan of the TIABScanner object.

This event fire each time the TWS ammends the results of a scan (every 30 seconds or so). Each Scan object holds an array of instruments. Access this like so:

  procedure IABSocket1.OnScannerData(Sender: TObject; Scan: TIABScan);
  var i, j; Integer; s: string; 
  begin
    for i := 0 to Scan.Count -1 do
      begin
        j := Scan.Items[i].Rank;
        s := Scan.Items[i].Symbol;
        ...




property OnVerifiedOrder = procedure(Sender: TObject; Order: TIABOrder) of object;

This event fires in response to a successful VerifyOrder method call. The Order will be stored on the VerifiedOrders property list. The Order's readonly Verified property will be true, and the GetQueryResult method will contain valid information.

See the VerifyOrder method for further details.



property OnDeltaNeutralValidation = procedure(Sender: TObject; DeltaNeutralContract: TIABDeltaNeutralContract) of object;

This event fires in response to conditions of the Option state. The DeltaNeutralContract record contains the following fields.

  TIABDeltaNeutralContract = record
    ConId: Integer;
    Delta, Price: Double;
  end;

The method that should trigger this, is not documented, or lost to old versions and changes of the API:

GetDeltaNeutralValidation(DataId: Integer; DeltaNeutralContract: TIABDeltaNeutralContract);




property OnSnapShotDataEnd = procedure(Sender: TObject; DataID: Integer) of object;

This event fires in response to a successful GetMarketSnapShot method call.



property OnUserInfo = procedure(Sender: TObject; DataID: Integer; UserInfo: string) of object;

This event fires in response to a successful RequestUserInfo method call. Not sure what its means though - possibly branding of the API?



TIABInstrumentSpec object


The TIABInstrumentSpec object is the InstrumentSpec property of TIABSocket. It maintains an array of TInstrumentSpecItem records. New additions are made as they arrive from the TWS. A call to GetInstrumentSpecs creates an OnInstrumentSpecDetails event.

It has these methods and properties to work with the TIABInstrumentSpecItem.

  TIABInstrumentSpec = class(TPersistent)
    function Add(IABInstrumentSpecItem: TIABInstrumentSpecItem): Integer;
    procedure Insert(Index: Integer; IABInstrumentSpecItem: TIABInstrumentSpecItem);
    procedure Delete(Index: Integer);
    function Find(IABInstrumentSpecItem: TIABInstrumentSpecItem): Integer;
    property Count: Integer;
    property Items[Index: Integer]: TIABInstrumentSpecItem;
  end;


The Items property is a zero based index of each TIABInstrumentSpecItem. Use Add, Delete, Insert, Find to manipulate the items.

The fields of a TIABInstrumentSpecItem are:

TIABInstrumentSpecItem = record
  MarketName: string;
  TradingClass: string;
  ContractId: Integer;
  Multiplier: string;
  MinimumTick: Double;
  OrderTypes: TIABOrderTypesSet;
  ValidExchanges: string;
  Symbol: string;
  SecurityType: TIABSecurityType;
  Expiry: string;
  Strike: Double;
  Right: TIABRight;
  Exchange: string;
  Currency: string;
  LocalSymbol: string;
  PriceMagnifier: Integer;
  DataID: Integer;
  UnderConId: Integer;
  LongName: string;
  PrimaryExchange: string;
  ContractMonth: string;
  Industry: string;
  Category: string;
  SubCategory: string;
  TimeZoneID: string;
  TradingHours: string;
  LiquidHours: string;
  EVRule: string;
  EVMultiplier: Double;
  SecIdList: TIABTagValueArray;
  AggGroup: Integer;
  UnderSymbol: string;
  UnderSecType: string;
  MarketRuleIds: string;
  DerivativeSecTypes: string;
  LastTradeTime: string;
  MinSize: BigDecimal;// Double;
  SizeIncrement: BigDecimal;// Double;
  SuggestedSizeIncrement: BigDecimal;// Double;
  FundValues: TIABFundValues;
  LastTradeDate: string;
end;


Fields with type Double, or BigDecimal, are depending on your compiler choices.

The last field above, FundValues is the from the following record:

TIABFundValues = record
  FundName: string;
  FundFamily: string;
  FundType: string;
  FundFrontLoad: string;
  FundBackLoad: string;
  FundBackLoadTimeInterval: string;
  FundManagementFee: string;
  FundClosed: Boolean;
  FundClosedForNewInvestors: Boolean;
  FundClosedForNewMoney: Boolean;
  FundNotifyAmount: string;
  FundMinimumInitialPurchase: string;
  FundSubsequentMinimumPurchase: string;
  FundBlueSkyStates: string;
  FundBlueSkyTerritories: string;
  FundDistributionPolicyIndicator: TIABFundDistributionPolicyIndicator;
  FundAssetType: TIABFundAssetType;
end;

TIABFundDistributionPolicyIndicator = (iabFundDistPolicyNone, iabFundDistPolicyAccumulationFund, iabFundDistPolicyIncomeFund);
TIABFundAssetType = (iabFundAssetTypeNone, iabFundAssetTypeOthers, iabFundAssetTypeMoneyMarket, iabFundAssetTypeFixedIncome,
  iabFundAssetTypeMultiAsset, iabFundAssetTypeEquity, iabFundAssetTypeSector, iabFundAssetTypeGuaranteed, iabFundAssetTypeAlternative);




TIABBondSpec object


The TIABBondSpec object is the BondSpec property of TIABSocket. It maintains an array of TBondSpecItem records. New additions are made as they arrive from the TWS. A call to GetInstrumentSpecs, using a Bond's Cusip or ISIN as a value in Symbol, creates an OnBondSpecDetails event.

It has these methods and properties to work with the TIABBondSpecItem.

  TIABBondSpec = class(TPersistent)
    function Add(IABBondSpecItem: TIABBondSpecItem): Integer;
    procedure Insert(Index: Integer; IABBondSpecItem: TIABBondSpecItem);
    procedure Delete(Index: Integer);
    function Find(IABBondSpecItem: TIABBondSpecItem): Integer;
    property Count: Integer;
    property Items[Index: Integer]: TIABBondSpecItem;
  end;


The Items property is a zero based index of each TIABBondSpecItem. Use Add, Delete, Insert, Find to manipulate the items.

The fields of a TIABBondSpecItem are:

  MarketName: string
  TradingClass: string
  ContractId: Integer
  MinimumTick: Double
  OrderTypes: TIABOrderTypesSet
  ValidExchanges: string
  Symbol: string
  SecurityType: TIABSecurityType
  Cusip: string
  Ratings: string
  DescAppend: string
  BondType: string
  CouponType: string
  Callable: Boolean
  Putable: Boolean
  Coupon: Double
  Convertible: Boolean
  Maturity: string
  IssueDate: string
  Exchange: string
  Currency: string
  NextOptionDate: string
  NextOptionType: string
  NextOptionPartial: Boolean
  Notes: string
  LongName: string
  DataId: Integer
  EVRule: string;
  EVMultiplier: Double;
  SecIdList: TIABTagValueArray;
  AggGroup: Integer;
  MarketRuleIds: string;
  TimeZoneID: string;
  LastTradeTime: string;
  MinSize: BigDecimal;// Double;
  SizeIncrement: BigDecimal;// Double;
  SuggestedSizeIncrement: BigDecimal;// Double;

Fields with type Double, or BigDecimal, are depending on your compiler choices.


TIABOrder object

This object represents a single order. To generate an order, create a TIABOrder, or use the DefOrder, fill in the various properties, and pass it to PlaceOrder. Access the properties of this order through the Orders property in TIABSocket. As the order is processed, the OnOrderStatus event fires.

TIABOrder properties



property Changed: Boolean;

Identifies if the Filled value has just changed. Check this to indicate if the last OnOrderStatus notification from TWS actually amended the Filled quantity. This is more reliable than interpreting the various order status. (read and write).

The Changed property is reset to false when an order status changes, but the filled quantity does not.



property Completed: Boolean;
property CompletedTime: string;
property CompletedStatus: string;

Completed is true when an order is successfully cancelled, or an order is completely filled, otherwise false. Value is set automatically from notifications from TWS (read and write).



property TempId: Integer;

The TempId is the identity used by TWS to identify this order. See also ClientId. (read and write).



property PermId: Integer;

PermId is created by TWS, and is filled in by TIABSocket component when first discovered. (read and write).



property Filled: BigDecimal; // Double;
property FilledQuantity: BigDecimal; // Double;
Total volume of executed filled shares / contracts for this order. Updated automatically. (read and write).
Type Double, or BigDecimal, are depending on your compiler choices.



property Remaining: BigDecimal; // Double;

Remaining of open volume of shares / contracts for this order. Updated automatically. (read and write).

Type Double, or BigDecimal, are depending on your compiler choices.



property FillPrice: Double;

Current fill price of executed shares. This value is the average price for all fills in this order so far. Updated automatically. (read and write).



property LatestFillQty: BigDecimal; // Double;

The last number of filled shares / contracts when a partial fill occurs. Updated automatically. (read and write).

Type Double, or BigDecimal, are depending on your compiler choices.



property LatestFillPrice: Double;

The price of the last filled shares / contracts when a partial fill occurs. This is the price of the portion of LatestFillQty shares / contracts. Updated automatically.

Note: API version 7.01 The TWS now sends this data. Prior versions the TWS does not send this data - it is a calculated value from the current accumulated Price. The TWS usually only goes to 4 decimal places, and often this isn't enough to calculate the actual price exactly of each partial fill portion. I recommend you use some rounding on this property. (read and write).



property Duration: Integer;

The help says....Specifies the duration of the order. Format: yyyymmdd hh:mm:ss TZ. For GTD orders. But thats a mistake as this property is an integer..? Do not use until its sorted out.




property Account: string;

For institutional customers only. Account number / name. (read and write).



property Action: TIABAction;

  TIABAction = (iabIdle,iabBuy,iabSell,iabShort,iabExercise,iabLapse);

Sets the action (buy, sell, short) for this order when passed to the PlaceOrder method. For Options use the ExerciseOptions method and the action set to iabExercise or iabLapse. Changing this property does not send the order. (read and write).



property AuxPrice: Double;

This is the STOP price for stop-limit orders, and the offset amount for Relative orders and Trail orders. In all other cases, specify zero. (read and write).



property CashQuantity: Double;

Forex orders can be placed in denomination of second currency in pair using CashQuantity field. (read and write).



property Currency: string;

Specifies the currency. This field is only required when the SecurityType = stCash. Otherwise it is ignored. (read and write).



property Exchange: string;

The order destination such as 'SMART' or 'GLOBEX'. NOTE: When you connect to TWS using any of the API components, you must route all U.S. stock and option orders through Smart order routing. (read and write).

Note: see also PrimaryExchange property.



property Expiry: string;

The expiration date of a Future or Option. The format is 'YYYYMM'. (read and write).



property LocalSymbol: string;

This is the local exchange symbol of the underlying asset. (read and write).



property OCAgroup: string;

Identifies an OCA (one cancels all) group. Set this to any unique string, and all open orders with same value, will be tied together. (read and write).



property OpenClose: string;

For institutional customers only. Specifies whether the order is an open or close order. Valid values are 'O', 'C'. (read and write, default = 'O').




property OrderRef: string;

For institutional customers only. The order reference. (read and write).



property OrderOrigin: TIABOrderOrigin;

TIABOrderOrigin = (orCustomer,orFirm,orUnknown); (read and write).



property OrderType: TIABOrderType;

TIABOrderType = (otNoChange,otMarket,otLimit,otStop,otStopLimit,otPassiveRel,otVWAP,otMarketClose,otLimitClose,otTrail, otLimitOpen,otMarketOpen,otOneCancelOther,otISEBlock, otPegMarket,otPegStock,otPegMidPt,otPegBench,otPegPrimary,otVolatility,otTrailLimit,otScale, otMarketTouch,otLimitTouch,otMarketToLimit,otAuction,otAuctionRel,otAuctionLimit,otAuctionPegStk, otSweepFill, otDiscretionary,otBoxTop,otMarketwProtect,otStopwProtect, otComboLimit,otComboMarket,otComboLimitLeg,otRelLimitCombo,otRelMktCombo, otNone,otUnknown);

Use otNoChange for a call to ModifyOrder only.

See ScaledOrder for details on parametrs affecting these order types.



property Quantity: BigDecimal; // Double;

Order share / contract quantity. (read and write).

Type Double, or BigDecimal, are depending on your compiler choices.



property Price: Double;

Order limit price. Maximum precision is 6 places, or 10 places with BigDecimal enabled. The TWS may limit this further depending on the asset and market. (read and write). For stop orders, set the AuxPrice as well.



property Right: TIABRight;

For options.
TIABRight = (rtNone,rtPut,rtCall); (read and write). Use rtNone for non Option orders.



property SecurityType: TIABSecurityType;

TIABSecurityType = (stStock,stOption,stFuture,stIndex,stFutOpt,stCash,stBag,stBond,stIOp,stCFD,stFund,stCmdty,    stCrypto,stConFut,stFutConFut,stWar,stNews,stAll);

(read and write).



property Strike: Double;

For options. (read and write).



property Symbol: string;

This is the symbol of the asset. (read and write).



property ComboLegsDescrip: string;

For Combo type orders. (Read Only)

Information about the combo order returned by the TWS.



property DeltaNeutralContractId: Integer;
property DeltaNeutralContractDelta: Double;
property DeltaNeutralContractPrice: Double;

Delta-Neutral Combo Orders: Submit Delta-Neutral Combo Orders and RFQs, and request corresponding market data.

Such combos should be constructed as follows:

a) OPT or FOP goes into the leg (e.g. comboLegs list contain 1 leg only)
b) Underlying (STK or FUT), delta and underlying price goes into newly added "underComp" attribute of a Contract.



property EFPBasisPoints: Double;

For use with EFP type orders. (Read Only) Default value = UNSET_DOUBLE




property EFPBasisType: Integer;

For use with EFP type orders. (Read Only) Default value = UNSET_INTEGER




property TimeInForce: TIABTimeInForce;

TIABTimeInForce = (tifDay,tifGTC,tifIOC,tifOPG,tifGTD,tifAUC,tifFillKill,tifDTC,tifGAT,tif5Mins,tifUnknown);

Values are Day, GoodTilCancelled, ImmediateOrCancel(any portion), OPG(used with MOO and LOO), Good Till Date, AUC(used with auction order), FillorKill(entire fill), DayTillCancel, GoodAfterTime, 5Minutes,

Crypto limit orders use tif5Mins. Crypto market orders use tifIOC.



property Transmit: Boolean;

Specifies whether the order will be transmitted by TWS. If set to false, the order will be created at TWS but will not be sent to the market. This is used with bracket orders to lodge the initial orders, without the worry of an early execution. (read and write).




property ParentId: Integer;

The order ID of the parent order, used for bracket and auto trailing stop orders. (read and write).




property BlockOrder: Boolean;

If set to true, specifies that the order is an ISE Block order. (read and write).




property SweepToFill: Boolean;

If set to true, specifies that the order is a Sweep-to-Fill order. (read and write).




property Multiplier: string;

The desired futures or options contract multiplier in any API operation that involves describing a contract. These operations are: placing orders, requesting market data, requesting market depth, and requesting contract (instrument) specifications. An example of when this functionality is useful is when a corporate action has resulted in more than one options contract being traded on the same underlying, with the same right (put or call), strike, and expiration. If a contract only trades with a single multiplier (typically 100), specifying the multiplier is not necessary.




property DisplaySize: Integer;

The publicly disclosed order size, used when placing Iceberg orders. (read and write).




property ShortSaleSlot: Integer;

Retail customers set to a value of 0.

Institutional (ie non-cleared) customer specify "Short Sale Slot" information when placing an order of side "SSHORT." This information concerns the location from which shares will be delivered, and has two parameters, "Short Sale Slot" and "Designated Location." If "Short Sale Slot" is 1, then shares will be delivered from the customer's clearing firm, and no "Designated Location" is specified. If "Short Sale Slot" is 2, then shares will be delivered from a "Designated Location" clearing firm, and the value of "Designated Location" is a comma-delimitted list of possible firms.




property ExtendedHours: Boolean;

If set to true, allows triggering of orders outside of regular trading hours. (read and write).

Effective API 9.40 and TWS 878 onwards. This property now replaces the RegTradingHoursOnly property.



property Hidden: Boolean;

If set to true, the order will not be visible when viewing the market depth. This option only applies to orders routed to the ISLAND exchange. (read and write).




property ClientId: Integer;

ClientId that generated this Order. This field is filled automatically on all orders placed from the TIABSocket. This value will normally be the TIABSocket.ClientId.

It becomes relevant when calling GetOpenOrdersAccount, to get details on orders generated by other clients, or within the TWS.




property Executions[Index: Integer]: TIABExecution;
property ExecutionsCount: Integer;
This property is an index property to the array of TIABExecution records, that the TWS has sent for this order. The count of items in the array is avaiable in the ExecutionsCount property. The Liquidation field will have a value of 1 if this execution is a result of a liquidation, and a value of 0 otherwise.

Access this property like so; LastOrderExid := IABSocket.Orders[2].Executions[0].ExecutionId;

  TIABExecution = record
    ExecutionId: string;
    Time: string;
    AcctNumber: string;
    Exchange: string;
    Side: TIABAction;
    Volume: BigDecimal; // Double;
    Price: Double;
    PermId: Integer;
    Liquidation: Integer;
    CumulativeQty: BigDecimal; // Double; Integer;
    AveragePrice: Double;
    OrderRef: string;
    EVRule: string;
    EVMultiplier: Double
    ModelCode: string;
    LastLiquidity: Integer;
    PendingPriceRevision: Boolean;
  end;


Volume and CumulatveQty will be of type Double, or BigDecimal, depending on your compiler choices.




property ComboLegs[Index: Integer]: TIABComboLeg;

property ComboLegsCount: Integer;
This property is an index property to the array of TIABComboLeg records, that you have added to create Combination Orders (BAG). The count of items in the array is avaiable in the ComboLegsCount property. Add new ComboLegs with the AddComboLeg method, and remove them with the DeleteComboLeg method.

Access this property like so;  AComboLegContractId := IABSocket.Orders[2].ComboLegs[0].ContractId;


  TIABComboLeg = record
    ContractId: Integer;
    Action: TIABAction;
    Ratio: Integer;
    Exchange: string;
    OpenClose: TIABLegOpenClose;
    ShortSaleSlot: Integer;
    DesignatedLocation: string;
    ExemptCode: Integer; // init to -1
  end;


The ShortSalelot and DesignatedLocation fields provide support for institutional customers to specify ShortSaleSlot / DesignatedLocation for an individual leg of a COMBO order. Valid values specified for ShortSaleSlot are as follows:

  0 - unapplicable (e.g. retail customer or not SSHORT leg (not Action of iabShort)
  1 - clearing broker
  2 - third party

When ShortSaleSlot = 2, a DesignatedLocation value is to be specified. Non-empty DesignatedLocation values for all other cases will cause orders to be rejected.

TIABLegOpenClose = (locSamePos,locOpenPos,locClosePos,locUnknownPos);

Another property related is the ComboLegPrice[Index: Integer]: Double. See also AddComboLegPrice.



property DiscretAmount: Double;
property DiscretionaryUpToLimitPrice: Boolean;
The amount off the limit price allowed for discretionary orders.



property FAdvGroup: string;
For Finacial Adviser accounts, otherwise a blank string '';




property FAdvMethod: string;
For Finacial Adviser accounts, otherwise a blank string '';




property FAdvPercentage: string;

For Finacial Adviser accounts, otherwise a blank string '';




property FAdvProfile: string;

For Finacial Adviser accounts, otherwise a blank string '';




property GoodAfterTime: string;

The trade's "Good After Time," format "YYYYMMDD HH:MM:SS" -- use an empty String if not applicable.




property GoodTillDate: string;

The trade's "Good Till Date," format "YYYYMMDD HH:MM:SS" -- use an empty String if not applicable.




property ExtOperator: string;

This is a regulartory attribute that applies to all US Commodity (Futures) Exchanges, provided to allow client to comply with CFTC Tag 50 Rules. see www.cmegroup.com.. tag50.html




property PrimaryExchange: string;

Specify the PrimaryExchange for Smart Routing.

You must specify the primary exchange when placing orders routed through SMART exchange, or when making SMART market data requests. Specifying the primary exchange allows the API to resolve routing ambiguities for example in instances when an asset trades in the same currency on multiple exchanges (i.e. QQQ trades in US dollars on both AMEX and NYSE).

This can be tricky guess work sometimes. Try looking at Contract specs, or a Symbol search, for clues on this. There are samples in IAB API help, or the cpp sample code.




property DesignatedLocation: string;

Unknown... see TWS help.




property OcaMethod: TIABOcaMethod;

TIABOcaMethod = (ocaCancelWithBlock, ocaReduceWithBlock, ocaReduceNonBlock);




property Rule80A: TIABRule80A;

TIABRule80A = (r80na,r80aIndividual, r80aAgency, r80aAgentOtherMember, r80aIndividualPTIA, r80aAgencyPTIA, r80aAgentOtherMemberPTIA, r80aIndividualPT, r80aAgencyPT, r80aAgentOtherMemberPT);




property ScalePriceIncrement: Double;
property ScaleInitLevelSize: Integer;
property ScaleSubsLevelSize: Integer;
property ScalePriceAdjustValue: Double;
property ScalePriceAdjustInterval: Integer;
property ScaleProfitOffset: Double;
property ScaleAutoReset: Boolean;
property ScaleInitPosition: Integer;
property ScaleInitFillQty: Integer;
property ScaleRandomPercent: Boolean;
property ScaleTable: string;


Parameters for the entry of a "Scale" order. The OrderType must be set to otScale for a Scaled order.

Either ScaleNumComponents (split order into X buckets) or ScaleComponentSize (split order so each bucket is of the size X) AND ScalePriceIncrement (price increment per bucket).

The PriceIncrement is unconditionally required, and only one of either NumComponents/ComponentSize must be specified.




property WhyHeld: string;

This property, when returned from TWS, contains the comma-separated list of reasons for order to be held. For orders being held due to SLAL, the value will be 'locate'.
For placing orders, this field is used to identify an order held when TWS is trying to locate shares for a short sell. The value used to indicate this is 'locate'.



property OverridePercentageConstraints: Boolean;

Overrides TWS's order price percentage constraints, which are applied to orders that TWS sees as deviating too much from the NBBO of the contract. This functionality was put into place to work in conjunction with the fact that TWS will no longer pop up a confirmation dialog when an API order violates the percentage constraints TWS imposes. If this is set to false, such orders going forward will be rejected. Keep in mind that orders with prices that severely depart from the contract's NBBO but would otherwise be filled will be rejected by IB's servers.




property SettlingFirm: string;
property Solicited: Boolean;
property Shareholder: string;
property IsOmsContainer: Boolean;

Pertains to institutional only.




property AllOrNone: Boolean;

Self explan.




property MinQuantity: Integer;

Minimum quantity.




property ModelCode: string;

Is used to place an order to a model. For example, "Technology" model can be used for tech stocks first created in TWS.




property PercentOffset: Double;

Pertains to relative orders only.




property NotHeld: Boolean;

Orders routed to IBDARK are tagged as "post only" and are held in IB's order book, where incoming SmartRouted orders from other IB customers are eligible to trade against them. For IBDARK orders only.




property ImbalanceOnly: Boolean;


Used to specify "imbalance only open orders" and / or "imbalance only closing orders". (OIO) Applies to NASDAQ orders only. see www.investopedia.com/terms/o/opening-imbalance-only-order-oio.asp



property RouteMarketableToBbo: Boolean;


Routes market order to Best Bid Offer.



property AuctionStrategy: TIABAuctionStrategy;;

TIABAuctionStrategy = (asUnset, asMatch, asImprovement, asTransparent);




property StartingPrice: Double;
property StockRangeUpper: Double;
property StockRangeLower: Double;
property Delta: Double;
property StockRefPrice: Double;


Pertains to BOX exchange only.




property Volatility: Double;
property VolatilityPeriod: TIABVolatilityPeriod;
property DeltaNeutralOrderType: TIABOrderType; default otNone
property DeltaNeutralAuxPrice: Double;
property ContinuousUpdate: Boolean;
property ReferencePrice: TIABReferencePrice;
property DeltaNeutralSettlingFirm:string;
property DeltaNeutralClearingAccount: string;
property DeltaNeutralClearingIntent: string;
property DeltaNeutralOpenClose: string;
property DeltaNeutralShortSale: Boolean;
property DeltaNeutralShortSaleSlot: Integer;
property DeltaNeutralDesignatedLocation: string;

type TIABVolatilityPeriod = (vpUnset,vpDaily,vpAnnual);
type TIABReferencePrice = (rpUnset,rpAverage,rpBidOrAsk);

Pertains to Dynamic Volatility Orders.

All volatility orders have these two parameters: Dynamic volatility orders have these five additional parameters:




property Verified: Boolean;


Read only property. An order that has been sent to the VerifyOrder method, and sucessfully processed, will have its Verified property set true, and the method GetQueryResult will contain valid data for commissions and margins.

See the VerifyOrder method for further details.



property ContractId: Integer;


This property will contain the Id number of the trading instrument, after the order has been submitted.




property ClearingAccount: string;
property ClearingIntent: string;


For IBExecution Customers: Away and PTA Orders Supported (requires TWS 879)

ClearingIntent: Valid values include: IB, Away, PTA.
ClearingAccount: The true beneficiary of the order.This value is required to be sent on FUT/FOP orders for reporting to the exchange.



property CompeteAgainstBestOffset: Double;
property MidOffsetAtWhole: Double;
property MidOffsetAtHalf: Double;
property MinCompeteSize: Integer;
property MinTradeQty: Integer;
property PostToAts: Integer;


Used with IBKRATS orders. see: IBKR ATS Orders



property Mifid2DecisionMake: string;
property Mifid2DecisionAlgo: string;
property Mifid2ExecutionTrader: string;
property Mifid2ExecutionAlgo: string;


For EEA investment firms required to comply with MiFIR reporting, and who have opted in to Enriched and Delegated Transaction Reporting, we have added four new order attributes to the Order class, and several new presets to TWS and IB Gateway Global Configuration.

Details of paramaters are available here: mifir-reporting



property AutoCancelDate: string;
property AdjustedOrderType: TIABOrderType;
property AdjustedStopPrice: Double;
property AdjustedStopLimitPrice: Double;
property AdjustedTrailingAmount: Double;
property AdjustableTrailingUnit: Integer;
property AutoCancelParent: Boolean;
property IsPeggedChangeAmountDecrease: Boolean;
property LmtPriceOffset: Double;
property ParentPermId: Int64;
property PeggedChangeAmount: Double;
property ReferenceChangeAmount: Double;
property ReferenceContractId: Integer;
property ReferenceExchangeId: string;
property TriggerMethod: Integer;
property TriggerPrice: Double;
property TrailStopPrice: Double;


This group of properties are used with Stop orders and the complex and advanced versions of them. More details at: Adjustable Stop order details

TriggerPrice: Specifies how Simulated Stop, Stop-Limit and Trailing Stop orders are triggered. Valid values are:
O - the default value. The "double bid/ask" method will be used for orders for OTC stocks and US options. All other orders will used the "last" method.
1 - use "double bid/ask" method, where stop orders are triggered based on two consecutive bid or ask prices.
2 - "last" method, where stop orders are triggered based on the last price.
3 - "double-last" method, where stop orders are triggered based on last two prices.
4 - Bid/ask function
7 - Last or bid/ask function
8 - Mid-point function

TriggerPrice is for Adjusted Stop orders: specifies the trigger price to execute.

Trigger method's and order types are shown in this table: TWS trigger methods.
For Trailing stop limit orders.

Use the order type of otTrailLimit. When placing trailing stop limit orders, the AuxPrice property specifies the trailing amount, and the stop price is specified as this TrailStopPrice property.
LmtPriceOffset: Adjusted Stop orders: specifies the price offset for the stop to move in increments. Used with TrailLimit type orders. (read and write).




property MarketCapPrice: Double;
property RefFuturesConId: Integer; Identifies the reference future conId.

Properties added in TWS API 975 and 976, 10.10 and 10.16.

Specific purpose not known or unsure at this time. Check the API help for details:
  https://ibkrcampus.com/ibkr-api-page/trader-workstation-api/




property AlgoID: string;
property AlgoParams[Index: Integer]: TIABTagValueArray;
property AlgoStrategy: string;
property AlgoParamsCount: Integer;
property UsePriceMgmtAlgo: Integer;

This will submit IBALGO orders using the API. The following new fields to the Order structure:

* String: AlgoStrategy * Vector: AlgoParams

Available Algos and parameters include:
For US Stocks:
For US Options:

See also the methods: AddAlgoParams and ClearAlgoParams.

  TIABTagValueArray = record
    Tag, Value: string;
  end;




property SoftDollarTier: TIABSoftDollarTier;

A record for storing Soft Dollar Tier information.

  TIABSoftDollarTier = record
    Name, Value, DisplayName: string;
 end;



property SmartComboRoutingParams[Index: Integer]: TIABTagValueArray;
property SmartComboRoutingParamsCount: Integer;


You can now add smartComboRoutingParams to an order. smartComboRoutingParams is similar to AlgoParams in that it makes use of tag/value pairs to add parameters to combo orders. The new parameters cover the following capabilities:
See also the methods: SmartComboRoutingParams and ClearSmartComboRoutingParams.

  TIABTagValueArray = record
    Tag, Value: string;
  end;




property MktDataOptions[Index: Integer]: TIABTagValueArray;
property MktDataOptionsCount: Integer;
property OrderMiscOptions[Index: Integer]: TIABTagValueArray;
property OrderMiscOptionsCount: Integer;



See also the methods: SmartComboRoutingParams and ClearSmartComboRoutingParams.

  TIABTagValueArray = record
    Tag, Value: string;
  end;




property OptOutSmartRouting: Boolean;

Opt Out of Default SmartRouting for ASX-Directed Orders

ASX exchange regulations require that SmartRouting be selected by default for orders routed directly to ASX, and require that any opting-out of SmartRouting be done on an order by order basis.

You can opt out of default SmartRouting for orders routed directly to ASX by using a new boolean Order attribute optOutSmartRouting. This new attribute defaults to false unless explicitly set to true. When optOutSmartRouting is set to false, orders routed directly to ASX will NOT use SmartRouting. When the attribute is set to true, orders routed directly to ASX orders WILL use SmartRouting.

When developing your own custom API application, you must not allow orders to be routed directly to ASX by default, and you must require opting out of SmartRouting on an order by order basis. For more information on these regulations, see the ASX website.




property ExemptCode: Integer;

Support for SSHORTX, Short Sale Exempt action, has been added. When this is implemented, you will use SSHORTX the same way you use SSHORT.
SSHORTX allows some orders to be marked as exempt from the new SEC Rule 201, which goes has not yet gone into effect. The API code will also include a code specifying the reason for the exemption.





property HedgeParam: string;
property HedgeType: TIABHedgeType;
property DontUseAutoPriceForHedge: Boolean;

Hedge orders are child orders that take additional fields. There are four types of hedging orders supported by the API:

  * Delta  * Beta  * FX  * Pair

To support these orders, the following fields have been added to order properties:

HedgeType: TIABHedgeType = (htUnset, htDelta, htBeta, htFX, htPair);

HedgeParam: string; value depends on the hedgeType; sent from the API only if hedgeType is NOT htUnset (default). HedgeParam is required for Pair hedge order, optional for Beta hedge orders, and ignored for Delta and FX hedge orders.

The following rules apply:
TIABHedgeType = (htUnset, htDelta, htBeta, htFX, htPair);




property TradingClass: string;

Used with mini options orders. Specifically, the tradingClass string attribute has been added to the Contract structure and removed from the ContractDetails structure in order to support mini options requested by the API. The following requests and callbacks that include the Contract structure as a parameter can now handle the tradingClass and multiplier attributes for mini options. Also, some of these requests can now use the conId attribute to identify a security.



property ActiveStartTime: string;
property ActiveStopTime: string;

Used with GTC orders.



property AdvancedErrorOverride: string;

Used with bitcoin orders. See the TWS API help for details at TWS API order submission.

The result or matching error msg sent from the TWS, comes appended to the regular error message, seperated with ">>>". It is reported to be a JSON text, so expect embedded LF & CR characters.



property ManualOrderTime: TDateTime;

Apparently it sets the order processing time from the TWS to the exchange ?? GMT, exchange, or local time ?? Probably the setting is only available on Financial Advisor accounts.




TIABOrder methods



procedure Assign(Source: TPersistent); override;

Assign the values of one TIABOrder to another. Use this to copy one TIABOrder to another.



function AddComboLeg(ComboLeg: TIABComboLeg): Integer;
function AddComboLegPrice(Price: Double): Integer;
procedure ClearComboLegPrice;

Adds a TIABComboLeg to the Order.ComboLegs property. The return value is the Index of this ComboLeg. These are used in Combination orders, and require the Order Type set to otBag.
AddComboLegPrice is a second array, this with just with Double values. Not sure what this does. ClearComboLegPrice will clear the array.
ComboLegPrice[Index: Integer] is the property.



procedure DeleteComboLeg(Index: Integer);

Deletes an existing TIABComboLeg from the Order.ComboLegs property. Calling this procedure with a value of -1 will delete all ComboLegs from this Order.



function GetQueryResult: TIABOrderQueryResult;


An order that has been sent to the VerifyOrder method, and sucessfully processed, will have its Verified property set true, and the method GetQueryResult will contain valid data for commissions and margins.

This method returns a record of type TIABOrderQueryResult.
  TIABOrderQueryResult = record
    Status: string;
    InitMarginAfter: string;
    MaintMarginAfter: string;
    EquityWithLoanAfter: string;
    InitMarginBefore: string;
    MaintMarginBefore: string;
    EquityWithLoanBefore: string;
    InitMarginChange: string;
    MaintMarginChange: string;
    EquityWithLoanChange: string;
    Commission: Double;
    MinCommission: Double;
    MaxCommission: Double;
    CommissionCurrency: string;
    WarningText: string;
    CompletedTime: string;
    CompletedStatus: string;
  end;


See the VerifyOrder method for further details.



function AddAlgoParams(TagValue: TIABTagValue): Integer;
procedure ClearAlgoParams;


AddAlgoParams will append a TIABTagValue object and return the index position.
ClearAlgoParams will clear all saved objects.

See also AlgoParams and AlgoStrategy and AlgoParamsCount



function AddSmartComboRoutingParams(TagValue: TIABTagValue): Integer;
procedure ClearSmartComboRoutingParams;
function AddMktDataOptions(TagValue: TIABTagValue): Integer;
procedure ClearMktDataOptions;
function AddOrderMiscOptions(TagValue: TIABTagValue): Integer;
procedure ClearOrderMiscOptions;


Some parameters are controlled by a pair of "tag=value" attributes. These allows for expansion of future settings. These are contained in a TIABTagValue record:

  TIABTagValueArray = record
    Tag, Value: string;
  end;
The above functions will append a TIABTagValue object and return the index position. Clear... will clear all saved objects.

The values for SmartComboRouting, is explained in the link at SmartComboRoutingParams
The other object values allowed in the above is not explained by IAB at this time.

See also SmartComboRoutingParams and SmartComboRoutingParamsCount



TIABOrder Events



property OnFill: TNotifyEvent;

Fires each time an order has a fill (partial or full). This event is not assigned in the TIABSocket component. Instead use the OnOrderStatus event and check the Order's Changed property.



property OnCompleted: TNotifyEvent

Fires when the order has been cancelled or completely filled. This event is not assigned in the TIABSocket component. Instead use the OnOrderStatus event and check the Order's Completed property.



TIABOrders object

This object manages the various TIABOrder objects. Access to a single order is done through this object via the Orders property in TIABSocket. The object will normally handle all adding and deleting of orders as they are sent, or arrive. There are methods to add orders manually, should you wish to add orders from a previous session. Also FindDuplicatePermIds is required to deal with some extra orders the TWS may generate.

TIABOrders properties




property Count: Integer;

Number of TIABOrder objects in the TIABOrders object. Based on 1. (read only).



property Items[Index: Integer]: TIABOrder;

Each individual TIABOrder item. Index is zero based. This is the default property of TIABOrders. (read and write).



TIABOrders methods



function Add(TempId, ClientId, PermId: Integer; IABOrder: TIABOrder): Integer;

Adds an order to the array. Return value is the Index. This is normally done by TIABSocket. The Add method takes ownership of the IABOrder object.



procedure Insert(Index, TempId, ClientId, PermId: Integer; IABOrder: TIABOrder);

Inserts an order into the array. Return value is the Index. This is normally done by TIABSocket. The Insert method takes ownership of the IABOrder object.



procedure Delete(Index: Integer);

Deletes a TIABOrder object from the array. Index is zero based. The TIABSocket normally does this.



function FindDuplicatePermIds(var Index1, Index2: Integer): Boolean;

Locates duplicate orders based on the PermId value. Index1 and Index2 will show the locations in the array. This method does not make any changes - you will need to combine, or delete the duplicate orders.

Call this method after the GetExecutions, GetOpenOrdersClient, GetOpenOrdersAccount methods.

This function returns false when all duplicates are removed. Note that this function finds the first duplicates encountered - and does not change them.



function IndexOfTempId(TempId, ClientId: Integer): Integer;

Find an Order by its TempId / ClientId pair. Result is Index or -1;



function IndexOfPermId(PermId: Integer): Integer;

Find an Order by its PermId. Result is Index or -1;



function TempToPermId(TempId, ClientId: Integer): Integer;

Finds the PermId of an order by its TempID and ClientId pair. Result is PermId or -1;



procedure SetPermId(TempId, ClientId, PermId: Integer);

Sets the PermId of an order. The TIABSocket normally does this when it first discovers the PermId of the order.



procedure GetOrder(TempId, ClientId: Integer): TIABOrder;

Retrieves an order based on TempId and ClientId.



TIABScanner & TIABScan object, TIABScanResultItem record

The scanner system allows API client to make TWS market scanning calls based on the criteria given. The API allows for 50 returned items and these are updated every 30 seconds. Multiple queries can run concurrently. More details at TWS API here.

The TIABScanner object is a manager for the various TIABScan objects. A TIABScan object represents a single scanner Query, and it contains TIABScanResultItem records. This TIABScanner object is accessed as the Scanner property of TIABSocket component. The primary methods are:

1/ Find available parameters of scanner;
  IABSocket1.Scanner.GetScannerParameters;
The return information is an XML string of parameters descibing the attributes of the Scanner - see OnScannerParam. You will need to parse this data string further. Use the data to construct a Query for a scan.

2/ Start a scan;
  IABSocket1.Scanner.InitializeScanCriteria(ScanCriteria);
  IABSocket1.Scanner.NewScan(ScanId, ScanCriteria);
The call to InitializeScanCriteria is required to format the data in various fields for the TWS. Create your scan query by setting the fields of the ScanCriteria record as required. All unused fields should left with the default initialized values. The ScannerSettingPairs field has this special purpose: Scanner setting pairs are delimited by slashes, making this parameter open ended as further developments occur. The "Annual,true" pairing would cause the "Top Option Implied Vol % Gainers" scan to return annualized volatilites.
ScanId is a unique number used to ID this query.

The ScanCriteria used in the request above, has these fields;

  TIABScanCriteria = record
    NumberOfRows: Integer;
    Instrument: string;
    LocationCode: string;
    ScanCode: string;
    AbovePrice: Double;
    BelowPrice: Double;
    AboveVolume: Integer;
    MarketCapAbove: Double;
    MarketCapBelow: Double;
    MoodyRatingAbove: string;
    MoodyRatingBelow: string;
    SPRatingAbove: string;
    SPRatingBelow: string;
    MaturityDateAbove: string;
    MaturityDateBelow: string;
    CouponRateAbove: Double;
    CouponRateBelow: Double;
    ExcludeConvertible: Integer;
    AverageOptionVolumeAbove: Integer;
    ScannerSettingPairs: string;
    StockTypeFilter: string;
    SubscriptionOptions: TIABTagValueArray;
    FilterOptions: TIABTagValueArray;
  end;
The results will return via the OnScannerData event every 30 seconds or so.
  procedure IABSocket1.OnScannerData(Sender: TObject; Scan: TIABScan);
  var i, j; Integer; s: string; 
  begin
    for i := 0 to Scan.Count -1 do
      begin
        j := Scan.Items[i].Rank;
        s := Scan.Items[i].Symbol;
        ...
3/ Cancel a scan;
  IABSocket1.Scanner.CancelScan(ScanId);

The component set will intercept incomming ammendments to each TIABScan object and a new event will fire. All TIABScanResultItem data in this TIABScan object is overwritten with each update Do not rely on persistant data in these objects - they will change frequently as market conditions change.


    //  the scanner objects manager
  TIABScanner = class(TPersistent)
  public
    function Add(IABScan: TIABScan): Integer;
    procedure CancelScan(ScanId: Integer);
    procedure Delete(Index: Integer);
    procedure GetScannerParameters;
    procedure Insert(Index: Integer; IABScan: TIABScan);
    procedure InitializeScanCriteria(PDetails: PTIABScanCriteria);
    function IndexOfScanId(ScanId: Integer): Integer;
    function NewScan(ScanId: Integer; Details: TIABScanCriteria): Integer;
    property Count: Integer read GetCount;
    property Items[Index: Integer]: TIABScan read GetItems; default;
    property Parameters: string read FParameters;
  end;


    //  An individual scan query
    //  accessed as Items property of TIABScanner
  TIABScan = class(TPersistent)
  public
    function Add(IABScanResultItem: TIABScanResultItem): Integer;
    procedure Insert(Index: Integer; IABScanResultItem: TIABScanResultItem);
    procedure Delete(Index: Integer);
    function Find(IABScanResultItem: TIABScanResultItem): Integer;
    function QueryCriteria: TIABScanCriteria;
    property Count: Integer read GetCount;
    property Items[Index: Integer]: TIABScanResultItem read GetItems write SetItems; default;
    property ScanId: Integer read FScanId;
  end;


    //  an instrument that meets the current criteria
    //  accessed as Items property of TIABScan
  TIABScanResultItem = record
    Rank: Integer;
    Symbol: string;
    SecurityType: TIABSecurityType;
    Expiry: string;
    Strike: Double;
    Right: TIABRight;
    Exchange: string;
    Currency: string;
    LocalSymbol: string;
    MarketName: string;
    TradingClass: string;
    Distance: string;
    Benchmark: string;
    Projection: string;
    LegsString: string;
    ContractId: Integer;
  end;




type  BigDecimal;

In version 10.10, the TWS API added a large decimal math capability. This became necessary as some instruments (namely bitcoins), are able to be traded down to 0.000000001 of a share. This is beyond the reliable range of using floats as decimals. The TWS chose the Intel® Decimal Floating-Point Math Library, but this is only available in C and is too complex to convert to pascal.

Fortunately a BigDecimal style library is available in pascal, thanks to the work of Rudy Velthuis. It is available here:

    https://github.com/rvelthuis/DelphiBigNumbers

A backup copy is here: https://www.hhssoftware.com/iabsocketapi/download/DelphiBigNumbers-master.zip

This API can be compiled both with or without using the DelphiBigNumbers feature. If you do not trade bitcoins or small fractions of shares, then there is little need for BigDecimal support.

If the DelphiBigNumbers library is not used, then the type BigDecimal in this API is a simple redefinition of type Double. The properties and fields involved are mostly the Size of ticks and Filled and Quantity of orders, and share sizes. In old API's, these were defined as a mix of integer and double. In this API forwards, they are either a double or BigDecimal. Existing application code from old API's will need some amending to compile.


*******************

To include the DelphiBigNumbers library code into this API ( requires XE2 or higher ) :

1/ Download the DelphiBigDecimal zip file from the link above, and extract the contents to your favorite extra code or third party add-on file location,

2/ Add the path of the "source" subfolder to your XE enviroment: menu, Tools, Options, Enviroment, Delphi options, Library, add to both the library path and browse paths, for 32 and 64 bits,

3/ Add a USE_BIGDECIMAL define to the project: menu, Project, options, Delphi compiler, Conditional defines, for 32 and 64 - all configs,

4/ Add the unit "Velthuis.BigDecimals" to the uses clause of your app anywhere that type BigDecimals are used.

5/ With the installed TIABSocket API components file (.dpk), Open, uninstall, add the USE_BIGDECIMAL define to the components file, per step 3 above, compile, and reinstall.

6/ In your application modify / replace the 5 (if used - see below) affected event function / procedure headers with the BigDecimal versions. This can get messy: try to comment out the event declaration and code from both the interface and implementation sections. Save the form, confirm delete unused references. Now create new the required event handlers and move your existing code into these.

7/ Adjust your application code to use BigDecimal routines for conversion and variables.

See the included pdf help files with the DelphiBigNumbers library. This includes new routines for conversion of BigDecimal to Integers and strings.

Using BigDecimals directly affects 5 Event procedures in TIABSocket API. These are OnTickSize, OnTickPriceAndSize, OnMarketDepth, OnMarketLevel2, OnHistogramData, OnProfitLossSingle. Many other properties have changed too, mostly volume, quantity and bid/ask sizes.

*******************

If the Big decimal library is not used, then the type BigDecimal is re-defined as a double per below. Therefore all BigDecimal declarations can be treated as Double's.

{$IFNDEF USE_BIGDECIMAL}
type BigDecimal = Double;
{$ENDIF}




TIABHistoricalData

The TIABHistoricalData object is an optional addon to this API package. The purpose is to intercept all incoming history data and tick history data, and store it in such a way, that it can be saved, searched, merged, sorted, duplicated, reloaded and appended too. This allows you to keep a local copy of the history that can be reloaded, and then add new data onto it the next day.

This object needs to be configured into your project through the use of compiler directives (conditional defines) in the project settings. Select the project options, Conditional defines, select All configs, All platforms and add the define value USE_IABHISTORICALDATA. Now the property IABSocket.HistoricalDataStore will become available for access to this data component. The boolean property IABSocket.StoredHistoricalData controls if this data component is utilized for each individual GetHistorical... method request.

Compiling and source: With the above configured, add the unit IABHistoricalData.pas to the project. The other API files are automatically set per the USE_IABHISTORICALDATA define.

Usage:

Turn on the object with the IABSocket.StoredHistoricalData property;
Manually create the event handler for the OnStoredHistoryItemUpdated event (described there);
Make the data request in the usual manner with all the normal parameters via the GetHistoricalData method;
When the data arrives, a new event OnStoredHistoryItemUpdated will notify of new and updated data. This event replaces the existing OnHistoricalData and OnHistoricalDataUpdate events;
Access the incoming data and methods via the property IABSocketAPI.StoredHistoricalData;
Cancel the data updates via the usual CancelHistoricalData method;


The sample project IABSocket included with this API, demonstrates how to effectively use this TIABHistoricalData object. This includes discussions on how to reloaded and resume building data, and how to make a merged history set.

The TIABHistoricalData object is structured so each "item" holds a specific GetHistorical..() request and its subsequent available data.

The TIABHistoricalData object offers these properties, methods and events.

function HistoricalItemCount: Integer; // Total number of request/response items (both data and tick) in this TIABHistoricalData object.
function HistoricalItemLineCount(ItemIndex: Integer): Integer; // number of lines of history in a single history item.
function HistoricalItemHistoryType(ItemIndex: Integer): Integer; // IABHISTORICALDATA_TYPE_HISTORY or IABHISTORICALDATA_TYPE_TICKS
function HistoricalDataRequestParams(ItemIndex: Integer): PTIABHistoricalDataReqParam; // Params used in the initial datarequest call.
function HistoricalDataLinesArray(ItemIndex: Integer): PTIABHistoricalDataLinesArray; // entire data array pointer
function HistoricalDataLinesItem(ItemIndex, LineIndex: Integer): PTIABHistoricalDataLineItem; // A single line of history data

function LoadHistoricalItem(Filename: string): Integer; // reload saved data - overwrites existing identical data item - if found.
procedure SaveHistoricalItem(ItemIndex: Integer; Filename: string); // saves data item
procedure DeleteHistoricalItem(ItemIndex: Integer); // beware the existing item indexes will change.

// Add a unique tag value, that is not modified by any merge operation. Preserved through a save and reload.
procedure SetItemTag(ItemIndex, Tag: Integer);
function GetItemTag(ItemIndex: Integer): Integer; // also can search for tag with SearchHistorical.

// Use this ONLY when reloading old dataset, and wanting to append new data from market.
// Set it to the DataID to be used in the upcomming GetHistoricalData call. This for force new data to be appended to old saved dataset
function SetDataIDOfHistoricalItem(ItemIndex, DataId: Integer): Boolean;
function GetIndexOfDataID(DataId: Integer): Integer;
function GetDataIDOfIndex(ItemIndex: Integer): Integer;

// Merges (appends) items of same historydata type. Dest is unsorted. Result is new ItemIndex of Dest.
// Params are adjusted so conflicting fields are set to -1 or 'many'. Hash is re-made.
function MergeHistoricalItem(SourceIndex, DestinationIndex: Integer): Integer;
function DuplicateHistoricalItem(ItemIndex: Integer): Integer; // exact copy
function EraseHistoricalItemLines(ItemIndex, FromLine, ToLine: Integer): Boolean; // remove n lines of history. Use ToLine = -1 to specify all lines to end of data.
function SortHistoricalDataLines(ItemIndex: Integer; var SortCriteria: TIABHistoricalDataLinesSortCriteria): Boolean; // uses quicksort
function StripOutDuplicateLines(ItemIndex: Integer; DataLineField: TIABHistoricalDataLineFields): Boolean; // Searches from low to high: low remains, higher deleted (includes a sort).

// SearchHistoricalDataItems() ... searches the HistoricalDataItems on the details given in the original request.
// example ( [scSymbol, scBarSize], ['MSFT', Ord(bs5Min)] ) Add as many Param/Values as needed. Enumerated types to be passed as Ord().
// Returns an array of the ItemIndex numbers that contain the matching data - sorted from 0..x, and all duplicates removed
function SearchHistoricalDataItems(SearchCriteriaParams: array of TIABHistoricalDataSearchCriteria; SearchCriteriaValues: array of const): TIABIntegerArray;

procedure Clear; // erase everything.



Reloading data:

When requesting and receiving new history items, the items are uniquely separated by the DataID used in the GetHistorical.. call, and incoming data is directed to the appropriate history item. Each of these items is accessed via its ItemIndex, but these indices can change if a DeleteHistoricalItem call is made.

Conversely, data that is saved to disk and reloaded will use an internal hash of the request parameters to identify itself. When reloading data from file, the code will look for a previously loaded item based on that hash, and overwrite the previously reloaded item that it found. The hash uses all the params in the request call, so items with different start dates, or different bar sizes, or any other param, will have different hashes, and result in separate a History Item when loaded.

To create a situation where the saved data is reloaded and then to start appending new fresh data onto it, follow this procedure: 1/ Reload the data, 2/ Decide on a new DataID, 3/ Set the new DataID into the reloaded data with SetDataIDOfHistoricalItem, 4/ Make the GetHistorical.. request using that same DataID. Now the new incoming data will be appended to the old reloaded item. Any overlapping or duplicate data lines (based on datetime of last data line), will be dropped.



Note: This TIABHistoricalData works with or without BigDecimal activation, but experience shows that using large numbers of BigDecimal types concurrently is not as reliable as it should be.



Updated on March 26th, 2024.  API v10.28