@tigeropenapi/tigeropen 0.3.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.
Files changed (64) hide show
  1. package/dist/cjs/client/case-convert.js +4 -3
  2. package/dist/cjs/client/http-client.js +123 -6
  3. package/dist/cjs/config/client-config.js +56 -12
  4. package/dist/cjs/config/index.js +3 -1
  5. package/dist/cjs/config/token-manager.js +54 -4
  6. package/dist/cjs/index.js +51 -2
  7. package/dist/cjs/model/enums.js +89 -7
  8. package/dist/cjs/model/order-status.js +46 -0
  9. package/dist/cjs/model/quote-requests.js +11 -0
  10. package/dist/cjs/model/trade-requests.js +13 -0
  11. package/dist/cjs/push/pb/OrderStatusData.js +24 -0
  12. package/dist/cjs/push/proto-message.js +6 -0
  13. package/dist/cjs/push/push-client.js +111 -16
  14. package/dist/cjs/push/push-message.js +4 -0
  15. package/dist/cjs/quote/quote-client.js +333 -9
  16. package/dist/cjs/trade/trade-client.js +204 -25
  17. package/dist/esm/client/api-request.js +1 -1
  18. package/dist/esm/client/api-response.js +1 -1
  19. package/dist/esm/client/case-convert.js +4 -3
  20. package/dist/esm/client/http-client.js +128 -11
  21. package/dist/esm/client/index.js +6 -6
  22. package/dist/esm/config/client-config.js +59 -15
  23. package/dist/esm/config/index.js +4 -3
  24. package/dist/esm/config/token-manager.js +55 -5
  25. package/dist/esm/index.js +15 -1
  26. package/dist/esm/logger/index.js +1 -1
  27. package/dist/esm/model/contract-helpers.js +1 -1
  28. package/dist/esm/model/enums.js +87 -6
  29. package/dist/esm/model/order-helpers.js +1 -1
  30. package/dist/esm/model/order-status.js +43 -0
  31. package/dist/esm/model/quote-requests.js +10 -0
  32. package/dist/esm/model/trade-requests.js +12 -0
  33. package/dist/esm/push/index.js +5 -5
  34. package/dist/esm/push/pb/OrderStatusData.js +24 -0
  35. package/dist/esm/push/pb/PushData.js +11 -11
  36. package/dist/esm/push/pb/QuoteBasicData.js +1 -1
  37. package/dist/esm/push/pb/Response.js +1 -1
  38. package/dist/esm/push/pb/index.js +17 -17
  39. package/dist/esm/push/proto-message.js +9 -3
  40. package/dist/esm/push/push-client.js +118 -23
  41. package/dist/esm/push/push-message.js +4 -0
  42. package/dist/esm/quote/index.js +1 -1
  43. package/dist/esm/quote/quote-client.js +335 -11
  44. package/dist/esm/signer/index.js +2 -2
  45. package/dist/esm/trade/index.js +1 -1
  46. package/dist/esm/trade/trade-client.js +206 -27
  47. package/dist/types/client/case-convert.d.ts +3 -1
  48. package/dist/types/client/http-client.d.ts +32 -1
  49. package/dist/types/config/client-config.d.ts +16 -1
  50. package/dist/types/config/index.d.ts +2 -0
  51. package/dist/types/config/token-manager.d.ts +27 -3
  52. package/dist/types/index.d.ts +22 -1
  53. package/dist/types/model/enums.d.ts +60 -6
  54. package/dist/types/model/order-status.d.ts +14 -0
  55. package/dist/types/model/quote-requests.d.ts +344 -0
  56. package/dist/types/model/quote.d.ts +261 -0
  57. package/dist/types/model/trade-requests.d.ts +260 -0
  58. package/dist/types/model/trade.d.ts +214 -1
  59. package/dist/types/push/pb/OrderStatusData.d.ts +4 -0
  60. package/dist/types/push/push-client.d.ts +36 -3
  61. package/dist/types/push/push-message.d.ts +4 -0
  62. package/dist/types/quote/quote-client.d.ts +121 -6
  63. package/dist/types/trade/trade-client.d.ts +95 -12
  64. package/package.json +2 -2
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ /**
3
+ * Order status normalization.
4
+ *
5
+ * 服务端返回的订单状态有时是整数(-2/-1/3/4/5/6/7/8),有时是字符串
6
+ * ("Invalid"/"Submitted"/...)。本模块把二者统一为 Java SDK OrderStatus 的
7
+ * 字符串值。不做跨别名合并。
8
+ *
9
+ * 对齐 Java SDK OrderStatus.java。
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.normalizeOrderStatus = normalizeOrderStatus;
13
+ const enums_1 = require("./enums");
14
+ /** 把数字状态码映射到字符串,未识别返回空串。 */
15
+ function statusIntToString(n) {
16
+ switch (n) {
17
+ case -2:
18
+ return enums_1.OrderStatus.Invalid;
19
+ case -1:
20
+ return enums_1.OrderStatus.Initial;
21
+ case 3:
22
+ return enums_1.OrderStatus.PendingCancel;
23
+ case 4:
24
+ return enums_1.OrderStatus.Cancelled;
25
+ case 5:
26
+ return enums_1.OrderStatus.Submitted;
27
+ case 6:
28
+ return enums_1.OrderStatus.Filled;
29
+ case 7:
30
+ return enums_1.OrderStatus.Inactive;
31
+ case 8:
32
+ return enums_1.OrderStatus.PendingSubmit;
33
+ }
34
+ return '';
35
+ }
36
+ /**
37
+ * 把服务端可能返回的 string/number 订单状态归一为字符串。
38
+ * 字符串原样透传;数字按映射表转换;其他输入返回空串。
39
+ */
40
+ function normalizeOrderStatus(raw) {
41
+ if (typeof raw === 'string')
42
+ return raw;
43
+ if (typeof raw === 'number')
44
+ return statusIntToString(raw);
45
+ return '';
46
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ /**
3
+ * Quote request interfaces (v0.4.0).
4
+ *
5
+ * 所有字段可选(用户调用时传一个空对象即可);字段名用 camelCase,
6
+ * client 层通过 keysToSnakeCase 转成服务端 wire 真名的 snake_case。
7
+ * **字段名设计规则:camelCase → snake_case 后必须等于服务端 wire 真名。**
8
+ *
9
+ * 参考 Go SDK model/quote_requests.go。
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * Trade request interfaces (v0.4.0).
4
+ *
5
+ * 所有字段可选(用户调用时传一个空对象即可);字段名用 camelCase,
6
+ * client 层通过 keysToSnakeCase 转成服务端 wire 真名的 snake_case。
7
+ * **字段名设计规则:camelCase → snake_case 后必须等于服务端 wire 真名。**
8
+ * 比如 Trade 用 `startDate`/`endDate`(wire `start_date`/`end_date`),
9
+ * 不用 `startTime`/`endTime`(会被转成 `start_time`/`end_time`,与 wire 不符)。
10
+ *
11
+ * 参考 Go SDK model/trade_requests.go。
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -54,6 +54,8 @@ function createBaseOrderStatusData() {
54
54
  gst: 0,
55
55
  attrList: [],
56
56
  timeInForce: "",
57
+ updateTime: 0,
58
+ latestTime: 0,
57
59
  };
58
60
  }
59
61
  exports.OrderStatusData = {
@@ -187,6 +189,12 @@ exports.OrderStatusData = {
187
189
  if (message.timeInForce !== "") {
188
190
  writer.uint32(346).string(message.timeInForce);
189
191
  }
192
+ if (message.updateTime !== 0) {
193
+ writer.uint32(352).uint64(message.updateTime);
194
+ }
195
+ if (message.latestTime !== 0) {
196
+ writer.uint32(360).uint64(message.latestTime);
197
+ }
190
198
  return writer;
191
199
  },
192
200
  decode(input, length) {
@@ -497,6 +505,20 @@ exports.OrderStatusData = {
497
505
  message.timeInForce = reader.string();
498
506
  continue;
499
507
  }
508
+ case 44: {
509
+ if (tag !== 352) {
510
+ break;
511
+ }
512
+ message.updateTime = longToNumber(reader.uint64());
513
+ continue;
514
+ }
515
+ case 45: {
516
+ if (tag !== 360) {
517
+ break;
518
+ }
519
+ message.latestTime = longToNumber(reader.uint64());
520
+ continue;
521
+ }
500
522
  }
501
523
  if ((tag & 7) === 4 || tag === 0) {
502
524
  break;
@@ -553,6 +575,8 @@ exports.OrderStatusData = {
553
575
  message.gst = object.gst ?? 0;
554
576
  message.attrList = object.attrList?.map((e) => e) || [];
555
577
  message.timeInForce = object.timeInForce ?? "";
578
+ message.updateTime = object.updateTime ?? 0;
579
+ message.latestTime = object.latestTime ?? 0;
556
580
  return message;
557
581
  },
558
582
  };
@@ -123,6 +123,12 @@ function subjectToDataType(subject) {
123
123
  return SocketCommon_1.SocketCommon_DataType.TradeTick;
124
124
  case push_message_1.SubjectType.QuoteBBO:
125
125
  return SocketCommon_1.SocketCommon_DataType.Quote;
126
+ case push_message_1.SubjectType.Cc:
127
+ // 加密货币推送
128
+ return SocketCommon_1.SocketCommon_DataType.Cc;
129
+ case push_message_1.SubjectType.Market:
130
+ // 市场状态推送协议上 dataType=Quote,只设置 market 字段
131
+ return SocketCommon_1.SocketCommon_DataType.Quote;
126
132
  default:
127
133
  return SocketCommon_1.SocketCommon_DataType.Unknown;
128
134
  }
@@ -65,7 +65,7 @@ const MAX_RECONNECT_INTERVAL = 60000;
65
65
  /** Default connect timeout (ms) */
66
66
  const DEFAULT_CONNECT_TIMEOUT = 30000;
67
67
  /** SDK version identifier */
68
- const SDK_VERSION = 'typescript/0.1.0';
68
+ const SDK_VERSION = 'typescript/0.4.0';
69
69
  /** Protocol version */
70
70
  const ACCEPT_VERSION = '1.0';
71
71
  /** Default send heartbeat interval (ms) */
@@ -86,11 +86,13 @@ class PushClient {
86
86
  constructor(config, options) {
87
87
  this.socket = null;
88
88
  this._state = ConnectionState.Disconnected;
89
+ /** Whether this connect attempt already fell back to unverified TLS */
90
+ this.tlsFallback = false;
89
91
  this.callbacks = {};
90
92
  /** Subscription state: subject -> Set<symbol> */
91
93
  this.subscriptions = new Map();
92
- /** Account-level subscriptions */
93
- this.accountSubs = new Set();
94
+ /** Account-level subscriptions: subject -> account string used at subscribe time */
95
+ this.accountSubs = new Map();
94
96
  this.heartbeatTimer = null;
95
97
  this.reconnectTimer = null;
96
98
  this.stopped = false;
@@ -124,6 +126,7 @@ class PushClient {
124
126
  }
125
127
  this._state = ConnectionState.Connecting;
126
128
  this.stopped = false;
129
+ this.tlsFallback = false;
127
130
  this.recvBuffer = Buffer.alloc(0);
128
131
  const socket = this.createSocket(this.pushHost, this.pushPort);
129
132
  this.socket = socket;
@@ -180,6 +183,24 @@ class PushClient {
180
183
  });
181
184
  socket.on('error', (err) => {
182
185
  if (!settled) {
186
+ // If this is a TLS certificate error, warn and retry without verification.
187
+ const isTlsCertError = err.message.includes('certificate') ||
188
+ err.message.includes('CERT') ||
189
+ err.code === 'DEPTH_ZERO_SELF_SIGNED_CERT' ||
190
+ err.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' ||
191
+ err.code === 'CERT_HAS_EXPIRED';
192
+ if (isTlsCertError && !this.tlsFallback) {
193
+ this.tlsFallback = true;
194
+ settled = true;
195
+ clearTimeout(timeout);
196
+ socket.destroy();
197
+ this.socket = null;
198
+ this._state = ConnectionState.Disconnected;
199
+ console.warn(`[TigerOpen] TLS certificate verification failed: ${err.message}. Retrying without verification.`);
200
+ // Retry immediately using unverified TLS
201
+ this.connect().then(resolve).catch(reject);
202
+ return;
203
+ }
183
204
  settled = true;
184
205
  clearTimeout(timeout);
185
206
  this._state = ConnectionState.Disconnected;
@@ -232,7 +253,7 @@ class PushClient {
232
253
  createSocket(host, port) {
233
254
  if (this.socketFactory)
234
255
  return this.socketFactory(host, port);
235
- return tls.connect({ host, port, rejectUnauthorized: false });
256
+ return tls.connect({ host, port, rejectUnauthorized: !this.tlsFallback });
236
257
  }
237
258
  /** Handle incoming TCP data: buffer + decode varint32 frames */
238
259
  handleData(chunk, onConnected) {
@@ -331,8 +352,8 @@ class PushClient {
331
352
  for (const [subject, symbols] of this.subscriptions) {
332
353
  this.doSubscribe(subject, Array.from(symbols));
333
354
  }
334
- for (const subject of this.accountSubs) {
335
- this.doSubscribe(subject, undefined, this.config.account);
355
+ for (const [subject, account] of this.accountSubs) {
356
+ this.doSubscribe(subject, undefined, account);
336
357
  }
337
358
  }
338
359
  /** Dispatch push data to the appropriate callback based on dataType */
@@ -387,6 +408,11 @@ class PushClient {
387
408
  if (pushData.klineData)
388
409
  cb.onKline?.(pushData.klineData);
389
410
  break;
411
+ case SocketCommon_1.SocketCommon_DataType.Cc:
412
+ // 加密货币(Cc)推送复用 QuoteData body,路由到 onQuote 回调
413
+ if (pushData.quoteData)
414
+ cb.onQuote?.(pushData.quoteData);
415
+ break;
390
416
  default:
391
417
  // FullTick and QuoteBBO use TradeTick/Quote dataType
392
418
  // TickData (fullTick) via tickData field
@@ -493,11 +519,77 @@ class PushClient {
493
519
  this.doUnsubscribe(push_message_1.SubjectType.Kline, symbols);
494
520
  this.removeSubscription(push_message_1.SubjectType.Kline, symbols);
495
521
  }
522
+ // ===== v0.4.0: stock_top / option_top / cc / market =====
523
+ /**
524
+ * Subscribe to stock top rankings (v0.4.0).
525
+ * @param market US / HK / CN
526
+ * @param indicators LATEST_PRICE / HIGHER / LOWER / VOLUME / AMOUNT / AMPLITUDE / TURNOVER_RATE
527
+ */
528
+ subscribeStockTop(market, indicators) {
529
+ this.doSubscribe(push_message_1.SubjectType.StockTop, indicators, undefined, market);
530
+ this.addSubscription(push_message_1.SubjectType.StockTop, indicators);
531
+ }
532
+ /** Unsubscribe from stock top rankings (v0.4.0). */
533
+ unsubscribeStockTop(market, indicators) {
534
+ const dataType = (0, proto_message_1.subjectToDataType)(push_message_1.SubjectType.StockTop);
535
+ const symbolsStr = indicators.join(',');
536
+ const req = (0, proto_message_1.buildUnSubscribeMessage)(dataType, symbolsStr, undefined, market);
537
+ this.sendMessage(req);
538
+ this.removeSubscription(push_message_1.SubjectType.StockTop, indicators);
539
+ }
540
+ /**
541
+ * Subscribe to option top rankings (v0.4.0).
542
+ * @param market US / HK / CN
543
+ */
544
+ subscribeOptionTop(market, indicators) {
545
+ this.doSubscribe(push_message_1.SubjectType.OptionTop, indicators, undefined, market);
546
+ this.addSubscription(push_message_1.SubjectType.OptionTop, indicators);
547
+ }
548
+ /** Unsubscribe from option top rankings (v0.4.0). */
549
+ unsubscribeOptionTop(market, indicators) {
550
+ const dataType = (0, proto_message_1.subjectToDataType)(push_message_1.SubjectType.OptionTop);
551
+ const symbolsStr = indicators.join(',');
552
+ const req = (0, proto_message_1.buildUnSubscribeMessage)(dataType, symbolsStr, undefined, market);
553
+ this.sendMessage(req);
554
+ this.removeSubscription(push_message_1.SubjectType.OptionTop, indicators);
555
+ }
556
+ /**
557
+ * Subscribe to crypto realtime quotes (v0.4.0).
558
+ * Data is delivered via the `onQuote` callback (same QuoteData body).
559
+ * @param symbols e.g. ["BTCUSD", "ETHUSD"]
560
+ */
561
+ subscribeCc(symbols) {
562
+ this.doSubscribe(push_message_1.SubjectType.Cc, symbols);
563
+ this.addSubscription(push_message_1.SubjectType.Cc, symbols);
564
+ }
565
+ /** Unsubscribe from crypto realtime quotes (v0.4.0). */
566
+ unsubscribeCc(symbols) {
567
+ this.doUnsubscribe(push_message_1.SubjectType.Cc, symbols);
568
+ this.removeSubscription(push_message_1.SubjectType.Cc, symbols);
569
+ }
570
+ /**
571
+ * Subscribe to market status updates (v0.4.0).
572
+ * Protocol uses dataType=Quote with only the `market` field set.
573
+ * Data is delivered via the `onQuote` callback.
574
+ */
575
+ subscribeMarket(market) {
576
+ // symbols 为空,只带 market 字段
577
+ this.doSubscribe(push_message_1.SubjectType.Market, undefined, undefined, market);
578
+ this.addSubscription(push_message_1.SubjectType.Market, [market]);
579
+ }
580
+ /** Unsubscribe from market status (v0.4.0). */
581
+ unsubscribeMarket(market) {
582
+ const dataType = (0, proto_message_1.subjectToDataType)(push_message_1.SubjectType.Market);
583
+ const req = (0, proto_message_1.buildUnSubscribeMessage)(dataType, undefined, undefined, market);
584
+ this.sendMessage(req);
585
+ this.removeSubscription(push_message_1.SubjectType.Market, [market]);
586
+ }
496
587
  // ===== Account push subscribe/unsubscribe =====
497
588
  /** Subscribe to asset changes */
498
589
  subscribeAsset(account) {
499
- this.doSubscribe(push_message_1.SubjectType.Asset, undefined, account || this.config.account);
500
- this.accountSubs.add(push_message_1.SubjectType.Asset);
590
+ const acct = account || this.config.account;
591
+ this.doSubscribe(push_message_1.SubjectType.Asset, undefined, acct);
592
+ this.accountSubs.set(push_message_1.SubjectType.Asset, acct);
501
593
  }
502
594
  /** Unsubscribe from asset changes */
503
595
  unsubscribeAsset() {
@@ -506,8 +598,9 @@ class PushClient {
506
598
  }
507
599
  /** Subscribe to position changes */
508
600
  subscribePosition(account) {
509
- this.doSubscribe(push_message_1.SubjectType.Position, undefined, account || this.config.account);
510
- this.accountSubs.add(push_message_1.SubjectType.Position);
601
+ const acct = account || this.config.account;
602
+ this.doSubscribe(push_message_1.SubjectType.Position, undefined, acct);
603
+ this.accountSubs.set(push_message_1.SubjectType.Position, acct);
511
604
  }
512
605
  /** Unsubscribe from position changes */
513
606
  unsubscribePosition() {
@@ -516,8 +609,9 @@ class PushClient {
516
609
  }
517
610
  /** Subscribe to order status */
518
611
  subscribeOrder(account) {
519
- this.doSubscribe(push_message_1.SubjectType.Order, undefined, account || this.config.account);
520
- this.accountSubs.add(push_message_1.SubjectType.Order);
612
+ const acct = account || this.config.account;
613
+ this.doSubscribe(push_message_1.SubjectType.Order, undefined, acct);
614
+ this.accountSubs.set(push_message_1.SubjectType.Order, acct);
521
615
  }
522
616
  /** Unsubscribe from order status */
523
617
  unsubscribeOrder() {
@@ -526,8 +620,9 @@ class PushClient {
526
620
  }
527
621
  /** Subscribe to transaction details */
528
622
  subscribeTransaction(account) {
529
- this.doSubscribe(push_message_1.SubjectType.Transaction, undefined, account || this.config.account);
530
- this.accountSubs.add(push_message_1.SubjectType.Transaction);
623
+ const acct = account || this.config.account;
624
+ this.doSubscribe(push_message_1.SubjectType.Transaction, undefined, acct);
625
+ this.accountSubs.set(push_message_1.SubjectType.Transaction, acct);
531
626
  }
532
627
  /** Unsubscribe from transaction details */
533
628
  unsubscribeTransaction() {
@@ -543,9 +638,9 @@ class PushClient {
543
638
  }
544
639
  return result;
545
640
  }
546
- /** Get account-level subscriptions */
641
+ /** Get account-level subscriptions: subject -> account */
547
642
  getAccountSubscriptions() {
548
- return Array.from(this.accountSubs);
643
+ return new Map(this.accountSubs);
549
644
  }
550
645
  }
551
646
  exports.PushClient = PushClient;
@@ -20,6 +20,10 @@ var SubjectType;
20
20
  SubjectType["OptionTop"] = "option_top";
21
21
  SubjectType["FullTick"] = "full_tick";
22
22
  SubjectType["QuoteBBO"] = "quote_bbo";
23
+ /** 加密货币实时行情 (v0.4.0) */
24
+ SubjectType["Cc"] = "cc";
25
+ /** 市场状态 (v0.4.0) */
26
+ SubjectType["Market"] = "market";
23
27
  SubjectType["Asset"] = "asset";
24
28
  SubjectType["Position"] = "position";
25
29
  SubjectType["Order"] = "order";