Skip to content

Spreadsheet

The Spreadsheet is a live worksheet. ORT_* formulas read the Portfolio, Underlying, Position, and System table data for a given account, and the cell value updates as new data arrives. The function names, field names, and arguments match the Excel RTD add-in.

The Cell Tracker records a selected cell’s value once per second and displays it as a quote, a sparkline, or a chart. A tracked cell can contain any formula.

The live spreadsheet with ORT formulas

The toolbar across the top of the sheet has four buttons.

  • Live / Paused - Pauses and resumes live updates. While paused, the sheet does not recalculate, which allows formulas to be edited without interruption. Resuming recomputes all cells.
  • Refresh - Rescans the sheet for ORT_* formulas and forces one recompute of all of them. Use it if a formula shows #NAME? after a paste or load. It also retrieves the latest recorded history from the server.
  • Dashboard - Opens and closes the charts panel on the right (single- and dual-curve line charts and bar charts). Quotes are shown separately in the always-visible quotes bar above.
  • Cell Tracker - Opens and closes the Cell Tracker box (the track list and add actions).

Type = in a cell and begin with ORT_ to see the list, or select a function from the OptionsRealTime group on the Formulas tab of the ribbon. Each function is a live read: the cell value updates as new data arrives, and only cells whose underlying data changed are recomputed.

A formula to confirm it is working:

=ORT_ACCOUNTS_SIZE()

That returns the number of connected accounts. From there:

=ORT_SYSTEM_VALUE("U1234567", "SYSTEM_STATUS")
  • Account argument - Accepts an account ID ("U1234567") or an account name ("My IRA"), case-insensitive.
  • Field name - Accepts the wire name ("NET_LIQUIDATION"), case-insensitive. Use the *_FIELD_AT functions to list the valid names for a table.
  • Indexes are 1-based - The first item is index 1, matching the Excel add-in.
  • conidOrSymbol - Where a function takes a contract, a number is treated as a contract ID and a string as a symbol (matched case-insensitively). When a symbol matches more than one contract, the lowest contract ID is used.
  • Dynamic arrays - Functions spill. When an array is passed in, an array is returned: =ORT_ACCOUNT_NAME_AT(SEQUENCE(ORT_ACCOUNTS_SIZE())) returns the full list of account names down a column.
  • Errors - #N/A means the value is not available yet (an account not connected, a name that has not arrived). #VALUE! means an argument was invalid (an unknown field name, a non-numeric index).

Each table exposes the same shape: a value accessor, row discovery (a count and an at-index lookup), and field discovery (a field count and an at-index name lookup). Pair a *_SIZE with the matching *_AT and SEQUENCE to list accounts, contracts, symbols, or field names dynamically.

FunctionReturns
ORT_ACCOUNTS_SIZE()Number of connected accounts.
ORT_ACCOUNT_AT(index)Account ID at a 1-based index, sorted by ID.
ORT_ACCOUNT_NAME_AT(index)Account name at a 1-based index (same order). Returns the ID until the name arrives.
ORT_ACCOUNT_NAME(account)Account name for an account ID or name.
ORT_ACCOUNT_ID(accountOrName)Canonical account ID for an ID or name.
FunctionReturns
ORT_SYSTEM_VALUE(account, fieldName)System-table value for an account.
ORT_SYSTEM_FIELDS_SIZE()Number of System fields.
ORT_SYSTEM_FIELD_AT(index)System field name at a 1-based index.

The Portfolio value reads the account-level Total row (the base-currency aggregate).

FunctionReturns
ORT_PORTFOLIO_VALUE(account, fieldName)Account-level Portfolio value.
ORT_PORTFOLIO_FIELDS_SIZE()Number of Portfolio fields.
ORT_PORTFOLIO_FIELD_AT(index)Portfolio field name at a 1-based index.

One row per held contract.

FunctionReturns
ORT_POSITION_VALUE(account, conidOrSymbol, fieldName)Position value for a contract (number = contract ID, string = symbol).
ORT_POSITION_CONIDS_SIZE(account)Number of position rows for the account.
ORT_POSITION_CONID_AT(account, index)Contract ID at a 1-based index, ascending.
ORT_POSITION_SYMBOLS_SIZE(account)Number of distinct position symbols.
ORT_POSITION_SYMBOL_AT(account, index)Symbol at a 1-based index, alphabetical.
ORT_POSITION_FIELDS_SIZE()Number of position fields.
ORT_POSITION_FIELD_AT(index)Position field name at a 1-based index.

One row per underlying (the position rows summarized to the underlying). Same shape as Position.

