No results for ""
Ready-to-Use Scripts
Copy any script below directly into the editor and click Start. Each follows all the rules on the Strict Rules page: top-level TD.on(), awaited Feed/Sheet calls, try/catch everywhere, response.success checks, and — for REST-backed templates — a single one-shot call with no loop or timer.
SYMBOL, SYMBOLS, EXPIRY, top, etc.) — the structure shouldn't otherwise need to change.| # | Template | Use when... | API family |
|---|---|---|---|
| 1 | Full multi-symbol watchlist | Live watchlist with full touchline fields for several symbols | TD.Feed + tick |
| 2 | Option chain → sheet | Dump the full option chain to the sheet once | getOptionChain |
| 3 | 1-min bar streaming (append) | Every new 1-min candle appended as a new row | TD.Feed + bar1min |
| 4 | Last N historical bars | One-time pull of recent past bars | getLastNBars |
| 5 | Top N OI gainers | Top open-interest gainers for CE or PE | getOIGainers |
| 6 | Most active by volume | Most actively traded symbols in an index | getMostActiveByVolume |
| 7 | Industry gainers | Top gainers within one sector/industry | getIndustryGainers |
| 8 | Index gainers (top N) | Top N gainers within an index | getIndexGainers |
| 9 | Option chain with Greeks → sheet | Greeks-enriched chain dumped to the sheet once | getOptionChainWithGreeks |
| 10 | Tick-by-tick log (append) | Every individual tick logged as a new row | TD.Feed + tick |
1. Full Multi-Symbol Watchlist (tick)
Live-updating watchlist with the complete touchline field set — LTP, OHLC, OI, change %, bid/ask — for multiple symbols, one fixed row per symbol.
const SYMBOLS = ["RELIANCE", "TCS", "NIFTY 50"];
let symbolMap = {}; // { symbolId: symbolName }
let rowMap = {
"RELIANCE": 2,
"TCS": 3,
"NIFTY 50": 4,
};
TD.on("tick", async (data) => {
try {
const symbolName = symbolMap[data[0]];
if (!symbolName) return;
const row = rowMap[symbolName];
if (!row) return;
const ltp = parseFloat(data[2]);
const prevClose = parseFloat(data[9]);
const oi = parseFloat(data[10]);
const prevOi = parseFloat(data[11]);
const change = ltp - prevClose;
const changePer = prevClose ? (change / prevClose) * 100 : 0;
const oiChange = oi - prevOi;
const oiChangePer = prevOi ? (oiChange / prevOi) * 100 : 0;
await TD.Sheet.setCellRange("A" + row, [
symbolName, data[1], ltp,
parseFloat(data[3]), parseFloat(data[4]), parseFloat(data[5]),
parseFloat(data[6]), parseFloat(data[7]), parseFloat(data[8]),
prevClose, change, changePer, oi, prevOi, oiChange, oiChangePer,
parseFloat(data[12]), data[14],
parseFloat(data[15]), parseFloat(data[16]),
parseFloat(data[17]), parseFloat(data[18]),
]);
} catch (err) {
TD.log("Tick error: " + err.message);
}
});
TD.onStart = async () => {
try {
symbolMap = {};
await TD.Sheet.setCellRange("A1", [
"Symbol", "LTT", "LTP", "LTQ", "ATP", "Total Volume", "Open", "High",
"Low", "Prev Close", "Change", "Change %", "Today OI", "Prev OI",
"OI Change", "OI Change %", "Turnover", "Tick Seq No",
"Bid", "Bid Qty", "Ask", "Ask Qty",
]);
const response = await TD.Feed.addSymbols(SYMBOLS);
if (!response.success) {
TD.log("Subscribe failed: " + response.message);
return;
}
for (const sym of response.symbollist) {
symbolMap[sym[1]] = sym[0];
}
TD.log("Full watchlist started.");
} catch (err) {
TD.log("Start error: " + err.message);
}
};
TD.onStop = async () => {
await TD.Feed.removeSymbols(SYMBOLS);
};
TD.onError = (err) => {
TD.log("Error: " + err.message);
};
2. Option Chain → Sheet
One-shot dump of the full option chain (header + all strikes) to the sheet. Index display names must be mapped first (Rule 12).
const SYMBOL = "NIFTY"; // already mapped — NOT "NIFTY 50"
const EXPIRY = "07-07-2026"; // DD-MM-YYYY
TD.onStart = async () => {
try {
const data = await TD.OptionChain.getOptionChain({
symbol: SYMBOL,
expiry: EXPIRY,
});
if (!data.records || data.records.length <= 1) {
TD.log("No option chain data found.");
return;
}
// records[0] is the header row — write everything, header included
for (let i = 0; i < data.records.length; i++) {
await TD.Sheet.setCellRange("A" + (i + 1), data.records[i]);
}
TD.log("Option chain loaded.");
} catch (err) {
TD.log("Error: " + err.message);
}
};
TD.onError = (err) => {
TD.log("Error: " + err.message);
};
3. 1-Min Bar Streaming (Append Rows)
Every new 1-minute bar is appended as a new row — builds a running candle history instead of overwriting one row.
const SYMBOLS = ["RELIANCE"];
let symbolMap = {};
let currentRow = 2;
TD.on("bar1min", async (data) => {
try {
const symbolId = data[0];
const symbolName = symbolMap[symbolId] || symbolId;
await TD.Sheet.setCellRange("A" + currentRow, [
symbolName, data[1],
parseFloat(data[2]), parseFloat(data[3]), parseFloat(data[4]),
parseFloat(data[5]), parseFloat(data[6]), parseFloat(data[7]),
]);
currentRow++;
} catch (err) {
TD.log("Bar write error: " + err.message);
}
});
TD.onStart = async () => {
try {
currentRow = 2;
symbolMap = {};
await TD.Sheet.setCellRange("A1", [
"Symbol", "Timestamp", "Open", "High", "Low", "Close", "Volume", "OI",
]);
const response = await TD.Feed.addSymbols(SYMBOLS);
if (!response.success) throw new Error(response.message);
for (const sym of response.symbollist) {
symbolMap[sym[1]] = sym[0];
}
TD.log("RELIANCE 1-min bar streaming started.");
} catch (err) {
TD.log("Start error: " + err.message);
}
};
TD.onStop = async () => {
await TD.Feed.removeSymbols(SYMBOLS);
};
TD.onError = (err) => {
TD.log("Error: " + err.message);
};
4. Last N Historical Bars
One-time pull of the most recent N bars for a symbol — no live updates, single REST call inside onStart.
TD.onStart = async () => {
try {
const data = await TD.Historical.getLastNBars({
symbol: "RELIANCE",
nbars: 20,
interval: "1min",
});
if (!data.records || data.records.length <= 1) {
TD.log("No bars received.");
return;
}
await TD.Sheet.setCellRange("A1", data.records[0]);
for (let i = 1; i < data.records.length; i++) {
await TD.Sheet.setCellRange("A" + (i + 1), data.records[i]);
}
TD.log("Loaded last 20 one-minute bars for RELIANCE.");
} catch (err) {
TD.log("Error: " + err.message);
}
};
TD.onError = (err) => {
TD.log("Error: " + err.message);
};
5. Top N OI Gainers
One-time pull of top open-interest gainers for a given option series ("CE" or "PE"). No segment parameter on this call.
TD.onStart = async () => {
try {
const data = await TD.Analytics.getOIGainers({
series: "CE",
top: 5,
});
if (!data.records || data.records.length <= 1) {
TD.log("No OI gainers data received.");
return;
}
await TD.Sheet.setCellRange("A1", data.records[0]);
for (let i = 1; i < data.records.length; i++) {
await TD.Sheet.setCellRange("A" + (i + 1), data.records[i]);
}
TD.log("Top 5 CE OI gainers loaded.");
} catch (err) {
TD.log("Error: " + err.message);
}
};
TD.onError = (err) => {
TD.log("Error: " + err.message);
};
6. Most Active by Volume
One-time pull of the most actively traded symbols (by volume) within an index.
TD.onStart = async () => {
try {
const data = await TD.Analytics.getMostActiveByVolume({
indexName: "NIFTY 50",
segment: "EQ",
top: 5,
});
if (!data.records || data.records.length <= 1) {
TD.log("No data received.");
return;
}
await TD.Sheet.setCellRange("A1", data.records[0]);
for (let i = 1; i < data.records.length; i++) {
await TD.Sheet.setCellRange("A" + (i + 1), data.records[i]);
}
TD.log("Top 5 most active by volume loaded.");
} catch (err) {
TD.log("Error: " + err.message);
}
};
TD.onError = (err) => {
TD.log("Error: " + err.message);
};
7. Industry Gainers
One-time pull of top gainers within a specific industry. Swap industry for any value from the supported industries list on the Analytics page.
TD.onStart = async () => {
try {
const data = await TD.Analytics.getIndustryGainers({
industry: "Telecommunication",
segment: "EQ",
top: 5,
});
if (!data.records || data.records.length <= 1) {
TD.log("No Telecommunication industry gainers data received.");
return;
}
await TD.Sheet.setCellRange("A1", data.records[0]);
for (let i = 1; i < data.records.length; i++) {
await TD.Sheet.setCellRange("A" + (i + 1), data.records[i]);
}
TD.log("Top 5 Telecommunication industry gainers loaded.");
} catch (err) {
TD.log("Error: " + err.message);
}
};
TD.onError = (err) => {
TD.log("Error: " + err.message);
};
8. Index Gainers (Top N)
One-time pull of top N gainers within an index. top controls how many rows come back — keep the log message in sync with the actual value.
TD.onStart = async () => {
try {
const TOP_N = 25;
const data = await TD.Analytics.getIndexGainers({
indexName: "NIFTY 50",
segment: "EQ",
top: TOP_N,
});
if (!data.records || data.records.length <= 1) {
TD.log("No NIFTY 50 gainers data received.");
return;
}
await TD.Sheet.setCellRange("A1", data.records[0]);
for (let i = 1; i < data.records.length; i++) {
await TD.Sheet.setCellRange("A" + (i + 1), data.records[i]);
}
TD.log(`Top ${TOP_N} NIFTY 50 index gainers loaded.`);
} catch (err) {
TD.log("Error: " + err.message);
}
};
TD.onError = (err) => {
TD.log("Error: " + err.message);
};
9. Option Chain with Greeks → Sheet
One-shot dump of the Greeks-enriched option chain to the sheet. Same index-mapping rule applies as template 2.
const SYMBOL = "NIFTY"; // already mapped — NOT "NIFTY 50"
const EXPIRY = "07-07-2026"; // DD-MM-YYYY
TD.onStart = async () => {
try {
const data = await TD.OptionChain.getOptionChainWithGreeks({
symbol: SYMBOL,
expiry: EXPIRY,
});
if (!data.records || data.records.length <= 1) {
TD.log("No option chain data found.");
return;
}
await TD.Sheet.setCellRange("A1", data.records[0]);
for (let i = 1; i < data.records.length; i++) {
await TD.Sheet.setCellRange("A" + (i + 1), data.records[i]);
}
TD.log("Option chain with Greeks loaded.");
} catch (err) {
TD.log("Error: " + err.message);
}
};
TD.onError = (err) => {
TD.log("Error: " + err.message);
};
10. Tick-by-Tick Log (Append Rows)
Every incoming tick is appended as a new row — an audit-style log instead of a single overwritten row. Contrast with Template 1, which keeps one fixed row per symbol.
const SYMBOLS = ["RELIANCE"];
let symbolMap = {};
let currentRow = 2;
TD.on("tick", async (data) => {
try {
const symbolName = symbolMap[data[0]] || data[0];
await TD.Sheet.setCellRange("A" + currentRow, [
symbolName, data[1],
parseFloat(data[2]), parseInt(data[3]),
parseFloat(data[15]), parseInt(data[16]),
parseFloat(data[17]), parseInt(data[18]),
]);
currentRow++;
} catch (err) {
TD.log("Tick write error: " + err.message);
}
});
TD.onStart = async () => {
try {
currentRow = 2;
symbolMap = {};
await TD.Sheet.setCellRange("A1", [
"Symbol", "Time", "LTP", "LTQ", "Bid", "Bid Qty", "Ask", "Ask Qty",
]);
const response = await TD.Feed.addSymbols(SYMBOLS);
if (!response.success) {
TD.log("Subscribe failed: " + response.message);
return;
}
for (const sym of response.symbollist) {
symbolMap[sym[1]] = sym[0];
}
TD.log("RELIANCE tick streaming started.");
} catch (err) {
TD.log("Start error: " + err.message);
}
};
TD.onStop = async () => {
await TD.Feed.removeSymbols(SYMBOLS);
};
TD.onError = (err) => {
TD.log("Error: " + err.message);
};
Empowering traders and analysts with high-performance real-time market data directly within their spreadsheets.
Resources
Support
© 2026 TrueData Market Data Services LLP. All rights reserved.