Symbols & Codes
stock-sdk v2 funnels the whole "how do I write a ticker" question through a single entry point: normalizeSymbol. Whether you write sh600519, 600519, 600519.SH, or { code: '600519' }, it all resolves to the same internal representation before being handed to each provider adapter.
This page covers two things:
- How to pass symbols (SDK methods primarily take
string/string[];normalizeSymbolsupports an optionalSymbolRef); - The fault-tolerant parsing rules, the pure-code ambiguities, and when a hint is required.
Input: string first-class
Public SDK methods primarily take string / string[]. SymbolRef is the disambiguation input exposed by stock-sdk/symbols for normalizeSymbol:
type SymbolInput = string | SymbolRef;
interface SymbolRef {
code: string;
market?: 'CN' | 'HK' | 'US' | 'GLOBAL';
assetType?: 'stock' | 'index' | 'fund' | 'bond' | 'futures' | 'option' | 'board';
exchange?: string; // 'SSE' | 'SZSE' | 'BSE' | 'HKEX' | 'NASDAQ' | ...
}A bare string is the preferred form and covers the vast majority of cases:
await sdk.quotes.cn(['sh600519', '000001']);
await sdk.quotes.hk(['00700']); // Hong Kong
await sdk.quotes.us(['AAPL']); // USSymbolRef is not a separate system — it's a "string with hints". Its code still goes through normalizeSymbol; it just carries extra market / assetType / exchange hints to disambiguate. When you need object hints, normalize first and then pass the explicit code string to the SDK method.
// Use SymbolRef only when a bare code can't be told apart
normalizeSymbol({ code: '510300', assetType: 'fund' });
await sdk.quotes.fund(['510300']);normalizeSymbol: unified fault-tolerant parsing
normalizeSymbol is exported from stock-sdk/symbols. It's a pure function — zero network, works in both browser and Node. Providers reuse it where needed, and you can use it directly to normalize symbols yourself.
import { normalizeSymbol } from 'stock-sdk/symbols';
normalizeSymbol('sh600519');
// → { market: 'CN', exchange: 'SSE', assetType: 'stock', code: '600519', input: 'sh600519' }
normalizeSymbol('AAPL');
// → { market: 'US', exchange: 'US', assetType: 'stock', code: 'AAPL', input: 'AAPL' }The returned NormalizedSymbol is the SDK's single internal representation:
interface NormalizedSymbol {
market: 'CN' | 'HK' | 'US' | 'GLOBAL';
exchange: string; // the strong discriminator
assetType: 'stock' | 'index' | 'fund' | 'bond' | 'futures' | 'option' | 'board';
code: string; // pure code, no prefix
variety?: string; // futures variety (e.g. 'IF' / 'RB')
input: string; // original input, for errors and debugging
}
marketdenotes the trading region / system;exchangeis the strong discriminator. For example, overseas futures fall undermarket: 'GLOBAL'and are distinguished byexchange(COMEX / NYMEX / CBOT / LME …).
Resolution priority chain (first match wins)
normalizeSymbol(input, hint?) tries the following rules in order and returns on the first match. When hint conflicts with SymbolRef fields, the explicit input (SymbolRef) wins.
| Order | Rule | Example |
|---|---|---|
| 1 | Dotted form: Eastmoney secid / suffix / futures exchange / board | 1.600519, 600519.SH, CFFEX.IF2412, 90.BK0475 |
| 2 | Letter prefix | sh600519, sz000001, bj430047, hk00700, usAAPL |
| 3 | Pure digits | 600519, 000001, 00700 |
| 4 | Bare futures contract with hint | rb2510 (with assetType:'futures') |
| 5 | Pure letters → US stock | AAPL, MSFT |
| 6 | Parse failure → throw InvalidSymbolError | '', @@@ |
Per-market cheat sheet
| Market | Accepted forms | Normalized result |
|---|---|---|
| A-share (Shanghai) | sh600519, 600519, 600519.SH, 1.600519 | CN / SSE / 600519 |
| A-share (Shenzhen) | sz000001, 000001, 000001.SZ, 0.000001 | CN / SZSE / 000001 |
| A-share (Beijing) | bj430047, 430047, 920819 | CN / BSE / 430047 |
| Hong Kong | 00700, hk00700, 700, 00700.HK, 116.00700 | HK / HKEX / 00700 |
| US | AAPL, usAAPL, 105.AAPL, 106.BABA | US / US (or NASDAQ / NYSE / AMEX) |
| CN futures | rb2510 (with hint), CFFEX.IF2412 | CN / SHFE, CFFEX … |
| Board | 90.BK0475 | CN / SSE / board |
Hong Kong codes shorter than 5 digits are zero-padded:
700→00700,hk700→00700. US tickers are upper-cased:aapl→AAPL.
Pure-code inference and ambiguity
When you supply only a pure code (no prefix, no suffix, no hint), inference follows these defaults:
| Shape | Default inference | Exchange refinement |
|---|---|---|
| 6 pure digits | A-share stock | starts with 6/5/9 → SSE; 0/3 → SZSE; 4/8 or the 92 range → BSE |
| 5 / 4 pure digits | Hong Kong stock | zero-padded to 5 digits |
| Pure letters | US stock | — |
Pure-code inference is "most-common-wins", so some cases simply cannot be told apart from the code alone and require a hint or SymbolRef when calling normalizeSymbol.
Known ambiguities that require a hint
① Fund vs. stock (overlapping code ranges)
On-exchange fund / ETF code ranges overlap with stock code ranges; a bare code can't distinguish them, so declare the asset type explicitly:
// Without a hint this is treated as a stock
normalizeSymbol('510300', { assetType: 'fund' });
await sdk.quotes.fund(['510300']);② Index vs. stock (both 6 digits)
For example, 000001 is both the Shanghai Composite Index and Ping An Bank. A bare code defaults to stock; to mean the index, add a hint:
normalizeSymbol('000001', { assetType: 'index' });③ A/B-share five-digit codes instead of Hong Kong
A 5-digit pure code defaults to Hong Kong. If you truly mean a 5-digit A/B-share code, specify the market explicitly:
normalizeSymbol('90001', { market: 'CN' });④ Overseas futures bare contracts
Futures with market: 'GLOBAL' must provide an explicit exchange; they will not default to a domestic exchange:
normalizeSymbol('GC', { market: 'GLOBAL', exchange: 'COMEX' });
// Missing exchange throws InvalidSymbolErrorRule of thumb: prefer an explicit form (prefix / suffix / secid) whenever it expresses your intent (e.g.
sh000001for the Shanghai Composite). Use a hint only when the system genuinely lacks enough information.
Parse failure: InvalidSymbolError
Unparseable input throws InvalidSymbolError (a subclass of SdkError, with code INVALID_SYMBOL), carrying the original input for diagnosis:
import { normalizeSymbol } from 'stock-sdk/symbols';
import { InvalidSymbolError } from 'stock-sdk/errors';
try {
normalizeSymbol('');
} catch (e) {
if (e instanceof InvalidSymbolError) {
console.log(e.code); // 'INVALID_SYMBOL'
}
}See Errors & Retry for the full error system.
The type fields above are subject to the final implementation; the resolution priority and known ambiguities are stable conventions.