Skip to content

Excel

Tradeboard Excel Add-In

Overview

Tradeboard is an Excel Add-In that provides seamless integration with the Tradeboard API for algorithmic trading. This add-in allows users to fetch market data, resolve symbols, analyse option chains and Greeks, place and manage orders, retrieve historical data, and stream real-time market data directly from Excel.

The add-in exposes 82 worksheet functions covering 55 of the 57 registered Tradeboard v1 REST method/path pairs, plus the full WebSocket streaming protocol.

Features

  • Account Management: Funds, order book, trade book, position book, holdings, and pre-trade margin.
  • Market Data: Real-time quotes, multi-symbol quotes, market depth, historical candles, and supported intervals.
  • Symbol Services: Symbol metadata, instrument search, and expiry dates.
  • Options Analytics: Option chain, Black-76 Greeks, batch Greeks, synthetic futures, and option symbol resolution.
  • Order Management: Place, modify, cancel, and query orders; smart, basket, split, and options orders.
  • GTT Orders: Place, modify, cancel, and list Good Till Triggered orders, including OCO.
  • Risk Management: Close all open positions for a strategy, and an explicit trading arm switch.
  • Analyzer Mode: Toggle between sandbox simulation and live trading, with sandbox P&L per symbol.
  • Market Calendar: Holidays, trading session timings, and a holiday check.
  • Messaging: WhatsApp and Telegram notifications.
  • WebSocket Streaming: Real-time LTP, Quote, Depth, and order updates pushed to individual cells via RTD.
  • Persistent Configuration: API key and settings are saved to disk and auto-loaded on Excel restart.

Prerequisites

  • .NET 8.0 Desktop Runtime installed
  • Excel-DNA Add-In (included in the project dependencies)
  • Microsoft Excel (Office 365 recommended)
  • A running Tradeboard server

Install the Tradeboard Excel Add-In

Before installing, ensure you are selecting the correct version based on your Excel installation.

Steps to Check Your Excel Version

  1. Open Microsoft Excel
  2. Click File > Account
  3. Click About Excel
  4. Look for 32-bit or 64-bit in the version details.

Which Version Should You Install?

  • If your Excel version is 64-bit > Install the 64-bit add-in (Recommended)
  • If your Excel version is 32-bit > Install the 32-bit add-in

The installer detects your Excel bitness automatically and installs the matching add-in.

Download the Tradeboard Excel Add-In: GitHub Releases

.NET 8 Desktop Runtime is Required

Tradeboard Excel Add-In is built using Excel-DNA, which requires the .NET 8 Desktop Runtime to run.

If the add-in is not working or Excel does not recognize it, install the .NET 8 Desktop Runtime from: Download .NET 8 Desktop Runtime

After installing the runtime, restart your system and try loading the add-in again.


Configuration

Setting API Key, Version, and Host URL

Function: oa_api(APIKey, [APIVersion], [HostURL])

This function must be called once to configure the API connection. The configuration is persisted to disk at %LOCALAPPDATA%\Tradeboard\config.json, so you only need to call it once. On subsequent Excel sessions, the saved API key is automatically loaded.

All other functions use these stored credentials.

ParameterRequiredDefaultDescription
api_keyYes-API key for authentication
versionNo"v1"API version
HostURLNo"http://127.0.0.1:5000"Tradeboard server URL
=oa_api("your_api_key")
=oa_api("your_api_key", "v1", "http://127.0.0.1:5000")

Check the Add-In Version and Configuration

Function: oa_version()

Returns the add-in version and the configuration in force: host URL, API version, REST base, WebSocket URL, timeouts, and whether an API key is set. Makes no network call, so quote this first when reporting a problem.

=oa_version()

Verify the Connection

Function: oa_ping()

Verifies the API key resolves to an active broker session and names the broker. This is an authenticated check, not a process health probe: a revoked key or a logged-out broker fails it.

=oa_ping()

Trading Safety Switch (optional)

Function: oa_trading_enabled([Enable])

Order functions work out of the box, so nothing needs to be enabled before placing an order. This switch is an optional guard you can turn on if you want it.

A worksheet formula re-evaluates whenever the sheet recalculates, so an order formula sitting in a cell can fire again on a full rebuild (Ctrl+Alt+F9). Setting the switch to FALSE makes every order function refuse to send until you set it back.

=oa_trading_enabled()        Read the current state
=oa_trading_enabled(FALSE)   Block order functions from sending
=oa_trading_enabled(TRUE)    Allow them again (the default)

The setting lives for the current Excel session only and is not saved.

Functions it controls: oa_placeorder, oa_placesmartorder, oa_basketorder, oa_splitorder, oa_modifyorder, oa_cancelorder, oa_cancelallorder, oa_closeposition, oa_placegttorder, oa_modifygttorder, oa_cancelgttorder, oa_optionsorder, oa_optionsmultiorder.


Generic Endpoint Access

Function: oa_request(Method, Path, [JSONBody])

