stock-sdk 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -6
- package/dist/index.cjs +9 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
基于腾讯财经 `qt.gtimg.cn` 非官方接口封装的 TypeScript SDK,支持 A 股、港股、美股、公募基金实时行情查询。
|
|
4
4
|
|
|
5
|
+
**同时支持浏览器端和 Node.js 端使用。**
|
|
6
|
+
|
|
7
|
+
## 特性
|
|
8
|
+
|
|
9
|
+
- ✅ 支持浏览器和 Node.js 双端运行
|
|
10
|
+
- ✅ 同时提供 ESM 和 CommonJS 两种模块格式
|
|
11
|
+
- ✅ 完整的 TypeScript 类型定义
|
|
12
|
+
- ✅ A 股、港股、美股、公募基金实时行情
|
|
13
|
+
- ✅ 资金流向、盘口大单等扩展数据
|
|
14
|
+
|
|
5
15
|
## 安装
|
|
6
16
|
|
|
7
17
|
```bash
|
|
@@ -13,9 +23,13 @@ yarn add stock-sdk
|
|
|
13
23
|
## 快速开始
|
|
14
24
|
|
|
15
25
|
```typescript
|
|
16
|
-
|
|
26
|
+
// ESM (浏览器 / Node.js)
|
|
27
|
+
import { TencentStockSDK } from 'stock-sdk';
|
|
17
28
|
|
|
18
|
-
|
|
29
|
+
// CommonJS (Node.js)
|
|
30
|
+
// const { TencentStockSDK } = require('stock-sdk');
|
|
31
|
+
|
|
32
|
+
const sdk = new TencentStockSDK();
|
|
19
33
|
|
|
20
34
|
// A 股全量行情
|
|
21
35
|
const fullQuotes = await sdk.getFullQuotes(['sz000858', 'sh600000']);
|
|
@@ -59,12 +73,21 @@ interface FullQuote {
|
|
|
59
73
|
volume2: number; // 成交量(手)
|
|
60
74
|
amount: number; // 成交额(万)
|
|
61
75
|
turnoverRate: number | null; // 换手率%
|
|
62
|
-
pe: number | null; // 市盈率
|
|
76
|
+
pe: number | null; // 市盈率(TTM)
|
|
77
|
+
amplitude: number | null; // 振幅%
|
|
63
78
|
circulatingMarketCap: number | null; // 流通市值(亿)
|
|
64
79
|
totalMarketCap: number | null; // 总市值(亿)
|
|
65
80
|
pb: number | null; // 市净率
|
|
66
81
|
limitUp: number | null; // 涨停价
|
|
67
82
|
limitDown: number | null; // 跌停价
|
|
83
|
+
volumeRatio: number | null; // 量比
|
|
84
|
+
avgPrice: number | null; // 均价
|
|
85
|
+
peStatic: number | null; // 市盈率(静)
|
|
86
|
+
peDynamic: number | null; // 市盈率(动)
|
|
87
|
+
high52w: number | null; // 52周最高价
|
|
88
|
+
low52w: number | null; // 52周最低价
|
|
89
|
+
circulatingShares: number | null; // 流通股本(股)
|
|
90
|
+
totalShares: number | null; // 总股本(股)
|
|
68
91
|
raw: string[]; // 原始字段数组
|
|
69
92
|
}
|
|
70
93
|
```
|
|
@@ -311,17 +334,33 @@ console.log(raw[0].fields); // ['51', '五 粮 液', '000858', ...]
|
|
|
311
334
|
|
|
312
335
|
---
|
|
313
336
|
|
|
337
|
+
## 浏览器使用说明
|
|
338
|
+
|
|
339
|
+
在浏览器端使用时,SDK 会自动使用浏览器原生的 `TextDecoder` 来解码 GBK 编码的响应数据,无需额外的 polyfill。
|
|
340
|
+
|
|
341
|
+
```html
|
|
342
|
+
<script type="module">
|
|
343
|
+
import { TencentStockSDK } from 'https://unpkg.com/stock-sdk/dist/index.js';
|
|
344
|
+
|
|
345
|
+
const sdk = new TencentStockSDK();
|
|
346
|
+
const quotes = await sdk.getFullQuotes(['sz000858']);
|
|
347
|
+
console.log(quotes[0].name, quotes[0].price);
|
|
348
|
+
</script>
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
> **注意**:由于 `qt.gtimg.cn` 接口不支持 CORS,在浏览器端使用时需要配置代理服务器。
|
|
352
|
+
|
|
314
353
|
## 开发
|
|
315
354
|
|
|
316
355
|
```bash
|
|
317
356
|
# 安装依赖
|
|
318
|
-
|
|
357
|
+
yarn install
|
|
319
358
|
|
|
320
359
|
# 运行测试
|
|
321
|
-
|
|
360
|
+
yarn test
|
|
322
361
|
|
|
323
362
|
# 构建
|
|
324
|
-
|
|
363
|
+
yarn build
|
|
325
364
|
```
|
|
326
365
|
|
|
327
366
|
## 许可证
|
package/dist/index.cjs
CHANGED
|
@@ -128,11 +128,20 @@ var TencentStockSDK = class {
|
|
|
128
128
|
amount: safeNumber(f[37]),
|
|
129
129
|
turnoverRate: safeNumberOrNull(f[38]),
|
|
130
130
|
pe: safeNumberOrNull(f[39]),
|
|
131
|
+
amplitude: safeNumberOrNull(f[43]),
|
|
131
132
|
circulatingMarketCap: safeNumberOrNull(f[44]),
|
|
132
133
|
totalMarketCap: safeNumberOrNull(f[45]),
|
|
133
134
|
pb: safeNumberOrNull(f[46]),
|
|
134
135
|
limitUp: safeNumberOrNull(f[47]),
|
|
135
136
|
limitDown: safeNumberOrNull(f[48]),
|
|
137
|
+
volumeRatio: safeNumberOrNull(f[49]),
|
|
138
|
+
avgPrice: safeNumberOrNull(f[51]),
|
|
139
|
+
peStatic: safeNumberOrNull(f[52]),
|
|
140
|
+
peDynamic: safeNumberOrNull(f[53]),
|
|
141
|
+
high52w: safeNumberOrNull(f[67]),
|
|
142
|
+
low52w: safeNumberOrNull(f[68]),
|
|
143
|
+
circulatingShares: safeNumberOrNull(f[72]),
|
|
144
|
+
totalShares: safeNumberOrNull(f[73]),
|
|
136
145
|
raw: f
|
|
137
146
|
};
|
|
138
147
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios';\nimport {\n FullQuote,\n SimpleQuote,\n FundFlow,\n PanelLargeOrder,\n HKQuote,\n USQuote,\n FundQuote,\n} from './types';\n\nexport * from './types';\n\nconst BASE_URL = 'http://qt.gtimg.cn';\n\n/**\n * 检测是否在浏览器环境\n */\nfunction isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n}\n\n/**\n * 将 ArrayBuffer 解码为 GBK 字符串\n * 浏览器端使用 TextDecoder,Node.js 端使用 iconv-lite\n */\nasync function decodeGBK(data: ArrayBuffer): Promise<string> {\n if (isBrowser()) {\n // 浏览器端使用 TextDecoder (原生支持 GBK)\n const decoder = new TextDecoder('gbk');\n return decoder.decode(data);\n } else {\n // Node.js 端使用 iconv-lite\n // 动态导入返回模块对象,需要处理 ESM/CJS 兼容性\n const iconvModule = await import('iconv-lite');\n const iconv = iconvModule.default || iconvModule;\n return iconv.decode(Buffer.from(data), 'gbk');\n }\n}\n\nfunction safeNumber(val: string | undefined): number {\n if (!val || val === '') return 0;\n const n = parseFloat(val);\n return Number.isNaN(n) ? 0 : n;\n}\n\nfunction safeNumberOrNull(val: string | undefined): number | null {\n if (!val || val === '') return null;\n const n = parseFloat(val);\n return Number.isNaN(n) ? null : n;\n}\n\n/**\n * 解析响应文本,按 `;` 拆行,提取 `v_xxx=\"...\"` 里的内容,返回 { key, fields }[]\n */\nfunction parseResponse(text: string): { key: string; fields: string[] }[] {\n const lines = text.split(';').map((l) => l.trim()).filter(Boolean);\n const results: { key: string; fields: string[] }[] = [];\n for (const line of lines) {\n const eqIdx = line.indexOf('=');\n if (eqIdx < 0) continue;\n let key = line.slice(0, eqIdx).trim();\n if (key.startsWith('v_')) key = key.slice(2);\n let raw = line.slice(eqIdx + 1).trim();\n if (raw.startsWith('\"') && raw.endsWith('\"')) {\n raw = raw.slice(1, -1);\n }\n const fields = raw.split('~');\n results.push({ key, fields });\n }\n return results;\n}\n\nexport class TencentStockSDK {\n private client: AxiosInstance;\n\n constructor() {\n this.client = axios.create({\n baseURL: BASE_URL,\n responseType: 'arraybuffer',\n timeout: 10000,\n });\n }\n\n private async fetch(params: string): Promise<{ key: string; fields: string[] }[]> {\n const resp = await this.client.get('/', { params: { q: params } });\n const text = await decodeGBK(resp.data);\n return parseResponse(text);\n }\n\n // ---------- 实时全量行情 ----------\n /**\n * 获取 A 股 / 指数 全量行情\n * @param codes 如 ['sz000858', 'sh600000']\n */\n async getFullQuotes(codes: string[]): Promise<FullQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFullQuote(d.fields));\n }\n\n private parseFullQuote(f: string[]): FullQuote {\n const bid: { price: number; volume: number }[] = [];\n for (let i = 0; i < 5; i++) {\n bid.push({ price: safeNumber(f[9 + i * 2]), volume: safeNumber(f[10 + i * 2]) });\n }\n const ask: { price: number; volume: number }[] = [];\n for (let i = 0; i < 5; i++) {\n ask.push({ price: safeNumber(f[19 + i * 2]), volume: safeNumber(f[20 + i * 2]) });\n }\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n prevClose: safeNumber(f[4]),\n open: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n outerVolume: safeNumber(f[7]),\n innerVolume: safeNumber(f[8]),\n bid,\n ask,\n time: f[30] ?? '',\n change: safeNumber(f[31]),\n changePercent: safeNumber(f[32]),\n high: safeNumber(f[33]),\n low: safeNumber(f[34]),\n volume2: safeNumber(f[36]),\n amount: safeNumber(f[37]),\n turnoverRate: safeNumberOrNull(f[38]),\n pe: safeNumberOrNull(f[39]),\n circulatingMarketCap: safeNumberOrNull(f[44]),\n totalMarketCap: safeNumberOrNull(f[45]),\n pb: safeNumberOrNull(f[46]),\n limitUp: safeNumberOrNull(f[47]),\n limitDown: safeNumberOrNull(f[48]),\n raw: f,\n };\n }\n\n // ---------- 简要行情 ----------\n /**\n * 获取简要行情\n * @param codes 如 ['s_sz000858', 's_sh000001']\n */\n async getSimpleQuotes(codes: string[]): Promise<SimpleQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseSimpleQuote(d.fields));\n }\n\n private parseSimpleQuote(f: string[]): SimpleQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n change: safeNumber(f[4]),\n changePercent: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n amount: safeNumber(f[7]),\n marketCap: safeNumberOrNull(f[9]),\n marketType: f[10] ?? '',\n raw: f,\n };\n }\n\n // ---------- 资金流向 ----------\n /**\n * 获取资金流向\n * @param codes 如 ['ff_sz000858']\n */\n async getFundFlow(codes: string[]): Promise<FundFlow[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFundFlow(d.fields));\n }\n\n private parseFundFlow(f: string[]): FundFlow {\n return {\n code: f[0] ?? '',\n mainInflow: safeNumber(f[1]),\n mainOutflow: safeNumber(f[2]),\n mainNet: safeNumber(f[3]),\n mainNetRatio: safeNumber(f[4]),\n retailInflow: safeNumber(f[5]),\n retailOutflow: safeNumber(f[6]),\n retailNet: safeNumber(f[7]),\n retailNetRatio: safeNumber(f[8]),\n totalFlow: safeNumber(f[9]),\n name: f[12] ?? '',\n date: f[13] ?? '',\n raw: f,\n };\n }\n\n // ---------- 盘口大单占比 ----------\n /**\n * 获取盘口大单占比\n * @param codes 如 ['s_pksz000858']\n */\n async getPanelLargeOrder(codes: string[]): Promise<PanelLargeOrder[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parsePanelLargeOrder(d.fields));\n }\n\n private parsePanelLargeOrder(f: string[]): PanelLargeOrder {\n return {\n buyLargeRatio: safeNumber(f[0]),\n buySmallRatio: safeNumber(f[1]),\n sellLargeRatio: safeNumber(f[2]),\n sellSmallRatio: safeNumber(f[3]),\n raw: f,\n };\n }\n\n // ---------- 港股扩展行情 ----------\n /**\n * 获取港股扩展行情\n * @param codes 如 ['r_hk09988']\n */\n async getHKQuotes(codes: string[]): Promise<HKQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseHKQuote(d.fields));\n }\n\n private parseHKQuote(f: string[]): HKQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n prevClose: safeNumber(f[4]),\n open: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n time: f[30] ?? '',\n change: safeNumber(f[31]),\n changePercent: safeNumber(f[32]),\n high: safeNumber(f[33]),\n low: safeNumber(f[34]),\n amount: safeNumber(f[36]),\n lotSize: safeNumberOrNull(f[40]),\n circulatingMarketCap: safeNumberOrNull(f[46]),\n totalMarketCap: safeNumberOrNull(f[47]),\n currency: f[f.length - 3] ?? '',\n raw: f,\n };\n }\n\n // ---------- 美股简要行情 ----------\n /**\n * 获取美股简要行情\n * @param codes 如 ['s_usBABA']\n */\n async getUSQuotes(codes: string[]): Promise<USQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseUSQuote(d.fields));\n }\n\n private parseUSQuote(f: string[]): USQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n change: safeNumber(f[4]),\n changePercent: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n amount: safeNumber(f[7]),\n marketCap: safeNumberOrNull(f[8]),\n raw: f,\n };\n }\n\n // ---------- 公募基金行情 ----------\n /**\n * 获取公募基金行情\n * @param codes 如 ['jj000001']\n */\n async getFundQuotes(codes: string[]): Promise<FundQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFundQuote(d.fields));\n }\n\n private parseFundQuote(f: string[]): FundQuote {\n return {\n code: f[0] ?? '',\n name: f[1] ?? '',\n nav: safeNumber(f[5]),\n accNav: safeNumber(f[6]),\n change: safeNumber(f[7]),\n navDate: f[8] ?? '',\n raw: f,\n };\n }\n\n // ---------- 批量混合查询 ----------\n /**\n * 批量混合查询,返回原始解析结果(key + fields)\n * @param params 如 'sz000858,s_sh000001,jj000001'\n */\n async batchRaw(params: string): Promise<{ key: string; fields: string[] }[]> {\n return this.fetch(params);\n }\n}\n\nexport default TencentStockSDK;\n\n"],"mappings":"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","names":["axios"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios';\nimport {\n FullQuote,\n SimpleQuote,\n FundFlow,\n PanelLargeOrder,\n HKQuote,\n USQuote,\n FundQuote,\n} from './types';\n\nexport * from './types';\n\nconst BASE_URL = 'http://qt.gtimg.cn';\n\n/**\n * 检测是否在浏览器环境\n */\nfunction isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n}\n\n/**\n * 将 ArrayBuffer 解码为 GBK 字符串\n * 浏览器端使用 TextDecoder,Node.js 端使用 iconv-lite\n */\nasync function decodeGBK(data: ArrayBuffer): Promise<string> {\n if (isBrowser()) {\n // 浏览器端使用 TextDecoder (原生支持 GBK)\n const decoder = new TextDecoder('gbk');\n return decoder.decode(data);\n } else {\n // Node.js 端使用 iconv-lite\n // 动态导入返回模块对象,需要处理 ESM/CJS 兼容性\n const iconvModule = await import('iconv-lite');\n const iconv = iconvModule.default || iconvModule;\n return iconv.decode(Buffer.from(data), 'gbk');\n }\n}\n\nfunction safeNumber(val: string | undefined): number {\n if (!val || val === '') return 0;\n const n = parseFloat(val);\n return Number.isNaN(n) ? 0 : n;\n}\n\nfunction safeNumberOrNull(val: string | undefined): number | null {\n if (!val || val === '') return null;\n const n = parseFloat(val);\n return Number.isNaN(n) ? null : n;\n}\n\n/**\n * 解析响应文本,按 `;` 拆行,提取 `v_xxx=\"...\"` 里的内容,返回 { key, fields }[]\n */\nfunction parseResponse(text: string): { key: string; fields: string[] }[] {\n const lines = text.split(';').map((l) => l.trim()).filter(Boolean);\n const results: { key: string; fields: string[] }[] = [];\n for (const line of lines) {\n const eqIdx = line.indexOf('=');\n if (eqIdx < 0) continue;\n let key = line.slice(0, eqIdx).trim();\n if (key.startsWith('v_')) key = key.slice(2);\n let raw = line.slice(eqIdx + 1).trim();\n if (raw.startsWith('\"') && raw.endsWith('\"')) {\n raw = raw.slice(1, -1);\n }\n const fields = raw.split('~');\n results.push({ key, fields });\n }\n return results;\n}\n\nexport class TencentStockSDK {\n private client: AxiosInstance;\n\n constructor() {\n this.client = axios.create({\n baseURL: BASE_URL,\n responseType: 'arraybuffer',\n timeout: 10000,\n });\n }\n\n private async fetch(params: string): Promise<{ key: string; fields: string[] }[]> {\n const resp = await this.client.get('/', { params: { q: params } });\n const text = await decodeGBK(resp.data);\n return parseResponse(text);\n }\n\n // ---------- 实时全量行情 ----------\n /**\n * 获取 A 股 / 指数 全量行情\n * @param codes 如 ['sz000858', 'sh600000']\n */\n async getFullQuotes(codes: string[]): Promise<FullQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFullQuote(d.fields));\n }\n\n private parseFullQuote(f: string[]): FullQuote {\n const bid: { price: number; volume: number }[] = [];\n for (let i = 0; i < 5; i++) {\n bid.push({ price: safeNumber(f[9 + i * 2]), volume: safeNumber(f[10 + i * 2]) });\n }\n const ask: { price: number; volume: number }[] = [];\n for (let i = 0; i < 5; i++) {\n ask.push({ price: safeNumber(f[19 + i * 2]), volume: safeNumber(f[20 + i * 2]) });\n }\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n prevClose: safeNumber(f[4]),\n open: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n outerVolume: safeNumber(f[7]),\n innerVolume: safeNumber(f[8]),\n bid,\n ask,\n time: f[30] ?? '',\n change: safeNumber(f[31]),\n changePercent: safeNumber(f[32]),\n high: safeNumber(f[33]),\n low: safeNumber(f[34]),\n volume2: safeNumber(f[36]),\n amount: safeNumber(f[37]),\n turnoverRate: safeNumberOrNull(f[38]),\n pe: safeNumberOrNull(f[39]),\n amplitude: safeNumberOrNull(f[43]),\n circulatingMarketCap: safeNumberOrNull(f[44]),\n totalMarketCap: safeNumberOrNull(f[45]),\n pb: safeNumberOrNull(f[46]),\n limitUp: safeNumberOrNull(f[47]),\n limitDown: safeNumberOrNull(f[48]),\n volumeRatio: safeNumberOrNull(f[49]),\n avgPrice: safeNumberOrNull(f[51]),\n peStatic: safeNumberOrNull(f[52]),\n peDynamic: safeNumberOrNull(f[53]),\n high52w: safeNumberOrNull(f[67]),\n low52w: safeNumberOrNull(f[68]),\n circulatingShares: safeNumberOrNull(f[72]),\n totalShares: safeNumberOrNull(f[73]),\n raw: f,\n };\n }\n\n // ---------- 简要行情 ----------\n /**\n * 获取简要行情\n * @param codes 如 ['s_sz000858', 's_sh000001']\n */\n async getSimpleQuotes(codes: string[]): Promise<SimpleQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseSimpleQuote(d.fields));\n }\n\n private parseSimpleQuote(f: string[]): SimpleQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n change: safeNumber(f[4]),\n changePercent: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n amount: safeNumber(f[7]),\n marketCap: safeNumberOrNull(f[9]),\n marketType: f[10] ?? '',\n raw: f,\n };\n }\n\n // ---------- 资金流向 ----------\n /**\n * 获取资金流向\n * @param codes 如 ['ff_sz000858']\n */\n async getFundFlow(codes: string[]): Promise<FundFlow[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFundFlow(d.fields));\n }\n\n private parseFundFlow(f: string[]): FundFlow {\n return {\n code: f[0] ?? '',\n mainInflow: safeNumber(f[1]),\n mainOutflow: safeNumber(f[2]),\n mainNet: safeNumber(f[3]),\n mainNetRatio: safeNumber(f[4]),\n retailInflow: safeNumber(f[5]),\n retailOutflow: safeNumber(f[6]),\n retailNet: safeNumber(f[7]),\n retailNetRatio: safeNumber(f[8]),\n totalFlow: safeNumber(f[9]),\n name: f[12] ?? '',\n date: f[13] ?? '',\n raw: f,\n };\n }\n\n // ---------- 盘口大单占比 ----------\n /**\n * 获取盘口大单占比\n * @param codes 如 ['s_pksz000858']\n */\n async getPanelLargeOrder(codes: string[]): Promise<PanelLargeOrder[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parsePanelLargeOrder(d.fields));\n }\n\n private parsePanelLargeOrder(f: string[]): PanelLargeOrder {\n return {\n buyLargeRatio: safeNumber(f[0]),\n buySmallRatio: safeNumber(f[1]),\n sellLargeRatio: safeNumber(f[2]),\n sellSmallRatio: safeNumber(f[3]),\n raw: f,\n };\n }\n\n // ---------- 港股扩展行情 ----------\n /**\n * 获取港股扩展行情\n * @param codes 如 ['r_hk09988']\n */\n async getHKQuotes(codes: string[]): Promise<HKQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseHKQuote(d.fields));\n }\n\n private parseHKQuote(f: string[]): HKQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n prevClose: safeNumber(f[4]),\n open: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n time: f[30] ?? '',\n change: safeNumber(f[31]),\n changePercent: safeNumber(f[32]),\n high: safeNumber(f[33]),\n low: safeNumber(f[34]),\n amount: safeNumber(f[36]),\n lotSize: safeNumberOrNull(f[40]),\n circulatingMarketCap: safeNumberOrNull(f[46]),\n totalMarketCap: safeNumberOrNull(f[47]),\n currency: f[f.length - 3] ?? '',\n raw: f,\n };\n }\n\n // ---------- 美股简要行情 ----------\n /**\n * 获取美股简要行情\n * @param codes 如 ['s_usBABA']\n */\n async getUSQuotes(codes: string[]): Promise<USQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseUSQuote(d.fields));\n }\n\n private parseUSQuote(f: string[]): USQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n change: safeNumber(f[4]),\n changePercent: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n amount: safeNumber(f[7]),\n marketCap: safeNumberOrNull(f[8]),\n raw: f,\n };\n }\n\n // ---------- 公募基金行情 ----------\n /**\n * 获取公募基金行情\n * @param codes 如 ['jj000001']\n */\n async getFundQuotes(codes: string[]): Promise<FundQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFundQuote(d.fields));\n }\n\n private parseFundQuote(f: string[]): FundQuote {\n return {\n code: f[0] ?? '',\n name: f[1] ?? '',\n nav: safeNumber(f[5]),\n accNav: safeNumber(f[6]),\n change: safeNumber(f[7]),\n navDate: f[8] ?? '',\n raw: f,\n };\n }\n\n // ---------- 批量混合查询 ----------\n /**\n * 批量混合查询,返回原始解析结果(key + fields)\n * @param params 如 'sz000858,s_sh000001,jj000001'\n */\n async batchRaw(params: string): Promise<{ key: string; fields: string[] }[]> {\n return this.fetch(params);\n }\n}\n\nexport default TencentStockSDK;\n\n"],"mappings":"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","names":["axios"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -46,8 +46,10 @@ interface FullQuote {
|
|
|
46
46
|
amount: number;
|
|
47
47
|
/** 换手率% */
|
|
48
48
|
turnoverRate: number | null;
|
|
49
|
-
/** 市盈率 */
|
|
49
|
+
/** 市盈率(TTM) */
|
|
50
50
|
pe: number | null;
|
|
51
|
+
/** 振幅% */
|
|
52
|
+
amplitude: number | null;
|
|
51
53
|
/** 流通市值(亿) */
|
|
52
54
|
circulatingMarketCap: number | null;
|
|
53
55
|
/** 总市值(亿) */
|
|
@@ -58,6 +60,22 @@ interface FullQuote {
|
|
|
58
60
|
limitUp: number | null;
|
|
59
61
|
/** 跌停价 */
|
|
60
62
|
limitDown: number | null;
|
|
63
|
+
/** 量比 */
|
|
64
|
+
volumeRatio: number | null;
|
|
65
|
+
/** 均价 */
|
|
66
|
+
avgPrice: number | null;
|
|
67
|
+
/** 市盈率(静) */
|
|
68
|
+
peStatic: number | null;
|
|
69
|
+
/** 市盈率(动) */
|
|
70
|
+
peDynamic: number | null;
|
|
71
|
+
/** 52周最高价 */
|
|
72
|
+
high52w: number | null;
|
|
73
|
+
/** 52周最低价 */
|
|
74
|
+
low52w: number | null;
|
|
75
|
+
/** 流通股本(股) */
|
|
76
|
+
circulatingShares: number | null;
|
|
77
|
+
/** 总股本(股) */
|
|
78
|
+
totalShares: number | null;
|
|
61
79
|
/** 原始字段数组(供扩展使用) */
|
|
62
80
|
raw: string[];
|
|
63
81
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -46,8 +46,10 @@ interface FullQuote {
|
|
|
46
46
|
amount: number;
|
|
47
47
|
/** 换手率% */
|
|
48
48
|
turnoverRate: number | null;
|
|
49
|
-
/** 市盈率 */
|
|
49
|
+
/** 市盈率(TTM) */
|
|
50
50
|
pe: number | null;
|
|
51
|
+
/** 振幅% */
|
|
52
|
+
amplitude: number | null;
|
|
51
53
|
/** 流通市值(亿) */
|
|
52
54
|
circulatingMarketCap: number | null;
|
|
53
55
|
/** 总市值(亿) */
|
|
@@ -58,6 +60,22 @@ interface FullQuote {
|
|
|
58
60
|
limitUp: number | null;
|
|
59
61
|
/** 跌停价 */
|
|
60
62
|
limitDown: number | null;
|
|
63
|
+
/** 量比 */
|
|
64
|
+
volumeRatio: number | null;
|
|
65
|
+
/** 均价 */
|
|
66
|
+
avgPrice: number | null;
|
|
67
|
+
/** 市盈率(静) */
|
|
68
|
+
peStatic: number | null;
|
|
69
|
+
/** 市盈率(动) */
|
|
70
|
+
peDynamic: number | null;
|
|
71
|
+
/** 52周最高价 */
|
|
72
|
+
high52w: number | null;
|
|
73
|
+
/** 52周最低价 */
|
|
74
|
+
low52w: number | null;
|
|
75
|
+
/** 流通股本(股) */
|
|
76
|
+
circulatingShares: number | null;
|
|
77
|
+
/** 总股本(股) */
|
|
78
|
+
totalShares: number | null;
|
|
61
79
|
/** 原始字段数组(供扩展使用) */
|
|
62
80
|
raw: string[];
|
|
63
81
|
}
|
package/dist/index.js
CHANGED
|
@@ -93,11 +93,20 @@ var TencentStockSDK = class {
|
|
|
93
93
|
amount: safeNumber(f[37]),
|
|
94
94
|
turnoverRate: safeNumberOrNull(f[38]),
|
|
95
95
|
pe: safeNumberOrNull(f[39]),
|
|
96
|
+
amplitude: safeNumberOrNull(f[43]),
|
|
96
97
|
circulatingMarketCap: safeNumberOrNull(f[44]),
|
|
97
98
|
totalMarketCap: safeNumberOrNull(f[45]),
|
|
98
99
|
pb: safeNumberOrNull(f[46]),
|
|
99
100
|
limitUp: safeNumberOrNull(f[47]),
|
|
100
101
|
limitDown: safeNumberOrNull(f[48]),
|
|
102
|
+
volumeRatio: safeNumberOrNull(f[49]),
|
|
103
|
+
avgPrice: safeNumberOrNull(f[51]),
|
|
104
|
+
peStatic: safeNumberOrNull(f[52]),
|
|
105
|
+
peDynamic: safeNumberOrNull(f[53]),
|
|
106
|
+
high52w: safeNumberOrNull(f[67]),
|
|
107
|
+
low52w: safeNumberOrNull(f[68]),
|
|
108
|
+
circulatingShares: safeNumberOrNull(f[72]),
|
|
109
|
+
totalShares: safeNumberOrNull(f[73]),
|
|
101
110
|
raw: f
|
|
102
111
|
};
|
|
103
112
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios';\nimport {\n FullQuote,\n SimpleQuote,\n FundFlow,\n PanelLargeOrder,\n HKQuote,\n USQuote,\n FundQuote,\n} from './types';\n\nexport * from './types';\n\nconst BASE_URL = 'http://qt.gtimg.cn';\n\n/**\n * 检测是否在浏览器环境\n */\nfunction isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n}\n\n/**\n * 将 ArrayBuffer 解码为 GBK 字符串\n * 浏览器端使用 TextDecoder,Node.js 端使用 iconv-lite\n */\nasync function decodeGBK(data: ArrayBuffer): Promise<string> {\n if (isBrowser()) {\n // 浏览器端使用 TextDecoder (原生支持 GBK)\n const decoder = new TextDecoder('gbk');\n return decoder.decode(data);\n } else {\n // Node.js 端使用 iconv-lite\n // 动态导入返回模块对象,需要处理 ESM/CJS 兼容性\n const iconvModule = await import('iconv-lite');\n const iconv = iconvModule.default || iconvModule;\n return iconv.decode(Buffer.from(data), 'gbk');\n }\n}\n\nfunction safeNumber(val: string | undefined): number {\n if (!val || val === '') return 0;\n const n = parseFloat(val);\n return Number.isNaN(n) ? 0 : n;\n}\n\nfunction safeNumberOrNull(val: string | undefined): number | null {\n if (!val || val === '') return null;\n const n = parseFloat(val);\n return Number.isNaN(n) ? null : n;\n}\n\n/**\n * 解析响应文本,按 `;` 拆行,提取 `v_xxx=\"...\"` 里的内容,返回 { key, fields }[]\n */\nfunction parseResponse(text: string): { key: string; fields: string[] }[] {\n const lines = text.split(';').map((l) => l.trim()).filter(Boolean);\n const results: { key: string; fields: string[] }[] = [];\n for (const line of lines) {\n const eqIdx = line.indexOf('=');\n if (eqIdx < 0) continue;\n let key = line.slice(0, eqIdx).trim();\n if (key.startsWith('v_')) key = key.slice(2);\n let raw = line.slice(eqIdx + 1).trim();\n if (raw.startsWith('\"') && raw.endsWith('\"')) {\n raw = raw.slice(1, -1);\n }\n const fields = raw.split('~');\n results.push({ key, fields });\n }\n return results;\n}\n\nexport class TencentStockSDK {\n private client: AxiosInstance;\n\n constructor() {\n this.client = axios.create({\n baseURL: BASE_URL,\n responseType: 'arraybuffer',\n timeout: 10000,\n });\n }\n\n private async fetch(params: string): Promise<{ key: string; fields: string[] }[]> {\n const resp = await this.client.get('/', { params: { q: params } });\n const text = await decodeGBK(resp.data);\n return parseResponse(text);\n }\n\n // ---------- 实时全量行情 ----------\n /**\n * 获取 A 股 / 指数 全量行情\n * @param codes 如 ['sz000858', 'sh600000']\n */\n async getFullQuotes(codes: string[]): Promise<FullQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFullQuote(d.fields));\n }\n\n private parseFullQuote(f: string[]): FullQuote {\n const bid: { price: number; volume: number }[] = [];\n for (let i = 0; i < 5; i++) {\n bid.push({ price: safeNumber(f[9 + i * 2]), volume: safeNumber(f[10 + i * 2]) });\n }\n const ask: { price: number; volume: number }[] = [];\n for (let i = 0; i < 5; i++) {\n ask.push({ price: safeNumber(f[19 + i * 2]), volume: safeNumber(f[20 + i * 2]) });\n }\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n prevClose: safeNumber(f[4]),\n open: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n outerVolume: safeNumber(f[7]),\n innerVolume: safeNumber(f[8]),\n bid,\n ask,\n time: f[30] ?? '',\n change: safeNumber(f[31]),\n changePercent: safeNumber(f[32]),\n high: safeNumber(f[33]),\n low: safeNumber(f[34]),\n volume2: safeNumber(f[36]),\n amount: safeNumber(f[37]),\n turnoverRate: safeNumberOrNull(f[38]),\n pe: safeNumberOrNull(f[39]),\n circulatingMarketCap: safeNumberOrNull(f[44]),\n totalMarketCap: safeNumberOrNull(f[45]),\n pb: safeNumberOrNull(f[46]),\n limitUp: safeNumberOrNull(f[47]),\n limitDown: safeNumberOrNull(f[48]),\n raw: f,\n };\n }\n\n // ---------- 简要行情 ----------\n /**\n * 获取简要行情\n * @param codes 如 ['s_sz000858', 's_sh000001']\n */\n async getSimpleQuotes(codes: string[]): Promise<SimpleQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseSimpleQuote(d.fields));\n }\n\n private parseSimpleQuote(f: string[]): SimpleQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n change: safeNumber(f[4]),\n changePercent: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n amount: safeNumber(f[7]),\n marketCap: safeNumberOrNull(f[9]),\n marketType: f[10] ?? '',\n raw: f,\n };\n }\n\n // ---------- 资金流向 ----------\n /**\n * 获取资金流向\n * @param codes 如 ['ff_sz000858']\n */\n async getFundFlow(codes: string[]): Promise<FundFlow[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFundFlow(d.fields));\n }\n\n private parseFundFlow(f: string[]): FundFlow {\n return {\n code: f[0] ?? '',\n mainInflow: safeNumber(f[1]),\n mainOutflow: safeNumber(f[2]),\n mainNet: safeNumber(f[3]),\n mainNetRatio: safeNumber(f[4]),\n retailInflow: safeNumber(f[5]),\n retailOutflow: safeNumber(f[6]),\n retailNet: safeNumber(f[7]),\n retailNetRatio: safeNumber(f[8]),\n totalFlow: safeNumber(f[9]),\n name: f[12] ?? '',\n date: f[13] ?? '',\n raw: f,\n };\n }\n\n // ---------- 盘口大单占比 ----------\n /**\n * 获取盘口大单占比\n * @param codes 如 ['s_pksz000858']\n */\n async getPanelLargeOrder(codes: string[]): Promise<PanelLargeOrder[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parsePanelLargeOrder(d.fields));\n }\n\n private parsePanelLargeOrder(f: string[]): PanelLargeOrder {\n return {\n buyLargeRatio: safeNumber(f[0]),\n buySmallRatio: safeNumber(f[1]),\n sellLargeRatio: safeNumber(f[2]),\n sellSmallRatio: safeNumber(f[3]),\n raw: f,\n };\n }\n\n // ---------- 港股扩展行情 ----------\n /**\n * 获取港股扩展行情\n * @param codes 如 ['r_hk09988']\n */\n async getHKQuotes(codes: string[]): Promise<HKQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseHKQuote(d.fields));\n }\n\n private parseHKQuote(f: string[]): HKQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n prevClose: safeNumber(f[4]),\n open: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n time: f[30] ?? '',\n change: safeNumber(f[31]),\n changePercent: safeNumber(f[32]),\n high: safeNumber(f[33]),\n low: safeNumber(f[34]),\n amount: safeNumber(f[36]),\n lotSize: safeNumberOrNull(f[40]),\n circulatingMarketCap: safeNumberOrNull(f[46]),\n totalMarketCap: safeNumberOrNull(f[47]),\n currency: f[f.length - 3] ?? '',\n raw: f,\n };\n }\n\n // ---------- 美股简要行情 ----------\n /**\n * 获取美股简要行情\n * @param codes 如 ['s_usBABA']\n */\n async getUSQuotes(codes: string[]): Promise<USQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseUSQuote(d.fields));\n }\n\n private parseUSQuote(f: string[]): USQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n change: safeNumber(f[4]),\n changePercent: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n amount: safeNumber(f[7]),\n marketCap: safeNumberOrNull(f[8]),\n raw: f,\n };\n }\n\n // ---------- 公募基金行情 ----------\n /**\n * 获取公募基金行情\n * @param codes 如 ['jj000001']\n */\n async getFundQuotes(codes: string[]): Promise<FundQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFundQuote(d.fields));\n }\n\n private parseFundQuote(f: string[]): FundQuote {\n return {\n code: f[0] ?? '',\n name: f[1] ?? '',\n nav: safeNumber(f[5]),\n accNav: safeNumber(f[6]),\n change: safeNumber(f[7]),\n navDate: f[8] ?? '',\n raw: f,\n };\n }\n\n // ---------- 批量混合查询 ----------\n /**\n * 批量混合查询,返回原始解析结果(key + fields)\n * @param params 如 'sz000858,s_sh000001,jj000001'\n */\n async batchRaw(params: string): Promise<{ key: string; fields: string[] }[]> {\n return this.fetch(params);\n }\n}\n\nexport default TencentStockSDK;\n\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import axios, { AxiosInstance } from 'axios';\nimport {\n FullQuote,\n SimpleQuote,\n FundFlow,\n PanelLargeOrder,\n HKQuote,\n USQuote,\n FundQuote,\n} from './types';\n\nexport * from './types';\n\nconst BASE_URL = 'http://qt.gtimg.cn';\n\n/**\n * 检测是否在浏览器环境\n */\nfunction isBrowser(): boolean {\n return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n}\n\n/**\n * 将 ArrayBuffer 解码为 GBK 字符串\n * 浏览器端使用 TextDecoder,Node.js 端使用 iconv-lite\n */\nasync function decodeGBK(data: ArrayBuffer): Promise<string> {\n if (isBrowser()) {\n // 浏览器端使用 TextDecoder (原生支持 GBK)\n const decoder = new TextDecoder('gbk');\n return decoder.decode(data);\n } else {\n // Node.js 端使用 iconv-lite\n // 动态导入返回模块对象,需要处理 ESM/CJS 兼容性\n const iconvModule = await import('iconv-lite');\n const iconv = iconvModule.default || iconvModule;\n return iconv.decode(Buffer.from(data), 'gbk');\n }\n}\n\nfunction safeNumber(val: string | undefined): number {\n if (!val || val === '') return 0;\n const n = parseFloat(val);\n return Number.isNaN(n) ? 0 : n;\n}\n\nfunction safeNumberOrNull(val: string | undefined): number | null {\n if (!val || val === '') return null;\n const n = parseFloat(val);\n return Number.isNaN(n) ? null : n;\n}\n\n/**\n * 解析响应文本,按 `;` 拆行,提取 `v_xxx=\"...\"` 里的内容,返回 { key, fields }[]\n */\nfunction parseResponse(text: string): { key: string; fields: string[] }[] {\n const lines = text.split(';').map((l) => l.trim()).filter(Boolean);\n const results: { key: string; fields: string[] }[] = [];\n for (const line of lines) {\n const eqIdx = line.indexOf('=');\n if (eqIdx < 0) continue;\n let key = line.slice(0, eqIdx).trim();\n if (key.startsWith('v_')) key = key.slice(2);\n let raw = line.slice(eqIdx + 1).trim();\n if (raw.startsWith('\"') && raw.endsWith('\"')) {\n raw = raw.slice(1, -1);\n }\n const fields = raw.split('~');\n results.push({ key, fields });\n }\n return results;\n}\n\nexport class TencentStockSDK {\n private client: AxiosInstance;\n\n constructor() {\n this.client = axios.create({\n baseURL: BASE_URL,\n responseType: 'arraybuffer',\n timeout: 10000,\n });\n }\n\n private async fetch(params: string): Promise<{ key: string; fields: string[] }[]> {\n const resp = await this.client.get('/', { params: { q: params } });\n const text = await decodeGBK(resp.data);\n return parseResponse(text);\n }\n\n // ---------- 实时全量行情 ----------\n /**\n * 获取 A 股 / 指数 全量行情\n * @param codes 如 ['sz000858', 'sh600000']\n */\n async getFullQuotes(codes: string[]): Promise<FullQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFullQuote(d.fields));\n }\n\n private parseFullQuote(f: string[]): FullQuote {\n const bid: { price: number; volume: number }[] = [];\n for (let i = 0; i < 5; i++) {\n bid.push({ price: safeNumber(f[9 + i * 2]), volume: safeNumber(f[10 + i * 2]) });\n }\n const ask: { price: number; volume: number }[] = [];\n for (let i = 0; i < 5; i++) {\n ask.push({ price: safeNumber(f[19 + i * 2]), volume: safeNumber(f[20 + i * 2]) });\n }\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n prevClose: safeNumber(f[4]),\n open: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n outerVolume: safeNumber(f[7]),\n innerVolume: safeNumber(f[8]),\n bid,\n ask,\n time: f[30] ?? '',\n change: safeNumber(f[31]),\n changePercent: safeNumber(f[32]),\n high: safeNumber(f[33]),\n low: safeNumber(f[34]),\n volume2: safeNumber(f[36]),\n amount: safeNumber(f[37]),\n turnoverRate: safeNumberOrNull(f[38]),\n pe: safeNumberOrNull(f[39]),\n amplitude: safeNumberOrNull(f[43]),\n circulatingMarketCap: safeNumberOrNull(f[44]),\n totalMarketCap: safeNumberOrNull(f[45]),\n pb: safeNumberOrNull(f[46]),\n limitUp: safeNumberOrNull(f[47]),\n limitDown: safeNumberOrNull(f[48]),\n volumeRatio: safeNumberOrNull(f[49]),\n avgPrice: safeNumberOrNull(f[51]),\n peStatic: safeNumberOrNull(f[52]),\n peDynamic: safeNumberOrNull(f[53]),\n high52w: safeNumberOrNull(f[67]),\n low52w: safeNumberOrNull(f[68]),\n circulatingShares: safeNumberOrNull(f[72]),\n totalShares: safeNumberOrNull(f[73]),\n raw: f,\n };\n }\n\n // ---------- 简要行情 ----------\n /**\n * 获取简要行情\n * @param codes 如 ['s_sz000858', 's_sh000001']\n */\n async getSimpleQuotes(codes: string[]): Promise<SimpleQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseSimpleQuote(d.fields));\n }\n\n private parseSimpleQuote(f: string[]): SimpleQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n change: safeNumber(f[4]),\n changePercent: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n amount: safeNumber(f[7]),\n marketCap: safeNumberOrNull(f[9]),\n marketType: f[10] ?? '',\n raw: f,\n };\n }\n\n // ---------- 资金流向 ----------\n /**\n * 获取资金流向\n * @param codes 如 ['ff_sz000858']\n */\n async getFundFlow(codes: string[]): Promise<FundFlow[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFundFlow(d.fields));\n }\n\n private parseFundFlow(f: string[]): FundFlow {\n return {\n code: f[0] ?? '',\n mainInflow: safeNumber(f[1]),\n mainOutflow: safeNumber(f[2]),\n mainNet: safeNumber(f[3]),\n mainNetRatio: safeNumber(f[4]),\n retailInflow: safeNumber(f[5]),\n retailOutflow: safeNumber(f[6]),\n retailNet: safeNumber(f[7]),\n retailNetRatio: safeNumber(f[8]),\n totalFlow: safeNumber(f[9]),\n name: f[12] ?? '',\n date: f[13] ?? '',\n raw: f,\n };\n }\n\n // ---------- 盘口大单占比 ----------\n /**\n * 获取盘口大单占比\n * @param codes 如 ['s_pksz000858']\n */\n async getPanelLargeOrder(codes: string[]): Promise<PanelLargeOrder[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parsePanelLargeOrder(d.fields));\n }\n\n private parsePanelLargeOrder(f: string[]): PanelLargeOrder {\n return {\n buyLargeRatio: safeNumber(f[0]),\n buySmallRatio: safeNumber(f[1]),\n sellLargeRatio: safeNumber(f[2]),\n sellSmallRatio: safeNumber(f[3]),\n raw: f,\n };\n }\n\n // ---------- 港股扩展行情 ----------\n /**\n * 获取港股扩展行情\n * @param codes 如 ['r_hk09988']\n */\n async getHKQuotes(codes: string[]): Promise<HKQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseHKQuote(d.fields));\n }\n\n private parseHKQuote(f: string[]): HKQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n prevClose: safeNumber(f[4]),\n open: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n time: f[30] ?? '',\n change: safeNumber(f[31]),\n changePercent: safeNumber(f[32]),\n high: safeNumber(f[33]),\n low: safeNumber(f[34]),\n amount: safeNumber(f[36]),\n lotSize: safeNumberOrNull(f[40]),\n circulatingMarketCap: safeNumberOrNull(f[46]),\n totalMarketCap: safeNumberOrNull(f[47]),\n currency: f[f.length - 3] ?? '',\n raw: f,\n };\n }\n\n // ---------- 美股简要行情 ----------\n /**\n * 获取美股简要行情\n * @param codes 如 ['s_usBABA']\n */\n async getUSQuotes(codes: string[]): Promise<USQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseUSQuote(d.fields));\n }\n\n private parseUSQuote(f: string[]): USQuote {\n return {\n marketId: f[0] ?? '',\n name: f[1] ?? '',\n code: f[2] ?? '',\n price: safeNumber(f[3]),\n change: safeNumber(f[4]),\n changePercent: safeNumber(f[5]),\n volume: safeNumber(f[6]),\n amount: safeNumber(f[7]),\n marketCap: safeNumberOrNull(f[8]),\n raw: f,\n };\n }\n\n // ---------- 公募基金行情 ----------\n /**\n * 获取公募基金行情\n * @param codes 如 ['jj000001']\n */\n async getFundQuotes(codes: string[]): Promise<FundQuote[]> {\n const data = await this.fetch(codes.join(','));\n return data.map((d) => this.parseFundQuote(d.fields));\n }\n\n private parseFundQuote(f: string[]): FundQuote {\n return {\n code: f[0] ?? '',\n name: f[1] ?? '',\n nav: safeNumber(f[5]),\n accNav: safeNumber(f[6]),\n change: safeNumber(f[7]),\n navDate: f[8] ?? '',\n raw: f,\n };\n }\n\n // ---------- 批量混合查询 ----------\n /**\n * 批量混合查询,返回原始解析结果(key + fields)\n * @param params 如 'sz000858,s_sh000001,jj000001'\n */\n async batchRaw(params: string): Promise<{ key: string; fields: string[] }[]> {\n return this.fetch(params);\n }\n}\n\nexport default TencentStockSDK;\n\n"],"mappings":"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","names":[]}
|