FunctionReturns
ORT_UNDERLYING_VALUE(account, conidOrUnderlying, fieldName)Underlying value (number = contract ID, string = underlying).
ORT_UNDERLYING_CONIDS_SIZE(account)Number of underlying rows for the account.
ORT_UNDERLYING_CONID_AT(account, index)Contract ID at a 1-based index, ascending.
ORT_UNDERLYING_SYMBOLS_SIZE(account)Number of distinct underlyings.
ORT_UNDERLYING_SYMBOL_AT(account, index)Underlying at a 1-based index, alphabetical.
ORT_UNDERLYING_FIELDS_SIZE()Number of underlying fields.
ORT_UNDERLYING_FIELD_AT(index)Underlying field name at a 1-based index.

Read a single value.

=ORT_SYSTEM_VALUE("U1234567", "BYTES_SYSTEM")
=ORT_PORTFOLIO_VALUE("My IRA", "NET_LIQUIDATION")
=ORT_POSITION_VALUE("U1234567", "AAPL", "PNL")
=ORT_POSITION_VALUE("U1234567", 265598, "DELTA_DOLLARS")
=ORT_UNDERLYING_VALUE("U1234567", "SPY", "THETA")

List the accounts. Read one at a time, or return the whole list with SEQUENCE.

=ORT_ACCOUNT_AT(1)
=ORT_ACCOUNTS_SIZE()
=ORT_ACCOUNT_AT(SEQUENCE(ORT_ACCOUNTS_SIZE()))
=ORT_ACCOUNT_NAME_AT(SEQUENCE(ORT_ACCOUNTS_SIZE()))

ORT_ACCOUNT_AT(1) returns one account ID, such as "U1234567", and ORT_ACCOUNTS_SIZE() returns the count. SEQUENCE turns the count into 1..n, so the last two return every account ID and every account name down a column. SEQUENCE(1, n) returns a row instead of a column.

Discover the field names. Every value function takes a fieldName. The valid names for a table are listed with the same size-then-at pattern: get the count, read one name, or return them all.

=ORT_SYSTEM_FIELDS_SIZE()
=ORT_SYSTEM_FIELD_AT(1)
=ORT_SYSTEM_FIELD_AT(SEQUENCE(ORT_SYSTEM_FIELDS_SIZE()))

ORT_SYSTEM_FIELDS_SIZE() is the count, ORT_SYSTEM_FIELD_AT(1) is the first name, and the spilled form returns all of them. Each name returned is a valid fieldName for ORT_SYSTEM_VALUE. The other tables follow the same pattern:

=ORT_PORTFOLIO_FIELD_AT(SEQUENCE(ORT_PORTFOLIO_FIELDS_SIZE()))
=ORT_POSITION_FIELD_AT(SEQUENCE(ORT_POSITION_FIELDS_SIZE()))
=ORT_UNDERLYING_FIELD_AT(SEQUENCE(ORT_UNDERLYING_FIELDS_SIZE()))

Contracts and symbols use the same pattern, but are per-account, so the account argument appears in both the *_SIZE and the *_AT. To list every underlying symbol held in one account:

=ORT_UNDERLYING_SYMBOL_AT("U1234567", SEQUENCE(ORT_UNDERLYING_SYMBOLS_SIZE("U1234567")))

ORT_UNDERLYING_SYMBOLS_SIZE("U1234567") is the count for that account, SEQUENCE makes it a column, and ORT_UNDERLYING_SYMBOL_AT reads each index, so the account’s symbols are returned down a column. The Position table has the same pair (ORT_POSITION_SYMBOL_AT with ORT_POSITION_SYMBOLS_SIZE), and contracts use the *_CONID_AT / *_CONIDS_SIZE pair.

Symbols and contracts are per-account and take the account argument; field names are the same schema for every account, so ORT_*_FIELDS_SIZE() and ORT_*_FIELD_AT() take none.

Build a dropdown. Set an in-cell dropdown (Data tab, Data validation, list type) to a spilled range such as the account names above. When the dropdown cell changes, formulas that reference it recompute against the new selection.

The Cell Tracker records a cell as a time series. Once per second it reads the cell’s current value and appends a (time, value) point to a rolling buffer; quotes and charts draw from that buffer. The cell can contain any formula, so a field, a spread, or a derived value can be recorded.

The Cell Tracker

Right-click a cell on the sheet and choose Track cell. A dialog opens with:

  • Label (required) - The name used for the cell in the tracker, quotes, and charts.
  • Add Quote - Also create a quote for it.
  • Add Chart - Also create a line chart for it.