Raw call to any Tradeboard endpoint, returning the JSON response in a single cell. The API key is added for you: do not put apikey in the body.

Function: oa_json(JSONText, Path)

Pulls a value out of JSON text with a JSONPath expression. Objects and arrays come back as compact JSON, scalars as numbers, booleans, or text.

=oa_request("POST", "ping")
=oa_json(A1, "data.broker")
=oa_json(A1, "data[0].symbol")

Use these to reach any endpoint the add-in does not wrap directly, such as POST /telegram/webhook.


Account Functions

Retrieve Funds

Function: oa_funds()

Account funds: available cash, collateral, realised and unrealised M2M, and utilised margin. Returns a two-column table.

=oa_funds()

Retrieve Order Book

Function: oa_orderbook()

All orders placed today, one row per order: order id, symbol, exchange, action, quantity, price, trigger price, price type, product, status, and timestamp.

Function: oa_orderbook_stats()

Order book summary counts: buy, sell, completed, open, and rejected orders.

=oa_orderbook()
=oa_orderbook_stats()

Retrieve Trade Book

Function: oa_tradebook()

Executed trades for today, one row per fill: order id, symbol, exchange, action, quantity, average price, product, timestamp, and trade value.

=oa_tradebook()

Retrieve Position Book

Function: oa_positionbook()

Open and closed positions for today with live P&L: symbol, exchange, product, quantity, average price, LTP, and PnL. A quantity of 0 means the position was closed and the row carries the realised P&L.

=oa_positionbook()

Retrieve Holdings

Function: oa_holdings()

Delivery holdings with P&L: symbol, exchange, product, quantity, PnL, and PnL percent.

Function: oa_holdings_stats()

Portfolio totals: current market value, invested value, total P&L, and total P&L percentage.

=oa_holdings()
=oa_holdings_stats()

Calculate Pre-Trade Margin

Function: oa_margin(Positions, [Exchange], [Product], [PriceType])

Pre-trade margin for a basket of up to 50 positions, including hedging benefit. Reads the basket from a range and returns total margin required, SPAN, exposure, and margin benefit.

ParameterRequiredDescription
PositionsYesRange of positions. With a header row, columns are matched by name
ExchangeNoDefault exchange applied to rows that do not specify one
ProductNoDefault product
PriceTypeNoDefault price type
=oa_margin(A2:E5)
=oa_margin(A2:E5, "NFO", "NRML")

Market Data Functions

Get Last Traded Price

Function: oa_ltp(Symbol, Exchange)

Last traded price as a single number. This is the most convenient function for building a watchlist column.

=oa_ltp("RELIANCE", "NSE")

Get a Single Quote Field

Function: oa_field(Symbol, Exchange, Field)

One named field of a market quote as a single value. Parallels the streaming oa_ws_field.

Supported fields: ltp, open, high, low, prev_close, bid, ask, volume, oi, plus the computed change and changepct.

=oa_field("RELIANCE", "NSE", "high")
=oa_field("RELIANCE", "NSE", "changepct")

Get Market Quotes

Function: oa_quotes(Symbol, Exchange)

Full market quote for a symbol as a key/value table, including computed Change and Change %.

=oa_quotes("RELIANCE", "NSE")

Get Quotes for Multiple Symbols

Function: oa_multiquotes(Symbols, DefaultExchange)

Quotes for a range of symbols, one row per symbol. Far more efficient than one oa_quotes call per symbol.

ParameterRequiredDescription
SymbolsYesRange: one column of symbols, or two columns of symbol and exchange
DefaultExchangeNoExchange applied when the range has no exchange column (default NSE)

Returns Symbol, Exchange, LTP, Open, High, Low, Prev Close, Change, Change %, Bid, Ask, OI, Volume, and an Error column for symbols the server could not resolve.

=oa_multiquotes(A2:A20)
=oa_multiquotes(A2:B20)
=oa_multiquotes(A2:A20, "NSE")

Get Market Depth

Function: oa_depth(Symbol, Exchange)

Order book depth with the day summary. Returns the five-level bid and ask ladder plus LTP, Volume, Open, High, Low, Prev Close, LTQ, OI, Total Buy Qty, and Total Sell Qty.

=oa_depth("RELIANCE", "NSE")

Fetch Historical Data

Function: oa_history(Symbol, Exchange, Interval, StartDate, EndDate, [Source])

ParameterRequiredDescription
SymbolYesTrading symbol
ExchangeYesExchange
IntervalYesCandle interval, for example "1m", "5m", "15m", "D"
StartDateYesStart date, YYYY-MM-DD or a real Excel date cell
EndDateYesEnd date, YYYY-MM-DD or a real Excel date cell
SourceNo"api" for the broker (default) or "db" for Historify stored data

Returns a table with Ticker, Date (a real Excel date serial), Time (IST), Open, High, Low, Close, Volume, and OI when the payload carries it.

