@itick/browser-sdk
Version:
Official iTick API SDK for browser. Real-time & historical data for global Stocks, Forex, Crypto, Indices, Futures, Funds, Precious Metals. REST (OHLCV/K-line) + low-latency WebSocket. Promise-based, TypeScript-ready. For quant trading & fintech
1,169 lines (1,162 loc) • 84.8 kB
JavaScript
/**
* Kline Period Enum (Standard Text Identifiers + Numeric Codes)
* Centrally maintained for global reuse
*/
const KlinePeriod = {
ONE_MIN: '1m',
FIVE_MIN: '5m',
FIFTEEN_MIN: '15m',
THIRTY_MIN: '30m',
ONE_HOUR: '1h',
TWO_HOUR: '2h',
FOUR_HOUR: '4h',
ONE_DAY: '1d',
ONE_WEEK: '1w',
ONE_MONTH: '1M',
};
// Numeric code mapping
const KlineTypeCode = {
[KlinePeriod.ONE_MIN]: 1,
[KlinePeriod.FIVE_MIN]: 2,
[KlinePeriod.FIFTEEN_MIN]: 3,
[KlinePeriod.THIRTY_MIN]: 4,
[KlinePeriod.ONE_HOUR]: 5,
[KlinePeriod.TWO_HOUR]: 6,
[KlinePeriod.FOUR_HOUR]: 7,
[KlinePeriod.ONE_DAY]: 8,
[KlinePeriod.ONE_WEEK]: 9,
[KlinePeriod.ONE_MONTH]: 10,
};
/**
* Market Data Subscription Types
* Supports both kline@1m and kline@1 formats
*/
const SubscribeType = {
// Basic market data
QUOTE: 'quote',
DEPTH: 'depth',
TICK: 'tick',
// Kline subscription
KLINE_1M: `kline@${KlinePeriod.ONE_MIN}`,
KLINE_5M: `kline@${KlinePeriod.FIVE_MIN}`,
KLINE_15M: `kline@${KlinePeriod.FIFTEEN_MIN}`,
KLINE_30M: `kline@${KlinePeriod.THIRTY_MIN}`,
KLINE_1H: `kline@${KlinePeriod.ONE_HOUR}`,
KLINE_2H: `kline@${KlinePeriod.TWO_HOUR}`,
KLINE_4H: `kline@${KlinePeriod.FOUR_HOUR}`,
KLINE_1D: `kline@${KlinePeriod.ONE_DAY}`,
KLINE_1W: `kline@${KlinePeriod.ONE_WEEK}`,
KLINE_1MTH: `kline@${KlinePeriod.ONE_MONTH}`,
};
// Numeric code mapping
const SubscribeTypeCode = {
[SubscribeType.KLINE_1M]: `kline@${KlineTypeCode[KlinePeriod.ONE_MIN]}`,
[SubscribeType.KLINE_5M]: `kline@${KlineTypeCode[KlinePeriod.FIVE_MIN]}`,
[SubscribeType.KLINE_15M]: `kline@${KlineTypeCode[KlinePeriod.FIFTEEN_MIN]}`,
[SubscribeType.KLINE_30M]: `kline@${KlineTypeCode[KlinePeriod.THIRTY_MIN]}`,
[SubscribeType.KLINE_1H]: `kline@${KlineTypeCode[KlinePeriod.ONE_HOUR]}`,
[SubscribeType.KLINE_2H]: `kline@${KlineTypeCode[KlinePeriod.TWO_HOUR]}`,
[SubscribeType.KLINE_4H]: `kline@${KlineTypeCode[KlinePeriod.FOUR_HOUR]}`,
[SubscribeType.KLINE_1D]: `kline@${KlineTypeCode[KlinePeriod.ONE_DAY]}`,
[SubscribeType.KLINE_1W]: `kline@${KlineTypeCode[KlinePeriod.ONE_WEEK]}`,
[SubscribeType.KLINE_1MTH]: `kline@${KlineTypeCode[KlinePeriod.ONE_MONTH]}`,
};
const STRICT_SYMBOL_REGEX = /^[A-Za-z0-9]+\$[A-Za-z0-9]+$/;
function buildApiUrl(baseURL, path) {
return `${baseURL.replace(/\/$/, '')}${path}`;
}
function buildWebSocketUrl(wssURL, path) {
return `${wssURL.replace(/\/$/, '')}${path}`;
}
/**
* Convert K-line period string to number
*/
function convertKlinePeriod(period) {
if (period === KlinePeriod.ONE_MIN)
return 1;
if (period === KlinePeriod.FIVE_MIN)
return 2;
if (period === KlinePeriod.FIFTEEN_MIN)
return 3;
if (period === KlinePeriod.THIRTY_MIN)
return 4;
if (period === KlinePeriod.ONE_HOUR)
return 5;
if (period === KlinePeriod.TWO_HOUR)
return 6;
if (period === KlinePeriod.FOUR_HOUR)
return 7;
if (period === KlinePeriod.ONE_DAY)
return 8;
if (period === KlinePeriod.ONE_WEEK)
return 9;
if (period === KlinePeriod.ONE_MONTH)
return 10;
return period;
}
/**
* Convert websocket subscription type
*/
function convertSubscribeType(type) {
if (type === SubscribeType.KLINE_1M)
return 'kline@1';
if (type === SubscribeType.KLINE_5M)
return 'kline@2';
if (type === SubscribeType.KLINE_15M)
return 'kline@3';
if (type === SubscribeType.KLINE_30M)
return 'kline@4';
if (type === SubscribeType.KLINE_1H)
return 'kline@5';
if (type === SubscribeType.KLINE_2H)
return 'kline@6';
if (type === SubscribeType.KLINE_4H)
return 'kline@7';
if (type === SubscribeType.KLINE_1D)
return 'kline@8';
if (type === SubscribeType.KLINE_1W)
return 'kline@9';
if (type === SubscribeType.KLINE_1MTH)
return 'kline@10';
return type;
}
/**
* Convert subscription type list
*/
function parseeSubscribeType(type) {
let rawList;
if (Array.isArray(type))
rawList = type.map(String);
else
rawList = type.split(',');
const validTypes = Object.values(SubscribeType);
const processedList = [];
const apiToEnumMap = {};
for (const enumValue of validTypes) {
// Ensure enumValue is a valid SubscribeType
if (typeof enumValue === 'string' || typeof enumValue === 'number') {
const apiFormat = convertSubscribeType(enumValue);
apiToEnumMap[apiFormat] = enumValue;
}
}
for (const item of rawList) {
const trimmed = item.trim();
if (!trimmed)
continue;
let targetEnum;
const isValid = validTypes.some(v => v === trimmed);
if (isValid)
targetEnum = trimmed;
else
targetEnum = apiToEnumMap[trimmed];
if (!targetEnum)
throw new Error(`Invalid subscribe type: "${trimmed}". Valid types are: ${validTypes.join(', ')}`);
processedList.push(convertSubscribeType(trimmed));
}
return [...new Set(processedList)].join(',');
}
/**
* Subscription product parameter formatting function
* @param input Subscription parameters
*/
function parseSymbols(input) {
const list = Array.isArray(input) ? input : input.split(',');
return [...new Set(list
.map(item => item.trim())
.filter(Boolean)
.map(item => {
if (!STRICT_SYMBOL_REGEX.test(item))
throw new Error(`Invalid symbol format: "${item}". Expected format is "SYMBOL$REGION", e.g. "AAPL$US".`);
return item.toUpperCase();
}))].join(',');
}
/**
* Build query string
*/
function buildQueryString(params) {
return Object.entries(params)
.filter(([_, value]) => value != null)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join('&');
}
/**
* HTTP request implementation for Browser environment (using fetch API)
*/
async function makeHttpRequest(url, options = {}) {
const { method = 'GET', headers = {}, body, params = {}, } = options;
// Build complete URL
let finalUrl = url;
// For GET requests, append params to URL
if (method === 'GET' && Object.keys(params).length > 0) {
const queryString = buildQueryString(params);
// Handle existing query parameters in the base URL
const separator = finalUrl.includes('?') ? '&' : '?';
finalUrl = `${finalUrl}${separator}${queryString}`;
}
// Prepare fetch options
const fetchOptions = {
method,
headers: {
'Content-Type': 'application/json',
...headers,
},
};
// Attach body for non-GET methods
if (body && method !== 'GET') {
fetchOptions.body = body;
}
try {
const response = await fetch(finalUrl, fetchOptions);
// Extract headers as a plain object
const responseHeaders = {};
response.headers.forEach((value, key) => {
responseHeaders[key] = value;
});
// Parse JSON response
let data;
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
try {
data = await response.json();
}
catch (e) {
// Fallback to text if JSON parsing fails but content-type suggests JSON
data = await response.text();
}
}
else {
// For non-JSON responses, get text
data = await response.text();
}
return {
status: response.status,
data,
headers: responseHeaders,
};
}
catch (error) {
// Network errors or other fetch failures
throw new Error(`Request failed: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Create WebSocket instance (Browser environment)
*/
async function createWebSocket(url, token) {
return new WebSocket(`${url}?token=${token}`);
}
class SocketClient {
constructor(token, options) {
// WebSocket connection related properties
this.socket = null;
this.isRunning = false;
this.reconnectAttempts = 0;
this.pingInterval = null;
this.reconnectTimeout = null;
// Callback functions
this.messageHandlers = [];
this.errorHandlers = [];
this.openHandlers = [];
this.closeHandlers = [];
// Subscription information storage
this.lastSubscription = null;
this.wssURL = options.wssURL ?? 'wss://api.itick.org';
this.wsPath = options.wsPath;
this.token = token;
this.RECONNECT_INTERVAL = options.reconnectInterval ?? 5000;
this.MAX_RECONNECT_ATTEMPTS = options.maxReconnectTimes ?? 0;
this.PING_INTERVAL = options.pingInterval ?? 30000;
this.lastSubscription = options.subscribeData ?? null;
this._connectWebSocket();
}
/**
* WebSocket Message Handler
*/
onSocketMessage(handler) {
this.messageHandlers.push(handler);
}
/**
* WebSocket Error Handler
*/
onSocketError(handler) {
this.errorHandlers.push(handler);
}
/**
* WebSocket Connection Open Handler
*/
onSocketOpen(handler) {
this.openHandlers.push(handler);
}
/**
* WebSocket Connection Close Handler
*/
onSocketClose(handler) {
this.closeHandlers.push(handler);
}
/**
* Internal WebSocket Connection Method
*/
async _connectWebSocket() {
const url = buildWebSocketUrl(this.wssURL, this.wsPath || '');
try {
this.isRunning = true;
this.socket = await createWebSocket(url, this.token);
this.socket.onopen = () => {
this.reconnectAttempts = 0;
this._startPing();
this.openHandlers.forEach(handler => handler());
// Subscribe to data after successful connection
this._resubscribeLast();
};
this.socket.onmessage = (event) => {
const messageStr = typeof event.data === 'string' ? event.data : event.data.toString();
this.messageHandlers.forEach(handler => handler(JSON.parse(messageStr)));
};
this.socket.onclose = (event) => {
this._stopPing();
this.closeHandlers.forEach(handler => handler(event));
if (this.isRunning) {
this._scheduleReconnect();
}
};
this.socket.onerror = (event) => {
this.errorHandlers.forEach(handler => handler(event));
};
}
catch (error) {
this.errorHandlers.forEach(handler => handler(error));
if (this.isRunning) {
this._scheduleReconnect();
}
}
}
/**
* Start heartbeat ping
*/
_startPing() {
this._stopPing();
this.pingInterval = setInterval(() => {
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify({ ac: "ping", params: Date.now() }));
}
}, this.PING_INTERVAL);
}
/**
* Stop heartbeat ping
*/
_stopPing() {
if (this.pingInterval) {
clearInterval(this.pingInterval);
this.pingInterval = null;
}
}
/**
* Schedule reconnection
*/
_scheduleReconnect() {
// When MAX_RECONNECT_ATTEMPTS is 0, it means unlimited reconnection
if (this.MAX_RECONNECT_ATTEMPTS > 0 && this.reconnectAttempts >= this.MAX_RECONNECT_ATTEMPTS) {
this.errorHandlers.forEach(handler => handler(new Error('Maximum reconnect attempts reached')));
return;
}
this.reconnectAttempts++;
this.reconnectTimeout = setTimeout(() => {
if (this.isRunning) {
this._connectWebSocket().catch((error) => { });
}
}, this.RECONNECT_INTERVAL);
}
/**
* WebSocket Subscription Method
* @description
* message object must contain ac, types and params fields
* - ac: operation type, must be "subscribe" or "unsubscribe"
* - types: subscription types, can be comma-separated string or string array, supports "quote", "depth", "tick", "kline@1m" etc. kline@1m can also be written as kline@1, SDK will automatically convert to correct format
* - params: subscription parameters, can be comma-separated string or string array, format is "code$region" (e.g., "AAPL$US") SDK will automatically handle formatting
* - String array format is recommended for clearer code and fewer errors
* @example
* Example 1: Subscribe to AAPL and TSA real-time quotes/order book/trades/1-minute K-line data
* ```json
* {
* "ac": "subscribe",
* "types": "quote,depth,tick,kline@1",
* "params": "AAPL$US,TSA$US"
* }
* ```
* Example 2: Subscribe to AAPL and TSA real-time quotes/order book/trades/1-minute K-line data
* ```json
* {
* "ac": "subscribe",
* "types": ["quote","depth","tick","kline@1m"],
* "params": ["AAPL$US","TSA$US"]
* }
* ```
*
* Both methods can correctly subscribe, SDK will automatically handle type conversion and parameter formatting
*
*/
subscribeSocket(data) {
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
throw new Error('WebSocket not connected');
}
try {
let { ac, types, codes } = data;
const type = parseeSubscribeType(types);
const symbol = parseSymbols(codes);
this.socket.send(JSON.stringify({ ac, types: type, params: symbol }));
}
catch (err) {
console.error(err);
}
}
/**
* Restore subscription after reconnection
*/
_resubscribeLast() {
if (!this.lastSubscription)
return;
try {
let { types, codes } = this.lastSubscription;
const type = parseeSubscribeType(types);
const symbol = parseSymbols(codes);
this.socket?.send(JSON.stringify({ ac: 'subscribe', types: type, params: symbol }));
}
catch (err) {
console.error(err);
}
}
/**
* Close WebSocket
*/
closeWebSocket() {
this.isRunning = false;
this._stopPing();
if (this.reconnectTimeout) {
clearTimeout(this.reconnectTimeout);
}
if (this.socket) {
this.socket.close();
}
// Clear last subscription information when closing
this.lastSubscription = null;
}
/**
* Check if WebSocket is connected
*/
checkSocketConnected() {
if (!this.socket)
return false;
return this.socket.readyState === WebSocket.OPEN;
}
disconnectSocket() {
this.closeWebSocket();
}
}
/**
* Core Client Class
* Provides basic functionality for WebSocket connections and HTTP requests
*/
class Client {
constructor(token, options = {}) {
this.token = token;
this.baseURL = options.baseURL ?? 'https://api.itick.org';
this.wssURL = options.wssURL ?? 'wss://api.itick.org';
}
/**
* Send GET request
*/
async _get(path, params = {}) {
try {
const url = buildApiUrl(this.baseURL, path);
const response = await makeHttpRequest(url, {
method: 'GET',
headers: {
'accept': 'application/json',
'token': this.token
},
params,
});
if (response.status >= 400) {
throw new Error(`HTTP Error: ${response.status}`);
}
return response.data;
}
catch (error) {
throw error;
}
}
_createSocket(path, options) {
return new SocketClient(this.token, { wssURL: this.wssURL, wsPath: path, ...options });
}
}
/**
* Stock Module
* Provides data access interfaces for stocks
*/
/**
* Stock SDK Client
* Specialized for stock data access
*/
class StockClient extends Client {
constructor(token, options) {
super(token, options);
}
/**
* Get Stock Information
* @description Query basic stock information based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., US, HK etc.), see {@link https://docs.itick.org/rest-api/stocks/stock-info Official Documentation} for complete supported list
* @param params.code - Stock code (e.g., AAPL, MSFT etc.)
* @param params.exchange - Optional Exchange code (e.g., NYSE, NASDAQ etc.)
* @returns Promise wrapped standard API response, data is stock information data {@link StockInfo}
* @example
* ```typescript
* // Get Apple Inc. stock information
* getInfo({ region: 'US', code: 'AAPL' }).then(response => {
* console.log('Stock information:', response.data);
* }).catch(err => {
* console.error('Failed to get stock information:', err);
* });
* ```
*/
async getInfo(params) {
const { region, code, exchange } = params;
return this._get('/stock/info', { type: 'stock', region, code, exchange });
}
/**
* Get Stock IPO Information
* @description Query stock initial public offering information based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., US, HK etc.), see {@link https://docs.itick.org/rest-api/stocks/stock-ipo Official Documentation} for complete supported list
* @param params.code - Stock code (e.g., AAPL, MSFT etc.)
* @returns Promise wrapped standard API response, data is stock IPO information data {@link StockIPO}
* @example
* ```typescript
* // Get Apple Inc. IPO information
* getIPO({ region: 'US', code: 'AAPL' }).then(response => {
* console.log('IPO information:', response.data);
* }).catch(err => {
* console.error('Failed to get IPO information:', err);
* });
* ```
*/
async getIPO(params) {
const { region, code } = params;
return this._get('/stock/ipo', { region, code });
}
/**
* Get Stock Adjustment Factor Information
* @description Query stock ex-rights and ex-dividend information based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., US, HK etc.), see {@link https://docs.itick.org/rest-api/stocks/stock-split Official Documentation} for complete supported list
* @param params.code - Stock code (e.g., AAPL, MSFT etc.)
* @returns Promise wrapped standard API response, data is stock adjustment factor information data {@link StockSplit}
* @example
* ```typescript
* // Get Apple Inc. adjustment information
* getSplit({ region: 'US', code: 'AAPL' }).then(response => {
* console.log('Adjustment information:', response.data);
* }).catch(err => {
* console.error('Failed to get adjustment information:', err);
* });
* ```
*/
async getSplit(params) {
const { region, code } = params;
return this._get('/stock/split', { region, code });
}
/**
* Get Stock Real-Time Trade Snapshot
* @description Query latest trade real-time market data for stock based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., US, HK etc.), see {@link https://docs.itick.org/rest-api/stocks/stock-tick Official Documentation} for complete supported list
* @param params.code - Stock code (e.g., AAPL, MSFT etc.)
* @returns Promise wrapped standard API response, data is real-time market data {@link TickData}
* @example
* ```typescript
* // Get real-time trade market data for Apple Inc. stock
* getTick({ region: 'US', code: 'AAPL' }).then(response => {
* console.log('Real-time market:', response.data);
* }).catch(err => {
* console.error('Failed to get market data:', err);
* });
* ```
*/
async getTick(params) {
const { region, code } = params;
return this._get('/stock/tick', { region, code });
}
/**
* Get Stock Latest Quote
* @description Query latest quote real-time market data for stock based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., US, HK etc.), see {@link https://docs.itick.org/rest-api/stocks/stock-quote Official Documentation} for complete supported list
* @param params.code - Stock code (e.g., AAPL, MSFT etc.)
* @returns Promise wrapped API response, data is latest quote data {@link QuoteData}
* @example
* ```typescript
* // Get latest quote for Apple Inc. stock
* getQuote({ region: 'US', code: 'AAPL' }).then(response => {
* console.log('Latest quote:', response.data);
* }).catch(err => {
* console.error('Failed to get quote:', err);
* });
* ```
*/
async getQuote(params) {
const { region, code } = params;
return this._get('/stock/quote', { region, code });
}
/**
* Get Stock Latest Order Book
* @description Query latest order book data for stock based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., US, HK etc.), see {@link https://docs.itick.org/rest-api/stocks/stock-depth Official Documentation} for complete supported list
* @param params.code - Stock code (e.g., AAPL, MSFT etc.)
* @returns Promise wrapped API response, data is latest order book data {@link DepthData}
* @example
* ```typescript
* // Get latest order book for Apple Inc. stock
* getDepth({ region: 'US', code: 'AAPL' }).then(response => {
* console.log('Latest order book:', response.data);
* }).catch(err => {
* console.error('Failed to get order book:', err);
* });
* ```
*/
async getDepth(params) {
const { region, code } = params;
return this._get('/stock/depth', { region, code });
}
/**
* Get Stock K-Line Data
* @description Query stock K-line data based on market code, symbol code, K-line period, end time and number of records to return
* @param options - Query parameters object {@link GetKlineOptions}
* @param options.region - Market code (e.g., US, HK etc.), see {@link https://docs.itick.org/rest-api/stocks/stock-kline Official Documentation} for complete supported list
* @param options.code - Stock code (e.g., AAPL, MSFT etc.)
* @returns Promise wrapped API response, data is K-line data array {@link KlineData}
* @example
* ```typescript
* // Get 5-minute K-line data for Apple Inc. stock
* getKline({ region: 'US', code: 'AAPL', interval: '5m', limit: 100 }).then(response => {
* console.log('K-line data:', response.data);
* }).catch(err => {
* console.error('Failed to get K-line data:', err);
* });
* ```
*/
async getKline(options) {
const { region, code, kType, interval, limit, et } = options;
const params = { region, code, kType: convertKlinePeriod(interval ?? kType), limit };
if (et)
params.et = et;
return this._get('/stock/kline', params);
}
/**
* Get Multiple Stocks Latest Trades
* @description Query latest trade real-time market data for multiple stocks based on market code and symbol code list
* @param params - Query parameters object
* @param params.region - Market code (e.g., US, HK etc.), see {@link https://docs.itick.org/rest-api/stocks/stock-ticks Official Documentation} for complete supported list
* @param params.codes - Symbol code list (e.g., AAPL, MSFT etc.)
* @returns Promise wrapped API response, data is multiple stocks latest trade data object {@link TickDataMap}
* @example
* ```typescript
* // Get latest trade market data for Apple Inc. and Microsoft Corp.
* getTicks({ region: 'US', codes: ['AAPL', 'MSFT'] }).then(response => {
* console.log('Latest trades:', response.data);
* }).catch(err => {
* console.error('Failed to get trade market data:', err);
* });
* ```
*/
async getTicks(params) {
const { region, codes } = params;
return this._get('/stock/ticks', { region, codes: Array.isArray(codes) ? codes.join(',') : codes });
}
/**
* Get Multiple Stocks Latest Quotes
* @description Query latest quote real-time market data for multiple stocks based on market code and symbol code list
* @param params - Query parameters object
* @param params.region - Market code (e.g., US, HK etc.), see {@link https://docs.itick.org/rest-api/stocks/stock-quotes Official Documentation} for complete supported list
* @param params.codes - Symbol code list (e.g., AAPL, MSFT etc.)
* @returns Promise wrapped API response, data is multiple stocks latest quote data object {@link QuoteDataMap}
* @example
* ```typescript
* // Get latest quotes for Apple Inc. and Microsoft Corp.
* getQuotes({ region: 'US', codes: ['AAPL', 'MSFT'] }).then(response => {
* console.log('Latest quotes:', response.data);
* }).catch(err => {
* console.error('Failed to get quotes:', err);
* });
* ```
*/
async getQuotes(params) {
const { region, codes } = params;
return this._get('/stock/quotes', { region, codes: Array.isArray(codes) ? codes.join(',') : codes });
}
/**
* Get Multiple Stocks Latest Order Books
* @description Query latest order book real-time market data for multiple stocks based on market code and symbol code list
* @param params - Query parameters object
* @param params.region - Market code (e.g., US, HK etc.), see {@link https://docs.itick.org/rest-api/stocks/stock-depths Official Documentation} for complete supported list
* @param params.codes - Symbol code list (e.g., AAPL, MSFT etc.)
* @returns Promise wrapped API response, data is multiple stocks latest order book data object {@link DepthDataMap}
* @example
* ```typescript
* // Get latest order books for Apple Inc. and Microsoft Corp.
* getDepths({ region: 'US', codes: ['AAPL', 'MSFT'] }).then(response => {
* console.log('Latest order books:', response.data);
* }).catch(err => {
* console.error('Failed to get order books:', err);
* });
* ```
*/
async getDepths(params) {
const { region, codes } = params;
return this._get('/stock/depths', { region, codes: Array.isArray(codes) ? codes.join(',') : codes });
}
/**
* Get Multiple Stocks K-Line Data
* @description Query K-line data for multiple stocks based on market code, symbol code list, K-line period, end time and number of records to return
* @param options - Query parameters object {@link GetKlinesOptions}
* @param options.region - Market code (e.g., US, HK etc.), see {@link https://docs.itick.org/rest-api/stocks/stock-klines Official Documentation} for complete supported list
* @param options.codes - Symbol code list (e.g., AAPL, MSFT etc.)
* @returns Promise wrapped API response, data is multiple stocks K-line data object {@link KlineDataMap}
* @example
* ```typescript
* // Get 5-minute K-line data for Apple Inc. and Microsoft Corp.
* getKlines({ region: 'US', codes: ['AAPL', 'MSFT'], kType: '5m', limit: 100 }).then(response => {
* console.log('K-line data:', response.data);
* }).catch(err => {
* console.error('Failed to get K-line data:', err);
* });
* ```
*/
async getKlines(options) {
const { region, codes, kType, interval, limit, et } = options;
const params = { region, codes: Array.isArray(codes) ? codes.join(',') : codes, kType: convertKlinePeriod(interval ?? kType), limit };
if (et)
params.et = et;
return this._get('/stock/klines', params);
}
/**
* Create WebSocket Connection
* @description Creates a WebSocket connection and returns a SocketClient object for managing connection and subscribing to real-time data. Subscription data can be specified through options parameter.
* Automatically handles connection retry and heartbeat mechanism to ensure connection stability and reliability.
* @param options - Optional options object for creating WebSocket connection {@link CreateSocketOptions}
* @returns SocketClient object for managing WebSocket connection
* @example
* ```typescript
* // Create a WebSocket connection and subscribe to latest tick and quote market data for Apple and Microsoft
* const client = new StockClient(token);
* const socket = client.createSocket({
* subscribeData: {
* codes: ['AAPL$US', 'MSFT$US'],
* types: ['tick','quote']
* }
* });
* socket.onSocketMessage(data => {
* console.log('Received WebSocket message:', data);
* });
* ```
* @see Official Documentation https://docs.itick.org/websocket/stocks
*/
createSocket(options) {
return this._createSocket('/stock', options);
}
}
/**
* Cryptocurrency Module
* Provides data access interfaces for cryptocurrencies
*/
/**
* Cryptocurrency SDK Client
* Specialized for cryptocurrency data access
*/
class CryptoClient extends Client {
constructor(token, options) {
super(token, options);
}
/**
* Get Cryptocurrency Real-Time Trade Snapshot
* @description Query latest trade real-time market data for cryptocurrency based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., BA, BT, PB etc.), see {@link https://docs.itick.org/rest-api/crypto/crypto-tick Official Documentation} for complete supported list
* @param params.code - Symbol code (e.g., BTCUSDT, ETHUSDT etc.)
* @returns Promise wrapped standard API response, data is real-time market data {@link TickData}
* @example
* ```typescript
* // Get real-time trade market data for BTCUSDT cryptocurrency pair
* getTick({ region: 'BA', code: 'BTCUSDT' }).then(response => {
* console.log('Real-time market:', response.data);
* }).catch(err => {
* console.error('Failed to get market data:', err);
* });
* ```
*/
async getTick(params) {
const { region, code } = params;
return this._get('/crypto/tick', { region, code });
}
/**
* Get Cryptocurrency Latest Quote
* @description Query latest quote real-time market data for cryptocurrency based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., BA, BT, PB etc.), see {@link https://docs.itick.org/rest-api/crypto/crypto-quote Official Documentation} for complete supported list
* @param params.code - Symbol code (e.g., BTCUSDT, ETHUSDT etc.)
* @returns Promise wrapped API response, data is latest quote data {@link QuoteData}
* @example
* ```typescript
* // Get latest quote for BTCUSDT cryptocurrency pair
* getQuote({ region: 'BA', code: 'BTCUSDT' }).then(response => {
* console.log('Latest quote:', response.data);
* }).catch(err => {
* console.error('Failed to get quote:', err);
* });
* ```
*/
async getQuote(params) {
const { region, code } = params;
return this._get('/crypto/quote', { region, code });
}
/**
* Get Cryptocurrency Latest Order Book
* @description Query latest order book data for cryptocurrency based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., BA, BT, PB etc.), see {@link https://docs.itick.org/rest-api/crypto/crypto-depth Official Documentation} for complete supported list
* @param params.code - Symbol code (e.g., BTCUSDT, ETHUSDT etc.)
* @returns Promise wrapped API response, data is latest order book data {@link DepthData}
* @example
* ```typescript
* // Get latest order book for BTCUSDT cryptocurrency pair
* getDepth({ region: 'BA', code: 'BTCUSDT' }).then(response => {
* console.log('Latest order book:', response.data);
* }).catch(err => {
* console.error('Failed to get order book:', err);
* });
* ```
*/
async getDepth(params) {
const { region, code } = params;
return this._get('/crypto/depth', { region, code });
}
/**
* Get Cryptocurrency K-Line Data
* @description Query cryptocurrency K-line data based on market code, symbol code, K-line period, end time and number of records to return
* @param options - Query parameters object see {@link GetKlineOptions}
* @param options.region - Market code (e.g., BA, BT, PB etc.), see {@link https://docs.itick.org/rest-api/crypto/crypto-kline Official Documentation} for complete supported list
* @param params.code - Symbol code (e.g., BTCUSDT, ETHUSDT etc.)
* @returns Promise wrapped API response, data is K-line data array {@link KlineData}
* @example
* ```typescript
* // Get 5-minute K-line data for BTCUSDT cryptocurrency pair
* getKline({ region: 'BA', code: 'BTCUSDT', interval: '5m', limit: 100 }).then(response => {
* console.log('K-line data:', response.data);
* }).catch(err => {
* console.error('Failed to get K-line data:', err);
* });
* ```
*/
async getKline(options) {
const { region, code, kType, interval, limit, et } = options;
const params = { region, code, kType: convertKlinePeriod(interval ?? kType), limit };
if (et)
params.et = et;
return this._get('/crypto/kline', params);
}
/**
* Get Multiple Cryptocurrencies Latest Trades
* @description Query latest trade real-time market data for multiple cryptocurrencies based on market code and symbol code list
* @param params - Query parameters object
* @param params.region - Market code (e.g., BA, BT, PB etc.), see {@link https://docs.itick.org/rest-api/crypto/crypto-ticks Official Documentation} for complete supported list
* @param params.codes - Symbol code list (e.g., BTCUSDT, ETHUSDT etc.)
* @returns Promise wrapped API response, data is multiple cryptocurrencies latest trade data object {@link TickDataMap}
* @example
* ```typescript
* // Get latest trade market data for BTCUSDT and ETHUSDT cryptocurrency pairs
* getTicks({ region: 'BA', codes: ['BTCUSDT', 'ETHUSDT'] }).then(response => {
* console.log('Latest trades:', response.data);
* }).catch(err => {
* console.error('Failed to get trade market data:', err);
* });
* ```
*/
async getTicks(params) {
const { region, codes } = params;
return this._get('/crypto/ticks', { region, codes: Array.isArray(codes) ? codes.join(',') : codes });
}
/**
* Get Multiple Cryptocurrencies Latest Quotes
* @description Query latest quote real-time market data for multiple cryptocurrencies based on market code and symbol code list
* @param params - Query parameters object
* @param params.region - Market code (e.g., BA, BT, PB etc.), see {@link https://docs.itick.org/rest-api/crypto/crypto-quotes Official Documentation} for complete supported list
* @param params.codes - Symbol code list (e.g., BTCUSDT, ETHUSDT etc.)
* @returns Promise wrapped API response, data is multiple cryptocurrencies latest quote data object {@link QuoteDataMap}
* @example
* ```typescript
* // Get latest quotes for BTCUSDT and ETHUSDT cryptocurrency pairs
* getQuotes({ region: 'BA', codes: ['BTCUSDT', 'ETHUSDT'] }).then(response => {
* console.log('Latest quotes:', response.data);
* }).catch(err => {
* console.error('Failed to get quotes:', err);
* });
* ```
*/
async getQuotes(params) {
const { region, codes } = params;
return this._get('/crypto/quotes', { region, codes: Array.isArray(codes) ? codes.join(',') : codes });
}
/**
* Get Multiple Cryptocurrencies Latest Order Books
* @description Query latest order book real-time market data for multiple cryptocurrencies based on market code and symbol code list
* @param params - Query parameters object
* @param params.region - Market code (e.g., BA, BT, PB etc.), see {@link https://docs.itick.org/rest-api/crypto/crypto-depths Official Documentation} for complete supported list
* @param params.codes - Symbol code list (e.g., BTCUSDT, ETHUSDT etc.)
* @returns Promise wrapped API response, data is multiple cryptocurrencies latest order book data object {@link DepthDataMap}
* @example
* ```typescript
* // Get latest order books for BTCUSDT and ETHUSDT cryptocurrency pairs
* getDepths({ region: 'BA', codes: ['BTCUSDT', 'ETHUSDT'] }).then(response => {
* console.log('Latest order books:', response.data);
* }).catch(err => {
* console.error('Failed to get order books:', err);
* });
* ```
*/
async getDepths(params) {
const { region, codes } = params;
return this._get('/crypto/depths', { region, codes: Array.isArray(codes) ? codes.join(',') : codes });
}
/**
* Get Multiple Cryptocurrencies K-Line Data
* @description Query K-line data for multiple cryptocurrencies based on market code, symbol code list, K-line period, end time and number of records to return
* @param options - Query parameters object {@link GetKlinesOptions}
* @param options.region - Market code (e.g., BA, BT, PB etc.), see {@link https://docs.itick.org/rest-api/crypto/crypto-klines Official Documentation} for complete supported list
* @param params.codes - Symbol code list (e.g., BTCUSDT, ETHUSDT etc.)
* @returns Promise wrapped API response, data is multiple cryptocurrencies K-line data object {@link KlineDataMap}
* @example
* ```typescript
* // Get 5-minute K-line data for BTCUSDT and ETHUSDT cryptocurrency pairs
* getKlines({ region: 'BA', codes: ['BTCUSDT', 'ETHUSDT'], interval: '5m', limit: 100 }).then(response => {
* console.log('K-line data:', response.data);
* }).catch(err => {
* console.error('Failed to get K-line data:', err);
* });
* ```
*/
async getKlines(options) {
const { region, codes, kType, interval, limit, et } = options;
const params = { region, codes: Array.isArray(codes) ? codes.join(',') : codes, kType: convertKlinePeriod(interval ?? kType), limit };
if (et)
params.et = et;
return this._get('/crypto/klines', params);
}
/**
* Create WebSocket Connection
* @description Creates a WebSocket connection and returns a SocketClient object for managing connection and subscribing to real-time data. Subscription data can be specified through options parameter.
* Automatically handles connection retry and heartbeat mechanism to ensure connection stability and reliability.
* @param options - Optional options object for creating WebSocket connection {@link CreateSocketOptions}
* @returns SocketClient object for managing WebSocket connection
* @example
* ```typescript
* // Create a WebSocket connection and subscribe to real-time trades, quotes, order books, 1-minute K-line data for BTCUSDT and ETHUSDT, with maximum reconnection attempts of 5
* const client = new CryptoClient(token);
* const socket = client.createSocket({
* maxReconnectTimes: 5,
* subscribeData: {
* codes: ['BTCUSDT$BA', 'ETHUSDT$BA'],
* types: ['tick','quote','depth','kline@1m'],
* }
* });
* socket.onSocketMessage(data => {
* console.log('Received WebSocket message:', data);
* });
* ```
* @see Official Documentation https://docs.itick.org/websocket/crypto
*/
createSocket(options) {
return this._createSocket('/crypto', options);
}
}
/**
* Forex Module
* Provides data access interfaces for forex
*/
/**
* Forex SDK Client
* Specialized for forex data access
*/
class ForexClient extends Client {
constructor(token, options) {
super(token, options);
}
/**
* Get Forex Real-Time Trade Snapshot
* @description Query latest trade real-time market data for forex based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., GB etc.), see {@link https://docs.itick.org/rest-api/forex/forex-tick Official Documentation} for complete supported list
* @param params.code - Symbol code (e.g., EURUSD, GBPUSD etc.)
* @returns Promise wrapped standard API response, data is real-time market data {@link TickData}
* @example
* ```typescript
* // Get real-time trade market data for EURUSD forex pair
* getTick({ region: 'GB', code: 'EURUSD' }).then(response => {
* console.log('Real-time market:', response.data);
* }).catch(err => {
* console.error('Failed to get market data:', err);
* });
* ```
*/
async getTick(params) {
const { region, code } = params;
return this._get('/forex/tick', { region, code });
}
/**
* Get Forex Latest Quote
* @description Query latest quote real-time market data for forex based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., GB etc.), see {@link https://docs.itick.org/rest-api/forex/forex-quote Official Documentation} for complete supported list
* @param params.code - Symbol code (e.g., EURUSD, GBPUSD etc.)
* @returns Promise wrapped API response, data is latest quote data {@link QuoteData}
* @example
* ```typescript
* // Get latest quote for EURUSD forex pair
* getQuote({ region: 'GB', code: 'EURUSD' }).then(response => {
* console.log('Latest quote:', response.data);
* }).catch(err => {
* console.error('Failed to get quote:', err);
* });
* ```
*/
async getQuote(params) {
const { region, code } = params;
return this._get('/forex/quote', { region, code });
}
/**
* Get Forex Latest Order Book
* @description Query latest order book data for forex based on market code and symbol code
* @param params - Query parameters object
* @param params.region - Market code (e.g., GB etc.), see {@link https://docs.itick.org/rest-api/forex/forex-depth Official Documentation} for complete supported list
* @param params.code - Symbol code (e.g., EURUSD, GBPUSD etc.)
* @returns Promise wrapped API response, data is latest order book data {@link DepthData}
* @example
* ```typescript
* // Get latest order book for EURUSD forex pair
* getDepth({ region: 'GB', code: 'EURUSD' }).then(response => {
* console.log('Latest order book:', response.data);
* }).catch(err => {
* console.error('Failed to get order book:', err);
* });
* ```
*/
async getDepth(params) {
const { region, code } = params;
return this._get('/forex/depth', { region, code });
}
/**
* Get Forex K-Line Data
* @description Query forex K-line data based on market code, symbol code, K-line period, end time and number of records to return
* @param options - Query parameters object see {@link GetKlineOptions}
* @param options.region - Market code (e.g., GB etc.), see {@link https://docs.itick.org/rest-api/forex/forex-kline Official Documentation} for complete supported list
* @param params.code - Symbol code (e.g., EURUSD, GBPUSD etc.)
* @returns Promise wrapped API response, data is K-line data array {@link KlineData}
* @example
* ```typescript
* // Get 5-minute K-line data for EURUSD forex pair
* getKline({ region: 'GB', code: 'EURUSD', interval: '5m', limit: 100 }).then(response => {
* console.log('K-line data:', response.data);
* }).catch(err => {
* console.error('Failed to get K-line data:', err);
* });
* ```
*/
async getKline(options) {
const { region, code, kType, interval, limit, et } = options;
const params = { region, code, kType: convertKlinePeriod(interval ?? kType), limit };
if (et)
params.et = et;
return this._get('/forex/kline', params);
}
/**
* Get Multiple Forex Latest Trades
* @description Query latest trade real-time market data for multiple forex pairs based on market code and symbol code list
* @param params - Query parameters object
* @param params.region - Market code (e.g., GB etc.), see {@link https://docs.itick.org/rest-api/forex/forex-ticks Official Documentation} for complete supported list
* @param params.codes - Symbol code list (e.g., EURUSD, GBPUSD etc.)
* @returns Promise wrapped API response, data is multiple forex latest trade data object {@link TickDataMap}
* @example
* ```typescript
* // Get latest trade market data for EURUSD and GBPUSD forex pairs
* getTicks({ region: 'GB', codes: ['EURUSD', 'GBPUSD'] }).then(response => {
* console.log('Latest trades:', response.data);
* }).catch(err => {
* console.error('Failed to get trade market data:', err);
* });
* ```
*/
async getTicks(params) {
const { region, codes } = params;
return this._get('/forex/ticks', { region, codes: Array.isArray(codes) ? codes.join(',') : codes });
}
/**
* Get Multiple Forex Latest Quotes
* @description Query latest quote real-time market data for multiple forex pairs based on market code and symbol code list
* @param params - Query parameters object
* @param params.region - Market code (e.g., GB etc.), see {@link https://docs.itick.org/rest-api/forex/forex-quotes Official Documentation} for complete supported list
* @param params.codes - Symbol code list (e.g., EURUSD, GBPUSD etc.)
* @returns Promise wrapped API response, data is multiple forex latest quote data object {@link QuoteDataMap}
* @example
* ```typescript
* // Get latest quotes for EURUSD and GBPUSD forex pairs
* getQuotes({ region: 'GB', codes: ['EURUSD', 'GBPUSD'] }).then(response => {
* console.log('Latest quotes:', response.data);
* }).catch(err => {
* console.error('Failed to get quotes:', err);
* });
* ```
*/
async getQuotes(params) {
const { region, codes } = params;
return this._get('/forex/quotes', { region, codes: Array.isArray(codes) ? codes.join(',') : codes });
}
/**
* Get Multiple Forex Latest Order Books
* @description Query latest order book real-time market data for multiple forex pairs based on market code and symbol code list
* @param params - Query parameters object
* @param params.region - Market code (e.g., GB etc.), see {@link https://docs.itick.org/rest-api/forex/forex-depths Official Documentation} for complete supported list
* @param params.codes - Symbol code list (e.g., EURUSD, GBPUSD etc.)
* @returns Promise wrapped API response, data is multiple forex latest order book data object {@link DepthDataMap}
* @example
* ```typescript
* // Get latest order books for EURUSD and GBPUSD forex pairs
* getDepths({ region: 'GB', codes: ['EURUSD', 'GBPUSD'] }).then(response => {
* console.log('Latest order books:', response.data);
* }).catch(err => {
* console.error('Failed to get order books:', err);
* });
* ```
*/
async getDepths(params) {
const { region, codes } = params;
return this._get('/forex/depths', { region, codes: Array.isArray(codes) ? codes.join(',') : codes });
}
/**
* Get Multiple Forex K-Line Data
* @description Query K-line data for multiple forex pairs based on market code, symbol code list, K-line period, end time and number of records to return
* @param options - Query parameters object see {@link GetKlinesOptions}
* @param options.region - Market code (e.g., GB etc.), see {@link https://docs.itick.org/rest-api/forex/forex-klines Official Documentation} for complete supported list
* @param params.codes - Symbol code list (e.g., EURUSD, GBPUSD etc.)
* @returns Promise wrapped API response, data is multiple forex K-line data object {@link KlineDataMap}
* @example
* ```typescript
* // Get 5-minute K-line data for EURUSD and GBPUSD forex pairs
* getKlines({ region: 'GB', codes: ['EURUSD', 'GBPUSD'], interval: '5m', limit: 100 }).then(response => {
* console.log('K-line data:', response.data);
* }).catch(err => {
* console.error('Failed to get K-line data:', err);
* });
* ```
*/
async getKlines(options) {
const { region, codes, kType, interval, limit, et } = options;
const params = { region, codes: Array.isArray(codes) ? codes.join(',') : codes, kType: convertKlinePeriod(interval ?? kType), limit