stock-sdk 1.2.0 → 1.2.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 CHANGED
@@ -5,12 +5,41 @@
5
5
  [![license](https://img.shields.io/npm/l/stock-sdk)](https://github.com/chengzuopeng/stock-sdk/blob/master/LICENSE)
6
6
  [![Test Coverage](https://img.shields.io/badge/coverage-95.88%25-brightgreen.svg)](https://github.com/chengzuopeng/stock-sdk)
7
7
 
8
- 轻量级股票行情 SDK,基于腾讯财经 `qt.gtimg.cn` 和东方财富等数据源,支持 A 股、港股、美股、公募基金实时行情及历史 K 线查询。
8
+ **[English](./README_EN.md)** | 中文
9
9
 
10
- **✨ 零依赖 | 🌐 浏览器 + Node.js 双端支持 | 📦 ESM + CommonJS**
10
+ **前端和 Node.js 设计的股票行情 SDK**。
11
+
12
+ 无需 Python、无需后端服务,直接在 **浏览器或 Node.js** 中获取 **A 股 / 港股 / 美股 / 公募基金** 的实时行情与 K 线数据。
13
+
14
+ **✨ 零依赖 | 🌐 Browser + Node.js | 📦 <10KB | 🧠 完整 TypeScript 类型**
11
15
 
12
16
  📦 [NPM](https://www.npmjs.com/package/stock-sdk) | 📖 [GitHub](https://github.com/chengzuopeng/stock-sdk) | 🎮 [在线演示](https://chengzuopeng.github.io/stock-sdk/)
13
17
 
18
+ ## Why stock-sdk?
19
+
20
+ 如果你是前端工程师,可能遇到过这些问题:
21
+
22
+ * 股票行情工具大多是 **Python 生态**,前端难以直接使用
23
+ * 想做行情看板 / Demo,不想额外维护后端服务
24
+ * 财经接口返回格式混乱、编码复杂(GBK / 并发 / 批量)
25
+ * AkShare 很强,但并不适合浏览器或 Node.js 项目
26
+
27
+ **stock-sdk 的目标很简单:**
28
+
29
+ > 让前端工程师,用最熟悉的 JavaScript / TypeScript,优雅地获取股票行情数据。
30
+
31
+ ---
32
+
33
+ ## 使用场景
34
+
35
+ * 📊 股票行情看板(Web / Admin)
36
+ * 📈 数据可视化(ECharts / TradingView)
37
+ * 🎓 股票 / 金融课程 Demo
38
+ * 🧪 量化策略原型验证(JS / Node)
39
+ * 🕒 Node.js 定时抓取行情数据
40
+
41
+ ---
42
+
14
43
  ## 特性
15
44
 
16
45
  - ✅ **零依赖**,轻量级(压缩后 < 10KB)
@@ -32,22 +61,38 @@ yarn add stock-sdk
32
61
  pnpm add stock-sdk
33
62
  ```
34
63
 
35
- ## 快速开始
64
+ ## 快速开始(10 行 Demo)
36
65
 
37
- ```typescript
66
+ ```ts
38
67
  import { StockSDK } from 'stock-sdk';
39
68
 
40
69
  const sdk = new StockSDK();
41
70
 
42
- // A 股全量行情
43
- const quotes = await sdk.getFullQuotes(['sz000858', 'sh600519']);
44
- console.log(quotes[0].name, quotes[0].price);
71
+ const quotes = await sdk.getSimpleQuotes([
72
+ 'sh000001',
73
+ 'sz000858',
74
+ 'sh600519',
75
+ ]);
76
+
77
+ quotes.forEach(q => {
78
+ console.log(`${q.name}: ${q.price} (${q.changePercent}%)`);
79
+ });
80
+ ```
45
81
 
46
- // 历史 K 线
47
- const klines = await sdk.getHistoryKline('000001', { period: 'daily' });
82
+ ## 示例:全市场 A 股行情
48
83
 
49
- // 当日分时
50
- const timeline = await sdk.getTodayTimeline('sz000001');
84
+ 前端直接一次性获取全市场 A 股行情(5000+股票),无需 Python 或后端服务。
85
+
86
+ ```ts
87
+ const allQuotes = await sdk.getAllAShareQuotes({
88
+ batchSize: 300,
89
+ concurrency: 5,
90
+ onProgress: (completed, total) => {
91
+ console.log(`进度: ${completed}/${total}`);
92
+ },
93
+ });
94
+
95
+ console.log(`共获取 ${allQuotes.length} 只股票`);
51
96
  ```
52
97
 
53
98
  ## API 文档
@@ -276,7 +321,7 @@ interface TodayTimelineResponse {
276
321
  interface TodayTimeline {
277
322
  time: string; // 时间 HH:mm
278
323
  price: number; // 成交价
279
- volume: number; // 累计成交量(手)
324
+ volume: number; // 累计成交量(股)
280
325
  amount: number; // 累计成交额(元)
281
326
  avgPrice: number; // 当日均价
282
327
  }
@@ -495,7 +540,7 @@ console.log(raw[0].fields); // ['51', '五 粮 液', '000858', ...]
495
540
 
496
541
  ---
497
542
 
498
- ## 浏览器使用
543
+ ## 浏览器直接使用
499
544
 
500
545
  SDK 使用原生 `TextDecoder` 解码 GBK 编码数据,无需额外 polyfill。
501
546
 
@@ -537,3 +582,7 @@ yarn dev
537
582
  ---
538
583
 
539
584
  📦 [NPM](https://www.npmjs.com/package/stock-sdk) | 📖 [GitHub](https://github.com/chengzuopeng/stock-sdk) | 🎮 [在线演示](https://chengzuopeng.github.io/stock-sdk/) | 🐛 [Issues](https://github.com/chengzuopeng/stock-sdk/issues)
585
+
586
+ ---
587
+
588
+ 如果这个项目对你有帮助,欢迎 Star ⭐ 或提出 Issue 反馈。
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var N=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var z=(a,e)=>{for(var n in e)N(a,n,{get:e[n],enumerable:!0})},B=(a,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of E(e))!_.call(a,t)&&t!==n&&N(a,t,{get:()=>e[t],enumerable:!(r=H(e,t))||r.enumerable});return a};var W=a=>B(N({},"__esModule",{value:!0}),a);var Y={};z(Y,{StockSDK:()=>A,default:()=>K});module.exports=W(Y);function U(a){return new TextDecoder("gbk").decode(a)}function s(a){if(!a||a==="")return 0;let e=parseFloat(a);return Number.isNaN(e)?0:e}function u(a){if(!a||a==="")return null;let e=parseFloat(a);return Number.isNaN(e)?null:e}function M(a){let e=a.split(";").map(r=>r.trim()).filter(Boolean),n=[];for(let r of e){let t=r.indexOf("=");if(t<0)continue;let o=r.slice(0,t).trim();o.startsWith("v_")&&(o=o.slice(2));let i=r.slice(t+1).trim();i.startsWith('"')&&i.endsWith('"')&&(i=i.slice(1,-1));let c=i.split("~");n.push({key:o,fields:c})}return n}function x(a,e){let n=[];for(let r=0;r<a.length;r+=e)n.push(a.slice(r,r+e));return n}async function L(a,e){let n=[],r=[];for(let t of a){let o=Promise.resolve().then(()=>t()).then(i=>{n.push(i)});if(r.push(o),r.length>=e){await Promise.race(r);for(let i=r.length-1;i>=0;i--)await Promise.race([r[i].then(()=>"fulfilled"),Promise.resolve("pending")])==="fulfilled"&&r.splice(i,1)}}return await Promise.all(r),n}var G="https://qt.gtimg.cn",V="https://web.ifzq.gtimg.cn/appstock/app/minute/query",J="https://assets.linkdiary.cn/shares/ashare-code.json",I="https://push2his.eastmoney.com/api/qt/stock/kline/get",X="https://push2his.eastmoney.com/api/qt/stock/trends2/get";function D(a){return a.startsWith("sh")?"1":a.startsWith("sz")||a.startsWith("bj")?"0":a.startsWith("6")?"1":"0"}function l(a){if(!a||a===""||a==="-")return null;let e=parseFloat(a);return Number.isNaN(e)?null:e}var A=class{constructor(e={}){this.baseUrl=e.baseUrl??G,this.timeout=e.timeout??1e4}async request(e){let n=`${this.baseUrl}/?q=${encodeURIComponent(e)}`,r=new AbortController,t=setTimeout(()=>r.abort(),this.timeout);try{let o=await fetch(n,{signal:r.signal});if(!o.ok)throw new Error(`HTTP error! status: ${o.status}`);let i=await o.arrayBuffer(),c=U(i);return M(c)}finally{clearTimeout(t)}}async getFullQuotes(e){return!e||e.length===0?[]:(await this.request(e.join(","))).filter(r=>r.fields&&r.fields.length>0&&r.fields[0]!=="").map(r=>this.parseFullQuote(r.fields))}parseFullQuote(e){let n=[];for(let t=0;t<5;t++)n.push({price:s(e[9+t*2]),volume:s(e[10+t*2])});let r=[];for(let t=0;t<5;t++)r.push({price:s(e[19+t*2]),volume:s(e[20+t*2])});return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:s(e[3]),prevClose:s(e[4]),open:s(e[5]),volume:s(e[6]),outerVolume:s(e[7]),innerVolume:s(e[8]),bid:n,ask:r,time:e[30]??"",change:s(e[31]),changePercent:s(e[32]),high:s(e[33]),low:s(e[34]),volume2:s(e[36]),amount:s(e[37]),turnoverRate:u(e[38]),pe:u(e[39]),amplitude:u(e[43]),circulatingMarketCap:u(e[44]),totalMarketCap:u(e[45]),pb:u(e[46]),limitUp:u(e[47]),limitDown:u(e[48]),volumeRatio:u(e[49]),avgPrice:u(e[51]),peStatic:u(e[52]),peDynamic:u(e[53]),high52w:u(e[67]),low52w:u(e[68]),circulatingShares:u(e[72]),totalShares:u(e[73]),raw:e}}async getSimpleQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseSimpleQuote(t.fields))}parseSimpleQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:s(e[3]),change:s(e[4]),changePercent:s(e[5]),volume:s(e[6]),amount:s(e[7]),marketCap:u(e[9]),marketType:e[10]??"",raw:e}}async getFundFlow(e){if(!e||e.length===0)return[];let n=e.map(t=>`ff_${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseFundFlow(t.fields))}parseFundFlow(e){return{code:e[0]??"",mainInflow:s(e[1]),mainOutflow:s(e[2]),mainNet:s(e[3]),mainNetRatio:s(e[4]),retailInflow:s(e[5]),retailOutflow:s(e[6]),retailNet:s(e[7]),retailNetRatio:s(e[8]),totalFlow:s(e[9]),name:e[12]??"",date:e[13]??"",raw:e}}async getPanelLargeOrder(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_pk${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parsePanelLargeOrder(t.fields))}parsePanelLargeOrder(e){return{buyLargeRatio:s(e[0]),buySmallRatio:s(e[1]),sellLargeRatio:s(e[2]),sellSmallRatio:s(e[3]),raw:e}}async getHKQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`r_hk${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseHKQuote(t.fields))}parseHKQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:s(e[3]),prevClose:s(e[4]),open:s(e[5]),volume:s(e[6]),time:e[30]??"",change:s(e[31]),changePercent:s(e[32]),high:s(e[33]),low:s(e[34]),amount:s(e[36]),lotSize:u(e[40]),circulatingMarketCap:u(e[46]),totalMarketCap:u(e[47]),currency:e[e.length-3]??"",raw:e}}async getUSQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_us${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseUSQuote(t.fields))}parseUSQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:s(e[3]),change:s(e[4]),changePercent:s(e[5]),volume:s(e[6]),amount:s(e[7]),marketCap:u(e[8]),raw:e}}async getFundQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`jj${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseFundQuote(t.fields))}parseFundQuote(e){return{code:e[0]??"",name:e[1]??"",nav:s(e[5]),accNav:s(e[6]),change:s(e[7]),navDate:e[8]??"",raw:e}}async batchRaw(e){return this.request(e)}async getTodayTimeline(e){let n=new AbortController,r=setTimeout(()=>n.abort(),this.timeout);try{let t=await fetch(`${V}?code=${e}`,{signal:n.signal});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);let o=await t.json();if(o.code!==0)throw new Error(o.msg||"API error");let i=o.data?.[e];if(!i)return{code:e,date:"",data:[]};let c=i.data?.data||[],d=i.data?.date||"",g=c.map(k=>{let p=k.split(" "),m=p[0],y=`${m.slice(0,2)}:${m.slice(2,4)}`,h=parseInt(p[2],10)||0,f=parseFloat(p[3])||0,w=h>0?f/(h*100):0;return{time:y,price:parseFloat(p[1])||0,volume:h,amount:f,avgPrice:Math.round(w*100)/100}});return{code:e,date:d,data:g}}finally{clearTimeout(r)}}async getAShareCodeList(e=!0){let n=new AbortController,r=setTimeout(()=>n.abort(),this.timeout);try{let t=await fetch(J,{signal:n.signal});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);let o=await t.json();return e?o:o.map(i=>i.replace(/^(sh|sz|bj)/,""))}finally{clearTimeout(r)}}async getAllAShareQuotes(e={}){let{batchSize:n=500,concurrency:r=7,onProgress:t}=e,o=await this.getAShareCodeList(),i=x(o,n),c=i.length,d=0,g=i.map(p=>async()=>{let m=await this.getFullQuotes(p);return d++,t&&t(d,c),m});return(await L(g,r)).flat()}async getAllQuotesByCodes(e,n={}){let{batchSize:r=500,concurrency:t=7,onProgress:o}=n,i=x(e,r),c=i.length,d=0,g=i.map(p=>async()=>{let m=await this.getFullQuotes(p);return d++,o&&o(d,c),m});return(await L(g,t)).flat()}async getHistoryKline(e,n={}){let{period:r="daily",adjust:t="hfq",startDate:o="19700101",endDate:i="20500101"}=n,c=e.replace(/^(sh|sz|bj)/,""),d={daily:"101",weekly:"102",monthly:"103"},g={"":"0",qfq:"1",hfq:"2"},k=`${D(c)}.${c}`,p=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6",fields2:"f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f116",ut:"7eea3edcaed734bea9cbfc24409ed989",klt:d[r],fqt:g[t],secid:k,beg:o,end:i}),m=new AbortController,y=setTimeout(()=>m.abort(),this.timeout);try{let h=await fetch(`${I}?${p.toString()}`,{signal:m.signal});if(!h.ok)throw new Error(`HTTP error! status: ${h.status}`);let w=(await h.json())?.data?.klines;return!Array.isArray(w)||w.length===0?[]:w.map(b=>{let[P,T,v,Q,S,F,j,q,C,R,$]=b.split(",");return{date:P,code:c,open:l(T),close:l(v),high:l(Q),low:l(S),volume:l(F),amount:l(j),amplitude:l(q),changePercent:l(C),change:l(R),turnoverRate:l($)}})}finally{clearTimeout(y)}}async getMinuteKline(e,n={}){let{period:r="1",adjust:t="hfq",startDate:o="1979-09-01 09:32:00",endDate:i="2222-01-01 09:32:00"}=n,c=e.replace(/^(sh|sz|bj)/,""),d=`${D(c)}.${c}`,g=new AbortController,k=setTimeout(()=>g.abort(),this.timeout);try{if(r==="1"){let p=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13",fields2:"f51,f52,f53,f54,f55,f56,f57,f58",ut:"7eea3edcaed734bea9cbfc24409ed989",ndays:"5",iscr:"0",secid:d}),m=await fetch(`${X}?${p.toString()}`,{signal:g.signal});if(!m.ok)throw new Error(`HTTP error! status: ${m.status}`);let h=(await m.json())?.data?.trends;if(!Array.isArray(h)||h.length===0)return[];let f=o.replace("T"," ").slice(0,16),w=i.replace("T"," ").slice(0,16);return h.map(b=>{let[P,T,v,Q,S,F,j,q]=b.split(",");return{time:P,open:l(T),close:l(v),high:l(Q),low:l(S),volume:l(F),amount:l(j),avgPrice:l(q)}}).filter(b=>b.time>=f&&b.time<=w)}else{let p={"":"0",qfq:"1",hfq:"2"},m=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6",fields2:"f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61",ut:"7eea3edcaed734bea9cbfc24409ed989",klt:r,fqt:p[t],secid:d,beg:"0",end:"20500000"}),y=await fetch(`${I}?${m.toString()}`,{signal:g.signal});if(!y.ok)throw new Error(`HTTP error! status: ${y.status}`);let f=(await y.json())?.data?.klines;if(!Array.isArray(f)||f.length===0)return[];let w=o.replace("T"," ").slice(0,16),b=i.replace("T"," ").slice(0,16);return f.map(P=>{let[T,v,Q,S,F,j,q,C,R,$,O]=P.split(",");return{time:T,open:l(v),close:l(Q),high:l(S),low:l(F),changePercent:l(R),change:l($),volume:l(j),amount:l(q),amplitude:l(C),turnoverRate:l(O)}}).filter(P=>P.time>=w&&P.time<=b)}}finally{clearTimeout(k)}}},K=A;0&&(module.exports={StockSDK});
1
+ "use strict";var N=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var z=(a,e)=>{for(var n in e)N(a,n,{get:e[n],enumerable:!0})},B=(a,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of E(e))!_.call(a,t)&&t!==n&&N(a,t,{get:()=>e[t],enumerable:!(r=H(e,t))||r.enumerable});return a};var W=a=>B(N({},"__esModule",{value:!0}),a);var Y={};z(Y,{StockSDK:()=>A,default:()=>K});module.exports=W(Y);function U(a){return new TextDecoder("gbk").decode(a)}function s(a){if(!a||a==="")return 0;let e=parseFloat(a);return Number.isNaN(e)?0:e}function u(a){if(!a||a==="")return null;let e=parseFloat(a);return Number.isNaN(e)?null:e}function I(a){let e=a.split(";").map(r=>r.trim()).filter(Boolean),n=[];for(let r of e){let t=r.indexOf("=");if(t<0)continue;let o=r.slice(0,t).trim();o.startsWith("v_")&&(o=o.slice(2));let i=r.slice(t+1).trim();i.startsWith('"')&&i.endsWith('"')&&(i=i.slice(1,-1));let m=i.split("~");n.push({key:o,fields:m})}return n}function x(a,e){let n=[];for(let r=0;r<a.length;r+=e)n.push(a.slice(r,r+e));return n}async function L(a,e){let n=[],r=[];for(let t of a){let o=Promise.resolve().then(()=>t()).then(i=>{n.push(i)});if(r.push(o),r.length>=e){await Promise.race(r);for(let i=r.length-1;i>=0;i--)await Promise.race([r[i].then(()=>"fulfilled"),Promise.resolve("pending")])==="fulfilled"&&r.splice(i,1)}}return await Promise.all(r),n}var G="https://qt.gtimg.cn",V="https://web.ifzq.gtimg.cn/appstock/app/minute/query",J="https://assets.linkdiary.cn/shares/ashare-code.json",M="https://push2his.eastmoney.com/api/qt/stock/kline/get",X="https://push2his.eastmoney.com/api/qt/stock/trends2/get";function D(a){return a.startsWith("sh")?"1":a.startsWith("sz")||a.startsWith("bj")?"0":a.startsWith("6")?"1":"0"}function l(a){if(!a||a===""||a==="-")return null;let e=parseFloat(a);return Number.isNaN(e)?null:e}var A=class{constructor(e={}){this.baseUrl=e.baseUrl??G,this.timeout=e.timeout??1e4}async request(e){let n=`${this.baseUrl}/?q=${encodeURIComponent(e)}`,r=new AbortController,t=setTimeout(()=>r.abort(),this.timeout);try{let o=await fetch(n,{signal:r.signal});if(!o.ok)throw new Error(`HTTP error! status: ${o.status}`);let i=await o.arrayBuffer(),m=U(i);return I(m)}finally{clearTimeout(t)}}async getFullQuotes(e){return!e||e.length===0?[]:(await this.request(e.join(","))).filter(r=>r.fields&&r.fields.length>0&&r.fields[0]!=="").map(r=>this.parseFullQuote(r.fields))}parseFullQuote(e){let n=[];for(let t=0;t<5;t++)n.push({price:s(e[9+t*2]),volume:s(e[10+t*2])});let r=[];for(let t=0;t<5;t++)r.push({price:s(e[19+t*2]),volume:s(e[20+t*2])});return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:s(e[3]),prevClose:s(e[4]),open:s(e[5]),volume:s(e[6]),outerVolume:s(e[7]),innerVolume:s(e[8]),bid:n,ask:r,time:e[30]??"",change:s(e[31]),changePercent:s(e[32]),high:s(e[33]),low:s(e[34]),volume2:s(e[36]),amount:s(e[37]),turnoverRate:u(e[38]),pe:u(e[39]),amplitude:u(e[43]),circulatingMarketCap:u(e[44]),totalMarketCap:u(e[45]),pb:u(e[46]),limitUp:u(e[47]),limitDown:u(e[48]),volumeRatio:u(e[49]),avgPrice:u(e[51]),peStatic:u(e[52]),peDynamic:u(e[53]),high52w:u(e[67]),low52w:u(e[68]),circulatingShares:u(e[72]),totalShares:u(e[73]),raw:e}}async getSimpleQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseSimpleQuote(t.fields))}parseSimpleQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:s(e[3]),change:s(e[4]),changePercent:s(e[5]),volume:s(e[6]),amount:s(e[7]),marketCap:u(e[9]),marketType:e[10]??"",raw:e}}async getFundFlow(e){if(!e||e.length===0)return[];let n=e.map(t=>`ff_${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseFundFlow(t.fields))}parseFundFlow(e){return{code:e[0]??"",mainInflow:s(e[1]),mainOutflow:s(e[2]),mainNet:s(e[3]),mainNetRatio:s(e[4]),retailInflow:s(e[5]),retailOutflow:s(e[6]),retailNet:s(e[7]),retailNetRatio:s(e[8]),totalFlow:s(e[9]),name:e[12]??"",date:e[13]??"",raw:e}}async getPanelLargeOrder(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_pk${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parsePanelLargeOrder(t.fields))}parsePanelLargeOrder(e){return{buyLargeRatio:s(e[0]),buySmallRatio:s(e[1]),sellLargeRatio:s(e[2]),sellSmallRatio:s(e[3]),raw:e}}async getHKQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`r_hk${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseHKQuote(t.fields))}parseHKQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:s(e[3]),prevClose:s(e[4]),open:s(e[5]),volume:s(e[6]),time:e[30]??"",change:s(e[31]),changePercent:s(e[32]),high:s(e[33]),low:s(e[34]),amount:s(e[36]),lotSize:u(e[40]),circulatingMarketCap:u(e[46]),totalMarketCap:u(e[47]),currency:e[e.length-3]??"",raw:e}}async getUSQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_us${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseUSQuote(t.fields))}parseUSQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:s(e[3]),change:s(e[4]),changePercent:s(e[5]),volume:s(e[6]),amount:s(e[7]),marketCap:u(e[8]),raw:e}}async getFundQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`jj${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseFundQuote(t.fields))}parseFundQuote(e){return{code:e[0]??"",name:e[1]??"",nav:s(e[5]),accNav:s(e[6]),change:s(e[7]),navDate:e[8]??"",raw:e}}async batchRaw(e){return this.request(e)}async getTodayTimeline(e){let n=new AbortController,r=setTimeout(()=>n.abort(),this.timeout);try{let t=await fetch(`${V}?code=${e}`,{signal:n.signal});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);let o=await t.json();if(o.code!==0)throw new Error(o.msg||"API error");let i=o.data?.[e];if(!i)return{code:e,date:"",data:[]};let m=i.data?.data||[],d=i.data?.date||"",h=!1;if(m.length>0){let p=m[0].split(" "),c=parseFloat(p[1])||0,g=parseInt(p[2],10)||0,f=parseFloat(p[3])||0;g>0&&c>0&&f/g>c*50&&(h=!0)}let k=m.map(p=>{let c=p.split(" "),g=c[0],f=`${g.slice(0,2)}:${g.slice(2,4)}`,y=parseInt(c[2],10)||0,b=parseFloat(c[3])||0,w=h?y*100:y,P=w>0?b/w:0;return{time:f,price:parseFloat(c[1])||0,volume:w,amount:b,avgPrice:Math.round(P*100)/100}});return{code:e,date:d,data:k}}finally{clearTimeout(r)}}async getAShareCodeList(e=!0){let n=new AbortController,r=setTimeout(()=>n.abort(),this.timeout);try{let t=await fetch(J,{signal:n.signal});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);let o=await t.json();return e?o:o.map(i=>i.replace(/^(sh|sz|bj)/,""))}finally{clearTimeout(r)}}async getAllAShareQuotes(e={}){let{batchSize:n=500,concurrency:r=7,onProgress:t}=e,o=await this.getAShareCodeList(),i=x(o,n),m=i.length,d=0,h=i.map(p=>async()=>{let c=await this.getFullQuotes(p);return d++,t&&t(d,m),c});return(await L(h,r)).flat()}async getAllQuotesByCodes(e,n={}){let{batchSize:r=500,concurrency:t=7,onProgress:o}=n,i=x(e,r),m=i.length,d=0,h=i.map(p=>async()=>{let c=await this.getFullQuotes(p);return d++,o&&o(d,m),c});return(await L(h,t)).flat()}async getHistoryKline(e,n={}){let{period:r="daily",adjust:t="hfq",startDate:o="19700101",endDate:i="20500101"}=n,m=e.replace(/^(sh|sz|bj)/,""),d={daily:"101",weekly:"102",monthly:"103"},h={"":"0",qfq:"1",hfq:"2"},k=`${D(m)}.${m}`,p=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6",fields2:"f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f116",ut:"7eea3edcaed734bea9cbfc24409ed989",klt:d[r],fqt:h[t],secid:k,beg:o,end:i}),c=new AbortController,g=setTimeout(()=>c.abort(),this.timeout);try{let f=await fetch(`${M}?${p.toString()}`,{signal:c.signal});if(!f.ok)throw new Error(`HTTP error! status: ${f.status}`);let b=(await f.json())?.data?.klines;return!Array.isArray(b)||b.length===0?[]:b.map(w=>{let[P,T,v,Q,S,F,j,q,C,R,$]=w.split(",");return{date:P,code:m,open:l(T),close:l(v),high:l(Q),low:l(S),volume:l(F),amount:l(j),amplitude:l(q),changePercent:l(C),change:l(R),turnoverRate:l($)}})}finally{clearTimeout(g)}}async getMinuteKline(e,n={}){let{period:r="1",adjust:t="hfq",startDate:o="1979-09-01 09:32:00",endDate:i="2222-01-01 09:32:00"}=n,m=e.replace(/^(sh|sz|bj)/,""),d=`${D(m)}.${m}`,h=new AbortController,k=setTimeout(()=>h.abort(),this.timeout);try{if(r==="1"){let p=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13",fields2:"f51,f52,f53,f54,f55,f56,f57,f58",ut:"7eea3edcaed734bea9cbfc24409ed989",ndays:"5",iscr:"0",secid:d}),c=await fetch(`${X}?${p.toString()}`,{signal:h.signal});if(!c.ok)throw new Error(`HTTP error! status: ${c.status}`);let f=(await c.json())?.data?.trends;if(!Array.isArray(f)||f.length===0)return[];let y=o.replace("T"," ").slice(0,16),b=i.replace("T"," ").slice(0,16);return f.map(w=>{let[P,T,v,Q,S,F,j,q]=w.split(",");return{time:P,open:l(T),close:l(v),high:l(Q),low:l(S),volume:l(F),amount:l(j),avgPrice:l(q)}}).filter(w=>w.time>=y&&w.time<=b)}else{let p={"":"0",qfq:"1",hfq:"2"},c=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6",fields2:"f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61",ut:"7eea3edcaed734bea9cbfc24409ed989",klt:r,fqt:p[t],secid:d,beg:"0",end:"20500000"}),g=await fetch(`${M}?${c.toString()}`,{signal:h.signal});if(!g.ok)throw new Error(`HTTP error! status: ${g.status}`);let y=(await g.json())?.data?.klines;if(!Array.isArray(y)||y.length===0)return[];let b=o.replace("T"," ").slice(0,16),w=i.replace("T"," ").slice(0,16);return y.map(P=>{let[T,v,Q,S,F,j,q,C,R,$,O]=P.split(",");return{time:T,open:l(v),close:l(Q),high:l(S),low:l(F),changePercent:l(R),change:l($),volume:l(j),amount:l(q),amplitude:l(C),turnoverRate:l(O)}}).filter(P=>P.time>=b&&P.time<=w)}}finally{clearTimeout(k)}}},K=A;0&&(module.exports={StockSDK});
package/dist/index.d.cts CHANGED
@@ -277,7 +277,7 @@ interface TodayTimeline {
277
277
  time: string;
278
278
  /** 成交价 */
279
279
  price: number;
280
- /** 累计成交量(手) */
280
+ /** 累计成交量(股) */
281
281
  volume: number;
282
282
  /** 累计成交额(元) */
283
283
  amount: number;
package/dist/index.d.ts CHANGED
@@ -277,7 +277,7 @@ interface TodayTimeline {
277
277
  time: string;
278
278
  /** 成交价 */
279
279
  price: number;
280
- /** 累计成交量(手) */
280
+ /** 累计成交量(股) */
281
281
  volume: number;
282
282
  /** 累计成交额(元) */
283
283
  amount: number;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- function L(i){return new TextDecoder("gbk").decode(i)}function r(i){if(!i||i==="")return 0;let e=parseFloat(i);return Number.isNaN(e)?0:e}function u(i){if(!i||i==="")return null;let e=parseFloat(i);return Number.isNaN(e)?null:e}function U(i){let e=i.split(";").map(s=>s.trim()).filter(Boolean),n=[];for(let s of e){let t=s.indexOf("=");if(t<0)continue;let o=s.slice(0,t).trim();o.startsWith("v_")&&(o=o.slice(2));let a=s.slice(t+1).trim();a.startsWith('"')&&a.endsWith('"')&&(a=a.slice(1,-1));let c=a.split("~");n.push({key:o,fields:c})}return n}function N(i,e){let n=[];for(let s=0;s<i.length;s+=e)n.push(i.slice(s,s+e));return n}async function x(i,e){let n=[],s=[];for(let t of i){let o=Promise.resolve().then(()=>t()).then(a=>{n.push(a)});if(s.push(o),s.length>=e){await Promise.race(s);for(let a=s.length-1;a>=0;a--)await Promise.race([s[a].then(()=>"fulfilled"),Promise.resolve("pending")])==="fulfilled"&&s.splice(a,1)}}return await Promise.all(s),n}var K="https://qt.gtimg.cn",O="https://web.ifzq.gtimg.cn/appstock/app/minute/query",H="https://assets.linkdiary.cn/shares/ashare-code.json",M="https://push2his.eastmoney.com/api/qt/stock/kline/get",E="https://push2his.eastmoney.com/api/qt/stock/trends2/get";function I(i){return i.startsWith("sh")?"1":i.startsWith("sz")||i.startsWith("bj")?"0":i.startsWith("6")?"1":"0"}function l(i){if(!i||i===""||i==="-")return null;let e=parseFloat(i);return Number.isNaN(e)?null:e}var A=class{constructor(e={}){this.baseUrl=e.baseUrl??K,this.timeout=e.timeout??1e4}async request(e){let n=`${this.baseUrl}/?q=${encodeURIComponent(e)}`,s=new AbortController,t=setTimeout(()=>s.abort(),this.timeout);try{let o=await fetch(n,{signal:s.signal});if(!o.ok)throw new Error(`HTTP error! status: ${o.status}`);let a=await o.arrayBuffer(),c=L(a);return U(c)}finally{clearTimeout(t)}}async getFullQuotes(e){return!e||e.length===0?[]:(await this.request(e.join(","))).filter(s=>s.fields&&s.fields.length>0&&s.fields[0]!=="").map(s=>this.parseFullQuote(s.fields))}parseFullQuote(e){let n=[];for(let t=0;t<5;t++)n.push({price:r(e[9+t*2]),volume:r(e[10+t*2])});let s=[];for(let t=0;t<5;t++)s.push({price:r(e[19+t*2]),volume:r(e[20+t*2])});return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:r(e[3]),prevClose:r(e[4]),open:r(e[5]),volume:r(e[6]),outerVolume:r(e[7]),innerVolume:r(e[8]),bid:n,ask:s,time:e[30]??"",change:r(e[31]),changePercent:r(e[32]),high:r(e[33]),low:r(e[34]),volume2:r(e[36]),amount:r(e[37]),turnoverRate:u(e[38]),pe:u(e[39]),amplitude:u(e[43]),circulatingMarketCap:u(e[44]),totalMarketCap:u(e[45]),pb:u(e[46]),limitUp:u(e[47]),limitDown:u(e[48]),volumeRatio:u(e[49]),avgPrice:u(e[51]),peStatic:u(e[52]),peDynamic:u(e[53]),high52w:u(e[67]),low52w:u(e[68]),circulatingShares:u(e[72]),totalShares:u(e[73]),raw:e}}async getSimpleQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseSimpleQuote(t.fields))}parseSimpleQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:r(e[3]),change:r(e[4]),changePercent:r(e[5]),volume:r(e[6]),amount:r(e[7]),marketCap:u(e[9]),marketType:e[10]??"",raw:e}}async getFundFlow(e){if(!e||e.length===0)return[];let n=e.map(t=>`ff_${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseFundFlow(t.fields))}parseFundFlow(e){return{code:e[0]??"",mainInflow:r(e[1]),mainOutflow:r(e[2]),mainNet:r(e[3]),mainNetRatio:r(e[4]),retailInflow:r(e[5]),retailOutflow:r(e[6]),retailNet:r(e[7]),retailNetRatio:r(e[8]),totalFlow:r(e[9]),name:e[12]??"",date:e[13]??"",raw:e}}async getPanelLargeOrder(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_pk${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parsePanelLargeOrder(t.fields))}parsePanelLargeOrder(e){return{buyLargeRatio:r(e[0]),buySmallRatio:r(e[1]),sellLargeRatio:r(e[2]),sellSmallRatio:r(e[3]),raw:e}}async getHKQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`r_hk${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseHKQuote(t.fields))}parseHKQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:r(e[3]),prevClose:r(e[4]),open:r(e[5]),volume:r(e[6]),time:e[30]??"",change:r(e[31]),changePercent:r(e[32]),high:r(e[33]),low:r(e[34]),amount:r(e[36]),lotSize:u(e[40]),circulatingMarketCap:u(e[46]),totalMarketCap:u(e[47]),currency:e[e.length-3]??"",raw:e}}async getUSQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_us${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseUSQuote(t.fields))}parseUSQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:r(e[3]),change:r(e[4]),changePercent:r(e[5]),volume:r(e[6]),amount:r(e[7]),marketCap:u(e[8]),raw:e}}async getFundQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`jj${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseFundQuote(t.fields))}parseFundQuote(e){return{code:e[0]??"",name:e[1]??"",nav:r(e[5]),accNav:r(e[6]),change:r(e[7]),navDate:e[8]??"",raw:e}}async batchRaw(e){return this.request(e)}async getTodayTimeline(e){let n=new AbortController,s=setTimeout(()=>n.abort(),this.timeout);try{let t=await fetch(`${O}?code=${e}`,{signal:n.signal});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);let o=await t.json();if(o.code!==0)throw new Error(o.msg||"API error");let a=o.data?.[e];if(!a)return{code:e,date:"",data:[]};let c=a.data?.data||[],d=a.data?.date||"",g=c.map(k=>{let p=k.split(" "),m=p[0],y=`${m.slice(0,2)}:${m.slice(2,4)}`,h=parseInt(p[2],10)||0,f=parseFloat(p[3])||0,w=h>0?f/(h*100):0;return{time:y,price:parseFloat(p[1])||0,volume:h,amount:f,avgPrice:Math.round(w*100)/100}});return{code:e,date:d,data:g}}finally{clearTimeout(s)}}async getAShareCodeList(e=!0){let n=new AbortController,s=setTimeout(()=>n.abort(),this.timeout);try{let t=await fetch(H,{signal:n.signal});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);let o=await t.json();return e?o:o.map(a=>a.replace(/^(sh|sz|bj)/,""))}finally{clearTimeout(s)}}async getAllAShareQuotes(e={}){let{batchSize:n=500,concurrency:s=7,onProgress:t}=e,o=await this.getAShareCodeList(),a=N(o,n),c=a.length,d=0,g=a.map(p=>async()=>{let m=await this.getFullQuotes(p);return d++,t&&t(d,c),m});return(await x(g,s)).flat()}async getAllQuotesByCodes(e,n={}){let{batchSize:s=500,concurrency:t=7,onProgress:o}=n,a=N(e,s),c=a.length,d=0,g=a.map(p=>async()=>{let m=await this.getFullQuotes(p);return d++,o&&o(d,c),m});return(await x(g,t)).flat()}async getHistoryKline(e,n={}){let{period:s="daily",adjust:t="hfq",startDate:o="19700101",endDate:a="20500101"}=n,c=e.replace(/^(sh|sz|bj)/,""),d={daily:"101",weekly:"102",monthly:"103"},g={"":"0",qfq:"1",hfq:"2"},k=`${I(c)}.${c}`,p=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6",fields2:"f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f116",ut:"7eea3edcaed734bea9cbfc24409ed989",klt:d[s],fqt:g[t],secid:k,beg:o,end:a}),m=new AbortController,y=setTimeout(()=>m.abort(),this.timeout);try{let h=await fetch(`${M}?${p.toString()}`,{signal:m.signal});if(!h.ok)throw new Error(`HTTP error! status: ${h.status}`);let w=(await h.json())?.data?.klines;return!Array.isArray(w)||w.length===0?[]:w.map(b=>{let[P,T,v,Q,S,F,j,q,C,R,$]=b.split(",");return{date:P,code:c,open:l(T),close:l(v),high:l(Q),low:l(S),volume:l(F),amount:l(j),amplitude:l(q),changePercent:l(C),change:l(R),turnoverRate:l($)}})}finally{clearTimeout(y)}}async getMinuteKline(e,n={}){let{period:s="1",adjust:t="hfq",startDate:o="1979-09-01 09:32:00",endDate:a="2222-01-01 09:32:00"}=n,c=e.replace(/^(sh|sz|bj)/,""),d=`${I(c)}.${c}`,g=new AbortController,k=setTimeout(()=>g.abort(),this.timeout);try{if(s==="1"){let p=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13",fields2:"f51,f52,f53,f54,f55,f56,f57,f58",ut:"7eea3edcaed734bea9cbfc24409ed989",ndays:"5",iscr:"0",secid:d}),m=await fetch(`${E}?${p.toString()}`,{signal:g.signal});if(!m.ok)throw new Error(`HTTP error! status: ${m.status}`);let h=(await m.json())?.data?.trends;if(!Array.isArray(h)||h.length===0)return[];let f=o.replace("T"," ").slice(0,16),w=a.replace("T"," ").slice(0,16);return h.map(b=>{let[P,T,v,Q,S,F,j,q]=b.split(",");return{time:P,open:l(T),close:l(v),high:l(Q),low:l(S),volume:l(F),amount:l(j),avgPrice:l(q)}}).filter(b=>b.time>=f&&b.time<=w)}else{let p={"":"0",qfq:"1",hfq:"2"},m=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6",fields2:"f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61",ut:"7eea3edcaed734bea9cbfc24409ed989",klt:s,fqt:p[t],secid:d,beg:"0",end:"20500000"}),y=await fetch(`${M}?${m.toString()}`,{signal:g.signal});if(!y.ok)throw new Error(`HTTP error! status: ${y.status}`);let f=(await y.json())?.data?.klines;if(!Array.isArray(f)||f.length===0)return[];let w=o.replace("T"," ").slice(0,16),b=a.replace("T"," ").slice(0,16);return f.map(P=>{let[T,v,Q,S,F,j,q,C,R,$,D]=P.split(",");return{time:T,open:l(v),close:l(Q),high:l(S),low:l(F),changePercent:l(R),change:l($),volume:l(j),amount:l(q),amplitude:l(C),turnoverRate:l(D)}}).filter(P=>P.time>=w&&P.time<=b)}}finally{clearTimeout(k)}}},_=A;export{A as StockSDK,_ as default};
1
+ function L(i){return new TextDecoder("gbk").decode(i)}function r(i){if(!i||i==="")return 0;let e=parseFloat(i);return Number.isNaN(e)?0:e}function u(i){if(!i||i==="")return null;let e=parseFloat(i);return Number.isNaN(e)?null:e}function U(i){let e=i.split(";").map(s=>s.trim()).filter(Boolean),n=[];for(let s of e){let t=s.indexOf("=");if(t<0)continue;let o=s.slice(0,t).trim();o.startsWith("v_")&&(o=o.slice(2));let a=s.slice(t+1).trim();a.startsWith('"')&&a.endsWith('"')&&(a=a.slice(1,-1));let m=a.split("~");n.push({key:o,fields:m})}return n}function N(i,e){let n=[];for(let s=0;s<i.length;s+=e)n.push(i.slice(s,s+e));return n}async function x(i,e){let n=[],s=[];for(let t of i){let o=Promise.resolve().then(()=>t()).then(a=>{n.push(a)});if(s.push(o),s.length>=e){await Promise.race(s);for(let a=s.length-1;a>=0;a--)await Promise.race([s[a].then(()=>"fulfilled"),Promise.resolve("pending")])==="fulfilled"&&s.splice(a,1)}}return await Promise.all(s),n}var K="https://qt.gtimg.cn",O="https://web.ifzq.gtimg.cn/appstock/app/minute/query",H="https://assets.linkdiary.cn/shares/ashare-code.json",I="https://push2his.eastmoney.com/api/qt/stock/kline/get",E="https://push2his.eastmoney.com/api/qt/stock/trends2/get";function M(i){return i.startsWith("sh")?"1":i.startsWith("sz")||i.startsWith("bj")?"0":i.startsWith("6")?"1":"0"}function l(i){if(!i||i===""||i==="-")return null;let e=parseFloat(i);return Number.isNaN(e)?null:e}var A=class{constructor(e={}){this.baseUrl=e.baseUrl??K,this.timeout=e.timeout??1e4}async request(e){let n=`${this.baseUrl}/?q=${encodeURIComponent(e)}`,s=new AbortController,t=setTimeout(()=>s.abort(),this.timeout);try{let o=await fetch(n,{signal:s.signal});if(!o.ok)throw new Error(`HTTP error! status: ${o.status}`);let a=await o.arrayBuffer(),m=L(a);return U(m)}finally{clearTimeout(t)}}async getFullQuotes(e){return!e||e.length===0?[]:(await this.request(e.join(","))).filter(s=>s.fields&&s.fields.length>0&&s.fields[0]!=="").map(s=>this.parseFullQuote(s.fields))}parseFullQuote(e){let n=[];for(let t=0;t<5;t++)n.push({price:r(e[9+t*2]),volume:r(e[10+t*2])});let s=[];for(let t=0;t<5;t++)s.push({price:r(e[19+t*2]),volume:r(e[20+t*2])});return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:r(e[3]),prevClose:r(e[4]),open:r(e[5]),volume:r(e[6]),outerVolume:r(e[7]),innerVolume:r(e[8]),bid:n,ask:s,time:e[30]??"",change:r(e[31]),changePercent:r(e[32]),high:r(e[33]),low:r(e[34]),volume2:r(e[36]),amount:r(e[37]),turnoverRate:u(e[38]),pe:u(e[39]),amplitude:u(e[43]),circulatingMarketCap:u(e[44]),totalMarketCap:u(e[45]),pb:u(e[46]),limitUp:u(e[47]),limitDown:u(e[48]),volumeRatio:u(e[49]),avgPrice:u(e[51]),peStatic:u(e[52]),peDynamic:u(e[53]),high52w:u(e[67]),low52w:u(e[68]),circulatingShares:u(e[72]),totalShares:u(e[73]),raw:e}}async getSimpleQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseSimpleQuote(t.fields))}parseSimpleQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:r(e[3]),change:r(e[4]),changePercent:r(e[5]),volume:r(e[6]),amount:r(e[7]),marketCap:u(e[9]),marketType:e[10]??"",raw:e}}async getFundFlow(e){if(!e||e.length===0)return[];let n=e.map(t=>`ff_${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseFundFlow(t.fields))}parseFundFlow(e){return{code:e[0]??"",mainInflow:r(e[1]),mainOutflow:r(e[2]),mainNet:r(e[3]),mainNetRatio:r(e[4]),retailInflow:r(e[5]),retailOutflow:r(e[6]),retailNet:r(e[7]),retailNetRatio:r(e[8]),totalFlow:r(e[9]),name:e[12]??"",date:e[13]??"",raw:e}}async getPanelLargeOrder(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_pk${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parsePanelLargeOrder(t.fields))}parsePanelLargeOrder(e){return{buyLargeRatio:r(e[0]),buySmallRatio:r(e[1]),sellLargeRatio:r(e[2]),sellSmallRatio:r(e[3]),raw:e}}async getHKQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`r_hk${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseHKQuote(t.fields))}parseHKQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:r(e[3]),prevClose:r(e[4]),open:r(e[5]),volume:r(e[6]),time:e[30]??"",change:r(e[31]),changePercent:r(e[32]),high:r(e[33]),low:r(e[34]),amount:r(e[36]),lotSize:u(e[40]),circulatingMarketCap:u(e[46]),totalMarketCap:u(e[47]),currency:e[e.length-3]??"",raw:e}}async getUSQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`s_us${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseUSQuote(t.fields))}parseUSQuote(e){return{marketId:e[0]??"",name:e[1]??"",code:e[2]??"",price:r(e[3]),change:r(e[4]),changePercent:r(e[5]),volume:r(e[6]),amount:r(e[7]),marketCap:u(e[8]),raw:e}}async getFundQuotes(e){if(!e||e.length===0)return[];let n=e.map(t=>`jj${t}`);return(await this.request(n.join(","))).filter(t=>t.fields&&t.fields.length>0&&t.fields[0]!=="").map(t=>this.parseFundQuote(t.fields))}parseFundQuote(e){return{code:e[0]??"",name:e[1]??"",nav:r(e[5]),accNav:r(e[6]),change:r(e[7]),navDate:e[8]??"",raw:e}}async batchRaw(e){return this.request(e)}async getTodayTimeline(e){let n=new AbortController,s=setTimeout(()=>n.abort(),this.timeout);try{let t=await fetch(`${O}?code=${e}`,{signal:n.signal});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);let o=await t.json();if(o.code!==0)throw new Error(o.msg||"API error");let a=o.data?.[e];if(!a)return{code:e,date:"",data:[]};let m=a.data?.data||[],d=a.data?.date||"",h=!1;if(m.length>0){let p=m[0].split(" "),c=parseFloat(p[1])||0,g=parseInt(p[2],10)||0,f=parseFloat(p[3])||0;g>0&&c>0&&f/g>c*50&&(h=!0)}let k=m.map(p=>{let c=p.split(" "),g=c[0],f=`${g.slice(0,2)}:${g.slice(2,4)}`,y=parseInt(c[2],10)||0,b=parseFloat(c[3])||0,w=h?y*100:y,P=w>0?b/w:0;return{time:f,price:parseFloat(c[1])||0,volume:w,amount:b,avgPrice:Math.round(P*100)/100}});return{code:e,date:d,data:k}}finally{clearTimeout(s)}}async getAShareCodeList(e=!0){let n=new AbortController,s=setTimeout(()=>n.abort(),this.timeout);try{let t=await fetch(H,{signal:n.signal});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);let o=await t.json();return e?o:o.map(a=>a.replace(/^(sh|sz|bj)/,""))}finally{clearTimeout(s)}}async getAllAShareQuotes(e={}){let{batchSize:n=500,concurrency:s=7,onProgress:t}=e,o=await this.getAShareCodeList(),a=N(o,n),m=a.length,d=0,h=a.map(p=>async()=>{let c=await this.getFullQuotes(p);return d++,t&&t(d,m),c});return(await x(h,s)).flat()}async getAllQuotesByCodes(e,n={}){let{batchSize:s=500,concurrency:t=7,onProgress:o}=n,a=N(e,s),m=a.length,d=0,h=a.map(p=>async()=>{let c=await this.getFullQuotes(p);return d++,o&&o(d,m),c});return(await x(h,t)).flat()}async getHistoryKline(e,n={}){let{period:s="daily",adjust:t="hfq",startDate:o="19700101",endDate:a="20500101"}=n,m=e.replace(/^(sh|sz|bj)/,""),d={daily:"101",weekly:"102",monthly:"103"},h={"":"0",qfq:"1",hfq:"2"},k=`${M(m)}.${m}`,p=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6",fields2:"f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f116",ut:"7eea3edcaed734bea9cbfc24409ed989",klt:d[s],fqt:h[t],secid:k,beg:o,end:a}),c=new AbortController,g=setTimeout(()=>c.abort(),this.timeout);try{let f=await fetch(`${I}?${p.toString()}`,{signal:c.signal});if(!f.ok)throw new Error(`HTTP error! status: ${f.status}`);let b=(await f.json())?.data?.klines;return!Array.isArray(b)||b.length===0?[]:b.map(w=>{let[P,T,v,Q,S,F,j,q,C,R,$]=w.split(",");return{date:P,code:m,open:l(T),close:l(v),high:l(Q),low:l(S),volume:l(F),amount:l(j),amplitude:l(q),changePercent:l(C),change:l(R),turnoverRate:l($)}})}finally{clearTimeout(g)}}async getMinuteKline(e,n={}){let{period:s="1",adjust:t="hfq",startDate:o="1979-09-01 09:32:00",endDate:a="2222-01-01 09:32:00"}=n,m=e.replace(/^(sh|sz|bj)/,""),d=`${M(m)}.${m}`,h=new AbortController,k=setTimeout(()=>h.abort(),this.timeout);try{if(s==="1"){let p=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13",fields2:"f51,f52,f53,f54,f55,f56,f57,f58",ut:"7eea3edcaed734bea9cbfc24409ed989",ndays:"5",iscr:"0",secid:d}),c=await fetch(`${E}?${p.toString()}`,{signal:h.signal});if(!c.ok)throw new Error(`HTTP error! status: ${c.status}`);let f=(await c.json())?.data?.trends;if(!Array.isArray(f)||f.length===0)return[];let y=o.replace("T"," ").slice(0,16),b=a.replace("T"," ").slice(0,16);return f.map(w=>{let[P,T,v,Q,S,F,j,q]=w.split(",");return{time:P,open:l(T),close:l(v),high:l(Q),low:l(S),volume:l(F),amount:l(j),avgPrice:l(q)}}).filter(w=>w.time>=y&&w.time<=b)}else{let p={"":"0",qfq:"1",hfq:"2"},c=new URLSearchParams({fields1:"f1,f2,f3,f4,f5,f6",fields2:"f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61",ut:"7eea3edcaed734bea9cbfc24409ed989",klt:s,fqt:p[t],secid:d,beg:"0",end:"20500000"}),g=await fetch(`${I}?${c.toString()}`,{signal:h.signal});if(!g.ok)throw new Error(`HTTP error! status: ${g.status}`);let y=(await g.json())?.data?.klines;if(!Array.isArray(y)||y.length===0)return[];let b=o.replace("T"," ").slice(0,16),w=a.replace("T"," ").slice(0,16);return y.map(P=>{let[T,v,Q,S,F,j,q,C,R,$,D]=P.split(",");return{time:T,open:l(v),close:l(Q),high:l(S),low:l(F),changePercent:l(R),change:l($),volume:l(j),amount:l(q),amplitude:l(C),turnoverRate:l(D)}}).filter(P=>P.time>=b&&P.time<=w)}}finally{clearTimeout(k)}}},_=A;export{A as StockSDK,_ as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stock-sdk",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",