@tigeropenapi/tigeropen 0.1.0 → 0.4.0

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 (141) hide show
  1. package/README.md +475 -104
  2. package/dist/cjs/client/api-request.js +16 -10
  3. package/dist/cjs/client/api-response.js +23 -3
  4. package/dist/cjs/client/case-convert.js +35 -0
  5. package/dist/cjs/client/http-client.js +47 -21
  6. package/dist/cjs/client/index.js +6 -2
  7. package/dist/cjs/config/client-config.js +130 -49
  8. package/dist/cjs/config/domain.js +21 -2
  9. package/dist/cjs/config/index.js +3 -1
  10. package/dist/cjs/index.js +1 -1
  11. package/dist/cjs/model/contract.js +1 -2
  12. package/dist/cjs/model/enums.js +89 -7
  13. package/dist/cjs/model/order-helpers.js +9 -9
  14. package/dist/cjs/model/order-status.js +46 -0
  15. package/dist/cjs/model/order.js +5 -2
  16. package/dist/cjs/model/position.js +1 -2
  17. package/dist/cjs/model/quote-requests.js +11 -0
  18. package/dist/cjs/model/quote.js +7 -0
  19. package/dist/cjs/model/trade-requests.js +13 -0
  20. package/dist/cjs/model/trade.js +2 -0
  21. package/dist/cjs/push/index.js +6 -3
  22. package/dist/cjs/push/pb/AssetData.js +208 -0
  23. package/dist/cjs/push/pb/KlineData.js +184 -0
  24. package/dist/cjs/push/pb/OptionTopData.js +427 -0
  25. package/dist/cjs/push/pb/OrderStatusData.js +592 -0
  26. package/dist/cjs/push/pb/OrderTransactionData.js +256 -0
  27. package/dist/cjs/push/pb/PositionData.js +316 -0
  28. package/dist/cjs/push/pb/PushData.js +219 -0
  29. package/dist/cjs/push/pb/QuoteBBOData.js +160 -0
  30. package/dist/cjs/push/pb/QuoteBasicData.js +329 -0
  31. package/dist/cjs/push/pb/QuoteData.js +507 -0
  32. package/dist/cjs/push/pb/QuoteDepthData.js +220 -0
  33. package/dist/cjs/push/pb/Request.js +278 -0
  34. package/dist/cjs/push/pb/Response.js +97 -0
  35. package/dist/cjs/push/pb/SocketCommon.js +86 -0
  36. package/dist/cjs/push/pb/StockTopData.js +199 -0
  37. package/dist/cjs/push/pb/TickData.js +202 -0
  38. package/dist/cjs/push/pb/TradeTickData.js +308 -0
  39. package/dist/cjs/push/pb/index.js +49 -0
  40. package/dist/cjs/push/proto-message.js +135 -0
  41. package/dist/cjs/push/push-client.js +361 -163
  42. package/dist/cjs/push/push-message.js +8 -60
  43. package/dist/cjs/push/varint.js +76 -0
  44. package/dist/cjs/quote/index.js +3 -2
  45. package/dist/cjs/quote/quote-client.js +440 -94
  46. package/dist/cjs/signer/signer.js +10 -10
  47. package/dist/cjs/trade/trade-client.js +197 -62
  48. package/dist/esm/client/api-request.js +14 -8
  49. package/dist/esm/client/api-response.js +22 -3
  50. package/dist/esm/client/case-convert.js +31 -0
  51. package/dist/esm/client/http-client.js +48 -22
  52. package/dist/esm/client/index.js +3 -2
  53. package/dist/esm/config/client-config.js +131 -51
  54. package/dist/esm/config/domain.js +20 -2
  55. package/dist/esm/config/index.js +2 -2
  56. package/dist/esm/index.js +1 -1
  57. package/dist/esm/model/contract.js +1 -2
  58. package/dist/esm/model/enums.js +87 -6
  59. package/dist/esm/model/order-helpers.js +9 -9
  60. package/dist/esm/model/order-status.js +43 -0
  61. package/dist/esm/model/order.js +5 -2
  62. package/dist/esm/model/position.js +1 -2
  63. package/dist/esm/model/quote-requests.js +10 -0
  64. package/dist/esm/model/quote.js +6 -0
  65. package/dist/esm/model/trade-requests.js +12 -0
  66. package/dist/esm/model/trade.js +1 -0
  67. package/dist/esm/push/index.js +4 -2
  68. package/dist/esm/push/pb/AssetData.js +205 -0
  69. package/dist/esm/push/pb/KlineData.js +181 -0
  70. package/dist/esm/push/pb/OptionTopData.js +424 -0
  71. package/dist/esm/push/pb/OrderStatusData.js +589 -0
  72. package/dist/esm/push/pb/OrderTransactionData.js +253 -0
  73. package/dist/esm/push/pb/PositionData.js +313 -0
  74. package/dist/esm/push/pb/PushData.js +216 -0
  75. package/dist/esm/push/pb/QuoteBBOData.js +157 -0
  76. package/dist/esm/push/pb/QuoteBasicData.js +326 -0
  77. package/dist/esm/push/pb/QuoteData.js +504 -0
  78. package/dist/esm/push/pb/QuoteDepthData.js +217 -0
  79. package/dist/esm/push/pb/Request.js +275 -0
  80. package/dist/esm/push/pb/Response.js +94 -0
  81. package/dist/esm/push/pb/SocketCommon.js +83 -0
  82. package/dist/esm/push/pb/StockTopData.js +196 -0
  83. package/dist/esm/push/pb/TickData.js +199 -0
  84. package/dist/esm/push/pb/TradeTickData.js +305 -0
  85. package/dist/esm/push/pb/index.js +25 -0
  86. package/dist/esm/push/proto-message.js +127 -0
  87. package/dist/esm/push/push-client.js +329 -164
  88. package/dist/esm/push/push-message.js +7 -56
  89. package/dist/esm/push/varint.js +72 -0
  90. package/dist/esm/quote/index.js +2 -2
  91. package/dist/esm/quote/quote-client.js +439 -94
  92. package/dist/esm/signer/signer.js +10 -10
  93. package/dist/esm/trade/trade-client.js +197 -62
  94. package/dist/types/client/api-request.d.ts +12 -11
  95. package/dist/types/client/api-response.d.ts +15 -7
  96. package/dist/types/client/case-convert.d.ts +16 -0
  97. package/dist/types/client/http-client.d.ts +26 -14
  98. package/dist/types/client/index.d.ts +3 -2
  99. package/dist/types/config/client-config.d.ts +29 -13
  100. package/dist/types/config/domain.d.ts +9 -0
  101. package/dist/types/config/index.d.ts +2 -2
  102. package/dist/types/index.d.ts +1 -1
  103. package/dist/types/model/contract.d.ts +13 -29
  104. package/dist/types/model/enums.d.ts +60 -6
  105. package/dist/types/model/order-helpers.d.ts +21 -20
  106. package/dist/types/model/order-status.d.ts +14 -0
  107. package/dist/types/model/order.d.ts +101 -55
  108. package/dist/types/model/position.d.ts +26 -24
  109. package/dist/types/model/quote-requests.d.ts +344 -0
  110. package/dist/types/model/quote.d.ts +572 -0
  111. package/dist/types/model/trade-requests.d.ts +195 -0
  112. package/dist/types/model/trade.d.ts +235 -0
  113. package/dist/types/push/callbacks.d.ts +32 -51
  114. package/dist/types/push/index.d.ts +5 -3
  115. package/dist/types/push/pb/AssetData.d.ts +47 -0
  116. package/dist/types/push/pb/KlineData.d.ts +43 -0
  117. package/dist/types/push/pb/OptionTopData.d.ts +76 -0
  118. package/dist/types/push/pb/OrderStatusData.d.ts +100 -0
  119. package/dist/types/push/pb/OrderTransactionData.d.ts +51 -0
  120. package/dist/types/push/pb/PositionData.d.ts +63 -0
  121. package/dist/types/push/pb/PushData.d.ts +46 -0
  122. package/dist/types/push/pb/QuoteBBOData.d.ts +35 -0
  123. package/dist/types/push/pb/QuoteBasicData.d.ts +66 -0
  124. package/dist/types/push/pb/QuoteData.d.ts +94 -0
  125. package/dist/types/push/pb/QuoteDepthData.d.ts +37 -0
  126. package/dist/types/push/pb/Request.d.ts +44 -0
  127. package/dist/types/push/pb/Response.d.ts +30 -0
  128. package/dist/types/push/pb/SocketCommon.d.ts +64 -0
  129. package/dist/types/push/pb/StockTopData.d.ts +37 -0
  130. package/dist/types/push/pb/TickData.d.ts +44 -0
  131. package/dist/types/push/pb/TradeTickData.d.ts +53 -0
  132. package/dist/types/push/pb/index.d.ts +39 -0
  133. package/dist/types/push/proto-message.d.ts +33 -0
  134. package/dist/types/push/push-client.d.ts +100 -68
  135. package/dist/types/push/push-message.d.ts +7 -147
  136. package/dist/types/push/varint.d.ts +23 -0
  137. package/dist/types/quote/index.d.ts +2 -2
  138. package/dist/types/quote/quote-client.d.ts +154 -47
  139. package/dist/types/signer/signer.d.ts +6 -6
  140. package/dist/types/trade/trade-client.d.ts +106 -38
  141. package/package.json +11 -6