=oa_history("RELIANCE", "NSE", "5m", "2026-04-01", "2026-04-08")
=oa_history("RELIANCE", "NSE", "D", "2025-01-01", "2026-01-01", "db")

Get Supported Intervals

Function: oa_intervals()

Candle intervals supported by the connected broker, grouped by category.

=oa_intervals()

Symbol Functions

Get Symbol Metadata

Function: oa_symbol(Symbol, Exchange)

Instrument metadata: name, broker symbol, instrument type, expiry, strike, lot size, tick size, freeze quantity, and token.

=oa_symbol("RELIANCE", "NSE")

Get Lot Size and Token

Function: oa_lotsize(Symbol, Exchange) returns the lot size as a single number, which is what you need when sizing an F&O order from a sheet.

Function: oa_token(Symbol, Exchange) returns the broker instrument token as text.

=oa_lotsize("NIFTY25AUG26FUT", "NFO")
=oa_token("RELIANCE", "NSE")

Search Instruments

Function: oa_search(Query, [Exchange])

Searches instruments by name, strike, month, or option type. The tradable symbol is the first column so another formula can reference it directly.

Returns Symbol, Name, Exchange, Instrument Type, Expiry, Strike, Lot Size, Tick Size, Freeze Qty, Broker Symbol, Broker Exchange, and Token.

=oa_search("NIFTY 25000 CE")
=oa_search("RELIANCE", "NSE")

This is the fastest way to find the correct Tradeboard symbol format for an F&O contract.


Get Expiry Dates

Function: oa_expiry(Symbol, Exchange, InstrumentType, [ExpiryType])

ParameterRequiredDescription
SymbolYesUnderlying symbol, for example NIFTY
ExchangeYesF&O exchange: NFO, BFO, MCX, CDS, CRYPTO
InstrumentTypeYes"futures" or "options"
ExpiryTypeNo"monthly", "weekly", or "all". Applied locally, see note below

Returns Expiry (in the DD-MMM-YY form the API expects back), Date (an Excel serial), and Type.

Note: expirytype is not a parameter the Tradeboard server accepts. ExpirySchema declares only apikey, symbol, exchange, and instrumenttype, and rejects unknown fields, so sending it returns HTTP 400. This add-in applies the filter locally after fetching the full list.

=oa_expiry("NIFTY", "NFO", "options")
=oa_expiry("NIFTY", "NFO", "options", "monthly")

Options Functions

Option Chain

Function: oa_optionchain(Underlying, Exchange, Expiry, [StrikeCount], [WithGreeks], [InterestRate])

ParameterRequiredDescription
UnderlyingYesUnderlying symbol, for example NIFTY, BANKNIFTY, SENSEX
ExchangeYesUnderlying exchange: NSE_INDEX or BSE_INDEX
ExpiryYesExpiry in DDMMMYY format, for example 25AUG26
StrikeCountNoStrikes above and below ATM, 1 to 100. Default is all strikes
WithGreeksNoTRUE to attach IV and Greeks to every leg. Default TRUE, costs no extra call
InterestRateNoRisk-free rate as an annualised percent, Greeks only. Default 0

Layout: row 1 carries the context (Underlying, Spot, Prev Close, ATM Strike, Expiry, Forward, Strike count). Row 2 carries column headers. From row 3, one row per strike, laid out calls on the left, strike in the centre, puts on the right, mirrored around the strike so the ladder reads outward from the money.

Per side: LTP, Bid, Bid Qty, Ask, Ask Qty, IV, Delta, Gamma, Theta, Vega, Volume, OI, Open, High, Low, Prev Close, Lot Size, Tick Size, Symbol. Width is 41 columns with Greeks, 31 without.

=oa_optionchain("NIFTY", "NSE_INDEX", "25AUG26")
=oa_optionchain("NIFTY", "NSE_INDEX", "25AUG26", 10)
=oa_optionchain("BANKNIFTY", "NSE_INDEX", "25AUG26", 15, FALSE)

Option Greeks

Function: oa_optiongreeks(Symbol, Exchange, [InterestRate], [ExpiryTime], [UnderlyingSymbol], [UnderlyingExchange], [ForwardPrice])

Black-76 Greeks and implied volatility for one option. Returns IV plus delta, gamma, theta, vega, and rho.

=oa_optiongreeks("NIFTY25AUG2625000CE", "NFO")
=oa_optiongreeks("NIFTY25AUG2625000CE", "NFO", 7.0, "15:30")

Batch Option Greeks

Function: oa_multioptiongreeks(Symbols, [InterestRate], [ExpiryTime])

Greeks and IV for up to 50 options in one call.

The range accepts one column (symbols, exchange defaults to NFO), two columns (symbol, exchange), or four columns adding per-item underlying_symbol and underlying_exchange overrides.

Row 1 is the batch summary (Total, Success, Failed). Then one row per contract: Symbol, Exchange, Status, IV, Delta, Gamma, Theta, Vega, Rho, Error.

Individual items can fail while the batch still reports success, so check the Status and Error columns per row.

