--- title: "StreamXLS — Reference" description: "StreamXLS Reference — the complete Excel =RTD() formula grammar and field catalog for Interactive Brokers TWS and IB Gateway: contract syntax, market-data ticks, account, position, and order fields." canonical: https://streamxls.com/docs-reference updated: 2026-08-15 source: markdown mirror of the HTML page at the canonical URL, generated at build time by gen-md.py — do not edit order_staging: "StreamXLS cannot send or trigger live orders. Staged orders do not transmit to the market unless a user clicks in TWS to submit." --- # Reference — The complete formula grammar. > **Orders — what StreamXLS cannot do:** StreamXLS cannot send or trigger live orders. Staged orders do not transmit to the market unless a user clicks in TWS to submit. Every StreamXLS value is a native Excel `=RTD()` formula against ProgID `Tws.Rtd`, addressed by a uniform topic-string tuple. One grammar covers six topic families: market data, accounts, positions, orders, order staging, and connection status. This page is the full catalog — contract syntax, every field name, and the return conventions. Topic and field names are case-insensitive throughout. For the machine-generated exhaustive reference (every field, key, and status value, produced from the engine itself), see the [complete reference on GitHub](https://github.com/StreamXLS/streamxls/blob/main/docs/reference.md). ## The grammar — One formula, six families The shape is always the same: ```excel =RTD("Tws.Rtd",, , ) ``` The first argument is the ProgID `Tws.Rtd`. The **second argument is ignored** — it is Excel’s “Server” parameter, and StreamXLS reads none of it. All connection and contract information lives in the third argument onward. Leave the second argument empty (`, ,`). > **Common mistake:** putting a value in the second argument — that is reserved by Excel and not passed to StreamXLS. Note the extra comma: > > - **Wrong:** `=RTD("Tws.Rtd", "127.0.0.1:7497", "AAPL", "BID")` > - **Right:** `=RTD("Tws.Rtd",, "127.0.0.1:7497", "AAPL", "BID")` ### The six topic families There are six families. Two of them come in *singular / list* pairs — `position`/`positions` and `order`/`orders` — so you will see eight topic words in total, but they group into six families. A bare contract (no leading topic word) selects market data. | Topic family | Grammar | Example formula | Result in the cell | |---|---|---|---| | [Status](https://streamxls.com/docs-reference#status) | `status, ` | `=RTD("Tws.Rtd",, "status", "IsConnected")` | `1` | | [Market data](https://streamxls.com/docs-reference#market-data) | `, ` | `=RTD("Tws.Rtd",, "AAPL", "LAST")` | `187.42` | | [Accounts](https://streamxls.com/docs-reference#accounts) | `account, , ` | `=RTD("Tws.Rtd",, "account", "U1234567", "NetLiquidation")` | `1,284,902` | | [Positions](https://streamxls.com/docs-reference#positions) | `position, , , ` | `=RTD("Tws.Rtd",, "position", "U1234567", "AAPL", "UnrealizedPnL")` | `10,824.00` | | [Order monitoring](https://streamxls.com/docs-reference#orders) | `orders, , ` | `=RTD("Tws.Rtd",, "orders", "*", "OpenListCsv")` | `822,823` | | [Order staging](https://streamxls.com/docs-reference#stageorder) | `StageOrder, , …` | `=RTD("Tws.Rtd",, "StageOrder", "sym=AAPL", "side=BUY", "shares=100", "type=LMT", "limit=150.05", "exch=SMART")` | `Staged` | > Each row links to its section below. **Return-value convention.** A field returns a number (or text) when its value is known to be current. When it is not — TWS disconnected or unresponsive — time-sensitive fields return `#N/A` rather than a stale value. A visible gap is safer than a silently frozen price. ## Connections & ports — Point a formula at a session With no connection tokens, StreamXLS connects to `127.0.0.1:7496` (TWS live). Add connection tokens anywhere in the topic arguments (order does not matter) to target a different host, port, or client ID. | Token | Format | Default | |---|---|---| | Host | `host=` | `127.0.0.1` | | Port | `port=` | `7496` | | Client ID | `clientid=` | auto-generated | ### Port aliases | Alias | Port | Session | |---|---|---| | `paper` | 7497 | TWS paper trading | | `gw` | 4001 | IB Gateway live | | `gwpaper` | 4002 | IB Gateway paper | > TWS live is `7496`; TWS paper `7497`; IB Gateway live `4001`; IB Gateway paper `4002`. ### Compact form Instead of separate `host=`/`port=`/`clientid=` tokens, use one `host:port` or `host:port:clientid` string. ```excel =RTD("Tws.Rtd",, "host=192.168.1.100", "port=4001", "clientid=5", "AAPL", "BID") =RTD("Tws.Rtd",, "192.168.1.100:4001:5", "AAPL", "BID") =RTD("Tws.Rtd",, "paper", "AAPL", "BID") ' 127.0.0.1:7497 ``` ### Multiple simultaneous connections Each distinct `host:port:clientid` is a separate connection. A single workbook can watch a live and a paper session at once — put a different connection token in each cell: ```excel =RTD("Tws.Rtd",, "port=7496", "AAPL", "BID") ' Live TWS =RTD("Tws.Rtd",, "port=7497", "AAPL", "BID") ' Paper TWS =RTD("Tws.Rtd",, "gw", "AAPL", "BID") ' Gateway live ``` The client ID can be pinned with the `TWS_RTD_CLIENT_ID` environment variable, which supplies the ID for any connection whose formula does not name one; a `clientid=` token in the formula wins over it. See [Configuration → Environment variables](https://streamxls.com/docs-config#env-vars). ## Contract specification — Four ways to name an instrument ### 1 · Simple symbol (stocks) A bare symbol assumes `SecType=STK`, `Exchange=SMART`, `Currency=USD`. ```excel =RTD("Tws.Rtd",, "AAPL", "BID") ``` ### 2 · Key=value (recommended for complex securities) ```excel =RTD("Tws.Rtd",, "sym=SPY", "sec=OPT", "strike=680", "right=C", "exp=20251219", "BID") ``` | Key | Aliases | Meaning | |---|---|---| | `sym` | `symbol` | Underlying symbol | | `sec` | `sectype`, `securitytype` | Security type (STK, OPT, FUT, CASH, BAG, …) | | `exch` | `exchange` | Exchange | | `prim` | `primexch`, `primary`, `primaryexchange` | Primary exchange | | `cur` | `curr`, `currency` | Currency | | `exp` | `expiry`, `expiration`, `lasttradedate` | Expiration (YYYYMMDD options, YYYYMM futures) | | `strike` | `strikeprice` | Option strike | | `right` | `putcall`, `optiontype` | Option right (C or P) | | `mult` | `multiplier` | Contract multiplier | | `loc` | `localsymbol`, `local` | Exchange-specific local symbol | | `tc` | `tradingclass`, `class` | Trading class | | `conid` | `contractid` | TWS Contract ID | ### 3 · Compact notation Use `@` for the exchange and `/` as a delimiter, omitting trailing segments you don’t need. Format: `SYMBOL@EXCH/PRIMEXCH/SECTYPE/EXP/RIGHT/STRIKE/CURRENCY`. ```excel =RTD("Tws.Rtd",, "AAPL@NASDAQ/STK/USD", "BID") =RTD("Tws.Rtd",, "ES@CME/FUT/202503/USD", "LAST") =RTD("Tws.Rtd",, "EUR.USD/CASH", "BID") ``` ### 4 · ConID (most precise) The TWS Contract ID identifies a contract unambiguously — useful for options with similar strikes. Find it in TWS via right-click → Financial Instrument Info → Description. ```excel =RTD("Tws.Rtd",, "conid=265598", "BID") ' AAPL ``` > **Case, and one instrument per formula.** Contract values are case-insensitive on every notation — `sym=spy`, `spy@arca/stk` and `spy` ask for the same contract as their upper-case spellings. The two exceptions are `loc=` and `tc=`, which are case-significant on TWS and pass through exactly as typed. A `key=value` argument overrides the same field written in compact form, so a column can change one part without rewriting the spec — except the symbol: a bare ticker that contradicts a `sym=` or stands beside a `conid=` names a *second* instrument, and fails loud rather than picking one. ### Worked examples | Instrument | Contract arguments | |---|---| | SPY option (call) | `"sym=SPY","sec=OPT","strike=680","right=C","exp=20251219"` | | ES future | `"sym=ES","sec=FUT","exch=CME","exp=202503"` | | MES micro future | `"sym=MES","sec=FUT","exch=CME","exp=202503"` | | EUR/USD forex | `"sym=EUR","sec=CASH","exch=IDEALPRO","cur=USD"` | | Specific future by local symbol | `"loc=ESH5","sec=FUT","exch=CME"` | ## Market data — Ticks, derived prices, and greeks Market-data formulas take a contract followed by a field: `=RTD("Tws.Rtd",, "", "")`. These are the fields nearly every workbook uses. ### Common price & size fields | Field | Meaning | Field | Meaning | |---|---|---|---| | `BID` | Best bid price | `BIDSIZE` | Size at best bid | | `ASK` | Best ask price | `ASKSIZE` | Size at best ask | | `LAST` | Last trade price | `LASTSIZE` | Last trade size | | `OPEN` | Session open | `VOLUME` | Total volume | | `HIGH` | Session high | `AVGVOLUME` | Average daily volume | | `LOW` | Session low | `LASTTIME` | Last-trade timestamp, as Unix epoch seconds in text | | `CLOSE` | Previous close | `HALTED` | Halt indicator (0 = not halted) | ### Derived price fields Two fields are computed by StreamXLS so a formula always has a reasonable price regardless of market hours or subscription: | Field | Precedence | |---|---| | `MarketPrice` | Mid `(BID+ASK)/2` when both present → else `LAST` → else `CLOSE`; blank until any source is available | | `LastOrClose` | `LAST` if available → else `CLOSE` | `Last` never falls through to a different tick field. ### Delayed-data indicators `TWS_RTD_MARKET_DATA_TYPE` (default `4`) is a *ceiling* request, not a description of your data: within one session TWS serves real-time to the symbols your subscriptions entitle and 15–20-minute-delayed data to the rest, *per contract*, and reports the served tier per contract. So “type 4 is set” never means every cell is delayed. Two per-contract fields read the served tier back, so a delayed price can’t silently pass for live: | Field | Meaning | |---|---| | `MarketDataType` | The tier TWS is **actually serving** this contract: `1` REALTIME · `2` FROZEN · `3` DELAYED · `4` DELAYED_FROZEN. `#N/A` until TWS reports it. Distinct from the [status-family `MarketDataType`](https://streamxls.com/docs-reference#status), which is the configured default you requested — the ceiling, not what any one contract got. | | `IsDelayed` | `1` when the served tier is delayed (`3` or `4`), `0` when real-time or frozen real-time (`1` or `2`), `#N/A` before TWS reports the tier. Sugar over `MarketDataType` — the simplest field to drive conditional formatting off. | > **Check `IsDelayed` per symbol** rather than assuming from the requested type. To instead turn every delayed price into visibly-marked text — at the cost of making the cell text — see [`TWS_RTD_DELAYED_ANNOTATION`](https://streamxls.com/docs-config#delayed-annotation). ### Option greeks For an option contract, greeks and model values are exposed per computation source. Field names compose as ``, where the source is `Bid`, `Ask`, `Last`, or `Model` and the measure is one of the eight below — e.g. `ModelDelta`, `BidImpliedVol`, `LastOptPrice`: | Measure | Meaning | |---|---| | `ImpliedVol` | Implied volatility | | `Delta` | Option delta | | `Gamma` | Option gamma | | `Theta` | Option theta | | `Vega` | Option vega | | `OptPrice` | Model option price | | `UndPrice` | Underlying price used in the computation | | `PvDividend` | Present value of dividends | ```excel =RTD("Tws.Rtd",, "sym=SPY", "sec=OPT", "strike=680", "right=C", "exp=20251219", "ModelDelta") ``` ### Option-chain enumeration Query an underlying to discover its option chain: | Field | Returns | |---|---| | `OptionExpirationsCSV` | Comma-separated expiration dates with options on the underlying | | `OptionStrikesCSV` | Comma-separated strike prices with options on the underlying | | `StrikeStep` | Minimum reported strike-price increment | ### Full tick catalog Every tick type StreamXLS maps, by field name. Core price/size ticks arrive for any tradeable security; the rest are requested per security type. When delayed data is active, the delayed tick IDs (66–76, 88, 90) feed the same base field names above — you keep using `BID`, `LAST`, etc. | RTD field | Tick ID | Description | |---|---|---| | `BIDSIZE` | 0 | Size at best bid | | `BID` | 1 | Best bid price | | `ASK` | 2 | Best ask price | | `ASKSIZE` | 3 | Size at best ask | | `LAST` | 4 | Last trade price | | `LASTSIZE` | 5 | Last trade size | | `HIGH` | 6 | Session high | | `LOW` | 7 | Session low | | `VOLUME` | 8 | Total volume | | `CLOSE` | 9 | Previous session close | | `OPEN` | 14 | Session open | | `WEEK13LO` / `WEEK13HI` | 15 / 16 | 13-week low / high | | `WEEK26LO` / `WEEK26HI` | 17 / 18 | 26-week low / high | | `WEEK52LO` / `WEEK52HI` | 19 / 20 | 52-week low / high | | `AVGVOLUME` | 21 | Average daily volume | | `OPTIONHISTORICALVOL` | 23 | Option historical volatility | | `OPTIONIMPLIEDVOL` | 24 | Option implied volatility | | `CALLOPTIONOPENINTEREST` | 27 | Call option open interest | | `PUTOPTIONOPENINTEREST` | 28 | Put option open interest | | `CALLOPTIONVOLUME` | 29 | Call option volume | | `PUTOPTIONVOLUME` | 30 | Put option volume | | `INDEXFUTUREPREMIUM` | 31 | Index-future premium | | `BIDEXCH` | 32 | Exchange(s) posting best bid | | `ASKEXCH` | 33 | Exchange(s) posting best ask | | `AUCTIONVOLUME` | 34 | Auction volume | | `AUCTIONPRICE` | 35 | Auction price | | `AUCTIONIMBALANCE` | 36 | Auction imbalance | | `PLPRICE` | 37 | P&L mark price | | `LASTTIME` | 45 | Timestamp of last trade (in Unix epoch seconds) | | `SHORTABLE` | 46 | Shortability indicator (>2.5 = easy) | | `HALTED` | 49 | Trading-halt indicator | | `TRADECOUNT` | 54 | Trade count | | `TRADERATE` | 55 | Trades per minute | | `VOLUMERATE` | 56 | Volume per minute | | `LASTRTHTRADE` | 57 | Last regular-hours trade | | `RTHISTORICALVOL` | 58 | Real-time historical volatility | | `IBDIVIDENDS` | 59 | Dividend info | | `BONDMULTIPLIER` | 60 | Bond factor multiplier | | `REGULATORYIMBALANCE` | 61 | Regulatory imbalance | | `SHORTTERMVOLUME3MIN` | 63 | 3-minute volume | | `SHORTTERMVOLUME5MIN` | 64 | 5-minute volume | | `SHORTTERMVOLUME10MIN` | 65 | 10-minute volume | | `CREDITMANMARKPRICE` | 78 | Credit mark price | | `CREDITMANSLOWMARKPRICE` | 79 | Slow credit mark price | | `LASTEXCH` | 84 | Exchange of last trade | | `FUTURESOPENINTEREST` | 86 | Futures open interest | | `AVGOPTVOLUME` | 87 | Average option volume (STK) | | `SHORTABLESHARES` | 89 | Shares available to short | | `ETFNAVLAST` | 96 | ETF NAV last | | `ETFFROZENNAVLAST` | 97 | Frozen ETF NAV last | | `ETFNAVHIGH` | 98 | ETF NAV high | | `ETFNAVLOW` | 99 | ETF NAV low | | `ESTIMATEDIPOMIDPOINT` | 101 | Estimated IPO midpoint | | `FINALIPOLAST` | 102 | Final IPO price | ## Accounts — Account values Read any IBKR account-summary value with `=RTD("Tws.Rtd",, "account", "", "")`. Numeric values return as numbers. Append a currency filter (`"cur=USD"`) to pull a per-currency variant instead of the generic figure. ```excel =RTD("Tws.Rtd",, "account", "U1234567", "NetLiquidation") =RTD("Tws.Rtd",, "account", "U1234567", "AvailableFunds", "cur=USD") =RTD("Tws.Rtd",, "account", "U1234567", "OpenPositionCount") ``` **Fields are pass-through.** Any IBKR account-summary tag resolves — case-insensitive and separator-tolerant (`"Net Liquidation"` matches `NetLiquidation`). Around 136 tags are delivered; the demo workbook’s **Account worksheet** is the canonical enumeration. Rather than list all of them, here are the common anchors: | Field | Field | Field | |---|---|---| | `NetLiquidation` | `AvailableFunds` | `BuyingPower` | | `TotalCashValue` | `ExcessLiquidity` | `MaintMarginReq` | | `GrossPositionValue` | `EquityWithLoanValue` | `OpenPositionCount` | `OpenPositionCount` is computed per-account from non-zero positions and updates live. For the full field list open [the demo workbook](https://streamxls.com/StreamXLS.xlsm) and read its Account worksheet. For clean resolution of aggregates vs. per-currency values, enable TWS’s “$LEDGER-” prefix API setting — see [Get Started → TWS / Gateway setup](https://streamxls.com/docs#tws-setup). **A key TWS never reports is named in the cell.** Because the keys are a pass-through, StreamXLS cannot check a spelling when you write the formula — it asks TWS. The cell reads `#N/A` while values are still arriving; once TWS has finished sending that account and reported other keys, a key that received nothing says so: `Account key 'NETLIQUIDATOIN' was not reported. TWS finished sending this account's values without reporting it — check the spelling; TWS also does not report every key for every account type. See streamxls.com/docs-reference.` The same message covers a real key TWS simply does not report for this account type, and it clears itself the moment a later delivery fills the cell. ## Positions — A single position, or the whole list ### Single / aggregate position `=RTD("Tws.Rtd",, "position", "", "", "")`. The account argument accepts one code, a comma-separated list, or `*` / blank for all accounts — matched positions aggregate (shares and market values sum; average cost is position-weighted). ```excel =RTD("Tws.Rtd",, "position", "U1234567", "AAPL", "UnrealizedPnL") =RTD("Tws.Rtd",, "position", "*", "AAPL@SMART", "MarketValue") ``` | Value fields | Contract-metadata fields | |---|---| | `Position` (shares) | `ConID`, `Symbol`, `SecType` | | `AverageCost` (per share) | `Strike`, `Right`, `Expiry` | | `MarketValue` | `Exchange`, `PrimaryExch` | | `DailyPNL` | `LocalSymbol`, `TradingClass` | | `RealizedPNL` / `UnrealizedPNL` | `Currency`, `Multiplier` | ### Positions list `=RTD("Tws.Rtd",, "positions", "", "")` enumerates the active positions across the accounts (every position where size ≠ 0 or market value ≠ 0). | Field | Returns | |---|---| | `SymbolsCsv` | Semicolon-delimited position identifiers (bare symbol for stocks; compact slash notation for options/futures) | | `ConIdCsv` | Semicolon-delimited ConIDs for the same positions | Spill the list across cells with `TEXTSPLIT` (Excel 365). The list delimiter is a semicolon: ```excel =TEXTSPLIT(RTD("Tws.Rtd", , "positions", , "SymbolsCsv"), ";") ' across columns =TEXTSPLIT(RTD("Tws.Rtd", , "positions", , "SymbolsCsv"), , ";") ' down rows =IFERROR(TEXTSPLIT(RTD("Tws.Rtd", , "positions", , "SymbolsCsv"), ";"), "") ' first-load guard ``` **Initial-load guard.** The server withholds the first `SymbolsCsv`/`ConIdCsv` until the initial positions snapshot completes, so wrap the spill in `IFERROR` to avoid a transient error on first load. To detect when the set changes, pair `SymbolsCsv` with the status field [`LastPositionListChangeUtc`](https://streamxls.com/docs-reference#status). ## Orders — Monitoring orders ### Orders list `=RTD("Tws.Rtd",, "orders", "", "")` returns a comma-separated list of PermIDs, filtered by account (`*` / blank = all). | Field | Returns | |---|---| | `ListCsv` | All orders the server has seen, including filled / cancelled / completed | | `OpenListCsv` | Active orders only — excludes Filled, Cancelled, Inactive, ApiCancelled | ### Single-order fields `=RTD("Tws.Rtd",, "order", "", "")`. Orders are addressed by **PermID** (the permanent, cross-client order ID that the orders lists return) — not the transient client-side order ID. Individual order fields always show last-known values regardless of order status. | Identity & status | Sizing & price | Contract & routing | |---|---|---| | `PERMID`, `PARENTID` | `QUANTITY` | `SYMBOL`, `CONID`, `SECTYPE` | | `Status` | `FILLED`, `REMAINING` | `EXCHANGE`, `CURRENCY` | | `SIDE` (`ACTION`) | `LMTPRICE`, `STOPPRICE` | `EXPIRY`, `STRIKE`, `RIGHT` | | `ORDERTYPE` (`TYPE`) | `AVGFILLPRICE` | `ACCOUNT`, `SUBMITTER` | | `ORDERREF` | `TRAILSTOPPRICE` | `TIF`, `GOODAFTERTIME` | | `FirstSeenUtc` | `TRAILINGPERCENT` | `GOODTILLDATE`, `OUTSIDERTH` | | `LastUpdateUtc` | `HIDDEN`, `DISPLAYSIZE` | `ALGOSTRATEGY`, `ALGOPARAMS` | | `WHYHELD` | `ALLOWPREOPEN` | `LOCALSYMBOL`, `TRADINGCLASS` | | `WARNINGTEXT` | `MINQTY`, `PERCENTOFFSET` | `MULTIPLIER`, `PRIMARYEXCHANGE` | | `REJECTREASON` | `DISCRETIONARYAMT`, `CASHQTY` | `ACTIVESTARTTIME`, `ACTIVESTOPTIME` | | `COMPLETEDTIME`, `COMPLETEDSTATUS` | `LMTPRICEOFFSET` | | | Group | Fields | |---|---| | Booleans | `BLOCKORDER`, `SWEEPTOFILL`, `ALLORNONE`, `NOTHELD`, `SOLICITED`, `WHATIF`, `INCLUDEOVERNIGHT` | | Commission & fees | `COMMISSIONANDFEES`, `MINCOMMISSIONANDFEES`, `MAXCOMMISSIONANDFEES`, `COMMISSIONANDFEESCURRENCY`, `MARGINCURRENCY` — from TWS whatIf/openOrder data | | Margin impact | `INITMARGINBEFORE`, `INITMARGINCHANGE`, `INITMARGINAFTER`, `MAINTMARGINBEFORE`, `MAINTMARGINCHANGE`, `MAINTMARGINAFTER`, `EQUITYWITHLOANBEFORE`, `EQUITYWITHLOANCHANGE`, `EQUITYWITHLOANAFTER` — from TWS whatIf/openOrder data | **Closed field set.** Order fields are a closed vocabulary: an unknown or misspelled field errors loudly in the cell at formula entry (e.g. `Unknown order field 'FOO'…`) rather than silently showing `#N/A`. The tables above are the more common fields; the [generated reference on GitHub](https://github.com/StreamXLS/streamxls/blob/main/docs/reference.md) lists the complete set, along with the TWS order properties that are deliberately not offered and why. (Need a field not offered? Contact support.) **`ORDERREF`** returns your bare `tag`/ClientTag for an engine-staged order — the engine strips its own `|SXLS:` suffix, so a tagless engine order reads `#N/A`, not blank. Orders entered in TWS or by other clients return their Order Ref verbatim. (The TWS-visible composed format is described under [Staging orders](https://streamxls.com/docs-reference#stageorder).) ### Order-status glossary | Status | Meaning | |---|---| | `PendingSubmit` | Transmitted but not yet confirmed | | `PendingCancel` | Cancel request sent, awaiting confirmation | | `PreSubmitted` | Simulated order accepted, awaiting election | | `Submitted` | Order accepted by the system | | `Filled` | Completely filled | | `Cancelled` | Cancelled (confirmed) | | `ApiCancelled` | Cancelled via API before acknowledgment | | `Inactive` | Rejected or cancelled | ## Staging orders — StageOrder `StageOrder` populates an order ticket in TWS as a side-effect of subscribing — entering the formula is what stages it. It takes `key=value` tokens in any order and returns a status string. (Note that *staging* does not create a live order; you must still click *submit* in TWS for the order to transmit to the market.) ```excel =RTD("Tws.Rtd",, "StageOrder", "sym=AAPL", "side=BUY", "shares=100", "type=LMT", "limit=150.05", "exch=SMART", "tag=SampleOrder#1") ``` ### Required keys | Key | Aliases | Notes | |---|---|---| | `sym` | `symbol` | Symbol | | `side` | `action` | `BUY` or `SELL` | | `shares` | `quantity`, `qty`, `size` | Integer quantity | | `type` | | `MKT`, `LMT`, `STP`, `STP LMT`, `TRAIL`, `TRAIL LIMIT`, … (other IB order types as supported) | | `limit` | | Required when `type=LMT` or `type=STP LMT` | > Type-dependent requirements, all checked by StreamXLS *before* anything is staged: `STP`/`STP LMT` require `stop`; `TRAIL` and `TRAIL LIMIT` each require exactly one of `stop` (the trailing amount) or `trailingpercent`; `stop`/`trailingpercent` on a type that cannot use them is rejected. `TRAIL LIMIT` adds two more requirements: `trailstop` (the initial trailing trigger price) and exactly one of `limit` or `limitoffset`. ### Common optional keys | Key | Sets | |---|---| | `exch` | Exchange (defaults to `SMART`) | | `account` | IB account code | | `fagroup` | FA group | | `algo` / `algostrategy` | Algo strategy name | | `algoparams` | Algo params, encoded `tag=value\|tag=value\|…`. Requires `algo=` — the parameters attach to a strategy, so without one the whole list would be dropped at staging. The pipe is the only separator | | `tag` / `nonce` / `seq` | Client tag for your tracking. Composed into the TWS-visible Order Ref ahead of the engine’s unique tracking token: `\|SXLS:` — your tag reads first; a tagless order carries only the `SXLS:`. (The StreamXLS [`ORDERREF` field](https://streamxls.com/docs-reference#orders) strips the SXLS token and returns only your tag.) | | `park` / `parked` / `saved` | `TRUE`/`FALSE` (default `FALSE`). `park=true` stages the order as a ticket visible only in your own TWS (released by clicking its **Transmit** button in TWS). The default StageOrder ticket is visible in every TWS instance (released by clicking **Submit** in TWS). | ### Order attribute keys (validated) | Key | Aliases | Value / validation | |---|---|---| | `tif` | | One of `DAY`, `GTC`, `IOC`, `FOK`, `OPG`, `GTD` (default `DAY`). `GTD` requires `goodtilldate` | | `goodtilldate` | `gtd` | Real date/time `YYYYMMDD [HH:MM:SS [TZ]]`; requires `tif=GTD` | | `goodaftertime` | `gat` | Real date/time `YYYYMMDD [HH:MM:SS [TZ]]`; any tif | | `outsiderth` | | `TRUE`/`FALSE` — allow fills outside regular trading hours | | `stop` | `aux`, `stopprice` | Decimal > 0. Required for `STP`/`STP LMT`; the trailing amount for `TRAIL` and `TRAIL LIMIT`, each of which requires exactly one of `stop` or `trailingpercent`; only valid on stop/trail types | | `trailingpercent` | | Decimal > 0 and ≤ 100; only valid on `TRAIL`/`TRAIL LIMIT`. The alternative to `stop` on *both* trailing types — each requires exactly one of the two | | `trailstop` | `trailstopprice` | Initial trailing *trigger* price, decimal > 0; only valid on `TRAIL`/`TRAIL LIMIT`. Required for `TRAIL LIMIT`; optional for `TRAIL` | | `limitoffset` | `lmtoffset` | Distance from the trailing trigger to the limit price; `TRAIL LIMIT` only. Any finite decimal — zero and negative offsets are accepted and passed through, their meaning defined by TWS. Mutually exclusive with `limit` | | `hidden` | | `TRUE`/`FALSE` — hidden order | | `display` | `displaysize` | Integer > 0 — iceberg display size | | `allornone` | `aon` | `TRUE`/`FALSE` | | `minqty` | | Integer > 0 — minimum fill quantity | | `ocagroup` + `ocatype` | | Required **together**. `ocagroup` = your OCA group name; `ocatype` = `1` (cancel remaining with block), `2` (reduce remaining with block), or `3` (reduce remaining without block) | > Every key is validated before anything is staged; an invalid value or an unrecognized key errors loudly and no order is created. Supplying two synonyms of the same key (e.g. `stop=` and `aux=`) is rejected rather than silently picking one. Whether an attribute applies to a given order type/exchange (`hidden`, `display`, `minqty`) is enforced by TWS. Any TWS error is returned to Excel as the value of the StageOrder formula. ### Return values | Value | Meaning | |---|---| | `Sending` | Order ticket delivering to TWS. | | `Staged` | Order ticket delivered to TWS, awaiting your action there. | | `PreSubmitted` / `Submitted` / `Filled` / `Inactive` | After you send the order from TWS, the StageOrder subscription follows TWS’s own status reports. | | `Cancelled` | The staged order was discarded, or the submitted order was cancelled. | | `SendOrder Error: …` / `Error nnn: …` | Validation / connection / TWS order error | How the staged order presents in TWS is chosen per formula with the optional `park` key. - **Default:** the order appears in TWS order lists as a deactivated (“PreSubmitted”) order with a **Submit** button. PreSubmitted orders are visible to other TWS instances viewing the same account, and survive a TWS restart. - **`park=true`** (synonyms `parked=`, `saved=`): populates a local order ticket, which appears only in *your* TWS order list with a **Transmit** button. Other TWS instances on the account don’t see it, and it does not appear in the API’s [Orders](https://streamxls.com/docs-reference#orders) list. (TWS assigns a permanent id only if it is transmitted.) Either way the order can never reach the market without a human click in TWS. Once you act on the order there, the cell tracks TWS’s reports — including recovery from a failed release attempt (e.g., a missing account allocation): fix and transmit in TWS and the cell updates to the working status. > **Deduplication.** Excel deduplicates RTD topics with identical parameters, so entering the exact same order description twice in a row places only one order. To describe a second order that would otherwise look identical, add a unique `tag`/`nonce` (e.g. `nonce=2`) so Excel creates a distinct subscription. > **A StageOrder cell is a trigger, not an order tracker.** Staging happens the moment a formula is *freshly entered* — typed, edited, or written by a macro. Three consequences follow, all deliberate: > > - **Editing a staged formula stages a *second* order.** Excel keys a formula by its exact arguments, so changing any token — fixing a price, a size, a typo — is a new subscription: StreamXLS stages a new order and leaves the previous one staged in TWS. (You now have two.) > - **Deleting the formula does not cancel the order.** After `Staged`, removing the cell only stops it from tracking — the ticket stays in TWS. Change or cancel it where it lives, in TWS. > - **Reopening a saved workbook does not re-stage.** StreamXLS recognizes the reopen and disarms each StageOrder formula with the value `Disarmed: workbook reopen does not re-stage orders`. To re-stage a disarmed StageOrder, re-enter the formula (F2, Enter). A TWS reconnect does not re-stage either. To watch and manage live orders, use the [Orders](https://streamxls.com/docs-reference#orders) topics. ## Status fields — Connection & data-freshness status `=RTD("Tws.Rtd",, "status", "")`. Most status fields are **per-connection**, so **name the connection in every status formula** — a connection token (`paper`/live, or `host=`/`port=`) alongside the field. A formula that names none piggybacks the sole connection while there is exactly one; once a second connection exists that binding no longer means anything, and the per-connection fields read `#AMBIGUOUS-CONNECTION` and the remedy rather than answer for a connection you never named. `ConnectionKey` reports the connection a cell actually bound to. Name exactly *one* field, too: an extra argument after the field fails loud — `Unexpected extra argument '…' for a 'status' topic. Name exactly one status field.` | Field | Meaning | |---|---| | `IsConnected` | Link with TWS: `1` when connected, `0` otherwise | | `ConnectionKey` | Which TWS *this cell* is actually reading, as `host:port:clientId` — a report, not a token to paste back into a formula. `#N/A` when the binding cannot be determined | | `RotationCount` | Lifetime automatic client-ID rotations on this connection | | `ActiveTopicCount` | Number of subscribed topics | | `LastUpdateUtc` | Timestamp of the last successful update (Excel UTC datetime) | | `ServerHeartbeatUtc` | Timestamp of the server’s most recent status pass — it measures StreamXLS running, not Excel calling, and never TWS liveness | | `AccountsCSV` | Comma-separated managed account IDs from the connection handshake | | `MarketDataType` | Configured default type — the ceiling you requested: 1 REALTIME · 2 FROZEN · 3 DELAYED · 4 DELAYED_FROZEN. (Per-contract, the [market-data field `MarketDataType`](https://streamxls.com/docs-reference#market-data) reports what TWS is *actually serving* that contract, which can differ.) | | `ServerVersion` | This connection’s negotiated TWS ServerVersion (int), or `Not Connected` | | `MarketDataState` | `Ok` (≥206) / `TooOld` (1–205) / `Unknown` (0) | | `MarketDataMessage` | Actionable “update your TWS API” text when `TooOld`, else empty | | `OrderDataState` | Disconnected / Idle / Requested / Receiving / Ready | | `LastOrderListChangeUtc` | Updates when the order-list membership changes for subscribed accounts | | `LastOrderUpdateUtc` | Advances whenever TWS delivers order information that actually *changed* something you could read in a cell — a poll that re-delivers identical orders does not move it | | `LastOrderPollUtc` | When the last complete open-orders response arrived, changed or not — order-feed liveness (every 15s by default). Pair it with the stamp above to tell “nothing happened” from “the feed stopped” | | `PositionDataState` | Disconnected / Idle / Requested / Receiving / Ready | | `LastPositionListChangeUtc` | Updates when the open-symbol list membership changes | | `LastPositionUpdateUtc` | Updates on every position data callback | | `ConfigWarnings` | `TWS_RTD_*` configuration-validation warnings; empty when clean (see [Configuration](https://streamxls.com/docs-config#env-vars)) | ## Metadata & license — Build, license, and TWS-API fields Metadata fields take no topic word — just the field: `=RTD("Tws.Rtd",, "")`. They resolve in every license state, so a workbook can surface build and license status without special handling. ### Build | Field | Returns | |---|---| | `VERSION` | Product version, SemVer (e.g. `1.0.0`) | | `BUILD_TIME` | When the DLL was compiled (UTC) | | `SERVER_PATH` | Full path to the loaded `StreamXLS.dll` | | `CONFIGURATION` | Build configuration (Debug / Release) | | `ASSEMBLY_NAME` | Assembly name (StreamXLS) | ### License | Field | Returns | |---|---| | `LICENSE_STATE` | Developer / Trial / Paid / Expired / Unknown | | `LICENSE_MESSAGE` | Human-readable status (trial days, reconnect heads-up, or purchase pointer) | | `LICENSE_DAYS_REMAINING` | Whole days left in the trial (empty when not in a trial). `#N/A` when a trial is running but its end date could not be read — never a guessed `0` | ### TWS-API binding | Field | Returns | |---|---| | `TWSAPI_STATE` | State of the runtime binding to IBKR’s `CSharpAPI.dll` | | `TWSAPI_MESSAGE` | Actionable guidance when the TWS API is absent / too old / incompatible | | `TWSAPI_VERSION` | Detected TWS API version (empty if not detected) | ### Update breadcrumb | Field | Returns | |---|---| | `UPDATE_AVAILABLE` | `1` when a newer release is available, `0` when a check has run and found none, `#N/A` when this computer has no completed update check on record — or the last one is more than two weeks old | | `UPDATE_CRITICAL` | `1` when that update is critical, `0` when it is not, `#N/A` on the same no-evidence terms | | `UPDATE_LATEST_VERSION` | Latest known version (empty when none) | | `UPDATE_MESSAGE` | Human-readable update notice: empty when up to date, the notice when an update is available, and an explanation when the update status is unknown | The `UPDATE_*` fields read a local breadcrumb left by the daily update check; the engine makes no network call. StreamXLS will not claim you are current on evidence it does not have: with no completed check on record — or one older than two weeks — the two flag fields read `#N/A` and `UPDATE_MESSAGE` says which case you are in. A real available update always reads `1`. Each field comes in two forms: as a metadata field (shown above) it resolves once when the cell connects, and the same four names are also available as *live* status fields — `=RTD("Tws.Rtd",,"status","UPDATE_CRITICAL")` — which re-check on every heartbeat, so a critical-update notice can reach a cell mid-session without re-entering the formula. For how the 30-day trial auto-starts and how to activate a license key, see [Get Started → Your trial & license](https://streamxls.com/docs#trial-license). [← Get Started](https://streamxls.com/docs) [Configuration →](https://streamxls.com/docs-config) [How it works](https://streamxls.com/how-it-works) --- *StreamXLS is not affiliated with, endorsed by, or sponsored by Interactive Brokers. Trader Workstation, the TWS API, and Excel are products of their respective owners; their use is governed by their respective licenses. StreamXLS does not provide investment advice or recommendations.* *Markdown mirror of , generated at build time. Every public page on this site is also served as markdown at the same path plus `.md`. Index: .*