Changelog
This page records the release history of Stock SDK. v2.0.0 is an architectural leap — without adding data sources, it reworks the symbol model, data contract, API surface, request layer, and error system, and adds a CLI / MCP and subpath exports.
v2.3.0
Released: 2026-07-06
Added
- Chip distribution
sdk.chips.cn / hk / us(#57, thanks @hawx1993 for the request): computed locally from daily K-lines + turnover rate (a TypeScript port of Eastmoney's front-end CYQ algorithm, no new data source) — per-day profit ratio, average cost, 90 / 70 cost ranges with concentration, and an optional 150-bucket chip-peak histogram viaincludeHistogram. Unit tests assert per-day, per-field golden parity against the original Eastmoney JS.- Pure function
calcChipDistribution(klines, options)is exported fromstock-sdk/indicatorsfor user-supplied K-lines; thetailoption avoids O(N²) work in full-accumulation mode - Conventions:
rangedefaults to120(matches the Eastmoney app);{ range: 0, adjust: '' }reproduces akshare'sstock_cyq_emoutput — see the chips docs - CLI
stock-sdk chips cn 600519and MCP toolsget_chip_distribution(core toolset) /get_hk_chip_distribution/get_us_chip_distributionderive automatically
- Pure function
- Per-stock intraday changes
marketEvent.individualChanges/individualChangesHistory(#54, thanks @hawx1993 for the request): a single A-share stock's all-type change-event stream for one trading day (time / type / trigger price / change%), plus an N-day (1~60, default 7) aggregation over the trading calendar — per-dayavailableflags,coverageof the actually-retrievable range, andstatskeyed by raw type code (with Chinese labels inline).- Data source is Eastmoney's per-stock push2ex endpoint (not covered by akshare); the server only retains roughly the last few weeks with occasional per-date gaps — always branch on the per-day
available - For a full 30-day view, combine with daily proxies — see the new guide 30-Day Per-Stock Changes Panorama
- MCP tools
get_individual_stock_changes/get_individual_stock_changes_historyand the CLI commands derive automatically
- Data source is Eastmoney's per-stock push2ex endpoint (not covered by akshare); the server only retains roughly the last few weeks with occasional per-date gaps — always branch on the per-day
marketEvent.stockChangesmulti-type & all:typewidens toStockChangeType | StockChangeType[] | 'all';'all'fetches all 22 types in one call and auto-paginates by the server-reported total (can exceed 10k rows on a trading day).
Changed
StockChangeItemfield extension: addstypeCode(raw server type code);changeTypewidens fromStockChangeTypetoStockChangeType | 'unknown'(new server-side codes no longer lose data). Consumers doing exhaustive switches overchangeTypeneed an'unknown'branch.
v2.2.2
Released: 2026-07-04
Added
- Indicator
decimalsoption: rounding indicators (ma / macd / boll / kdj / rsi / wr / bias / cci / atr) acceptdecimals?: numberto control output precision (e.g.calcMA(closes, { periods: [5], decimals: 2 })), available through the SDK,kline.withIndicatorsand MCP.
Changed
- Default indicator precision goes from 2 to 3 decimals (based on #55, thanks @Ahaochan): MA curves of low-priced instruments (e.g. a 3-CNY ETF) no longer look step-shaped. Note this is more than an extra digit: MACD / BOLL / BIAS consume internally rounded EMA/SMA intermediates, so some values differ from the old release at the 2nd decimal even after re-rounding (roughly half of the MACD histogram values in measurement; golden/death crosses can shift by ±1 bar), and KC shifts with its internal EMA/ATR inputs; recalibrate backtests that snapshot indicator values. The 9 duplicated
round()helpers are consolidated into one shared module. - obv / roc / dmi / sar / kc keep emitting raw floats (no rounding), matching previous behavior.
v2.2.1
Released: 2026-07-03
Added
- Special Eastmoney index support (reworked from #51, thanks @wubh2012): CSI indices recognized by code shape (
93xxxx/H+5 digits, e.g.930955,H30533, secid prefix2., viakline.cn); named indicesHSHCI(Hang Seng Healthcare Index,124., viakline.hk) andGDAXI(German DAX,100., via thekline.us('100.GDAXI')raw-secid passthrough). The secid forms (2.930955, etc.) are valid inputs and round-trip.
Fixed
- CSI indices were previously inferred as "starts with 9 → Shanghai", building secids like
1.930955that returned silently empty klines; shape-based recognition fixes the whole family (including future codes) at once.
Changed
- Special-index code shapes are syntax-certain classifications: conflicting hints and prefix / suffix assertions (
sh930955,hkHSHCI, etc.) throwInvalidSymbolErrorwith guidance, while explicit assertions likeusGDAXIand1.930955keep their original meaning.marketOf('HSHCI')becomes'HK',marketOf('GDAXI')becomes'GLOBAL'. - Unsupported paths fail fast uniformly (previously silent empty arrays or guaranteed-empty queries):
toTencentSymbol/ CLIquote/fundFlow.individualreject special indices, and auto-routing entries give a raw-secid hint forGLOBALsymbols. Known limitations: see the symbols guide.
v2.2.0
Released: 2026-06-27
Added
- Theme fund API
sdk.fund.theme.*: browse funds by industry / concept theme, also derived to the CLI and MCP (get_theme_list/get_theme_funds).getThemeList(options?)— full theme list (industry / concept, with daily change and 1W / 1M / 3M / 6M / 1Y / 3Y / 5Y stage returns, sortable and paginated)getThemeFunds(themeCode, options?)— fund ranking within a theme (fund type, stage returns, latest NAV)
v2.1.0
Released: 2026-06-23
Added
sdk.fund.profile(code): fetch a fund's deep profile in one request (the full set of Eastmoney pingzhongdata fields) — top-10 stock holdings, top-5 bond holdings, quarterly asset allocation, daily position estimates, fund managers (with star rating and ability scores), performance evaluation, holder structure, scale changes, purchase / redemption, stage returns (1 / 3 / 6-month, 1-year) and same-category peers. Shares the data source withnavHistory/rankHistory(the same pingzhongdata file), and is also derived to the CLI (fund profile) and MCP (get_fund_profile).
Fixed
- Fund date alignment: dates returned by
fund.navHistory/fund.rankHistory/fund.profilewere sliced from the UTC date and came out one day earlier than the actual trading day (pingzhongdata timestamps are Beijing midnight); now resolved in the Beijing timezone, verified against Tiantian Fund's authoritative NAV date (jzrq). fetchJsVarssingle-quote support: on Node, single-quoted JS literals (e.g.swithSameType) now get a fallback parse to match the browser<script>-injection path, so such fields are no longer dropped on Node.
v2.0.0
Released: 2026-06-18
v2.0.0 is the first stable release of v2, rolling up all the work since the beta. For the detailed changes and breaking-change notes see the
v2.0.0-beta.1entry below; upgrading from v1? Read the v1 → v2 migration guide first.
Since beta.1
- The docs site now owns the primary domain
stock-sdk.linkdiary.cn; v1 docs are archived at v1.stock-sdk.linkdiary.cn - Wired up a dedicated Grafana Faro monitoring collect channel (app:
stock-sdk-docs-v2) with sourcemap upload on production builds - Homepage red theme + live-quote Hero + full Playground rebuild
- npm dist-tags:
latestofstock-sdknow points to v2.0.0; the v1 stable line stays installable asstock-sdk@legacy(1.10.1)
v2.0.0-beta.1
This release rolls up the v2 stabilization work currently ahead of
origin/feature-v2: the namespace-only API is now in place, request / time / symbol / provider correctness is tightened, CLI and MCP share one method-spec source, and the v2 docs site plus Playground are filled in.
Breaking changes
- v1 flat facade methods removed: 80 compatibility methods such as
sdk.getXxx()/sdk.xxx()are gone. The public SDK surface is nowsdk.<namespace>.<method>(), plus the top-levelsdk.search(keyword). - CLI / MCP contracts derive from one shared spec: commands and MCP tools are generated from
src/spec/methods.ts, so enums, defaults and argument shapes are validated from the same source of truth.
SDK correctness
- Request cancellation and timeout classification hardened: external
AbortSignal, timeout, customfetchImpl, failure accounting and circuit-breaker half-open handling now distinguish cancellation, timeout and upstream failures more reliably. - Time and date handling fixed:
wallTimeToUTCno longer drifts by one hour on DST transition days; date normalization and validation are shared across provider / SDK / CLI paths. - Symbol parsing consolidated:
normalizeSymbolnow handles hint precedence, dotted secids, HK / US / BSE / futures ambiguities and rejects cross-market conflicts instead of silently fetching the wrong market. - Provider resilience improved: upstream empty responses, pagination guards, direction validation, negative cache behavior, dividend typing and East Money secid edge cases now fail more predictably.
- Indicators and K-line stability improved:
kline.withIndicatorshas a safer warmup / refetch strategy; recursive-indicator slicing drift is fixed;addIndicatorsaccepts docs-friendly shorthands such as{ ma: [5, 20] }and{ rsi: { period: 14 } }.
CLI and MCP
stock-sdk callfixed: namespaced methodthisbinding is preserved, and callable paths are constrained by a shared walker and whitelist.- MCP tools derive from the shared spec: the tool surface is generated from the same method catalog, with
kline.withIndicatorskept as the hand-written adapter for nested indicator options. - MCP argument validation is stricter: unknown fields, type mismatches and optional object params passed as
nullnow returnINVALID_ARGUMENTat the boundary instead of leaking into SDK calls asUNKNOWN. - stdio transport is quieter: EPIPE / disconnect boundaries are handled more cleanly when MCP clients close the connection.
Performance and internals
- Indicator computation optimized: SMA / BOLL / KDJ / signal-line style calculations use rolling implementations, with parity tests pinning value-level behavior.
- Less unnecessary K-line work: minute K-lines are clipped server-side where possible;
withIndicatorsshort-circuits avoidable double requests; indicator computation now happens after slicing. - Hot-path allocation reduced: formatter keys, per-bar object rebuilds, quote double parsing and
sortBycopies were trimmed. - Parallel implementations removed: symbol / time / parsing helpers, path walkers, East Money minute-K factories and date helpers are consolidated.
Docs site and Playground
- v2 docs site upgraded: added the red-market visual theme, live-quote Hero, navigation updates and UI polish.
- Full Playground added:
site-v2now includes Playground components, method categories, code generation, runner logic, parameter overrides and bilingual pages. - CLI docs filled in: new Chinese and English CLI commands pages cover commands, flags, output formats and common flows.
- docs validation wired to v2:
docs:meta/docs:check/ GitHub Pages builds now supportsite-v2, with forbidden tokens guarding against old broken examples. - Examples aligned with implementation: fixed old K-line period examples, string-array indicator examples, instance-screener examples, per-call signal examples,
--simpledocs and related drift.
Beta-stage notes
- Unified units remain the v2 target contract. In this beta, runtime values still follow each provider's raw convention until per-source calibration lands.
- Some legacy fields / type names may remain during beta to protect migration. New code should target the namespace API, the
Quoteunion and pure-computation subpath entries.
v2.0.0-beta.0
🧪 First public beta (
npm i stock-sdk@beta): the v2.0.0 API surface is stable — try it and send feedback; minor adjustments are still possible before the final release. The items below are the breaking changes and new capabilities relative to v1.v2 is a hard, single-track switch — there is no
compatentry point and no v1 legacy method aliases. When migrating from v1, read it alongside the v1 → v2 migration guide.
Breaking changes
- Namespaced API: all 105 methods move from the flat
sdk.getXxx()to namespacessdk.<ns>.<method>()(e.g.sdk.getFullQuotes()→sdk.quotes.cn(),sdk.getETFOptionDailyKline()→sdk.options.etf.dailyKline()). There are no compatibility aliases; see the migration guide and the API Overview for the full mapping. Quotediscriminated union: quote types are consolidated from separate interfaces (FullQuote/HKQuote/USQuote/FundQuote…) into aQuoteunion discriminated byassetType. Legacy type names may remain during beta to protect migration; new code should targetQuoteand narrow withswitch(q.assetType).rawfield removed: theraw: string[]field on 8 return types (which leaked implementation details) is deleted. The escape hatch becomes a provider-levelgetXxxRaw()debug function and no longer pollutes data objects.- Unified units and conventions (target contract):
volumetargets shares;amount/price/ market cap target the major unit of each asset's quote currency (CNY for A-shares, HKD for HK, USD for US, indicated bycurrency, with no cross-currency conversion); percentages are percentage numbers (e.g.5.2means 5.2%). Once fully landed, some numeric conventions will change relative to v1, so backtest / display logic must be recalibrated.⚠️ Unit conversions (lots→shares ×100, 万→yuan ×10000, etc.) must be calibrated per source against real data; for now values are emitted in each source's raw convention and landed after calibration — subject to the final implementation.
timestamp:NaN→null: unparsable times change fromNaNtonumber | null; null-checks move fromNumber.isNaN(...)to=== null. Atz(market time zone) field is also added to dated records.- Legacy entries and signatures cleaned up: v1 flat methods and the legacy
booleansignaturesgetAShareCodeList(boolean)/getUSCodeList(boolean)are removed in favor of namespaced APIs and options-object signatures. Some legacy fields / type names may remain during beta to protect migration; the final source of truth is the type definitions and migration guide. - Errors unified as
SdkError: the SDK now throws onlySdkError, no longer leaking rawTypeError/DOMException/RangeError. Every error carries a unifiedcode, with two new codes —ABORTED(external signal cancellation, distinct fromTIMEOUT) andUPSTREAM_ERROR(upstream returned a structured error, distinct from the empty-dataUPSTREAM_EMPTY). Importable fromstock-sdk/errors.
New capabilities
- Unified symbol model:
stringis first-class plus an optionalSymbolRef;normalizeSymbolparses leniently (sh600519/600519/600519.SH/00700/hk00700/AAPL/105.AAPL/rb2510/CFFEX.IF2412, etc.). See Symbols & code rules. - CLI:
stock-sdk <command>fetches quotes / K-line / search right in the terminal (quote/kline/search/mcp…), with a zero-dependency hand-written arg parser and JSON output by default. - MCP server:
stock-sdk mcpstarts an MCP server in one command for AI tools like Cursor / Claude / Codex. A zero-dependency, hand-written minimal MCP (thestdio + toolssubset) that does not pull in@modelcontextprotocol/sdk. - Subpath exports: new sub-entries
stock-sdk/indicators,stock-sdk/signals,stock-sdk/symbols,stock-sdk/screener,stock-sdk/cache,stock-sdk/errors. Users of pure computation only (indicators / symbols / signals) no longer dragRequestClientand all providers into their bundle. - Composable request layer:
RequestClientOptions/GetOptionsgainfetchImpl(inject a custom fetch) andsignal(external cancellation); client-level lifecyclehooksare added. See Request governance. - Signal layer:
calcSignals(event detection for golden / death crosses, overbought / oversold, etc.) — pure computation, no network — exported fromstock-sdk/signals. - Screener + backtest:
screen()for local filtering plusbacktest()for strategy backtesting, exported fromstock-sdk/screener. - Unified cache layer: low-level cache primitives are exported (
MemoryCache/getSharedCache/cacheThroughvia thestock-sdk/cachesubpath); the SDK uses them internally for the trading calendar, code lists and board mappings with tiered TTLs. Note: caches are currently module-level (shared across instances); injecting aCacheStoreat construction time with per-endpoint policies is not implemented yet and is on the 2.0.0 roadmap.
Compatibility & baseline
- Zero runtime dependencies maintained (both CLI and MCP are dependency-free); browser + Node 18+ dual-target; ESM + CJS dual-format.
- Node baseline stays at
>=18(AbortSignal.anyhas a runtime fallback). - Hard single-track switch: v1 code must be migrated wholesale per the migration guide; there is no smooth transition path.
The v1.x changelog history lives in the v1 docs site. This page records releases starting from v2.0.0.