=oa_multioptiongreeks(A2:A20)
=oa_multioptiongreeks(A2:B20, 7.0)

Resolve an Option Symbol

Function: oa_optionsymbol(Underlying, Exchange, Expiry, StrikeOffset, OptionType)

Resolves an option trading symbol from underlying, expiry, and strike offset. strike_offset is ATM, ITM1 to ITM50, or OTM1 to OTM50. option_type is CE or PE.

The resolved symbol is the first data row, so INDEX(range, 2, 2) feeds it into another formula.

=oa_optionsymbol("NIFTY", "NSE_INDEX", "25AUG26", "ATM", "CE")
=oa_optionsymbol("NIFTY", "NSE_INDEX", "25AUG26", "OTM2", "PE")

Synthetic Future

Function: oa_syntheticfuture(Underlying, Exchange, Expiry)

Synthetic futures price for an expiry, derived from ATM options using put-call parity. Also reports the Basis (synthetic minus spot).

=oa_syntheticfuture("NIFTY", "NSE_INDEX", "25AUG26")

Place an Option Order

Function: oa_optionsorder(Strategy, Underlying, Exchange, Expiry, StrikeOffset, OptionType, Action, Quantity, [PriceType], [Product], [Price], [TriggerPrice], [SplitSize])

Places an option order by strike offset rather than by resolved symbol.

ParameterRequiredDefaultDescription
StrategyYes-Strategy identifier recorded against the order
UnderlyingYes-Underlying symbol
ExchangeYes-NSE_INDEX, BSE_INDEX, NFO, or BFO
ExpiryYes-Expiry in DDMMMYY format
StrikeOffsetYes-ATM, ITM1 to ITM50, OTM1 to OTM50
OptionTypeYes-CE or PE
ActionYes-BUY or SELL
QuantityYes-Quantity in units, not lots
PriceTypeNoMARKETMARKET, LIMIT, SL, SL-M
ProductNoMISMIS or NRML
PriceNo0Limit price for LIMIT and SL
TriggerPriceNo0Trigger price for SL and SL-M
SplitSizeNo0Split into chunks of this size, 0 for no split
=oa_optionsorder("MyStrategy", "NIFTY", "NSE_INDEX", "25AUG26", "ATM", "CE", "BUY", 75)

Place a Multi-Leg Option Strategy

Function: oa_optionsmultiorder(Strategy, Underlying, Exchange, Expiry, Legs)

Places a multi-leg option strategy from a table of legs (1 to 20).

The legs range needs a header row. Recognised columns: Offset, Option Type, Action, Quantity (required), and optionally Expiry, PriceType, Product, SplitSize, Price, TriggerPrice. Annotation columns such as Leg, Notes, and Remarks are ignored.

Returns one row per leg with its own Symbol, Order ID, Status, and Message, so a failed leg inside an otherwise successful strategy is visible.

Example sheet layout for a short strangle:

OffsetOption TypeActionQuantity
OTM3CESELL75
OTM3PESELL75
=oa_optionsmultiorder("Strangle", "NIFTY", "NSE_INDEX", "25AUG26", A1:D3)

Order Functions

Place an Order

Function: oa_placeorder(Strategy, Symbol, Action, Exchange, PriceType, Product, [Quantity], [Price], [TriggerPrice], [DisclosedQuantity])

ParameterRequiredDescription
StrategyYesTrading strategy name
SymbolYesTrading symbol
ActionYesBUY or SELL
ExchangeYesExchange code
PriceTypeYesMARKET, LIMIT, SL, SL-M
ProductYesMIS, CNC, NRML
QuantityNoOrder quantity
PriceNoLimit price
TriggerPriceNoTrigger price
DisclosedQuantityNoDisclosed quantity

Returns a Status / Order ID / Message table.

=oa_placeorder("MyStrategy", "RELIANCE", "BUY", "NSE", "MARKET", "MIS", 10)

Place a Smart Order

Function: oa_placesmartorder(Strategy, Symbol, Action, Exchange, PriceType, Product, [Quantity], [PositionSize], [Price], [TriggerPrice], [DisclosedQuantity])

Places an order that targets a desired net position size rather than a raw quantity.

=oa_placesmartorder("MyStrategy", "RELIANCE", "BUY", "NSE", "MARKET", "MIS", 10, 50)

Place a Basket Order

Function: oa_basketorder(Strategy, Orders)

Places several orders in one call from a range. A header row is detected and skipped.

Column order: Symbol, Exchange, Action, Quantity, and optionally PriceType, Product, Price, TriggerPrice, DisclosedQuantity.

Returns one row per leg: Symbol, Status, Order ID, Message.

=oa_basketorder("MyStrategy", A2:D5)

Place a Split Order

Function: oa_splitorder(Strategy, Symbol, Action, Exchange, [Quantity], [SplitSize], PriceType, Product, [Price], [TriggerPrice], [DisclosedQuantity])

Splits a large quantity into chunks. Returns one row per child order: Order Num, Order ID, Quantity, Status, Message.

