English | 中文
A stock market data JavaScript SDK for frontend and Node.js.
No Python. No backend service. Fetch real-time quotes and K-line data for A-shares / Hong Kong stocks / US stocks / mutual funds directly in the browser or Node.js. It also ships a command-line tool and an MCP server — one command to pull quotes or wire up AI tools.
✨ Zero dependencies, Lightweight distribution | 🌐 Browser + Node.js | 📦 ESM + CJS + subpaths | 🧠 Full TypeScript typings | 🖥️ CLI | 🤖 MCP
✨ v2.0.0: v2 is an architectural leap (namespaced API, unified symbol model,
Quotediscriminated union, unified error system, CLI / MCP / subpath exports). Install:npm i stock-sdk. Upgrading from v1? Read the v1 → v2 migration guide first (breaking changes, no compat aliases).
👉 https://stock-sdk.linkdiary.cn/en/
Full API, namespace overview, CLI / MCP guides, the online Playground, and the v1 → v2 migration guide all live here. Start with the docs for the fastest onboarding.
(v1 stable docs are archived)
📦 NPM | 📖 GitHub | 🎮 Live Playground
🧭 Stock Dashboard: A stock market dashboard demo built with stock-sdk. Feel free to try it.
If you're a frontend engineer, you may have encountered these problems:
stock-sdk's goal is simple:
Let frontend engineers fetch stock market data elegantly, using the JavaScript / TypeScript they already know.
sdk.quotes.cn() / sdk.kline.cn() / sdk.options.etf.dailyKline(), grouped by domain, great IDE autocompletestring as a first-class input — sh600519 / 600519 / 600519.SH / 00700 / hk00700 / AAPL / 105.AAPL are all parsed tolerantly; special indices supported (930955 / H30533 / HSHCI / GDAXI, see the symbols guide)calcSignals (golden/death cross, overbought/oversold, etc.), a chainable screener, local backtestingstock-sdk/{indicators,signals,symbols,screener,cache,errors} — pure-compute imports don't pull in the network layer (tree-shake friendly)SdkError is thrown to callers, each with a stable code, importable from stock-sdk/errorsfetchImpl / signal / lifecycle hooksstock-sdk quote 600519 to pull quotes straight from the terminalstock-sdk mcp wires up Cursor / Claude / Codex and other AI tools in one line (hand-written, zero deps, no @modelcontextprotocol/sdk)# Latest (v2: namespaced API / CLI / MCP)
npm install stock-sdk
# v1 legacy (frozen, critical fixes only)
npm install stock-sdk@legacy
import { StockSDK } from 'stock-sdk';
const sdk = new StockSDK();
// Namespaced API (v2) — symbol input is tolerant: '600519' / 'sh600519' / '600519.SH' all work
const quotes = await sdk.quotes.cnSimple(['sh000001', 'sz000858', 'sh600519']);
quotes.forEach((q) => {
console.log(`${q.name}: ${q.price} (${q.changePercent}%)`);
});
// History K-line + technical indicators
const kline = await sdk.kline.withIndicators('600519', {
period: 'daily',
indicators: { ma: { periods: [5, 10, 20] }, macd: {} },
});
// Whole-market A-share quotes (5000+ stocks, built-in concurrency control)
const all = await sdk.batch.cn({ concurrency: 5 });
console.log(`${all.length} stocks`);
HK
'00700'/'hk00700', US'AAPL'/'105.AAPL'— all normalized bynormalizeSymbol.
After install you get the stock-sdk command (or use npx):
# Quotes (market auto-detected from the code)
npx stock-sdk quote 600519 00700 AAPL
# K-line with output truncation
npx stock-sdk kline 600519 --period weekly --limit 30
# With technical indicators
npx stock-sdk indicators 600519 --ma 5,10,20 --macd
# Search
npx stock-sdk search 茅台
# Direct access to any namespace method
npx stock-sdk quotes cn sh600519 sz000001
JSON output by default; add --format table|csv, --pretty, --limit N.
v2 ships a built-in, zero-dependency MCP server — start it with one command:
npx stock-sdk mcp
Wire it into Cursor / Claude Desktop / Codex / Gemini, etc. (mcpServers config):
{
"mcpServers": {
"stock-sdk": {
"command": "npx",
"args": ["-y", "stock-sdk", "mcp"]
}
}
}
STOCK_SDK_MCP_TOOLS=core|full|<comma-separated tool names> controls the tool set (default core).
import { calcSignals } from 'stock-sdk/signals';
import { screen, backtest } from 'stock-sdk/screener';
// Event detection (golden/death cross, overbought/oversold) on indicator-enriched K-lines
const signals = calcSignals(klineWithIndicators, {
ma: { fast: 5, slow: 20 },
rsi: {},
});
// Chainable screening over any quote array — purely local, no network
const picks = screen(allQuotes)
.where((q) => q.pe != null && q.pe < 20)
.where((q) => q.changePercent > 3)
.sortBy((q) => q.amount)
.top(20);
// Local backtest
const report = backtest({
klines,
strategy: (bar, i, all) => 'hold', // return 'buy' | 'sell' | 'hold'
});
console.log(report.totalReturn, report.winRate, report.maxDrawdown);
import { StockSDK } from 'stock-sdk';
import { HttpError, getSdkErrorCode } from 'stock-sdk/errors';
const sdk = new StockSDK({
retry: { maxRetries: 2, baseDelay: 500 },
providerPolicies: {
eastmoney: { timeout: 12000, rateLimit: { requestsPerSecond: 3, maxBurst: 3 } },
},
});
try {
await sdk.quotes.cnSimple(['sh600519']);
} catch (error) {
// v2 only throws SdkError, each carrying a stable code
if (error instanceof HttpError) console.log(error.status, error.statusText);
console.log(getSdkErrorCode(error)); // HTTP_ERROR / NETWORK_ERROR / TIMEOUT / ABORTED / PARSE_ERROR ...
}
For pure-compute use (indicators / symbols / signals / screener), import from a subpath so the bundle doesn't pull in RequestClient or any provider:
// 14 indicators, 17 pure functions in total (the MA family ships calcSMA /
// calcEMA / calcWMA variants): calcSMA / calcEMA / calcWMA / calcMA /
// calcMACD / calcBOLL / calcKDJ / calcRSI / calcWR / calcBIAS / calcCCI /
// calcATR / calcOBV / calcROC / calcDMI / calcSAR / calcKC
import { calcMACD, calcKDJ } from 'stock-sdk/indicators';
import { normalizeSymbol, toTencentSymbol } from 'stock-sdk/symbols';
import { calcSignals } from 'stock-sdk/signals';
import { screen, backtest } from 'stock-sdk/screener';
import { MemoryCacheStore, cacheThrough } from 'stock-sdk/cache';
import { SdkError, isSdkError, getSdkErrorCode } from 'stock-sdk/errors';
Coverage varies by market — this table helps you quickly check whether the SDK fits your scenario.
| Capability | A-share | HK | US | Mutual fund | Futures | Options |
|---|---|---|---|---|---|---|
| Real-time quotes | ✅ | ✅ | ✅ | ✅ | ✅ global | ✅ ETF / CFFEX / commodity |
| History K-line (D/W/M) | ✅ | ✅ | ✅ | ⚠️ listed ETF/LOF | ✅ domestic + global | ✅ |
| Minute K-line (5/15/30/60) | ✅ | ✅ kline.hkMinute |
✅ kline.usMinute |
⚠️ listed ETF/LOF | ❌ | ❌ |
| Intraday (1-min) | ✅ quotes.timeline |
✅ kline.hkMinute(period='1') |
✅ kline.usMinute(period='1') |
⚠️ listed ETF/LOF | ❌ | ✅ ETF options |
| Dividends | ✅ | ❌ | ❌ | ✅ fund + ETF | — | — |
| Fund flow | ✅ stock/market/rank/sector | ❌ | ❌ | — | — | — |
| Sectors (industry / concept) | ✅ | ❌ | ❌ | ❌ | — | — |
| Dragon-tiger list | ✅ | — | — | — | — | ✅ option LHB |
| Stock Connect / northbound | ✅ northbound | ✅ southbound | — | — | — | — |
| Block trades / margin | ✅ | ❌ | ❌ | — | — | — |
| Limit-up pool / abnormal moves | ✅ | — | — | — | — | — |
| Code list / batch quotes | ✅ 5000+ | ✅ | ✅ | ✅ codes | ❌ | ❌ |
| Inventory data | — | — | — | — | ✅ domestic + COMEX | — |
| Trading calendar | ✅ calendar.* |
⚠️ market status only | ⚠️ market status only | — | — | — |
Data latency: real-time quotes come from public endpoints (Tencent Finance / Eastmoney, etc.), not exchange matching feeds — typically delayed by seconds to minutes. Not suitable for high-frequency trading decisions.
💡 Full API in the documentation. In v2, every method lives under a namespace:
| Namespace | Representative methods |
|---|---|
sdk.quotes |
.cn / .cnSimple / .hk / .us / .fund / .fundFlow / .largeOrder / .timeline |
sdk.codes |
.cn / .us / .hk / .fund |
sdk.batch |
.cn / .hk / .us / .byCodes / .raw |
sdk.kline |
.cn / .cnMinute / .hk / .hkMinute / .us / .usMinute / .withIndicators |
sdk.board |
.industry.* / .concept.* (list / spot / constituents / kline / minuteKline) |
sdk.options |
.index.* / .etf.* / .commodity.* / .cffex.* / .lhb |
sdk.futures |
.kline / .globalSpot / .globalKline / .inventory / .comexInventory … |
sdk.fundFlow |
.individual / .market / .rank / .sectorRank / .sectorHistory |
sdk.northbound |
.minute / .summary / .holdingRank / .history / .individual |
sdk.marketEvent |
.ztPool / .stockChanges / .boardChanges |
sdk.dragonTiger |
.detail / .stockStats / .institution / .branchRank / .seatDetail |
sdk.blockTrade / sdk.margin |
block trades / margin trading |
sdk.fund |
.dividendList / .navHistory / .estimate / .rankHistory / .profile / .theme.* |
sdk.calendar |
.isTradingDay / .nextTradingDay / .prevTradingDay / .marketStatus |
sdk.reference |
.dividendDetail / .tradingCalendar |
| top-level | sdk.search(keyword) |
Indicator math moved from the main package to a subpath:
import { calcMACD } from 'stock-sdk/indicators'. Migrating from the v1 flat API? See the v1 → v2 migration guide (with the fullsdk.getXxx()→sdk.<ns>.<method>()mapping).
pnpm typecheck
pnpm build
pnpm test
pnpm test:integration:smoke # smoke integration (real network)
pnpm test:integration:full # full integration regression
🌐 Website | 📦 NPM | 📖 GitHub | 🎮 Live Demo | 🧭 Stock Dashboard | 🐛 Issues
If this project helps you, a Star ⭐ or an Issue is very welcome.
$ claude mcp add stock-sdk \
-- python -m otcore.mcp_server <graph>