@@ -1,95 +1,230 @@
1
1
  import { createApiRequest } from '../client/api-request';
2
- /**
3
- * 交易客户端,封装所有交易相关 API。
4
- */
2
+ import { unmarshalData } from '../client/api-response';
3
+ import { normalizeOrderStatus } from '../model/order-status';
4
+ /** Normalize `Order.status` field in-place (handles int → string). */
5
+ function normalizeOrderInPlace(o) {
6
+ if (o && o.status !== undefined && o.status !== null) {
7
+ o.status = normalizeOrderStatus(o.status);
8
+ }
9
+ }
10
+ /** Normalize every Order in a list in-place. */
11
+ function normalizeOrders(orders) {
12
+ for (const o of orders)
13
+ normalizeOrderInPlace(o);
14
+ return orders;
15
+ }
16
+ /** Shallow-copy a request object and fill account if empty. */
17
+ function withAccount(req, account) {
18
+ const r = { ...(req ?? {}) };
19
+ if (!r.account)
20
+ r.account = account;
21
+ return r;
22
+ }
23
+ /** Trading client wrapping all trade-related APIs. */
5
24
  export class TradeClient {
6
25
  constructor(httpClient, account) {
7
26
  this.httpClient = httpClient;
8
27
  this.account = account;
9
28
  }
10
- /**
11
- * 内部通用方法:构造请求、发送、返回 data 字段
12
- */
13
- async execute(method, bizParams) {
29
+ async callInto(method, bizParams) {
14
30
  const request = createApiRequest(method, bizParams);
15
31
  const response = await this.httpClient.executeRequest(request);
16
- return response.data;
17
- }
18
- // === 合约查询方法 ===
19
- /** 查询单个合约 */
20
- async contract(symbol, secType) {
21
- return this.execute('contract', {
32
+ return unmarshalData(response.data);
33
+ }
34
+ /** Strip `{items: [...]}` envelope used by most trade read endpoints. */
35
+ async callIntoItems(method, bizParams) {
36
+ const wrap = await this.callInto(method, bizParams);
37
+ if (Array.isArray(wrap))
38
+ return wrap;
39
+ return wrap?.items ?? [];
40
+ }
41
+ // === Contracts ===
42
+ async getContract(symbol, secType) {
43
+ return this.callIntoItems('contract', {
22
44
  account: this.account, symbol, secType,
23
45
  });
24
46
  }
25
- /** 批量查询合约 */
26
- async contracts(symbols, secType) {
27
- return this.execute('contracts', {
47
+ async getContracts(symbols, secType) {
48
+ return this.callIntoItems('contracts', {
28
49
  account: this.account, symbols, secType,
29
50
  });
30
51
  }
31
- /** 查询衍生品合约 */
32
- async quoteContract(symbol, secType) {
33
- return this.execute('quote_contract', {
34
- account: this.account, symbol, secType,
52
+ /**
53
+ * Derivative contracts (OPT / WAR / IOPT only).
54
+ * `symbol` is the underlying (e.g. "AAPL"); `expiry` is "YYYYMMDD".
55
+ */
56
+ async getQuoteContract(symbol, secType, expiry) {
57
+ return this.callIntoItems('quote_contract', {
58
+ account: this.account, symbols: [symbol], secType, expiry,
35
59
  });
36
60
  }
37
- // === 订单操作方法 ===
38
- /** 下单 */
61
+ // === Order operations ===
39
62
  async placeOrder(order) {
40
- const params = { ...order, account: this.account };
41
- return this.execute('place_order', params);
63
+ return this.callInto('place_order', { ...order, account: this.account });
42
64
  }
43
- /** 预览订单 */
44
65
  async previewOrder(order) {
45
- const params = { ...order, account: this.account };
46
- return this.execute('preview_order', params);
66
+ return this.callInto('preview_order', { ...order, account: this.account });
47
67
  }
48
- /** 修改订单 */
49
68
  async modifyOrder(id, order) {
50
- const params = { ...order, account: this.account, id };
51
- return this.execute('modify_order', params);
69
+ return this.callInto('modify_order', { ...order, account: this.account, id });
52
70
  }
53
- /** 取消订单 */
54
71
  async cancelOrder(id) {
55
- return this.execute('cancel_order', {
56
- account: this.account, id,
57
- });
72
+ return this.callInto('cancel_order', { account: this.account, id });
58
73
  }
59
- // === 订单查询方法 ===
60
- /** 查询全部订单 */
61
- async orders() {
62
- return this.execute('orders', { account: this.account });
74
+ // === Order queries (BREAKING v0.4.0) ===
75
+ /**
76
+ * Query all historical orders. v0.4.0: optional OrdersRequest for filtering.
77
+ *
78
+ * @example
79
+ * // Default (unfiltered)
80
+ * await tc.getOrders();
81
+ * // Filter by status
82
+ * await tc.getOrders({ states: ['Filled'], limit: 100 });
83
+ */
84
+ async getOrders(req) {
85
+ return normalizeOrders(await this.callIntoItems('orders', withAccount(req, this.account)));
63
86
  }
64
- /** 查询待成交订单 */
65
- async activeOrders() {
66
- return this.execute('active_orders', { account: this.account });
87
+ /** Query active (open) orders. v0.4.0: supports ParentId to filter attached legs. */
88
+ async getActiveOrders(req) {
89
+ return normalizeOrders(await this.callIntoItems('active_orders', withAccount(req, this.account)));
67
90
  }
68
- /** 查询已撤销订单 */
69
- async inactiveOrders() {
70
- return this.execute('inactive_orders', { account: this.account });
91
+ /** Query inactive/cancelled orders. */
92
+ async getInactiveOrders(req) {
93
+ return normalizeOrders(await this.callIntoItems('inactive_orders', withAccount(req, this.account)));
71
94
  }
72
- /** 查询已成交订单 */
73
- async filledOrders() {
74
- return this.execute('filled_orders', { account: this.account });
95
+ /**
96
+ * Query filled orders. v0.4.0 BREAKING: signature changed from positional
97
+ * (startDateMs, endDateMs) to OrdersRequest object.
98
+ *
99
+ * @example
100
+ * // Last 30 days
101
+ * const now = Date.now();
102
+ * await tc.getFilledOrders({ startDate: now - 30*24*3600*1000, endDate: now });
103
+ */
104
+ async getFilledOrders(req) {
105
+ return normalizeOrders(await this.callIntoItems('filled_orders', withAccount(req, this.account)));
75
106
  }
76
- // === 持仓和资产查询方法 ===
77
- /** 查询持仓 */
78
- async positions() {
79
- return this.execute('positions', { account: this.account });
107
+ /**
108
+ * Get a single order by ID (v0.4.0 new).
109
+ * Wire method: `orders` with id/order_id param; server returns a single Order object
110
+ * (not `{items:[]}` envelope).
111
+ *
112
+ * Returns `undefined` if no match.
113
+ */
114
+ async getOrder(req) {
115
+ const merged = withAccount(req, this.account);
116
+ const out = await this.callInto('orders', merged);
117
+ if (!out || (!out.id && !out.orderId))
118
+ return undefined;
119
+ normalizeOrderInPlace(out);
120
+ return out;
80
121
  }
81
- /** 查询资产 */
82
- async assets() {
83
- return this.execute('assets', { account: this.account });
122
+ /**
123
+ * Query order transaction details. v0.4.0 BREAKING: all fields now optional
124
+ * (previously symbol/secType required).
125
+ */
126
+ async getOrderTransactions(req) {
127
+ return this.callIntoItems('order_transactions', withAccount(req, this.account));
84
128
  }
85
- /** 查询综合账户资产 */
86
- async primeAssets() {
87
- return this.execute('prime_assets', { account: this.account });
129
+ // === Positions & assets (BREAKING v0.4.0) ===
130
+ /** Query positions. v0.4.0: supports Symbol / SecType / Currency / Market filters. */
131
+ async getPositions(req) {
132
+ return this.callIntoItems('positions', withAccount(req, this.account));
88
133
  }
89
- /** 查询订单成交明细 */
90
- async orderTransactions(id) {
91
- return this.execute('order_transactions', {
92
- account: this.account, id,
93
- });
134
+ /** Query assets. v0.4.0: supports sub-account list and aggregation options. */
135
+ async getAssets(req) {
136
+ return this.callIntoItems('assets', withAccount(req, this.account));
137
+ }
138
+ /** Query prime assets. v0.4.0: takes AssetsRequest for filters. */
139
+ async getPrimeAssets(req) {
140
+ return this.callInto('prime_assets', withAccount(req, this.account));
141
+ }
142
+ // ===== v0.4.0 NEW: Account management =====
143
+ /** Query managed sub-accounts (institutional). */
144
+ async getManagedAccounts(req) {
145
+ return this.callIntoItems('accounts', withAccount(req, this.account));
146
+ }
147
+ /**
148
+ * Query derivative contracts list. Same wire as getQuoteContract but accepts
149
+ * full request struct. Python: `get_derivative_contracts`.
150
+ */
151
+ async getDerivativeContracts(req) {
152
+ return this.callIntoItems('quote_contract', withAccount(req, this.account));
153
+ }
154
+ // ===== v0.4.0 NEW: Asset analytics =====
155
+ /** Daily P&L / net-value / holding-value analytics. */
156
+ async getAnalyticsAsset(req) {
157
+ return this.callIntoItems('analytics_asset', withAccount(req, this.account));
158
+ }
159
+ /** Aggregate assets (prime) by base currency. */
160
+ async getAggregateAssets(req) {
161
+ return this.callInto('aggregate_assets', withAccount(req, this.account));
162
+ }
163
+ /** Estimate tradable quantity given order parameters. */
164
+ async getEstimateTradableQuantity(req) {
165
+ return this.callInto('estimate_tradable_quantity', withAccount(req, this.account));
166
+ }
167
+ // ===== v0.4.0 NEW: Forex =====
168
+ /** Place forex order (sub-account base-currency swap). */
169
+ async placeForexOrder(req) {
170
+ return this.callInto('place_forex_order', withAccount(req, this.account));
171
+ }
172
+ // ===== v0.4.0 NEW: Segment fund transfer =====
173
+ /** Query amount available for inter-segment transfer. Returns array. */
174
+ async getSegmentFundAvailable(req) {
175
+ return this.callInto('segment_fund_available', withAccount(req, this.account));
176
+ }
177
+ /** Query segment fund transfer history. Server returns plain array (no items wrapper). */
178
+ async getSegmentFundHistory(req) {
179
+ return this.callInto('segment_fund_history', withAccount(req, this.account));
180
+ }
181
+ /** Execute an inter-segment fund transfer. */
182
+ async transferSegmentFund(req) {
183
+ return this.callInto('transfer_segment_fund', withAccount(req, this.account));
184
+ }
185
+ /** Cancel a pending inter-segment transfer. */
186
+ async cancelSegmentFund(req) {
187
+ return this.callInto('cancel_segment_fund', withAccount(req, this.account));
188
+ }
189
+ // ===== v0.4.0 NEW: Fund details / history =====
190
+ /** Fund-movement details (by segment / currency / fund-type). */
191
+ async getFundDetails(req) {
192
+ return this.callIntoItems('fund_details', withAccount(req, this.account));
193
+ }
194
+ /** Funding history (wire method: `transfer_fund`). */
195
+ async getFundingHistory(req) {
196
+ return this.callIntoItems('transfer_fund', withAccount(req, this.account));
197
+ }
198
+ // ===== v0.4.0 NEW: Internal / external position transfer =====
199
+ /**
200
+ * Internal position transfer (cross sub-account).
201
+ * @note Uses `fromAccount` / `toAccount` (not `account`).
202
+ */
203
+ async transferPosition(req) {
204
+ const merged = { ...req };
205
+ if (!merged.fromAccount)
206
+ merged.fromAccount = this.account;
207
+ return this.callInto('position_transfer', merged);
208
+ }
209
+ /** Query internal position transfer records. Uses `accountId` (wire: `account_id`). */
210
+ async getPositionTransferRecords(req) {
211
+ const merged = { ...req };
212
+ if (!merged.accountId)
213
+ merged.accountId = this.account;
214
+ return this.callIntoItems('position_transfer_records', merged);
215
+ }
216
+ /** Query single internal position transfer detail by ID. */
217
+ async getPositionTransferDetail(req) {
218
+ const merged = { ...req };
219
+ if (!merged.accountId)
220
+ merged.accountId = this.account;
221
+ return this.callInto('position_transfer_detail', merged);
222
+ }
223
+ /** Query external position transfer records (DWAC / FOP / etc.). */
224
+ async getPositionTransferExternalRecords(req) {
225
+ const merged = { ...req };
226
+ if (!merged.accountId)
227
+ merged.accountId = this.account;
228
+ return this.callIntoItems('position_transfer_external_records', merged);
94
229
  }
95
230
  }
@@ -1,18 +1,19 @@
1
- /**
2
- * API 请求构造模块
3
- */
4
- /** API 请求接口 */
1
+ /** API request interface */
5
2
  export interface ApiRequest {
6
- /** API 方法名(如 "market_state"、"place_order") */
3
+ /** API method name (e.g. "market_state", "place_order") */
7
4
  method: string;
8
- /** 业务参数 JSON 字符串 */
5
+ /** Business parameters as JSON string (already snake_case) */
9
6
  bizContent: string;
7
+ /** Optional API version override (default: "2.0") */
8
+ version?: string;
10
9
  }
11
10
  /**
12
- * 创建 API 请求,将业务参数序列化为 JSON 字符串作为 bizContent。
11
+ * Create an API request, serializing business parameters to JSON as bizContent.
12
+ * camelCase keys are automatically converted to snake_case to match the server.
13
13
  *
14
- * @param method - API 方法名
15
- * @param bizParams - 业务参数(对象、字符串或 null)
16
- * @returns ApiRequest 对象
14
+ * @param method - API method name
15
+ * @param bizParams - Business parameters (object, string, or null); objects are converted recursively
16
+ * @param version - Optional API version override
17
+ * @returns ApiRequest object
17
18
  */
18
- export declare function createApiRequest(method: string, bizParams: unknown): ApiRequest;
19
+ export declare function createApiRequest(method: string, bizParams: unknown, version?: string): ApiRequest;
@@ -1,16 +1,24 @@
1
- /** API 响应接口 */
1
+ /** API response envelope */
2
2
  export interface ApiResponse {
3
- /** 状态码(0=成功) */
3
+ /** Result code (0 = success) */
4
4
  code: number;
5
- /** 状态描述 */
5
+ /** Human-readable message */
6
6
  message: string;
7
- /** 业务数据 */
7
+ /** Business payload */
8
8
  data: unknown;
9
- /** 服务器时间戳 */
9
+ /** Server timestamp */
10
10
  timestamp: number;
11
+ /** Response signature for verification */
12
+ sign?: string;
11
13
  }
12
14
  /**
13
- * 解析 API 响应 JSON 字符串。
14
- * code 为 0 时返回 ApiResponse;code 不为 0 时抛出 TigerError。
15
+ * Parse the raw HTTP response body.
16
+ * Throws TigerError when code != 0.
15
17
  */
16
18
  export declare function parseApiResponse(body: string): ApiResponse;
19
+ /**
20
+ * Decode an ApiResponse.data payload into a typed value.
21
+ * Handles the server's occasional double-encoded JSON (where `data` is a
22
+ * JSON string that itself wraps JSON), seen on some trade endpoints.
23
+ */
24
+ export declare function unmarshalData<T>(data: unknown): T | undefined;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Case conversion utilities.
3
+ *
4
+ * TypeScript SDK uses camelCase idiomatically. The server expects
5
+ * snake_case for request field names and returns camelCase for responses.
6
+ * These helpers convert camelCase objects to snake_case before
7
+ * serialization; response side needs no conversion.
8
+ */
9
+ /** Convert a single camelCase key to snake_case. */
10
+ export declare function camelToSnake(key: string): string;
11
+ /**
12
+ * Recursively convert all object keys from camelCase to snake_case.
13
+ * Preserves arrays, primitives, and Date/null/undefined.
14
+ * Keys already containing an underscore are kept as-is (already snake_case).
15
+ */
16
+ export declare function keysToSnakeCase(value: unknown): unknown;
@@ -1,22 +1,26 @@
1
1
  /**
2
- * HttpClient - HTTP 客户端
2
+ * HttpClient - HTTP client
3
3
  *
4
- * 封装 HTTP 请求、签名、重试、超时。
5
- * 使用 Node.js 内置 fetch(Node 18+)。
4
+ * Handles HTTP requests, signing, retry, and timeout.
5
+ * Uses Node.js built-in fetch (Node 18+).
6
6
  */
7
7
  import type { ClientConfig } from '../config/client-config';
8
8
  import { RetryPolicy } from './retry';
9
9
  import { type ApiResponse } from './api-response';
10
10
  import type { ApiRequest } from './api-request';
11
11
  /**
12
- * HttpClient 封装 HTTP 请求、签名、重试、超时
12
+ * HttpClient handles HTTP requests, signing, retry, and timeout
13
13
  */
14
14
  export declare class HttpClient {
15
15
  private config;
16
16
  private retryPolicy;
17
- constructor(config: ClientConfig, retryPolicy?: RetryPolicy);
17
+ /** Override the target URL (used by quote client to hit quote server) */
18
+ private targetUrl;
19
+ constructor(config: ClientConfig, retryPolicy?: RetryPolicy, options?: {
20
+ useQuoteServerUrl?: boolean;
21
+ });
18
22
  /**
19
- * 构造公共请求参数
23
+ * Build common request parameters
20
24
  */
21
25
  private buildCommonParams;
22
26
  /**
@@ -24,22 +28,30 @@ export declare class HttpClient {
24
28
  */
25
29
  private signParams;
26
30
  /**
27
- * 发送 HTTP POST 请求
31
+ * Send HTTP POST request
28
32
  */
29
33
  private doHttpPost;
30
34
  /**
31
- * 执行结构化 API 请求,返回解析后的 ApiResponse。
32
- * 供 QuoteClient/TradeClient 内部使用。
35
+ * Execute a structured API request, returning a parsed ApiResponse.
36
+ * Used internally by QuoteClient/TradeClient.
33
37
  */
34
38
  executeRequest(request: ApiRequest): Promise<ApiResponse>;
35
39
  /**
36
- * 通用 API 调用方法。
40
+ * General-purpose API call method.
37
41
  *
38
- * @param apiMethod - API 方法名(如 "market_state"、"place_order")
39
- * @param requestJson - 原始 biz_content JSON 字符串
40
- * @returns 原始 response JSON 字符串,不做任何解析
42
+ * @param apiMethod - API method name (e.g. "market_state", "place_order")
43
+ * @param requestJson - Raw biz_content JSON string
44
+ * @returns Raw response JSON string, unparsed
41
45
  */
42
46
  execute(apiMethod: string, requestJson: string): Promise<string>;
43
- /** 延迟指定毫秒 */
47
+ /** Delay for the specified milliseconds */
44
48
  private sleep;
49
+ /**
50
+ * Verify the response signature using the tiger public key.
51
+ *
52
+ * @param timestamp - The timestamp sent in the request params
53
+ * @param signBase64 - The `sign` field from the response body
54
+ * @throws TigerError if the signature is missing or invalid
55
+ */
56
+ private verifyResponseSign;
45
57
  }
@@ -1,8 +1,9 @@
1
1
  /**
2
- * 传输层模块导出
2
+ * Transport layer exports.
3
3
  */
4
4
  export { HttpClient } from './http-client';
5
5
  export { TigerError, classifyErrorCode, type ErrorCategory } from './errors';
6
6
  export { RetryPolicy, defaultRetryPolicy, isTradeOperation } from './retry';
7
7
  export { type ApiRequest, createApiRequest } from './api-request';
8
- export { type ApiResponse, parseApiResponse } from './api-response';
8
+ export { type ApiResponse, parseApiResponse, unmarshalData } from './api-response';
9
+ export { camelToSnake, keysToSnakeCase } from './case-convert';
@@ -1,4 +1,4 @@
1
- /** 客户端配置接口 */
1
+ /** Client configuration interface */
2
2
  export interface ClientConfig {
3
3
  tigerId: string;
4
4
  privateKey: string;
@@ -7,12 +7,16 @@ export interface ClientConfig {
7
7
  language: string;
8
8
  timezone?: string;
9
9
  timeout: number;
10
- sandboxDebug: boolean;
11
10
  token?: string;
12
11
  tokenRefreshDuration?: number;
13
12
  serverUrl: string;
13
+ /** Quote server URL for quote-specific requests; falls back to serverUrl */
14
+ quoteServerUrl: string;
15
+ /** Device identifier (auto-detected MAC address) */
16
+ deviceId: string;
17
+ tigerPublicKey: string;
14
18
  }
15
- /** 创建配置时的选项参数 */
19
+ /** Options for creating a client configuration */
16
20
  export interface ClientConfigOptions {
17
21
  tigerId?: string;
18
22
  privateKey?: string;
@@ -21,23 +25,35 @@ export interface ClientConfigOptions {
21
25
  language?: string;
22
26
  timezone?: string;
23
27
  timeout?: number;
24
- sandboxDebug?: boolean;
25
28
  token?: string;
26
29
  tokenRefreshDuration?: number;
27
30
  serverUrl?: string;
28
- /** 是否启用动态域名获取(默认 true) */
31
+ /** Explicit quote server URL; resolved dynamically if not set */
32
+ quoteServerUrl?: string;
33
+ /** Enable dynamic domain resolution (default: true) */
29
34
  enableDynamicDomain?: boolean;
30
- /** properties 配置文件路径(同步读取) */
35
+ /** Explicit properties file path (synchronous read) */
31
36
  propertiesFilePath?: string;
32
37
  }
33
38
  /**
34
- * 创建客户端配置。
39
+ * Load and parse a Java-style properties file.
35
40
  *
36
- * 优先级:环境变量 > 代码设置(含配置文件) > 默认值。
37
- * 必填字段 tigerId 和 privateKey 为空时抛出错误。
41
+ * @param filePath - Absolute or relative path to the properties file
42
+ * @returns Parsed key-value pairs, or empty object if the file cannot be read
43
+ */
44
+ export declare function loadPropertiesFile(filePath: string): Record<string, string>;
45
+ /**
46
+ * Create a client configuration.
47
+ *
48
+ * When called with no arguments (or without `propertiesFilePath`), the function
49
+ * automatically searches for `tiger_openapi_config.properties` in the current
50
+ * directory and `~/.tigeropen/`. Discovered values serve as defaults; explicit
51
+ * options and environment variables take precedence.
52
+ *
53
+ * Priority: environment variables > code options > config file > defaults
38
54
  *
39
- * @param options - 配置选项
40
- * @returns 完整的客户端配置对象
41
- * @throws tigerId 或 privateKey 为空时抛出错误
55
+ * @param options - Configuration options (optional)
56
+ * @returns Complete client configuration object
57
+ * @throws When tigerId or privateKey is empty after all resolution
42
58
  */
43
- export declare function createClientConfig(options: ClientConfigOptions): ClientConfig;
59
+ export declare function createClientConfig(options?: ClientConfigOptions): ClientConfig;
@@ -16,3 +16,12 @@ export declare function queryDomains(license?: string): Record<string, unknown>;
16
16
  * 返回空字符串表示无法解析(应使用默认地址)。
17
17
  */
18
18
  export declare function resolveDynamicServerUrl(domainConf: Record<string, unknown>, license?: string): string;
19
+ /**
20
+ * Resolve the quote server URL from dynamic domain configuration.
21
+ * Uses the `{LICENSE}-QUOTE` key, falling back to empty string.
22
+ *
23
+ * @param domainConf - Domain configuration map from queryDomains
24
+ * @param license - License type (e.g. "TBNZ")
25
+ * @returns Quote server URL with gateway suffix, or empty string
26
+ */
27
+ export declare function resolveDynamicQuoteServerUrl(domainConf: Record<string, unknown>, license?: string): string;
@@ -2,6 +2,6 @@
2
2
  * 配置层导出
3
3
  */
4
4
  export { parsePropertiesFile, parsePropertiesString } from './config-parser';
5
- export { createClientConfig } from './client-config';
5
+ export { createClientConfig, loadPropertiesFile } from './client-config';
6
6
  export type { ClientConfig, ClientConfigOptions } from './client-config';
7
- export { queryDomains, resolveDynamicServerUrl } from './domain';
7
+ export { queryDomains, resolveDynamicServerUrl, resolveDynamicQuoteServerUrl } from './domain';
@@ -15,4 +15,4 @@
15
15
  * @packageDocumentation
16
16
  */
17
17
  /** SDK 版本号 */
18
- export declare const VERSION = "0.1.0";
18
+ export declare const VERSION = "0.4.0";
@@ -1,60 +1,44 @@
1
1
  /**
2
- * Contract 合约接口
3
- * 字段名 camelCase 与 API JSON 天然一致,不改名、不加封装层
2
+ * Contract / TickSize models.
4
3
  */
5
- /** 最小报价单位价格区间 */
4
+ /** Tick size tier */
6
5
  export interface TickSize {
7
- /** 起始价格(字符串,如 "0"、"1") */
8
6
  begin?: string;
9
- /** 结束价格(字符串,如 "1"、"Infinity") */
10
7
  end?: string;
11
- /** 最小报价单位 */
12
8
  tickSize?: number;
13
- /** 类型(CLOSED/OPEN) */
14
9
  type?: string;
15
10
  }
16
- /** 合约模型,字段名词根保持与 API JSON 一致 */
11
+ /** Contract model (returned by contract / contracts / quoteContract / derivative queries) */
17
12
  export interface Contract {
18
- /** 合约 ID */
19
13
  contractId?: number;
20
- /** 标的代码(如 AAPL) */
21
14
  symbol: string;
22
- /** 证券类型(STK/OPT/FUT/WAR/CASH/FUND 等) */
23
15
  secType: string;
24
- /** 货币 */
25
16
  currency?: string;
26
- /** 交易所 */
27
17
  exchange?: string;
28
- /** 到期日(期权/期货) */
18
+ primaryExchange?: string;
19
+ localSymbol?: string;
20
+ tradingClass?: string;
29
21
  expiry?: string;
30
- /** 行权价(期权) */
31
22
  strike?: number;
32
- /** 看涨/看跌(PUT/CALL),保持 API 原始名 right,不改为 putCall */
33
23
  right?: string;
34
- /** 合约乘数 */
35
24
  multiplier?: number;
36
- /** 合约标识符 */
37
25
  identifier?: string;
38
- /** 合约名称 */
39
26
  name?: string;
40
- /** 市场 */
41
27
  market?: string;
42
- /** 是否可交易,保持 API 原始名 tradeable,不改为 trade */
43
28
  tradeable?: boolean;
44
- /** 合约内部 ID,保持 API 原始名 conid,不改为 contractId */
45
29
  conid?: number;
46
- /** 做空保证金比例 */
30
+ status?: number;
31
+ marginable?: boolean;
32
+ shortable?: boolean;
33
+ closeOnly?: boolean;
34
+ isEtf?: boolean;
35
+ supportOvernightTrading?: boolean;
36
+ supportFractionalShare?: boolean;
47
37
  shortMargin?: number;
48
- /** 做空初始保证金比例 */
49
38
  shortInitialMargin?: number;
50
- /** 做空维持保证金比例 */
51
39
  shortMaintenanceMargin?: number;
52
- /** 做多初始保证金 */
53
40
  longInitialMargin?: number;
54
- /** 做多维持保证金 */
55
41
  longMaintenanceMargin?: number;
56
- /** 最小报价单位价格区间 */
57
42
  tickSizes?: TickSize[];
58
- /** 每手数量 */
59
43
  lotSize?: number;
60
44
  }