=oa_splitorder("MyStrategy", "RELIANCE", "BUY", "NSE", 100, 25, "MARKET", "MIS")

Modify an Order

Function: oa_modifyorder(Strategy, OrderID, Symbol, Action, Exchange, [Quantity], PriceType, Product, [Price], [TriggerPrice], [DisclosedQuantity])

The server schema marks price, quantity, trigger_price, disclosed_quantity, pricetype, and product as required for a modify, so all of them are sent even when left blank.

=oa_modifyorder("MyStrategy", "250820000012345", "RELIANCE", "BUY", "NSE", 20, "LIMIT", "MIS", 1250)

Cancel an Order

Function: oa_cancelorder(Strategy, OrderID)

=oa_cancelorder("MyStrategy", "250820000012345")

Cancel All Orders

Function: oa_cancelallorder(Strategy)

Cancels all open orders for a strategy. Returns Order ID, Result, and Reason rows so failed cancellations are visible.

=oa_cancelallorder("MyStrategy")

Close All Open Positions

Function: oa_closeposition(Strategy)

=oa_closeposition("MyStrategy")

Get Order Status

Function: oa_orderstatus(Strategy, OrderID)

Returns the full order record as a key/value table.

=oa_orderstatus("MyStrategy", "250820000012345")

Get Open Position

Function: oa_openposition(Strategy, Symbol, Exchange, Product)

Returns the net open position quantity as a single number, so it can feed a formula directly.

=oa_openposition("MyStrategy", "RELIANCE", "NSE", "MIS")

GTT Order Functions

Good Till Triggered orders rest at the broker until their trigger fires. Both SINGLE and OCO trigger types are supported.

Place a GTT Order

Function: oa_placegttorder(Strategy, Symbol, Exchange, Action, Product, TriggerType, Quantity, [PriceType], [Price], [TriggerPriceSL], [TriggerPriceTG], [StopLoss], [Target])

Trigger typeFields to supply
SINGLEOne of trigger_price_sl or trigger_price_tg, plus price for a LIMIT
OCOAll four: trigger_price_sl, stoploss, trigger_price_tg, target

For OCO, trigger_price_sl must be below trigger_price_tg. Validation happens locally before any network call.

=oa_placegttorder("MyStrategy", "RELIANCE", "NSE", "SELL", "CNC", "SINGLE", 10, "LIMIT", 1300, , 1300)
=oa_placegttorder("MyStrategy", "RELIANCE", "NSE", "SELL", "CNC", "OCO", 10, "LIMIT", , 1150, 1300, 1145, 1305)

Modify a GTT Order

Function: oa_modifygttorder(Strategy, TriggerID, Symbol, Exchange, Action, Product, TriggerType, Quantity, [PriceType], [Price], [TriggerPriceSL], [TriggerPriceTG], [StopLoss], [Target])

A modify replaces the whole trigger, so send every field you want to keep.

=oa_modifygttorder("MyStrategy", "12345678", "RELIANCE", "NSE", "SELL", "CNC", "SINGLE", 10, "LIMIT", 1320, , 1320)

Cancel a GTT Order

Function: oa_cancelgttorder(Strategy, TriggerID)

Cancelling an OCO removes both legs.

=oa_cancelgttorder("MyStrategy", "12345678")

Retrieve the GTT Order Book

Function: oa_gttorderbook()

One row per trigger with its legs flattened into blocks. A book of only SINGLE triggers is 15 columns wide; a book containing an OCO widens to 21 with Leg 1 and Leg 2 prefixes.

=oa_gttorderbook()

Analyzer Functions

Analyzer mode simulates orders in a sandbox instead of sending them to the broker. Check this before arming a strategy.

Get Analyzer Status

Function: oa_analyzerstatus()

Reports whether orders are simulated or sent live, and how many orders the analyzer has logged.

=oa_analyzerstatus()

Toggle Analyzer Mode

Function: oa_analyzertoggle(Mode)

Accepts TRUE/FALSE or "analyze"/"live". The returned table states the resulting mode in its first row.

Warning: switching to live means every order function sends real orders to the broker.

=oa_analyzertoggle(TRUE)      Sandbox
=oa_analyzertoggle("live")    Live trading

Sandbox P&L by Symbol

Function: oa_pnl_symbols()

Sandbox P&L per symbol with realised, unrealised, and today totals. Analyzer mode only: in live mode the API answers HTTP 400 and this function says so.

=oa_pnl_symbols()

Market Calendar Functions

Market Holidays

Function: oa_holidays([Year], [Exchange])

Market holidays for a year: date, description, holiday type, the exchanges that are closed, and any special sessions. Times shown in IST.

=oa_holidays()
=oa_holidays(2026, "NSE")

Trading Timings

Function: oa_timings([Date])

Trading sessions for a date, one row per exchange, with IST start and end times. Defaults to today. An empty schedule means the market is closed that day.

=oa_timings()
=oa_timings("2026-08-15")

