TrueData TrueData Sheets
search
Searching...
functions Formulas
menu_book Pages
manage_search Content Match
search_off

No results for ""

Loading Content
rule

Strict Rules

Read this once before writing any script. Violating these rules causes silent failures or wrong data — not crashes you'll notice immediately. Rule 17, covering REST call usage, lives on the Best Practices page alongside the Do/Avoid checklist.

1

All values from Feed / tick are strings

All values in the addSymbols response and tick/bar events arrive as strings, not numbers. Always use parseFloat() or parseInt() before doing math or comparisons.

close Wrong
const ltp = data[2];
// "1332.9" — math/comparison fails
check Correct
const ltp = parseFloat(data[2]);
// 1332.9
2

addSymbols takes symbol names, not IDs

Always pass the symbol name string, e.g. "RELIANCE", "NIFTY 50". Never pass numeric symbolIds.

close Wrong
await TD.Feed.addSymbols([100001262]);
check Correct
await TD.Feed.addSymbols(["RELIANCE"]);
3

Always await Feed and Sheet calls

addSymbols, removeSymbols, setCell, setCellRange, getCell, getCellRange are all async. Missing await causes race conditions and unpredictable behavior.

close Wrong
TD.Feed.addSymbols(["RELIANCE"]);
check Correct
await TD.Feed.addSymbols(["RELIANCE"]);
4

tick data[0] is a symbolId string, not the symbol name

In the tick event, data[0] is the symbolId (e.g. "100001262"), NOT the symbol name. To match by name, build a lookup map during onStart.

close Wrong
if (data[0] === "RELIANCE") { ... }
// data[0] is "100001262", not the name
check Correct
const symbolMap = {}; // { symbolId: symbolName }

TD.onStart = async () => {
  const response = await TD.Feed.addSymbols(["RELIANCE"]);
  for (const sym of response.symbollist) {
    symbolMap[sym[1]] = sym[0];
  }
};

TD.on("tick", (data) => {
  const name = symbolMap[data[0]]; // "RELIANCE"
});
5

addSymbols response is an object, not an array

The response has the shape { success, message, symbollist }. Access response.symbollist[0], not response[0].

close Wrong
const data = response[0]; // undefined
check Correct
const data = response.symbollist[0];
6

Always check response.success before using symbollist

If the symbol name is invalid or the feed fails, success is false and symbollist is empty. Accessing symbollist[0] without checking will crash.

Example
const response = await TD.Feed.addSymbols(["RELIANCE"]);
if (!response.success) {
  TD.log("Subscribe failed: " + response.message);
  return;
}
const data = response.symbollist[0];
7

Register TD.on() handlers outside all hooks

Event listeners must be at the top level of the script — not inside onStart, onStop, or any function.

close Wrong
TD.onStart = async () => {
  TD.on("tick", (data) => { ... });
  // inside a hook — wrong
};
check Correct
TD.on("tick", (data) => { ... }); // top level

TD.onStart = async () => {
  await TD.Feed.addSymbols(["RELIANCE"]);
};
8

Always unsubscribe in onStop

Every symbol subscribed in onStart must be unsubscribed in onStop to avoid memory leaks.

TD.onStop = async () => {
  await TD.Feed.removeSymbols(["RELIANCE", "NIFTY 50"]);
};
9

Only four Sheet methods exist

Do not use or invent other Sheet methods. The only available ones are setCell, setCellRange, getCell, getCellRange. See Sheet Read / Write for full usage.

10

Analytics and Historical calls go inside TD.onStart

TD.Analytics.* and TD.Historical.* are async and must be awaited inside TD.onStart, or an async function called from it.

11

greeks needs a full option symbol string

Subscribe using the full TD option symbol format: "NIFTY26062323500CE" (symbol + YYMMDD + strike + CE/PE). Do not pass the base symbol like "NIFTY" or "NIFTY 50".

close Wrong
await TD.Feed.addSymbols(["NIFTY"]);
// base symbol won't produce greeks
check Correct
await TD.Feed.addSymbols(["NIFTY26062323500CE"]);
12

Option chain index symbols must be mapped first

The option chain API needs the mapped short symbol, not the display name. This mapping applies only to these five indices — every other symbol (e.g. "RELIANCE") passes through unchanged.

Display name Pass as symbol
NIFTY 50 "NIFTY"
NIFTY BANK "BANKNIFTY"
NIFTY MID SELECT "MIDCPNIFTY"
NIFTY NEXT 50 "NIFTYNXT50"
NIFTY FIN SERVICE "FINNIFTY"
close Wrong
await TD.OptionChain.getOptionChain({
  symbol: "NIFTY 50",
  expiry: "23-06-2026",
});
// "NIFTY BANK" / "BANK NIFTY" also wrong
check Correct
await TD.OptionChain.getOptionChain({
  symbol: "NIFTY",
  expiry: "23-06-2026",
});
13

Expiry date format is "DD-MM-YYYY"

Always pass expiry in "DD-MM-YYYY" format, e.g. "23-06-2026".

14

getTopNGainers / getTopNLosers use "NSEEQ" or "BSEEQ"

These Historical functions use different segment strings than Analytics functions. Do not use "EQ" here.

close Wrong
await TD.Historical.getTopNGainers({
  segment: "EQ", topn: 5
});
check Correct
await TD.Historical.getTopNGainers({
  segment: "NSEEQ", topn: 5
});
15

Wrap all async calls in try/catch

Always wrap async calls in try/catch and log errors via TD.log().

TD.onStart = async () => {
  try {
    const response = await TD.Feed.addSymbols(["RELIANCE"]);
    if (!response.success) throw new Error(response.message);
  } catch (err) {
    TD.log("Error: " + err.message);
  }
};
16

records[0] is always the header row

In Historical, Analytics, and Option Chain responses, records[0] is always the header row. Data rows start at records[1]. Never process records[0] as data.

const records = data.records;
const headers = records[0]; // header row — skip this
for (let i = 1; i < records.length; i++) {
  const row = records[i]; // actual data
}
info Rule 17 — prefer sockets over REST calls, and never loop or poll a REST call — is covered in depth on the Best Practices page, since it governs the overall shape of a script rather than a single line of code.
Truedata Icon Sheets by Truedata

Empowering traders and analysts with high-performance real-time market data directly within their spreadsheets.

© 2026 TrueData Market Data Services LLP. All rights reserved.