@tigeropenapi/tigeropen 0.4.0 → 0.4.5
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/dist/cjs/client/case-convert.js +4 -3
- package/dist/cjs/client/http-client.js +122 -5
- package/dist/cjs/config/client-config.js +56 -12
- package/dist/cjs/config/index.js +3 -1
- package/dist/cjs/config/token-manager.js +54 -4
- package/dist/cjs/index.js +51 -2
- package/dist/cjs/push/push-client.js +40 -15
- package/dist/cjs/quote/quote-client.js +14 -2
- package/dist/cjs/trade/trade-client.js +40 -2
- package/dist/esm/client/api-request.js +1 -1
- package/dist/esm/client/api-response.js +1 -1
- package/dist/esm/client/case-convert.js +4 -3
- package/dist/esm/client/http-client.js +127 -10
- package/dist/esm/client/index.js +6 -6
- package/dist/esm/config/client-config.js +59 -15
- package/dist/esm/config/index.js +4 -3
- package/dist/esm/config/token-manager.js +55 -5
- package/dist/esm/index.js +15 -1
- package/dist/esm/logger/index.js +1 -1
- package/dist/esm/model/contract-helpers.js +1 -1
- package/dist/esm/model/order-helpers.js +1 -1
- package/dist/esm/model/order-status.js +1 -1
- package/dist/esm/push/index.js +5 -5
- package/dist/esm/push/pb/PushData.js +11 -11
- package/dist/esm/push/pb/QuoteBasicData.js +1 -1
- package/dist/esm/push/pb/Response.js +1 -1
- package/dist/esm/push/pb/index.js +17 -17
- package/dist/esm/push/proto-message.js +3 -3
- package/dist/esm/push/push-client.js +47 -22
- package/dist/esm/quote/index.js +1 -1
- package/dist/esm/quote/quote-client.js +16 -4
- package/dist/esm/signer/index.js +2 -2
- package/dist/esm/trade/index.js +1 -1
- package/dist/esm/trade/trade-client.js +43 -5
- package/dist/types/client/case-convert.d.ts +3 -1
- package/dist/types/client/http-client.d.ts +32 -1
- package/dist/types/config/client-config.d.ts +16 -1
- package/dist/types/config/index.d.ts +2 -0
- package/dist/types/config/token-manager.d.ts +27 -3
- package/dist/types/index.d.ts +22 -1
- package/dist/types/model/trade-requests.d.ts +65 -0
- package/dist/types/model/trade.d.ts +102 -11
- package/dist/types/push/push-client.d.ts +5 -3
- package/dist/types/quote/quote-client.d.ts +3 -1
- package/dist/types/trade/trade-client.d.ts +15 -4
- package/package.json +2 -2
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// source: QuoteBasicData.proto
|
|
6
6
|
/* eslint-disable */
|
|
7
7
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
|
8
|
-
import { QuoteData_Minute } from "./QuoteData";
|
|
8
|
+
import { QuoteData_Minute } from "./QuoteData.js";
|
|
9
9
|
export const protobufPackage = "com.tigerbrokers.stock.openapi.client.socket.data.pb";
|
|
10
10
|
function createBaseQuoteBasicData() {
|
|
11
11
|
return {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// source: Response.proto
|
|
6
6
|
/* eslint-disable */
|
|
7
7
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
|
8
|
-
import { PushData } from "./PushData";
|
|
8
|
+
import { PushData } from "./PushData.js";
|
|
9
9
|
export const protobufPackage = "com.tigerbrokers.stock.openapi.client.socket.data.pb";
|
|
10
10
|
function createBaseResponse() {
|
|
11
11
|
return { command: 0, id: undefined, code: undefined, msg: undefined, body: undefined };
|
|
@@ -4,22 +4,22 @@
|
|
|
4
4
|
* 由 ts-proto 从 proto 文件生成的所有类型、枚举和编解码函数
|
|
5
5
|
*/
|
|
6
6
|
// 基础层:命令和数据类型枚举
|
|
7
|
-
export { SocketCommon_Command, SocketCommon_DataType, SocketCommon_QuoteType, } from './SocketCommon';
|
|
7
|
+
export { SocketCommon_Command, SocketCommon_DataType, SocketCommon_QuoteType, } from './SocketCommon.js';
|
|
8
8
|
// 协议层:请求和响应消息
|
|
9
|
-
export { Request, Request_Connect, Request_Subscribe } from './Request';
|
|
10
|
-
export { Response } from './Response';
|
|
11
|
-
export { PushData } from './PushData';
|
|
9
|
+
export { Request, Request_Connect, Request_Subscribe } from './Request.js';
|
|
10
|
+
export { Response } from './Response.js';
|
|
11
|
+
export { PushData } from './PushData.js';
|
|
12
12
|
// 数据层:业务数据消息
|
|
13
|
-
export { QuoteData } from './QuoteData';
|
|
14
|
-
export { QuoteBasicData } from './QuoteBasicData';
|
|
15
|
-
export { QuoteBBOData } from './QuoteBBOData';
|
|
16
|
-
export { QuoteDepthData } from './QuoteDepthData';
|
|
17
|
-
export { TradeTickData } from './TradeTickData';
|
|
18
|
-
export { TickData } from './TickData';
|
|
19
|
-
export { AssetData } from './AssetData';
|
|
20
|
-
export { PositionData } from './PositionData';
|
|
21
|
-
export { OrderStatusData } from './OrderStatusData';
|
|
22
|
-
export { OrderTransactionData } from './OrderTransactionData';
|
|
23
|
-
export { StockTopData } from './StockTopData';
|
|
24
|
-
export { OptionTopData } from './OptionTopData';
|
|
25
|
-
export { KlineData } from './KlineData';
|
|
13
|
+
export { QuoteData } from './QuoteData.js';
|
|
14
|
+
export { QuoteBasicData } from './QuoteBasicData.js';
|
|
15
|
+
export { QuoteBBOData } from './QuoteBBOData.js';
|
|
16
|
+
export { QuoteDepthData } from './QuoteDepthData.js';
|
|
17
|
+
export { TradeTickData } from './TradeTickData.js';
|
|
18
|
+
export { TickData } from './TickData.js';
|
|
19
|
+
export { AssetData } from './AssetData.js';
|
|
20
|
+
export { PositionData } from './PositionData.js';
|
|
21
|
+
export { OrderStatusData } from './OrderStatusData.js';
|
|
22
|
+
export { OrderTransactionData } from './OrderTransactionData.js';
|
|
23
|
+
export { StockTopData } from './StockTopData.js';
|
|
24
|
+
export { OptionTopData } from './OptionTopData.js';
|
|
25
|
+
export { KlineData } from './KlineData.js';
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* 对齐 Java SDK 的 ProtoMessageUtil,提供构建各种 Request 消息的工具函数。
|
|
5
5
|
* 所有构建函数共享一个递增的 requestId 计数器。
|
|
6
6
|
*/
|
|
7
|
-
import { Request, Request_Connect, Request_Subscribe, } from './pb/Request';
|
|
8
|
-
import { SocketCommon_Command, SocketCommon_DataType, } from './pb/SocketCommon';
|
|
9
|
-
import { SubjectType } from './push-message';
|
|
7
|
+
import { Request, Request_Connect, Request_Subscribe, } from './pb/Request.js';
|
|
8
|
+
import { SocketCommon_Command, SocketCommon_DataType, } from './pb/SocketCommon.js';
|
|
9
|
+
import { SubjectType } from './push-message.js';
|
|
10
10
|
/** 递增请求 ID 计数器(单线程环境,简单递增变量) */
|
|
11
11
|
let requestId = 0;
|
|
12
12
|
/**
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
* heartbeat keep-alive, and automatic reconnection.
|
|
10
10
|
*/
|
|
11
11
|
import * as tls from 'tls';
|
|
12
|
-
import { signWithRSA } from '../signer/signer';
|
|
13
|
-
import { SubjectType } from './push-message';
|
|
14
|
-
import { Request } from './pb/Request';
|
|
15
|
-
import { Response } from './pb/Response';
|
|
16
|
-
import { SocketCommon_Command, SocketCommon_DataType } from './pb/SocketCommon';
|
|
17
|
-
import { encodeVarint32, decodeVarint32 } from './varint';
|
|
18
|
-
import { buildConnectMessage, buildHeartBeatMessage, buildSubscribeMessage, buildUnSubscribeMessage, buildDisconnectMessage, subjectToDataType, } from './proto-message';
|
|
12
|
+
import { signWithRSA } from '../signer/signer.js';
|
|
13
|
+
import { SubjectType } from './push-message.js';
|
|
14
|
+
import { Request } from './pb/Request.js';
|
|
15
|
+
import { Response } from './pb/Response.js';
|
|
16
|
+
import { SocketCommon_Command, SocketCommon_DataType } from './pb/SocketCommon.js';
|
|
17
|
+
import { encodeVarint32, decodeVarint32 } from './varint.js';
|
|
18
|
+
import { buildConnectMessage, buildHeartBeatMessage, buildSubscribeMessage, buildUnSubscribeMessage, buildDisconnectMessage, subjectToDataType, } from './proto-message.js';
|
|
19
19
|
/** Default push server host */
|
|
20
20
|
const DEFAULT_PUSH_HOST = 'openapi.tigerfintech.com';
|
|
21
21
|
/** Default push server port */
|
|
@@ -50,11 +50,13 @@ export class PushClient {
|
|
|
50
50
|
constructor(config, options) {
|
|
51
51
|
this.socket = null;
|
|
52
52
|
this._state = ConnectionState.Disconnected;
|
|
53
|
+
/** Whether this connect attempt already fell back to unverified TLS */
|
|
54
|
+
this.tlsFallback = false;
|
|
53
55
|
this.callbacks = {};
|
|
54
56
|
/** Subscription state: subject -> Set<symbol> */
|
|
55
57
|
this.subscriptions = new Map();
|
|
56
|
-
/** Account-level subscriptions */
|
|
57
|
-
this.accountSubs = new
|
|
58
|
+
/** Account-level subscriptions: subject -> account string used at subscribe time */
|
|
59
|
+
this.accountSubs = new Map();
|
|
58
60
|
this.heartbeatTimer = null;
|
|
59
61
|
this.reconnectTimer = null;
|
|
60
62
|
this.stopped = false;
|
|
@@ -88,6 +90,7 @@ export class PushClient {
|
|
|
88
90
|
}
|
|
89
91
|
this._state = ConnectionState.Connecting;
|
|
90
92
|
this.stopped = false;
|
|
93
|
+
this.tlsFallback = false;
|
|
91
94
|
this.recvBuffer = Buffer.alloc(0);
|
|
92
95
|
const socket = this.createSocket(this.pushHost, this.pushPort);
|
|
93
96
|
this.socket = socket;
|
|
@@ -144,6 +147,24 @@ export class PushClient {
|
|
|
144
147
|
});
|
|
145
148
|
socket.on('error', (err) => {
|
|
146
149
|
if (!settled) {
|
|
150
|
+
// If this is a TLS certificate error, warn and retry without verification.
|
|
151
|
+
const isTlsCertError = err.message.includes('certificate') ||
|
|
152
|
+
err.message.includes('CERT') ||
|
|
153
|
+
err.code === 'DEPTH_ZERO_SELF_SIGNED_CERT' ||
|
|
154
|
+
err.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' ||
|
|
155
|
+
err.code === 'CERT_HAS_EXPIRED';
|
|
156
|
+
if (isTlsCertError && !this.tlsFallback) {
|
|
157
|
+
this.tlsFallback = true;
|
|
158
|
+
settled = true;
|
|
159
|
+
clearTimeout(timeout);
|
|
160
|
+
socket.destroy();
|
|
161
|
+
this.socket = null;
|
|
162
|
+
this._state = ConnectionState.Disconnected;
|
|
163
|
+
console.warn(`[TigerOpen] TLS certificate verification failed: ${err.message}. Retrying without verification.`);
|
|
164
|
+
// Retry immediately using unverified TLS
|
|
165
|
+
this.connect().then(resolve).catch(reject);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
147
168
|
settled = true;
|
|
148
169
|
clearTimeout(timeout);
|
|
149
170
|
this._state = ConnectionState.Disconnected;
|
|
@@ -196,7 +217,7 @@ export class PushClient {
|
|
|
196
217
|
createSocket(host, port) {
|
|
197
218
|
if (this.socketFactory)
|
|
198
219
|
return this.socketFactory(host, port);
|
|
199
|
-
return tls.connect({ host, port, rejectUnauthorized:
|
|
220
|
+
return tls.connect({ host, port, rejectUnauthorized: !this.tlsFallback });
|
|
200
221
|
}
|
|
201
222
|
/** Handle incoming TCP data: buffer + decode varint32 frames */
|
|
202
223
|
handleData(chunk, onConnected) {
|
|
@@ -295,8 +316,8 @@ export class PushClient {
|
|
|
295
316
|
for (const [subject, symbols] of this.subscriptions) {
|
|
296
317
|
this.doSubscribe(subject, Array.from(symbols));
|
|
297
318
|
}
|
|
298
|
-
for (const subject of this.accountSubs) {
|
|
299
|
-
this.doSubscribe(subject, undefined,
|
|
319
|
+
for (const [subject, account] of this.accountSubs) {
|
|
320
|
+
this.doSubscribe(subject, undefined, account);
|
|
300
321
|
}
|
|
301
322
|
}
|
|
302
323
|
/** Dispatch push data to the appropriate callback based on dataType */
|
|
@@ -530,8 +551,9 @@ export class PushClient {
|
|
|
530
551
|
// ===== Account push subscribe/unsubscribe =====
|
|
531
552
|
/** Subscribe to asset changes */
|
|
532
553
|
subscribeAsset(account) {
|
|
533
|
-
|
|
534
|
-
this.
|
|
554
|
+
const acct = account || this.config.account;
|
|
555
|
+
this.doSubscribe(SubjectType.Asset, undefined, acct);
|
|
556
|
+
this.accountSubs.set(SubjectType.Asset, acct);
|
|
535
557
|
}
|
|
536
558
|
/** Unsubscribe from asset changes */
|
|
537
559
|
unsubscribeAsset() {
|
|
@@ -540,8 +562,9 @@ export class PushClient {
|
|
|
540
562
|
}
|
|
541
563
|
/** Subscribe to position changes */
|
|
542
564
|
subscribePosition(account) {
|
|
543
|
-
|
|
544
|
-
this.
|
|
565
|
+
const acct = account || this.config.account;
|
|
566
|
+
this.doSubscribe(SubjectType.Position, undefined, acct);
|
|
567
|
+
this.accountSubs.set(SubjectType.Position, acct);
|
|
545
568
|
}
|
|
546
569
|
/** Unsubscribe from position changes */
|
|
547
570
|
unsubscribePosition() {
|
|
@@ -550,8 +573,9 @@ export class PushClient {
|
|
|
550
573
|
}
|
|
551
574
|
/** Subscribe to order status */
|
|
552
575
|
subscribeOrder(account) {
|
|
553
|
-
|
|
554
|
-
this.
|
|
576
|
+
const acct = account || this.config.account;
|
|
577
|
+
this.doSubscribe(SubjectType.Order, undefined, acct);
|
|
578
|
+
this.accountSubs.set(SubjectType.Order, acct);
|
|
555
579
|
}
|
|
556
580
|
/** Unsubscribe from order status */
|
|
557
581
|
unsubscribeOrder() {
|
|
@@ -560,8 +584,9 @@ export class PushClient {
|
|
|
560
584
|
}
|
|
561
585
|
/** Subscribe to transaction details */
|
|
562
586
|
subscribeTransaction(account) {
|
|
563
|
-
|
|
564
|
-
this.
|
|
587
|
+
const acct = account || this.config.account;
|
|
588
|
+
this.doSubscribe(SubjectType.Transaction, undefined, acct);
|
|
589
|
+
this.accountSubs.set(SubjectType.Transaction, acct);
|
|
565
590
|
}
|
|
566
591
|
/** Unsubscribe from transaction details */
|
|
567
592
|
unsubscribeTransaction() {
|
|
@@ -577,8 +602,8 @@ export class PushClient {
|
|
|
577
602
|
}
|
|
578
603
|
return result;
|
|
579
604
|
}
|
|
580
|
-
/** Get account-level subscriptions */
|
|
605
|
+
/** Get account-level subscriptions: subject -> account */
|
|
581
606
|
getAccountSubscriptions() {
|
|
582
|
-
return
|
|
607
|
+
return new Map(this.accountSubs);
|
|
583
608
|
}
|
|
584
609
|
}
|
package/dist/esm/quote/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createApiRequest } from '../client/api-request';
|
|
2
|
-
import { unmarshalData } from '../client/api-response';
|
|
1
|
+
import { createApiRequest } from '../client/api-request.js';
|
|
2
|
+
import { unmarshalData } from '../client/api-response.js';
|
|
3
3
|
/**
|
|
4
4
|
* Parse an OCC-style option identifier like "AAPL 260619C00150000"
|
|
5
5
|
* into its component parts.
|
|
@@ -357,9 +357,21 @@ export class QuoteClient {
|
|
|
357
357
|
}
|
|
358
358
|
return acc;
|
|
359
359
|
}
|
|
360
|
-
/** Futures tick trades. wire: future_tick (API v3.0)
|
|
360
|
+
/** Futures tick trades. wire: future_tick (API v3.0)
|
|
361
|
+
* Server returns {contractCode, items:[...]}; unwrap items and backfill contractCode.
|
|
362
|
+
* endIndex defaults to 30 when not set (consistent with Python/Go SDK). */
|
|
361
363
|
async getFutureTradeTicks(req) {
|
|
362
|
-
|
|
364
|
+
if (!req.endIndex)
|
|
365
|
+
req.endIndex = 30;
|
|
366
|
+
const wrap = await this.callInto('future_tick', req, '3.0');
|
|
367
|
+
const items = wrap?.items ?? [];
|
|
368
|
+
if (wrap?.contractCode) {
|
|
369
|
+
for (const item of items) {
|
|
370
|
+
if (!item.contractCode)
|
|
371
|
+
item.contractCode = wrap.contractCode;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return items;
|
|
363
375
|
}
|
|
364
376
|
/** Futures depth. wire: future_depth */
|
|
365
377
|
async getFutureDepth(req) {
|
package/dist/esm/signer/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 认证层(RSA Signer)统一导出
|
|
3
3
|
*/
|
|
4
|
-
export { loadPrivateKey, signWithRSA, verifyWithRSA } from './signer';
|
|
5
|
-
export { getSignContent } from './sign-content';
|
|
4
|
+
export { loadPrivateKey, signWithRSA, verifyWithRSA } from './signer.js';
|
|
5
|
+
export { getSignContent } from './sign-content.js';
|
package/dist/esm/trade/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createApiRequest } from '../client/api-request';
|
|
2
|
-
import { unmarshalData } from '../client/api-response';
|
|
3
|
-
import { normalizeOrderStatus } from '../model/order-status';
|
|
1
|
+
import { createApiRequest } from '../client/api-request.js';
|
|
2
|
+
import { unmarshalData } from '../client/api-response.js';
|
|
3
|
+
import { normalizeOrderStatus } from '../model/order-status.js';
|
|
4
4
|
/** Normalize `Order.status` field in-place (handles int → string). */
|
|
5
5
|
function normalizeOrderInPlace(o) {
|
|
6
6
|
if (o && o.status !== undefined && o.status !== null) {
|
|
@@ -191,9 +191,10 @@ export class TradeClient {
|
|
|
191
191
|
async getFundDetails(req) {
|
|
192
192
|
return this.callIntoItems('fund_details', withAccount(req, this.account));
|
|
193
193
|
}
|
|
194
|
-
/** Funding history (wire method: `transfer_fund`).
|
|
194
|
+
/** Funding history (wire method: `transfer_fund`).
|
|
195
|
+
* Server returns bare list (no items wrapper). */
|
|
195
196
|
async getFundingHistory(req) {
|
|
196
|
-
return this.
|
|
197
|
+
return this.callInto('transfer_fund', withAccount(req, this.account));
|
|
197
198
|
}
|
|
198
199
|
// ===== v0.4.0 NEW: Internal / external position transfer =====
|
|
199
200
|
/**
|
|
@@ -227,4 +228,41 @@ export class TradeClient {
|
|
|
227
228
|
merged.accountId = this.account;
|
|
228
229
|
return this.callIntoItems('position_transfer_external_records', merged);
|
|
229
230
|
}
|
|
231
|
+
/** 行权检验:预估行权/作废后正股持仓变化 (wire: option_exercise_check) */
|
|
232
|
+
async checkOptionExercise(req) {
|
|
233
|
+
const merged = { ...req };
|
|
234
|
+
if (!merged.account)
|
|
235
|
+
merged.account = this.account;
|
|
236
|
+
return this.callInto('option_exercise_check', merged);
|
|
237
|
+
}
|
|
238
|
+
/** 查询可行权持仓列表 (wire: option_exercise_position) */
|
|
239
|
+
async getOptionExercisePositions(req) {
|
|
240
|
+
const merged = { ...req };
|
|
241
|
+
if (!merged.account)
|
|
242
|
+
merged.account = this.account;
|
|
243
|
+
return this.callInto('option_exercise_position', merged);
|
|
244
|
+
}
|
|
245
|
+
/** 提交行权/作废申请 (wire: option_exercise_submit) */
|
|
246
|
+
async submitOptionExercise(req) {
|
|
247
|
+
const merged = { ...req };
|
|
248
|
+
if (!merged.account)
|
|
249
|
+
merged.account = this.account;
|
|
250
|
+
const result = await this.callInto('option_exercise_submit', merged);
|
|
251
|
+
return result ?? false;
|
|
252
|
+
}
|
|
253
|
+
/** 分页查询行权记录 (wire: option_exercise_record) */
|
|
254
|
+
async getOptionExerciseRecords(req) {
|
|
255
|
+
const merged = { ...req };
|
|
256
|
+
if (!merged.account)
|
|
257
|
+
merged.account = this.account;
|
|
258
|
+
return this.callInto('option_exercise_record', merged);
|
|
259
|
+
}
|
|
260
|
+
/** 撤销行权申请 (wire: option_exercise_cancel) */
|
|
261
|
+
async cancelOptionExercise(req) {
|
|
262
|
+
const merged = { ...req };
|
|
263
|
+
if (!merged.account)
|
|
264
|
+
merged.account = this.account;
|
|
265
|
+
const result = await this.callInto('option_exercise_cancel', merged);
|
|
266
|
+
return result ?? false;
|
|
267
|
+
}
|
|
230
268
|
}
|
|
@@ -11,6 +11,8 @@ export declare function camelToSnake(key: string): string;
|
|
|
11
11
|
/**
|
|
12
12
|
* Recursively convert all object keys from camelCase to snake_case.
|
|
13
13
|
* Preserves arrays, primitives, and Date/null/undefined.
|
|
14
|
-
*
|
|
14
|
+
*
|
|
15
|
+
* Note: camelToSnake is idempotent for pure snake_case keys (no uppercase
|
|
16
|
+
* letters → no replacements), so no pre-check is needed.
|
|
15
17
|
*/
|
|
16
18
|
export declare function keysToSnakeCase(value: unknown): unknown;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Uses Node.js built-in fetch (Node 18+).
|
|
6
6
|
*/
|
|
7
7
|
import type { ClientConfig } from '../config/client-config';
|
|
8
|
+
import { TokenManager, type TokenManagerOptions } from '../config/token-manager';
|
|
8
9
|
import { RetryPolicy } from './retry';
|
|
9
10
|
import { type ApiResponse } from './api-response';
|
|
10
11
|
import type { ApiRequest } from './api-request';
|
|
@@ -16,9 +17,16 @@ export declare class HttpClient {
|
|
|
16
17
|
private retryPolicy;
|
|
17
18
|
/** Override the target URL (used by quote client to hit quote server) */
|
|
18
19
|
private targetUrl;
|
|
20
|
+
/** non-null when auto-refresh is active */
|
|
21
|
+
private tokenManager;
|
|
19
22
|
constructor(config: ClientConfig, retryPolicy?: RetryPolicy, options?: {
|
|
20
23
|
useQuoteServerUrl?: boolean;
|
|
21
24
|
});
|
|
25
|
+
/**
|
|
26
|
+
* Stop the background token auto-refresh timer.
|
|
27
|
+
* Call this when the HttpClient is no longer needed to avoid timer leaks.
|
|
28
|
+
*/
|
|
29
|
+
close(): void;
|
|
22
30
|
/**
|
|
23
31
|
* Build common request parameters
|
|
24
32
|
*/
|
|
@@ -41,9 +49,32 @@ export declare class HttpClient {
|
|
|
41
49
|
*
|
|
42
50
|
* @param apiMethod - API method name (e.g. "market_state", "place_order")
|
|
43
51
|
* @param requestJson - Raw biz_content JSON string
|
|
52
|
+
* @param version - Optional API version override (default: "2.0")
|
|
44
53
|
* @returns Raw response JSON string, unparsed
|
|
45
54
|
*/
|
|
46
|
-
execute(apiMethod: string, requestJson: string): Promise<string>;
|
|
55
|
+
execute(apiMethod: string, requestJson: string, version?: string): Promise<string>;
|
|
56
|
+
/**
|
|
57
|
+
* 调用 user_token_refresh 接口获取新 token,返回新 token 字符串。
|
|
58
|
+
* 此方法仅查询,不修改 config 中的 token。
|
|
59
|
+
*/
|
|
60
|
+
queryToken(): Promise<string>;
|
|
61
|
+
/**
|
|
62
|
+
* 刷新 token:调用接口获取新 token 后更新 config.token。
|
|
63
|
+
*
|
|
64
|
+
* @param tokenManager - 可选外部 TokenManager;若提供则调用 setToken() 写文件并触发回调。
|
|
65
|
+
* 若 NewHttpClient 已自动启动内部 TokenManager,其内存 token 也会同步更新。
|
|
66
|
+
*/
|
|
67
|
+
refreshToken(tokenManager?: TokenManager | null): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* 启动后台 token 自动刷新。
|
|
70
|
+
*
|
|
71
|
+
* @param tokenManager - 可为 null:SDK 内部自动创建一个仅内存的 TokenManager,
|
|
72
|
+
* 适合直接通过 token 在代码里设置、不使用文件的场景。
|
|
73
|
+
* @param options - 仅在 tokenManager 为 null 时生效,用于配置内部 TokenManager
|
|
74
|
+
* (refreshDuration / refreshInterval / tokenWriter / tokenLoader)。
|
|
75
|
+
* @returns 使用或创建的 TokenManager 实例
|
|
76
|
+
*/
|
|
77
|
+
startTokenAutoRefresh(tokenManager: TokenManager | null, options?: TokenManagerOptions): TokenManager;
|
|
47
78
|
/** Delay for the specified milliseconds */
|
|
48
79
|
private sleep;
|
|
49
80
|
/**
|
|
@@ -9,6 +9,12 @@ export interface ClientConfig {
|
|
|
9
9
|
timeout: number;
|
|
10
10
|
token?: string;
|
|
11
11
|
tokenRefreshDuration?: number;
|
|
12
|
+
/** 后台 token 检查间隔(毫秒),仅 tokenRefreshDuration > 0 时生效,默认 5 分钟 */
|
|
13
|
+
tokenCheckInterval?: number;
|
|
14
|
+
/** 自定义 token 加载函数,替代默认的文件加载 */
|
|
15
|
+
tokenLoader?: () => Promise<string> | string;
|
|
16
|
+
/** token 刷新写入后的可选回调 */
|
|
17
|
+
tokenWriter?: (token: string) => void;
|
|
12
18
|
serverUrl: string;
|
|
13
19
|
/** Quote server URL for quote-specific requests; falls back to serverUrl */
|
|
14
20
|
quoteServerUrl: string;
|
|
@@ -27,13 +33,22 @@ export interface ClientConfigOptions {
|
|
|
27
33
|
timeout?: number;
|
|
28
34
|
token?: string;
|
|
29
35
|
tokenRefreshDuration?: number;
|
|
36
|
+
/** 后台 token 检查间隔(毫秒),仅 tokenRefreshDuration > 0 时生效,默认 5 分钟 */
|
|
37
|
+
tokenCheckInterval?: number;
|
|
38
|
+
/** 自定义 token 加载函数,替代默认的文件加载 */
|
|
39
|
+
tokenLoader?: () => Promise<string> | string;
|
|
40
|
+
/** token 刷新写入后的可选回调 */
|
|
41
|
+
tokenWriter?: (token: string) => void;
|
|
30
42
|
serverUrl?: string;
|
|
31
43
|
/** Explicit quote server URL; resolved dynamically if not set */
|
|
32
44
|
quoteServerUrl?: string;
|
|
33
45
|
/** Enable dynamic domain resolution (default: true) */
|
|
34
46
|
enableDynamicDomain?: boolean;
|
|
35
|
-
/** Explicit properties file path (synchronous read)
|
|
47
|
+
/** Explicit properties file path or directory (synchronous read).
|
|
48
|
+
* If a directory is given, appends 'tiger_openapi_config.properties' automatically. */
|
|
36
49
|
propertiesFilePath?: string;
|
|
50
|
+
/** Override Tiger public key (e.g. for sandbox/QA environments) */
|
|
51
|
+
tigerPublicKey?: string;
|
|
37
52
|
}
|
|
38
53
|
/**
|
|
39
54
|
* Load and parse a Java-style properties file.
|
|
@@ -4,4 +4,6 @@
|
|
|
4
4
|
export { parsePropertiesFile, parsePropertiesString } from './config-parser';
|
|
5
5
|
export { createClientConfig, loadPropertiesFile } from './client-config';
|
|
6
6
|
export type { ClientConfig, ClientConfigOptions } from './client-config';
|
|
7
|
+
export { TokenManager } from './token-manager';
|
|
8
|
+
export type { TokenManagerOptions, RefreshFn } from './token-manager';
|
|
7
9
|
export { queryDomains, resolveDynamicServerUrl, resolveDynamicQuoteServerUrl } from './domain';
|
|
@@ -4,6 +4,10 @@ export interface TokenManagerOptions {
|
|
|
4
4
|
refreshInterval?: number;
|
|
5
5
|
/** Token 刷新阈值(秒),0 表示不刷新,最小 30 秒 */
|
|
6
6
|
refreshDuration?: number;
|
|
7
|
+
/** 自定义 token 加载函数,优先于文件加载 */
|
|
8
|
+
tokenLoader?: () => Promise<string> | string;
|
|
9
|
+
/** token 写入后的回调(SetToken 成功后触发,SyncToken 不触发) */
|
|
10
|
+
tokenWriter?: (token: string) => void;
|
|
7
11
|
}
|
|
8
12
|
/** Token 刷新函数类型 */
|
|
9
13
|
export type RefreshFn = () => Promise<string>;
|
|
@@ -13,16 +17,36 @@ export type RefreshFn = () => Promise<string>;
|
|
|
13
17
|
export declare class TokenManager {
|
|
14
18
|
private token;
|
|
15
19
|
private filePath;
|
|
20
|
+
/** 仅当显式传入 filePath 时才写文件(fileEnabled = true) */
|
|
21
|
+
private fileEnabled;
|
|
16
22
|
private refreshInterval;
|
|
17
23
|
private refreshDuration;
|
|
18
24
|
private timer;
|
|
25
|
+
private tokenLoader;
|
|
26
|
+
private tokenWriter;
|
|
19
27
|
constructor(options?: TokenManagerOptions);
|
|
20
|
-
/**
|
|
21
|
-
|
|
28
|
+
/**
|
|
29
|
+
* 从 properties 文件(或自定义 tokenLoader)加载 Token。
|
|
30
|
+
* 若设置了 tokenLoader,优先调用;否则从 properties 文件读取。
|
|
31
|
+
*/
|
|
32
|
+
loadToken(): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* 同步版文件加载(仅用于无 tokenLoader 时的兼容入口)。
|
|
35
|
+
* 建议优先使用 loadToken()(异步)。
|
|
36
|
+
*/
|
|
37
|
+
loadTokenSync(): string;
|
|
22
38
|
/** 获取当前 Token */
|
|
23
39
|
getToken(): string;
|
|
24
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* 设置 Token;若启用了文件持久化(显式传入 filePath),则同步写文件。
|
|
42
|
+
* 成功后触发 tokenWriter 回调(如有)。
|
|
43
|
+
*/
|
|
25
44
|
setToken(token: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* 仅更新内存中的 token,不写文件,不触发 tokenWriter 回调。
|
|
47
|
+
* 用于多个组件共享 token 时的内部同步。
|
|
48
|
+
*/
|
|
49
|
+
syncToken(token: string): void;
|
|
26
50
|
/** 将 Token 保存到 properties 文件 */
|
|
27
51
|
private saveTokenToFile;
|
|
28
52
|
/**
|
package/dist/types/index.d.ts
CHANGED
|
@@ -15,4 +15,25 @@
|
|
|
15
15
|
* @packageDocumentation
|
|
16
16
|
*/
|
|
17
17
|
/** SDK 版本号 */
|
|
18
|
-
export declare const VERSION = "0.4.
|
|
18
|
+
export declare const VERSION = "0.4.4";
|
|
19
|
+
export { createClientConfig, loadPropertiesFile } from './config';
|
|
20
|
+
export type { ClientConfig, ClientConfigOptions } from './config';
|
|
21
|
+
export { TokenManager } from './config';
|
|
22
|
+
export type { TokenManagerOptions, RefreshFn } from './config';
|
|
23
|
+
export { HttpClient } from './client';
|
|
24
|
+
export { TigerError, classifyErrorCode } from './client';
|
|
25
|
+
export type { ErrorCategory } from './client';
|
|
26
|
+
export { QuoteClient, parseOptionIdentifier } from './quote';
|
|
27
|
+
export { TradeClient } from './trade';
|
|
28
|
+
export { PushClient, ConnectionState, SubjectType } from './push';
|
|
29
|
+
export type { PushClientOptions } from './push';
|
|
30
|
+
export type { Order, OrderRequest } from './model/order';
|
|
31
|
+
export { marketOrder, limitOrder, stopOrder, stopLimitOrder } from './model/order-helpers';
|
|
32
|
+
export { normalizeOrderStatus } from './model/order-status';
|
|
33
|
+
export type { Contract } from './model/contract';
|
|
34
|
+
export type { Position } from './model/position';
|
|
35
|
+
export type { Asset, AssetSegment, PrimeAsset, PreviewResult, PlaceOrderResult, OrderIdResult, Transaction, ManagedAccount, AnalyticsAsset, AggregateAssets, EstimateTradableQuantity, ForexOrderResult, SegmentFund, SegmentFundAvailableItem, SegmentFundHistoryItem, FundDetails, FundingHistoryItem, PositionTransferRecord, PositionTransferDetail, PositionTransferExternalRecord, OptionExerciseCheckResult, OptionExercisePositionPageResult, OptionExerciseRecordPageResult, } from './model/trade';
|
|
36
|
+
export type { OrdersRequest, GetOrderRequest, OrderTransactionsRequest, PositionsRequest, AssetsRequest, ManagedAccountsRequest, DerivativeContractsRequest, AnalyticsAssetRequest, AggregateAssetsRequest, EstimateTradableQuantityRequest, ForexOrderRequest, SegmentFundRequest, FundDetailsRequest, FundingHistoryRequest, PositionTransferRequest, PositionTransferRecordsRequest, PositionTransferDetailRequest, PositionTransferExternalRecordsRequest, OptionExerciseCheckRequest, OptionExercisePositionRequest, OptionExerciseSubmitRequest, OptionExerciseRecordsRequest, OptionExerciseCancelRequest, } from './model/trade-requests';
|
|
37
|
+
export type { MarketState, Brief, Kline, KlineItem, Timeline, TimelineItem, TradeTick, TradeTickItem, Depth, DepthLevel, OptionExpiration, OptionChain, OptionChainRow, OptionSymbol, FutureExchange, FutureContractInfo, FutureQuote, FutureKline, FutureKlineItem, FutureDepth, FutureTradeTickItem, FutureTradingTime, FinancialDailyItem, FinancialReportItem, CorporateAction, CapitalFlow, CapitalFlowItem, CapitalDistribution, ScannerResult, ScannerResultItem, QuotePermission, SymbolName, TradeMeta, StockDetail, StockBroker, StockBrokerItem, ShortInterest, StockIndustry, IndustryItem, IndustryStock, WarrantBrief, WarrantFilterResult, FundContractInfo, FundQuote, FundHistoryQuote, QuoteOvernight, KlineQuota, MarketScannerTag, MarketScannerTags, OptionAnalysis, OptionLeg, OptionVolatilityPoint, ExchangeRate, FinancialCurrency, BrokerDetail, TradingCalendarItem, FutureMainContractHistory, } from './model/quote';
|
|
38
|
+
export type { BriefRequest, DepthQuoteRequest, TradeTickRequest, BarsRequest, BarsByPageRequest, FutureBriefRequest, FutureBarsRequest, FutureBarsByPageRequest, FutureTradeTicksRequest, FutureDepthRequest, FutureContractSingleRequest, FutureContinuousContractsRequest, FutureHistoryMainContractRequest, FutureTradingTimesRequest, AllFutureContractsRequest, OptionBarsRequest, OptionTradeTicksRequest, OptionTimelineRequest, OptionDepthRequest, OptionSymbolsRequest, OptionAnalysisRequest, OptionQueryItem, ShortInterestRequest, StockBrokerRequest, StockDetailsRequest, StockFundamentalRequest, StockIndustryRequest, StockDelayBriefsRequest, SymbolsRequest, TradeMetasRequest, TradeRankRequest, TimelineHistoryRequest, TradingCalendarRequest, KlineQuotaRequest, QuotePermissionRequest, QuoteOvernightRequest, IndustryListRequest, IndustryStocksRequest, FundSymbolsRequest, FundContractsRequest, FundQuoteRequest, FundHistoryQuoteRequest, WarrantBriefsRequest, WarrantFilterRequest, MarketScannerTagsRequest, FinancialCurrencyRequest, FinancialExchangeRateRequest, } from './model/quote-requests';
|
|
39
|
+
export { OrderStatus, SecurityType, OrderType, TimeInForce, Market, Currency, QuoteRight, SegmentType, OrderSortBy, CorporateActionType, IndustryLevel, SortDirection, OptionAnalysisPeriod, FinancialReportPeriod, Language, License, BarPeriod, orderStatusCode, } from './model/enums';
|
|
@@ -193,3 +193,68 @@ export interface PositionTransferExternalRecordsRequest {
|
|
|
193
193
|
limit?: number;
|
|
194
194
|
lang?: string;
|
|
195
195
|
}
|
|
196
|
+
/** 行权检验请求 (wire: option_exercise_check) */
|
|
197
|
+
export interface OptionExerciseCheckRequest {
|
|
198
|
+
account?: string;
|
|
199
|
+
secretKey?: string;
|
|
200
|
+
/** 期权合约 ID */
|
|
201
|
+
contractId: number;
|
|
202
|
+
/** Exercise | Expire */
|
|
203
|
+
type: string;
|
|
204
|
+
quantity?: number;
|
|
205
|
+
/** yyyy-MM-dd,Exercise 类型建议填 */
|
|
206
|
+
executingDate?: string;
|
|
207
|
+
/** Exercise 类型建议填 */
|
|
208
|
+
isForce?: boolean;
|
|
209
|
+
/** 0–10,Expire 类型专用 */
|
|
210
|
+
itmRate?: number;
|
|
211
|
+
lang?: string;
|
|
212
|
+
}
|
|
213
|
+
/** 查询可行权持仓请求 (wire: option_exercise_position) */
|
|
214
|
+
export interface OptionExercisePositionRequest {
|
|
215
|
+
account?: string;
|
|
216
|
+
secretKey?: string;
|
|
217
|
+
/** Exercise | Expire */
|
|
218
|
+
type: string;
|
|
219
|
+
lang?: string;
|
|
220
|
+
}
|
|
221
|
+
/** 提交行权申请请求 (wire: option_exercise_submit) */
|
|
222
|
+
export interface OptionExerciseSubmitRequest {
|
|
223
|
+
account?: string;
|
|
224
|
+
secretKey?: string;
|
|
225
|
+
contractId: number;
|
|
226
|
+
/** Exercise | Expire */
|
|
227
|
+
type: string;
|
|
228
|
+
quantity: number;
|
|
229
|
+
/** Exercise 必填,yyyy-MM-dd */
|
|
230
|
+
executingDate?: string;
|
|
231
|
+
/** Exercise 必填 */
|
|
232
|
+
isForce?: boolean;
|
|
233
|
+
/** 0–10,Expire 专用 */
|
|
234
|
+
itmRate?: number;
|
|
235
|
+
lang?: string;
|
|
236
|
+
}
|
|
237
|
+
/** 分页查询行权记录请求 (wire: option_exercise_record) */
|
|
238
|
+
export interface OptionExerciseRecordsRequest {
|
|
239
|
+
account?: string;
|
|
240
|
+
secretKey?: string;
|
|
241
|
+
/** 从 1 开始,默认 1 */
|
|
242
|
+
page?: number;
|
|
243
|
+
/** 1–100,默认 20 */
|
|
244
|
+
size?: number;
|
|
245
|
+
/** New | Cancel | Success | Fail */
|
|
246
|
+
status?: string;
|
|
247
|
+
/** Exercise | Expire */
|
|
248
|
+
type?: string;
|
|
249
|
+
symbol?: string;
|
|
250
|
+
/** symbol | expire_date | strike | is_call */
|
|
251
|
+
orderBy?: string;
|
|
252
|
+
lang?: string;
|
|
253
|
+
}
|
|
254
|
+
/** 撤销行权申请请求 (wire: option_exercise_cancel) */
|
|
255
|
+
export interface OptionExerciseCancelRequest {
|
|
256
|
+
account?: string;
|
|
257
|
+
secretKey?: string;
|
|
258
|
+
id: number;
|
|
259
|
+
lang?: string;
|
|
260
|
+
}
|