Holiday Check

Function: oa_isholiday(Date, [Exchange])

Returns TRUE when the market is closed on the date.

Derived from /market/timings, since Tradeboard has no /checkholiday endpoint: an empty session schedule means a weekend or holiday. With an exchange given, TRUE means that exchange has no session that day, so an MCX evening session on an NSE holiday correctly returns FALSE for MCX and TRUE for NSE.

=oa_isholiday("2026-08-15")
=oa_isholiday(TODAY(), "NSE")

Chart Preferences

Function: oa_chart() reads the chart workspace preferences stored for this API key. The first column holds the exact preference key, so it can be fed straight back into oa_chart_set.

Function: oa_chart_set(Key, Value) updates one preference. A value that parses as JSON is sent as JSON, anything else as text. Keys are limited to 50 characters.

=oa_chart()
=oa_chart_set("tv_theme", "dark")
=oa_chart_set("tv_chart_layout", "{""interval"":""15m""}")

Messaging Functions

WhatsApp

Function: oa_whatsapp([Message], [Recipient], [RecipientType], [ImagePath], [DocumentPath], [Caption], [Filename], [WaitForDelivery])

Sends a WhatsApp text, image, or document to yourself, a linked username, one phone number, or up to 5.

ParameterRequiredDescription
MessageNo*Text body, max 4096 characters
RecipientNoUsername, phone number, or a range of up to 5 phone numbers
RecipientTypeNoself, username, phone, or phones. Inferred when omitted
ImagePathNoServer-local path to an image
DocumentPathNoServer-local path to a document
CaptionNoCaption for the image
FilenameNoOverride the document's display name
WaitForDeliveryNoTRUE to block and return a per-recipient delivery report

* Message is optional only when ImagePath or DocumentPath is supplied.

Exactly one recipient form is required; combining them is not supported. Attachments are read from the Tradeboard server's filesystem, never uploaded from Excel, and must sit inside the directories listed in WHATSAPP_ATTACHMENT_ROOTS. The 5-recipient cap is a terms-of-service guardrail. Limit 30 calls per minute.

POST /whatsapp/notify is the entire public WhatsApp REST surface. Pairing, start/stop, config, users, broadcast, stats, and preferences are admin-only behind the web session cookie and are deliberately not reachable with an API key.

=oa_whatsapp("Strategy armed", , "self")
=oa_whatsapp("Order filled", "919876543210", "phone")
=oa_whatsapp("EOD chart", "rajan", "username", "/srv/charts/nifty.png")

Telegram

Function: oa_telegram(Username, Message, [WaitForDelivery], [Priority])

Sends a Telegram message to one linked Tradeboard user. Mirrors client.telegram(username=..., message=...) in the Python SDK.

ParameterRequiredDescription
UsernameYesTradeboard username already linked to a Telegram ID
MessageYesMessage text, max 4096 characters
WaitForDeliveryNoTRUE to attempt delivery immediately instead of queueing
PriorityNo1 to 10

By default the call returns as soon as the message is queued, so success means queued, not delivered. Pass TRUE to WaitForDelivery to attempt it immediately. Limit 30 calls per minute.

=oa_telegram("rajan", "NIFTY crossed 26000")
=oa_telegram("rajan", "Position opened", TRUE)

The Telegram management endpoints (bot config, start, stop, linked users, broadcast, stats, per-user preferences) are deliberately not wrapped, matching the SDK, which exposes only the notification call. Reach them with oa_request when needed:

=oa_request("GET", "telegram/stats")
=oa_request("POST", "telegram/start")

WebSocket Functions (Real-Time Streaming)

How It Works

Each streaming cell registers as its own RTD topic. When a tick arrives for that symbol, only the cells watching it update. Nothing is volatile, and the add-in never asks Excel to recalculate, so the rest of your workbook is untouched and Excel stays responsive.

The data functions auto-subscribe: just type the formula and the subscription is created in the background. A cell shows Subscribing... then Waiting for data... before the first tick arrives.

Connection Management

Connect to WebSocket

Function: oa_ws_connect([WebSocketURL])