The right-click menu also has direct actions on an already-tracked cell: Set Title, Add Quote, Add Chart, Retrack, and Delete Track.

The Cell Tracker box lists tracks grouped by sheet. Each row begins with a checkbox and a color swatch, followed by the name, the cell reference in brackets, and the current value. Checking the row’s box selects the stream: its cell is outlined on the sheet in the stream’s color, and the stream is included in the batch actions at the top of the box. The remaining per-row controls are:

  • Aa - Rename the track.
  • The retrack button - Re-point the track to a different cell (see below).
  • x - Delete the track.

At the top of the box:

  • Cells - Shows or hides the outline for every tracked cell at once, which also selects or clears all rows.
  • The count line - The number of tracks, quotes, and charts, and how many rows are selected.
  • Chrt, Bar, Qt - Act on the selected rows: add a line chart for each, one bar chart of the selected set, or a quote for each.

Each track is assigned a color, used wherever the stream appears:

  • The cell outline on the sheet, when the row is selected.
  • The line and its Y axis in a line chart.
  • The bar in a bar chart.
  • The quote in the quotes bar.

The same color identifies the stream in each location.

A track points at a fixed cell position. To move it to a different cell - for example after an inserted column shifted the original - use Retrack: open it, click the new cell on the sheet, and confirm. The track keeps its name, color, and chart membership; only its location changes. Deleting the row or column a tracked cell occupies removes that track.

  • Sampling resolution is one second. The recorder captures reference values, not individual ticks.
  • A point is stored when the value changes, plus a confirmation point every minute so a flat value still renders as a line.
  • A gap longer than a few seconds (a reload, a suspended machine) breaks the line rather than drawing a segment across the missing interval. An overnight gap renders as a break, not a move.
  • History is retained for 12 hours per track.
  • Recording continues across navigation: the recorder keeps sampling while another page is open.
  • Recording is stored on the server. Reopening the View, including on another machine on the LAN, restores the recorded lines.

While the sheet is paused, tracked cells freeze with the rest of the sheet.

A quote shows one track’s label, current value, and a sparkline, in the track’s color. Add one from the right-click menu (Add Quote) or the Qt button in the tracker or on a chart. Quotes appear in the quotes bar at the top of the application. That bar is shared by every component and is always visible, so a tracked cell stays in view on other pages.

Open the dashboard (the Dashboard toolbar button or the pull tab on the right) to view charts. The panel holds line charts and bar charts; quotes are shown separately in the quotes bar above. There are two chart types.

Line charts and a bar chart in the dashboard panel

A line chart holds one or two tracks. With two, each has its own Y axis (left and right), the title reads A vs B, and the axis numbers are drawn in each line’s color to distinguish the two scales. The chart header contains:

  • Aa - Rename a stream.
  • Qt - Toggle a quote for that stream.
  • The swap button - Swap the left and right axes (two-stream charts).
  • + / - - Add a second stream, or remove one.
  • Move arrows - Reposition the chart left, right, up, or down among the other charts.
  • Maximize - Expand the chart to fill the panel; click again to restore.
  • x - Remove the chart.

Hovering the chart shows a crosshair with the time and each line’s value at that point. Gestures on the chart body: left-drag to zoom a time range, right-drag to pan, Ctrl or Cmd with the mouse wheel to zoom to the cursor, and double-click to reset to the current Window.

A bar chart shows one bar per stream, each in the stream’s color, at its current value (negative values extend below the zero line). The header has Aa to title the chart and a sort control (by value or by name, ascending or descending), applied on each update, so a value sort re-orders the bars as values change. Hovering a bar shows its name and value.

The Window row in the Display controls sets the shared time range for every line chart (the last minute, the last hour, and so on). Zooming a single chart detaches it from the shared Window; selecting a Window preset returns all charts to that range. The Display controls also set chart height.

The dashboard reads values computed in the sheet. The path is one-directional:

  1. An ORT_* formula in a cell reads table data and produces a value.
  2. Tracking the cell registers it with the recorder, which samples it once per second.
  3. The recorded points feed the quotes, sparklines, and charts.

A tracked cell can hold any formula, so the recorded series reflects whatever the formula computes. Changing the formula restarts recording under the new formula.

Saving the Spreadsheet View stores the workbook (all of its sheets, with their cells, formulas, and formatting), the tracks, the quotes, the charts, and the panel layout. Definitions are written only on an explicit Save, so an unsaved edit does not overwrite the saved layout.

Recorded history is stored separately on the server and written continuously by every open browser. Loading a View restores the layout and replays the recorded history into it, so opening the View on another machine on the LAN restores both the layout and the recorded data.