Connects and authenticates using the API key set with oa_api(). The URL defaults to the saved value (ws://127.0.0.1:8765) and any URL you pass is persisted.

=oa_ws_connect()
=oa_ws_connect("wss://yourdomain.com/ws")

Subscriptions are restored automatically after a reconnect.

Disconnect

Function: oa_ws_disconnect()

Unsubscribes everything and closes the connection.

=oa_ws_disconnect()
Connection Status
FunctionReturns
oa_ws_status()The current connection state
oa_ws_ping()Round trip to the server in milliseconds
oa_ws_brokers()Brokers supported by the connected server
oa_ws_brokerinfo()Broker and adapter status for the authenticated session
=oa_ws_status()
=oa_ws_ping()
=oa_ws_brokers()
=oa_ws_brokerinfo()

Streaming Data Functions

LTP

Function: oa_ws_ltp(Symbol, Exchange)

Streams the last traded price as a single number.

=oa_ws_ltp("RELIANCE", "NSE")
Quote

Function: oa_ws_quote(Symbol, Exchange)

Streams the full quote as a two-column key/value table.

=oa_ws_quote("RELIANCE", "NSE")
Depth

Function: oa_ws_depth(Symbol, Exchange, [DepthLevel])

Streams the order book as a seven-column table: Bid Orders, Bid Qty, Bid Price, LTP, Ask Price, Ask Qty, Ask Orders.

=oa_ws_depth("RELIANCE", "NSE")
=oa_ws_depth("RELIANCE", "NSE", 20)
Single Field

Function: oa_ws_field(Symbol, Exchange, Field, [Mode])

Streams one named field as a single value. mode defaults to 2 (Quote).

=oa_ws_field("RELIANCE", "NSE", "ltp")
=oa_ws_field("RELIANCE", "NSE", "volume", 2)
Order Updates

Function: oa_ws_orders([MaxRows])

Streams real-time order updates for the account as a table, newest first. Buffered up to 200 entries.

Function: oa_ws_unsubscribe_orders() stops the stream.

=oa_ws_unsubscribe_orders()
=oa_ws_orders()
=oa_ws_orders(20)

Update Rate

There are two independent throttles between a tick arriving and a cell changing. Both must be open for real-time updates.

ThrottleOwned byDefaultSet with
How often the add-in pushes a topicThis add-in0 (every tick)oa_ws_throttle()
How often Excel collects pushed valuesExcel2000 msoa_rtd_interval()
Excel's RTD interval

Function: oa_rtd_interval([Milliseconds])

Excel applies its own limit, Application.RTD.ThrottleInterval, to every RTD server. It ships at 2000 ms, so a streaming cell repaints only once every two seconds no matter how fast data arrives. Broker feeds run at roughly 1 to 11 updates per second, so Excel's default discards most of them and live data looks frozen.

The add-in sets this to 0 on load and again on oa_ws_connect(). Use this function to read or change it.

=oa_rtd_interval()      Read the value Excel is using
=oa_rtd_interval(0)     Update as soon as data arrives (default)
=oa_rtd_interval(2000)  Excel's own default
=oa_rtd_interval(-1)    Freeze streaming until a manual recalculation

This is a per-user Excel setting, not a workbook setting, and Excel persists it. oa_version() reports the live value, so a reading of 2000 there explains a sheet that looks stalled.

The add-in's own throttle

Function: oa_ws_throttle([Milliseconds])

Sets the minimum gap between two pushed updates for one streaming cell. Omit the argument to read the current value. The setting is persisted.

=oa_ws_throttle()       Read the current value
=oa_ws_throttle(0)      Default: push every tick
=oa_ws_throttle(250)    At most 4 updates per second per cell

The throttle is leading plus trailing edge. Its guarantee: the last value the server sent for a topic always reaches the cell, at most throttle milliseconds late. A tick held back by the throttle is released by a trailing flush rather than dropped, so the final print of an illiquid strike, or a closing price, never sits stale in the sheet.

Leave it at 0 for real-time behaviour. Raise it only if a very large sheet on a fast feed starts to feel heavy.


Subscription Management

Subscribe Manually

Function: oa_ws_subscribe(Symbol, Exchange, Mode, [DepthLevel])

=oa_ws_subscribe("RELIANCE", "NSE", 1)
=oa_ws_subscribe("RELIANCE", "NSE", 3, 20)

Per-mode shorthands matching the Python SDK's subscribe_ltp, subscribe_quote and subscribe_depth:

FunctionEquivalent to
oa_ws_subscribe_ltp(symbol, exchange)oa_ws_subscribe(..., 1)
oa_ws_subscribe_quote(symbol, exchange)oa_ws_subscribe(..., 2)
oa_ws_subscribe_depth(symbol, exchange, [depth_level])oa_ws_subscribe(..., 3)
=oa_ws_subscribe_ltp("RELIANCE", "NSE")
=oa_ws_subscribe_quote("RELIANCE", "NSE")
=oa_ws_subscribe_depth("RELIANCE", "NSE", 20)
Unsubscribe
FunctionPurpose
oa_ws_unsubscribe(symbol, exchange, mode)One symbol and mode
oa_ws_unsubscribe_ltp(symbol, exchange)LTP only
oa_ws_unsubscribe_quote(symbol, exchange)Quote only
oa_ws_unsubscribe_depth(symbol, exchange)Depth only
oa_ws_unsubscribe_all()Everything
=oa_ws_unsubscribe("RELIANCE", "NSE", 1)
=oa_ws_unsubscribe_ltp("RELIANCE", "NSE")
=oa_ws_unsubscribe_quote("RELIANCE", "NSE")
=oa_ws_unsubscribe_depth("RELIANCE", "NSE")
=oa_ws_unsubscribe_all()

After a manual unsubscribe the cell shows Unsubscribed and does not auto-resubscribe.

View Active Subscriptions

Function: oa_ws_subscriptions()

=oa_ws_subscriptions()
Debug

Function: oa_ws_debug(Symbol, Exchange, Mode)

Shows subscription status and cached data keys.

=oa_ws_debug("RELIANCE", "NSE", 1)

WebSocket Data Modes

ModeNameContents
1LTPLast traded price only, lightest
2QuoteOHLC, volume, LTP, change
3DepthFull order book, 5 to 50 levels by broker

WebSocket Quick Start Example

A1: =oa_api("your_api_key")
A2: =oa_ws_connect()
A3: =oa_ws_status()

A5: =oa_ws_ltp("RELIANCE", "NSE")
A6: =oa_ws_ltp("TCS", "NSE")
A7: =oa_ws_ltp("INFY", "NSE")

A9: =oa_ws_depth("RELIANCE", "NSE")

Debugging and Logs

LocationContents
%LOCALAPPDATA%\Tradeboard\websocket.logWebSocket connection and subscription log
%LOCALAPPDATA%\Tradeboard\config.jsonSaved API key, host URL, and settings

Start any troubleshooting with =oa_version() and =oa_ping().


Notes

  • All functions require oa_api() to be configured first. The key is persisted, so this is normally a one-time step.
  • Order functions send as soon as they are called. oa_trading_enabled(FALSE) is an optional guard against a recalculation re-placing an order.
  • Streaming functions (oa_ws_ltp, oa_ws_quote, oa_ws_depth, oa_ws_field, oa_ws_orders) update by RTD push. They are not volatile and do not trigger workbook recalculation.
  • If streaming looks frozen, check oa_rtd_interval(). Excel caps RTD collection at 2000 ms by default; the add-in lowers it to 0, but a policy or another add-in can raise it again.
  • REST functions cache their result. Excel-DNA keys the async result on the function name plus its arguments, so a function such as oa_funds() fetches once and keeps returning the same value. Press Ctrl+Alt+F9 to force a full rebuild and refetch, or edit the formula.
  • Cells show #N/A while a request is in flight.
  • Order IDs and instrument tokens are returned as text, so they keep their exact digits. Reference them directly rather than retyping.
  • Timestamps are converted to IST. oa_history returns a real Excel date serial that charts directly.
  • Functions are grouped in the Excel function wizard under categories beginning with Tradeboard.
  • The add-in ships IntelliSense, so argument names and descriptions appear as you type.

Function Index

CategoryFunctions
Configurationoa_api, oa_version, oa_ping, oa_trading_enabled, oa_request, oa_json
Accountoa_funds, oa_orderbook, oa_orderbook_stats, oa_tradebook, oa_positionbook, oa_holdings, oa_holdings_stats, oa_margin
Market Dataoa_ltp, oa_field, oa_quotes, oa_multiquotes, oa_depth, oa_history, oa_intervals
Symbolsoa_symbol, oa_search, oa_expiry, oa_lotsize, oa_token
Optionsoa_optionchain, oa_optiongreeks, oa_multioptiongreeks, oa_optionsymbol, oa_syntheticfuture, oa_optionsorder, oa_optionsmultiorder
Ordersoa_placeorder, oa_placesmartorder, oa_basketorder, oa_splitorder, oa_modifyorder, oa_cancelorder, oa_cancelallorder, oa_closeposition, oa_orderstatus, oa_openposition
GTToa_placegttorder, oa_modifygttorder, oa_cancelgttorder, oa_gttorderbook
Analyzeroa_analyzerstatus, oa_analyzertoggle, oa_pnl_symbols
Calendaroa_holidays, oa_timings, oa_isholiday
Chartoa_chart, oa_chart_set
Messagingoa_whatsapp, oa_telegram
WebSocketoa_ws_connect, oa_ws_disconnect, oa_ws_status, oa_ws_ping, oa_ws_brokers, oa_ws_brokerinfo, oa_ws_ltp, oa_ws_quote, oa_ws_depth, oa_ws_field, oa_ws_orders, oa_ws_throttle, oa_rtd_interval, oa_ws_subscribe, oa_ws_subscribe_ltp, oa_ws_subscribe_quote, oa_ws_subscribe_depth, oa_ws_unsubscribe, oa_ws_unsubscribe_ltp, oa_ws_unsubscribe_quote, oa_ws_unsubscribe_depth, oa_ws_unsubscribe_orders, oa_ws_unsubscribe_all, oa_ws_subscriptions, oa_ws_debug

Support and Contributions

  • Issues: Report issues at the repository's issue tracker.
  • Contributions: PRs are welcome to improve features, documentation, or bug fixes.
  • License: Tradeboard is open-source and distributed under the AGPL-3.0 License.

References

Disclaimer

The creators of this add-in are not responsible for any issues, losses, or damages that may arise from its use. It is strongly recommended to test all functionalities in Tradeboard Analyzer Mode before applying them to live trading. Always verify API responses and exercise caution while executing trades.