@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.
- package/dist/cjs/client/case-convert.js +4 -3
- package/dist/cjs/client/http-client.js +123 -6
- 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/model/enums.js +89 -7
- package/dist/cjs/model/order-status.js +46 -0
- package/dist/cjs/model/quote-requests.js +11 -0
- package/dist/cjs/model/trade-requests.js +13 -0
- package/dist/cjs/push/pb/OrderStatusData.js +24 -0
- package/dist/cjs/push/proto-message.js +6 -0
- package/dist/cjs/push/push-client.js +111 -16
- package/dist/cjs/push/push-message.js +4 -0
- package/dist/cjs/quote/quote-client.js +333 -9
- package/dist/cjs/trade/trade-client.js +204 -25
- 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 +128 -11
- 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/enums.js +87 -6
- package/dist/esm/model/order-helpers.js +1 -1
- package/dist/esm/model/order-status.js +43 -0
- package/dist/esm/model/quote-requests.js +10 -0
- package/dist/esm/model/trade-requests.js +12 -0
- package/dist/esm/push/index.js +5 -5
- package/dist/esm/push/pb/OrderStatusData.js +24 -0
- 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 +9 -3
- package/dist/esm/push/push-client.js +118 -23
- package/dist/esm/push/push-message.js +4 -0
- package/dist/esm/quote/index.js +1 -1
- package/dist/esm/quote/quote-client.js +335 -11
- package/dist/esm/signer/index.js +2 -2
- package/dist/esm/trade/index.js +1 -1
- package/dist/esm/trade/trade-client.js +206 -27
- 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/enums.d.ts +60 -6
- package/dist/types/model/order-status.d.ts +14 -0
- package/dist/types/model/quote-requests.d.ts +344 -0
- package/dist/types/model/quote.d.ts +261 -0
- package/dist/types/model/trade-requests.d.ts +260 -0
- package/dist/types/model/trade.d.ts +214 -1
- package/dist/types/push/pb/OrderStatusData.d.ts +4 -0
- package/dist/types/push/push-client.d.ts +36 -3
- package/dist/types/push/push-message.d.ts +4 -0
- package/dist/types/quote/quote-client.d.ts +121 -6
- package/dist/types/trade/trade-client.d.ts +95 -12
- package/package.json +2 -2
|
@@ -45,12 +45,31 @@ class QuoteClient {
|
|
|
45
45
|
const response = await this.httpClient.executeRequest(request);
|
|
46
46
|
return (0, api_response_1.unmarshalData)(response.data);
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Some endpoints return either a list or a single object depending on the
|
|
50
|
+
* server response shape (future_contract_by_contract_code /
|
|
51
|
+
* future_continuous_contracts). Unify into an array.
|
|
52
|
+
*/
|
|
53
|
+
async callIntoListOrObject(method, bizParams, version) {
|
|
54
|
+
const raw = await this.callInto(method, bizParams, version);
|
|
55
|
+
if (raw == null)
|
|
56
|
+
return [];
|
|
57
|
+
if (Array.isArray(raw))
|
|
58
|
+
return raw;
|
|
59
|
+
return [raw];
|
|
60
|
+
}
|
|
61
|
+
/** Unwrap server {"items":[...]} envelope. */
|
|
62
|
+
async callIntoItems(method, bizParams, version) {
|
|
63
|
+
const wrap = await this.callInto(method, bizParams, version);
|
|
64
|
+
return wrap?.items ?? [];
|
|
65
|
+
}
|
|
48
66
|
// === Basic market data ===
|
|
49
67
|
async getMarketState(market) {
|
|
50
68
|
return this.callInto('market_state', { market });
|
|
51
69
|
}
|
|
52
|
-
|
|
53
|
-
|
|
70
|
+
/** Real-time stock briefs. wire: quote_real_time */
|
|
71
|
+
async getBrief(req) {
|
|
72
|
+
return this.callInto('quote_real_time', req);
|
|
54
73
|
}
|
|
55
74
|
async getKline(symbol, period) {
|
|
56
75
|
return this.callInto('kline', { symbols: [symbol], period });
|
|
@@ -58,12 +77,13 @@ class QuoteClient {
|
|
|
58
77
|
async getTimeline(symbols) {
|
|
59
78
|
return this.callInto('timeline', { symbols });
|
|
60
79
|
}
|
|
61
|
-
|
|
62
|
-
|
|
80
|
+
/** Tick-by-tick trades. wire: trade_tick */
|
|
81
|
+
async getTradeTick(req) {
|
|
82
|
+
return this.callInto('trade_tick', req);
|
|
63
83
|
}
|
|
64
|
-
/** Depth snapshot.
|
|
65
|
-
async getQuoteDepth(
|
|
66
|
-
return this.callInto('quote_depth',
|
|
84
|
+
/** Depth snapshot. wire: quote_depth */
|
|
85
|
+
async getQuoteDepth(req) {
|
|
86
|
+
return this.callInto('quote_depth', req);
|
|
67
87
|
}
|
|
68
88
|
// === Options ===
|
|
69
89
|
async getOptionExpiration(symbol) {
|
|
@@ -98,8 +118,9 @@ class QuoteClient {
|
|
|
98
118
|
async getFutureContracts(exchange) {
|
|
99
119
|
return this.callInto('future_contract_by_exchange_code', { exchangeCode: exchange });
|
|
100
120
|
}
|
|
101
|
-
|
|
102
|
-
|
|
121
|
+
/** Real-time futures quotes. wire: future_real_time_quote */
|
|
122
|
+
async getFutureRealTimeQuote(req) {
|
|
123
|
+
return this.callInto('future_real_time_quote', req);
|
|
103
124
|
}
|
|
104
125
|
/** Futures K-line; use -1 for unbounded beginTime / endTime. */
|
|
105
126
|
async getFutureKline(req) {
|
|
@@ -140,5 +161,308 @@ class QuoteClient {
|
|
|
140
161
|
async grabQuotePermission() {
|
|
141
162
|
return this.callInto('grab_quote_permission');
|
|
142
163
|
}
|
|
164
|
+
// ==========================================================================
|
|
165
|
+
// Batch 3: stock basics + time series
|
|
166
|
+
// ==========================================================================
|
|
167
|
+
/** All symbol codes (string list). wire: all_symbols */
|
|
168
|
+
async getSymbols(req) {
|
|
169
|
+
return this.callInto('all_symbols', req);
|
|
170
|
+
}
|
|
171
|
+
/** All symbols with names. wire: all_symbol_names */
|
|
172
|
+
async getSymbolNames(req) {
|
|
173
|
+
return this.callInto('all_symbol_names', req);
|
|
174
|
+
}
|
|
175
|
+
/** Trade meta (lot size / tick size). wire: quote_stock_trade */
|
|
176
|
+
async getTradeMetas(req) {
|
|
177
|
+
return this.callInto('quote_stock_trade', req);
|
|
178
|
+
}
|
|
179
|
+
/** Stock details. wire: stock_detail. Server returns {items:[...]}. */
|
|
180
|
+
async getStockDetails(req) {
|
|
181
|
+
return this.callIntoItems('stock_detail', req);
|
|
182
|
+
}
|
|
183
|
+
/** Delayed stock briefs. wire: quote_delay */
|
|
184
|
+
async getStockDelayBriefs(req) {
|
|
185
|
+
return this.callInto('quote_delay', req);
|
|
186
|
+
}
|
|
187
|
+
/** K-line bars (full request). wire: kline */
|
|
188
|
+
async getBars(req) {
|
|
189
|
+
return this.callInto('kline', req);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Client-side paginated K-line fetch — loops over getBars until TotalSize
|
|
193
|
+
* bars are collected. Items are returned oldest-first, matching
|
|
194
|
+
* Python/Go get_bars_by_page behaviour.
|
|
195
|
+
*/
|
|
196
|
+
async getBarsByPage(req) {
|
|
197
|
+
const pageSize = req.pageSize && req.pageSize > 0 ? req.pageSize : 200;
|
|
198
|
+
const totalSize = req.totalSize && req.totalSize > 0 ? req.totalSize : 1000;
|
|
199
|
+
let beginTime = req.beginTime ?? -1;
|
|
200
|
+
let endTime = req.endTime ?? -1;
|
|
201
|
+
if (beginTime === 0)
|
|
202
|
+
beginTime = -1;
|
|
203
|
+
if (endTime === 0)
|
|
204
|
+
endTime = -1;
|
|
205
|
+
const acc = [];
|
|
206
|
+
while (acc.length < totalSize) {
|
|
207
|
+
const sub = {
|
|
208
|
+
symbols: req.symbol ? [req.symbol] : undefined,
|
|
209
|
+
period: req.period,
|
|
210
|
+
right: req.right,
|
|
211
|
+
beginTime,
|
|
212
|
+
endTime,
|
|
213
|
+
limit: pageSize,
|
|
214
|
+
tradeSession: req.tradeSession,
|
|
215
|
+
lang: req.lang,
|
|
216
|
+
};
|
|
217
|
+
const pageOut = await this.callInto('kline', sub);
|
|
218
|
+
if (!pageOut || pageOut.length === 0 || !pageOut[0].items || pageOut[0].items.length === 0) {
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
const items = pageOut[0].items;
|
|
222
|
+
acc.push(...items);
|
|
223
|
+
if (items.length < pageSize)
|
|
224
|
+
break;
|
|
225
|
+
// next page endTime = oldest bar time - 1
|
|
226
|
+
let oldest = items[0].time;
|
|
227
|
+
for (const it of items) {
|
|
228
|
+
if (it.time < oldest)
|
|
229
|
+
oldest = it.time;
|
|
230
|
+
}
|
|
231
|
+
endTime = oldest - 1;
|
|
232
|
+
}
|
|
233
|
+
return acc;
|
|
234
|
+
}
|
|
235
|
+
/** Historical intraday timeline. wire: history_timeline */
|
|
236
|
+
async getTimelineHistory(req) {
|
|
237
|
+
return this.callInto('history_timeline', req);
|
|
238
|
+
}
|
|
239
|
+
/** Trade rank (top movers / volume). wire: trade_rank */
|
|
240
|
+
async getTradeRank(req) {
|
|
241
|
+
return this.callInto('trade_rank', req);
|
|
242
|
+
}
|
|
243
|
+
/** Short interest / shortable. wire: quote_shortable_stocks */
|
|
244
|
+
async getShortInterest(req) {
|
|
245
|
+
return this.callInto('quote_shortable_stocks', req);
|
|
246
|
+
}
|
|
247
|
+
/** Broker queue. wire: stock_broker */
|
|
248
|
+
async getStockBroker(req) {
|
|
249
|
+
return this.callInto('stock_broker', req);
|
|
250
|
+
}
|
|
251
|
+
/** Stock fundamentals (server returns grouped map). wire: stock_fundamental */
|
|
252
|
+
async getStockFundamental(req) {
|
|
253
|
+
const out = await this.callInto('stock_fundamental', req);
|
|
254
|
+
return out ?? {};
|
|
255
|
+
}
|
|
256
|
+
/** Stock industry classification (array). wire: stock_industry */
|
|
257
|
+
async getStockIndustry(req) {
|
|
258
|
+
return this.callInto('stock_industry', req);
|
|
259
|
+
}
|
|
260
|
+
/** Quote permission detail. wire: get_quote_permission */
|
|
261
|
+
async getQuotePermission(req) {
|
|
262
|
+
return this.callInto('get_quote_permission', req);
|
|
263
|
+
}
|
|
264
|
+
/** K-line quota usage. wire: kline_quota */
|
|
265
|
+
async getKlineQuota(req) {
|
|
266
|
+
return this.callInto('kline_quota', req);
|
|
267
|
+
}
|
|
268
|
+
// ==========================================================================
|
|
269
|
+
// Batch 4: option / future extensions
|
|
270
|
+
// ==========================================================================
|
|
271
|
+
/** Option K-line. wire: option_kline (v2.0) */
|
|
272
|
+
async getOptionBars(req) {
|
|
273
|
+
return this.callInto('option_kline', req, '2.0');
|
|
274
|
+
}
|
|
275
|
+
/** Option tick trades. wire: option_trade_tick */
|
|
276
|
+
async getOptionTradeTicks(req) {
|
|
277
|
+
return this.callInto('option_trade_tick', req);
|
|
278
|
+
}
|
|
279
|
+
/** Option intraday timeline. wire: option_timeline */
|
|
280
|
+
async getOptionTimeline(req) {
|
|
281
|
+
return this.callInto('option_timeline', req);
|
|
282
|
+
}
|
|
283
|
+
/** Option depth. wire: option_depth */
|
|
284
|
+
async getOptionDepth(req) {
|
|
285
|
+
return this.callInto('option_depth', req);
|
|
286
|
+
}
|
|
287
|
+
/** Available option symbols. wire: option_symbol */
|
|
288
|
+
async getOptionSymbols(req) {
|
|
289
|
+
return this.callInto('option_symbol', req);
|
|
290
|
+
}
|
|
291
|
+
/** Option analysis (volatility). wire: option_analysis */
|
|
292
|
+
async getOptionAnalysis(req) {
|
|
293
|
+
return this.callInto('option_analysis', req);
|
|
294
|
+
}
|
|
295
|
+
/** Single futures contract by code. wire: future_contract_by_contract_code */
|
|
296
|
+
async getFutureContract(req) {
|
|
297
|
+
return this.callIntoListOrObject('future_contract_by_contract_code', req);
|
|
298
|
+
}
|
|
299
|
+
/** All futures contracts. wire: future_contracts */
|
|
300
|
+
async getAllFutureContracts(req) {
|
|
301
|
+
return this.callInto('future_contracts', req);
|
|
302
|
+
}
|
|
303
|
+
/** Current main contract. wire: future_current_contract */
|
|
304
|
+
async getCurrentFutureContract(req) {
|
|
305
|
+
return this.callInto('future_current_contract', req);
|
|
306
|
+
}
|
|
307
|
+
/** Continuous main contracts. wire: future_continuous_contracts */
|
|
308
|
+
async getFutureContinuousContracts(req) {
|
|
309
|
+
return this.callIntoListOrObject('future_continuous_contracts', req);
|
|
310
|
+
}
|
|
311
|
+
/** Historical main contracts. wire: future_main_contract */
|
|
312
|
+
async getFutureHistoryMainContract(req) {
|
|
313
|
+
return this.callInto('future_main_contract', req);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Futures K-line (full request with index pagination). wire: future_kline
|
|
317
|
+
* begin_time / end_time default to -1 when unset (server requires them present).
|
|
318
|
+
*/
|
|
319
|
+
async getFutureBars(req) {
|
|
320
|
+
const body = {
|
|
321
|
+
...req,
|
|
322
|
+
beginTime: req.beginTime ?? -1,
|
|
323
|
+
endTime: req.endTime ?? -1,
|
|
324
|
+
};
|
|
325
|
+
return this.callInto('future_kline', body);
|
|
326
|
+
}
|
|
327
|
+
/** Client-side paginated futures K-line fetch. */
|
|
328
|
+
async getFutureBarsByPage(req) {
|
|
329
|
+
const pageSize = req.pageSize && req.pageSize > 0 ? req.pageSize : 200;
|
|
330
|
+
const totalSize = req.totalSize && req.totalSize > 0 ? req.totalSize : 1000;
|
|
331
|
+
let beginTime = req.beginTime ?? -1;
|
|
332
|
+
let endTime = req.endTime ?? -1;
|
|
333
|
+
if (beginTime === 0)
|
|
334
|
+
beginTime = -1;
|
|
335
|
+
if (endTime === 0)
|
|
336
|
+
endTime = -1;
|
|
337
|
+
const acc = [];
|
|
338
|
+
while (acc.length < totalSize) {
|
|
339
|
+
const sub = {
|
|
340
|
+
contractCode: req.contractCode,
|
|
341
|
+
period: req.period,
|
|
342
|
+
beginTime,
|
|
343
|
+
endTime,
|
|
344
|
+
limit: pageSize,
|
|
345
|
+
lang: req.lang,
|
|
346
|
+
};
|
|
347
|
+
const pageOut = await this.callInto('future_kline', sub);
|
|
348
|
+
if (!pageOut || pageOut.length === 0 || !pageOut[0].items || pageOut[0].items.length === 0) {
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
const items = pageOut[0].items;
|
|
352
|
+
acc.push(...items);
|
|
353
|
+
if (items.length < pageSize)
|
|
354
|
+
break;
|
|
355
|
+
let oldest = items[0].time;
|
|
356
|
+
for (const it of items) {
|
|
357
|
+
if (it.time < oldest)
|
|
358
|
+
oldest = it.time;
|
|
359
|
+
}
|
|
360
|
+
endTime = oldest - 1;
|
|
361
|
+
}
|
|
362
|
+
return acc;
|
|
363
|
+
}
|
|
364
|
+
/** Futures tick trades. wire: future_tick (API v3.0)
|
|
365
|
+
* Server returns {contractCode, items:[...]}; unwrap items and backfill contractCode.
|
|
366
|
+
* endIndex defaults to 30 when not set (consistent with Python/Go SDK). */
|
|
367
|
+
async getFutureTradeTicks(req) {
|
|
368
|
+
if (!req.endIndex)
|
|
369
|
+
req.endIndex = 30;
|
|
370
|
+
const wrap = await this.callInto('future_tick', req, '3.0');
|
|
371
|
+
const items = wrap?.items ?? [];
|
|
372
|
+
if (wrap?.contractCode) {
|
|
373
|
+
for (const item of items) {
|
|
374
|
+
if (!item.contractCode)
|
|
375
|
+
item.contractCode = wrap.contractCode;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return items;
|
|
379
|
+
}
|
|
380
|
+
/** Futures depth. wire: future_depth */
|
|
381
|
+
async getFutureDepth(req) {
|
|
382
|
+
return this.callInto('future_depth', req);
|
|
383
|
+
}
|
|
384
|
+
/** Futures trading times (single-object response). wire: future_trading_date */
|
|
385
|
+
async getFutureTradingTimes(req) {
|
|
386
|
+
return this.callInto('future_trading_date', req);
|
|
387
|
+
}
|
|
388
|
+
// ==========================================================================
|
|
389
|
+
// Batch 5: fund / warrant / industry / corporate / financial / calendar
|
|
390
|
+
// ==========================================================================
|
|
391
|
+
/** Fund symbols. wire: fund_all_symbols */
|
|
392
|
+
async getFundSymbols(req) {
|
|
393
|
+
return this.callInto('fund_all_symbols', req);
|
|
394
|
+
}
|
|
395
|
+
/** Fund contracts. wire: fund_contracts */
|
|
396
|
+
async getFundContracts(req) {
|
|
397
|
+
return this.callInto('fund_contracts', req);
|
|
398
|
+
}
|
|
399
|
+
/** Fund real-time NAV. wire: fund_quote */
|
|
400
|
+
async getFundQuote(req) {
|
|
401
|
+
return this.callInto('fund_quote', req);
|
|
402
|
+
}
|
|
403
|
+
/** Fund historical NAV. wire: fund_history_quote */
|
|
404
|
+
async getFundHistoryQuote(req) {
|
|
405
|
+
return this.callInto('fund_history_quote', req);
|
|
406
|
+
}
|
|
407
|
+
/** Warrant briefs. wire: warrant_briefs */
|
|
408
|
+
async getWarrantBriefs(req) {
|
|
409
|
+
return this.callInto('warrant_briefs', req);
|
|
410
|
+
}
|
|
411
|
+
/** Warrant filter (paged). wire: warrant_filter */
|
|
412
|
+
async getWarrantFilter(req) {
|
|
413
|
+
return this.callInto('warrant_filter', req);
|
|
414
|
+
}
|
|
415
|
+
/** Industry list. wire: industry_list */
|
|
416
|
+
async getIndustryList(req) {
|
|
417
|
+
return this.callInto('industry_list', req);
|
|
418
|
+
}
|
|
419
|
+
/** Stocks inside an industry. wire: industry_stock_list */
|
|
420
|
+
async getIndustryStocks(req) {
|
|
421
|
+
return this.callInto('industry_stock_list', req);
|
|
422
|
+
}
|
|
423
|
+
/** Corporate split (flattened). wire: corporate_action (action_type=split) */
|
|
424
|
+
async getCorporateSplit(req) {
|
|
425
|
+
const body = { ...req, actionType: 'split' };
|
|
426
|
+
const grouped = await this.callInto('corporate_action', body);
|
|
427
|
+
if (!grouped || typeof grouped !== 'object')
|
|
428
|
+
return [];
|
|
429
|
+
return Object.values(grouped).flat();
|
|
430
|
+
}
|
|
431
|
+
/** Corporate dividend (flattened). wire: corporate_action (action_type=dividend) */
|
|
432
|
+
async getCorporateDividend(req) {
|
|
433
|
+
const body = { ...req, actionType: 'dividend' };
|
|
434
|
+
const grouped = await this.callInto('corporate_action', body);
|
|
435
|
+
if (!grouped || typeof grouped !== 'object')
|
|
436
|
+
return [];
|
|
437
|
+
return Object.values(grouped).flat();
|
|
438
|
+
}
|
|
439
|
+
/** Corporate earnings calendar (flattened). wire: corporate_action (action_type=earning) */
|
|
440
|
+
async getCorporateEarningsCalendar(req) {
|
|
441
|
+
const body = { ...req, actionType: 'earning' };
|
|
442
|
+
const grouped = await this.callInto('corporate_action', body);
|
|
443
|
+
if (!grouped || typeof grouped !== 'object')
|
|
444
|
+
return [];
|
|
445
|
+
return Object.values(grouped).flat();
|
|
446
|
+
}
|
|
447
|
+
/** Financial currency per symbol. wire: financial_currency */
|
|
448
|
+
async getFinancialCurrency(req) {
|
|
449
|
+
return this.callInto('financial_currency', req);
|
|
450
|
+
}
|
|
451
|
+
/** FX rates. wire: financial_exchange_rate */
|
|
452
|
+
async getFinancialExchangeRate(req) {
|
|
453
|
+
return this.callInto('financial_exchange_rate', req);
|
|
454
|
+
}
|
|
455
|
+
/** Trading calendar. wire: trading_calendar */
|
|
456
|
+
async getTradingCalendar(req) {
|
|
457
|
+
return this.callInto('trading_calendar', req);
|
|
458
|
+
}
|
|
459
|
+
/** Available market-scanner tags. wire: market_scanner_tags */
|
|
460
|
+
async getMarketScannerTags(req) {
|
|
461
|
+
return this.callInto('market_scanner_tags', req);
|
|
462
|
+
}
|
|
463
|
+
/** Overnight quote. wire: quote_overnight */
|
|
464
|
+
async getQuoteOvernight(req) {
|
|
465
|
+
return this.callInto('quote_overnight', req);
|
|
466
|
+
}
|
|
143
467
|
}
|
|
144
468
|
exports.QuoteClient = QuoteClient;
|
|
@@ -3,6 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TradeClient = void 0;
|
|
4
4
|
const api_request_1 = require("../client/api-request");
|
|
5
5
|
const api_response_1 = require("../client/api-response");
|
|
6
|
+
const order_status_1 = require("../model/order-status");
|
|
7
|
+
/** Normalize `Order.status` field in-place (handles int → string). */
|
|
8
|
+
function normalizeOrderInPlace(o) {
|
|
9
|
+
if (o && o.status !== undefined && o.status !== null) {
|
|
10
|
+
o.status = (0, order_status_1.normalizeOrderStatus)(o.status);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Normalize every Order in a list in-place. */
|
|
14
|
+
function normalizeOrders(orders) {
|
|
15
|
+
for (const o of orders)
|
|
16
|
+
normalizeOrderInPlace(o);
|
|
17
|
+
return orders;
|
|
18
|
+
}
|
|
19
|
+
/** Shallow-copy a request object and fill account if empty. */
|
|
20
|
+
function withAccount(req, account) {
|
|
21
|
+
const r = { ...(req ?? {}) };
|
|
22
|
+
if (!r.account)
|
|
23
|
+
r.account = account;
|
|
24
|
+
return r;
|
|
25
|
+
}
|
|
6
26
|
/** Trading client wrapping all trade-related APIs. */
|
|
7
27
|
class TradeClient {
|
|
8
28
|
constructor(httpClient, account) {
|
|
@@ -54,40 +74,199 @@ class TradeClient {
|
|
|
54
74
|
async cancelOrder(id) {
|
|
55
75
|
return this.callInto('cancel_order', { account: this.account, id });
|
|
56
76
|
}
|
|
57
|
-
// === Order queries ===
|
|
58
|
-
|
|
59
|
-
|
|
77
|
+
// === Order queries (BREAKING v0.4.0) ===
|
|
78
|
+
/**
|
|
79
|
+
* Query all historical orders. v0.4.0: optional OrdersRequest for filtering.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* // Default (unfiltered)
|
|
83
|
+
* await tc.getOrders();
|
|
84
|
+
* // Filter by status
|
|
85
|
+
* await tc.getOrders({ states: ['Filled'], limit: 100 });
|
|
86
|
+
*/
|
|
87
|
+
async getOrders(req) {
|
|
88
|
+
return normalizeOrders(await this.callIntoItems('orders', withAccount(req, this.account)));
|
|
60
89
|
}
|
|
61
|
-
|
|
62
|
-
|
|
90
|
+
/** Query active (open) orders. v0.4.0: supports ParentId to filter attached legs. */
|
|
91
|
+
async getActiveOrders(req) {
|
|
92
|
+
return normalizeOrders(await this.callIntoItems('active_orders', withAccount(req, this.account)));
|
|
63
93
|
}
|
|
64
|
-
|
|
65
|
-
|
|
94
|
+
/** Query inactive/cancelled orders. */
|
|
95
|
+
async getInactiveOrders(req) {
|
|
96
|
+
return normalizeOrders(await this.callIntoItems('inactive_orders', withAccount(req, this.account)));
|
|
66
97
|
}
|
|
67
98
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
99
|
+
* Query filled orders. v0.4.0 BREAKING: signature changed from positional
|
|
100
|
+
* (startDateMs, endDateMs) to OrdersRequest object.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* // Last 30 days
|
|
104
|
+
* const now = Date.now();
|
|
105
|
+
* await tc.getFilledOrders({ startDate: now - 30*24*3600*1000, endDate: now });
|
|
70
106
|
*/
|
|
71
|
-
async getFilledOrders(
|
|
72
|
-
return this.callIntoItems('filled_orders',
|
|
73
|
-
account: this.account, startDate: startDateMs, endDate: endDateMs,
|
|
74
|
-
});
|
|
107
|
+
async getFilledOrders(req) {
|
|
108
|
+
return normalizeOrders(await this.callIntoItems('filled_orders', withAccount(req, this.account)));
|
|
75
109
|
}
|
|
76
|
-
/**
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Get a single order by ID (v0.4.0 new).
|
|
112
|
+
* Wire method: `orders` with id/order_id param; server returns a single Order object
|
|
113
|
+
* (not `{items:[]}` envelope).
|
|
114
|
+
*
|
|
115
|
+
* Returns `undefined` if no match.
|
|
116
|
+
*/
|
|
117
|
+
async getOrder(req) {
|
|
118
|
+
const merged = withAccount(req, this.account);
|
|
119
|
+
const out = await this.callInto('orders', merged);
|
|
120
|
+
if (!out || (!out.id && !out.orderId))
|
|
121
|
+
return undefined;
|
|
122
|
+
normalizeOrderInPlace(out);
|
|
123
|
+
return out;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Query order transaction details. v0.4.0 BREAKING: all fields now optional
|
|
127
|
+
* (previously symbol/secType required).
|
|
128
|
+
*/
|
|
129
|
+
async getOrderTransactions(req) {
|
|
130
|
+
return this.callIntoItems('order_transactions', withAccount(req, this.account));
|
|
131
|
+
}
|
|
132
|
+
// === Positions & assets (BREAKING v0.4.0) ===
|
|
133
|
+
/** Query positions. v0.4.0: supports Symbol / SecType / Currency / Market filters. */
|
|
134
|
+
async getPositions(req) {
|
|
135
|
+
return this.callIntoItems('positions', withAccount(req, this.account));
|
|
136
|
+
}
|
|
137
|
+
/** Query assets. v0.4.0: supports sub-account list and aggregation options. */
|
|
138
|
+
async getAssets(req) {
|
|
139
|
+
return this.callIntoItems('assets', withAccount(req, this.account));
|
|
140
|
+
}
|
|
141
|
+
/** Query prime assets. v0.4.0: takes AssetsRequest for filters. */
|
|
142
|
+
async getPrimeAssets(req) {
|
|
143
|
+
return this.callInto('prime_assets', withAccount(req, this.account));
|
|
144
|
+
}
|
|
145
|
+
// ===== v0.4.0 NEW: Account management =====
|
|
146
|
+
/** Query managed sub-accounts (institutional). */
|
|
147
|
+
async getManagedAccounts(req) {
|
|
148
|
+
return this.callIntoItems('accounts', withAccount(req, this.account));
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Query derivative contracts list. Same wire as getQuoteContract but accepts
|
|
152
|
+
* full request struct. Python: `get_derivative_contracts`.
|
|
153
|
+
*/
|
|
154
|
+
async getDerivativeContracts(req) {
|
|
155
|
+
return this.callIntoItems('quote_contract', withAccount(req, this.account));
|
|
156
|
+
}
|
|
157
|
+
// ===== v0.4.0 NEW: Asset analytics =====
|
|
158
|
+
/** Daily P&L / net-value / holding-value analytics. */
|
|
159
|
+
async getAnalyticsAsset(req) {
|
|
160
|
+
return this.callIntoItems('analytics_asset', withAccount(req, this.account));
|
|
161
|
+
}
|
|
162
|
+
/** Aggregate assets (prime) by base currency. */
|
|
163
|
+
async getAggregateAssets(req) {
|
|
164
|
+
return this.callInto('aggregate_assets', withAccount(req, this.account));
|
|
165
|
+
}
|
|
166
|
+
/** Estimate tradable quantity given order parameters. */
|
|
167
|
+
async getEstimateTradableQuantity(req) {
|
|
168
|
+
return this.callInto('estimate_tradable_quantity', withAccount(req, this.account));
|
|
169
|
+
}
|
|
170
|
+
// ===== v0.4.0 NEW: Forex =====
|
|
171
|
+
/** Place forex order (sub-account base-currency swap). */
|
|
172
|
+
async placeForexOrder(req) {
|
|
173
|
+
return this.callInto('place_forex_order', withAccount(req, this.account));
|
|
174
|
+
}
|
|
175
|
+
// ===== v0.4.0 NEW: Segment fund transfer =====
|
|
176
|
+
/** Query amount available for inter-segment transfer. Returns array. */
|
|
177
|
+
async getSegmentFundAvailable(req) {
|
|
178
|
+
return this.callInto('segment_fund_available', withAccount(req, this.account));
|
|
179
|
+
}
|
|
180
|
+
/** Query segment fund transfer history. Server returns plain array (no items wrapper). */
|
|
181
|
+
async getSegmentFundHistory(req) {
|
|
182
|
+
return this.callInto('segment_fund_history', withAccount(req, this.account));
|
|
183
|
+
}
|
|
184
|
+
/** Execute an inter-segment fund transfer. */
|
|
185
|
+
async transferSegmentFund(req) {
|
|
186
|
+
return this.callInto('transfer_segment_fund', withAccount(req, this.account));
|
|
187
|
+
}
|
|
188
|
+
/** Cancel a pending inter-segment transfer. */
|
|
189
|
+
async cancelSegmentFund(req) {
|
|
190
|
+
return this.callInto('cancel_segment_fund', withAccount(req, this.account));
|
|
191
|
+
}
|
|
192
|
+
// ===== v0.4.0 NEW: Fund details / history =====
|
|
193
|
+
/** Fund-movement details (by segment / currency / fund-type). */
|
|
194
|
+
async getFundDetails(req) {
|
|
195
|
+
return this.callIntoItems('fund_details', withAccount(req, this.account));
|
|
196
|
+
}
|
|
197
|
+
/** Funding history (wire method: `transfer_fund`).
|
|
198
|
+
* Server returns bare list (no items wrapper). */
|
|
199
|
+
async getFundingHistory(req) {
|
|
200
|
+
return this.callInto('transfer_fund', withAccount(req, this.account));
|
|
201
|
+
}
|
|
202
|
+
// ===== v0.4.0 NEW: Internal / external position transfer =====
|
|
203
|
+
/**
|
|
204
|
+
* Internal position transfer (cross sub-account).
|
|
205
|
+
* @note Uses `fromAccount` / `toAccount` (not `account`).
|
|
206
|
+
*/
|
|
207
|
+
async transferPosition(req) {
|
|
208
|
+
const merged = { ...req };
|
|
209
|
+
if (!merged.fromAccount)
|
|
210
|
+
merged.fromAccount = this.account;
|
|
211
|
+
return this.callInto('position_transfer', merged);
|
|
212
|
+
}
|
|
213
|
+
/** Query internal position transfer records. Uses `accountId` (wire: `account_id`). */
|
|
214
|
+
async getPositionTransferRecords(req) {
|
|
215
|
+
const merged = { ...req };
|
|
216
|
+
if (!merged.accountId)
|
|
217
|
+
merged.accountId = this.account;
|
|
218
|
+
return this.callIntoItems('position_transfer_records', merged);
|
|
219
|
+
}
|
|
220
|
+
/** Query single internal position transfer detail by ID. */
|
|
221
|
+
async getPositionTransferDetail(req) {
|
|
222
|
+
const merged = { ...req };
|
|
223
|
+
if (!merged.accountId)
|
|
224
|
+
merged.accountId = this.account;
|
|
225
|
+
return this.callInto('position_transfer_detail', merged);
|
|
226
|
+
}
|
|
227
|
+
/** Query external position transfer records (DWAC / FOP / etc.). */
|
|
228
|
+
async getPositionTransferExternalRecords(req) {
|
|
229
|
+
const merged = { ...req };
|
|
230
|
+
if (!merged.accountId)
|
|
231
|
+
merged.accountId = this.account;
|
|
232
|
+
return this.callIntoItems('position_transfer_external_records', merged);
|
|
233
|
+
}
|
|
234
|
+
/** 行权检验:预估行权/作废后正股持仓变化 (wire: option_exercise_check) */
|
|
235
|
+
async checkOptionExercise(req) {
|
|
236
|
+
const merged = { ...req };
|
|
237
|
+
if (!merged.account)
|
|
238
|
+
merged.account = this.account;
|
|
239
|
+
return this.callInto('option_exercise_check', merged);
|
|
240
|
+
}
|
|
241
|
+
/** 查询可行权持仓列表 (wire: option_exercise_position) */
|
|
242
|
+
async getOptionExercisePositions(req) {
|
|
243
|
+
const merged = { ...req };
|
|
244
|
+
if (!merged.account)
|
|
245
|
+
merged.account = this.account;
|
|
246
|
+
return this.callInto('option_exercise_position', merged);
|
|
81
247
|
}
|
|
82
|
-
|
|
83
|
-
async
|
|
84
|
-
|
|
248
|
+
/** 提交行权/作废申请 (wire: option_exercise_submit) */
|
|
249
|
+
async submitOptionExercise(req) {
|
|
250
|
+
const merged = { ...req };
|
|
251
|
+
if (!merged.account)
|
|
252
|
+
merged.account = this.account;
|
|
253
|
+
const result = await this.callInto('option_exercise_submit', merged);
|
|
254
|
+
return result ?? false;
|
|
85
255
|
}
|
|
86
|
-
|
|
87
|
-
|
|
256
|
+
/** 分页查询行权记录 (wire: option_exercise_record) */
|
|
257
|
+
async getOptionExerciseRecords(req) {
|
|
258
|
+
const merged = { ...req };
|
|
259
|
+
if (!merged.account)
|
|
260
|
+
merged.account = this.account;
|
|
261
|
+
return this.callInto('option_exercise_record', merged);
|
|
88
262
|
}
|
|
89
|
-
|
|
90
|
-
|
|
263
|
+
/** 撤销行权申请 (wire: option_exercise_cancel) */
|
|
264
|
+
async cancelOptionExercise(req) {
|
|
265
|
+
const merged = { ...req };
|
|
266
|
+
if (!merged.account)
|
|
267
|
+
merged.account = this.account;
|
|
268
|
+
const result = await this.callInto('option_exercise_cancel', merged);
|
|
269
|
+
return result ?? false;
|
|
91
270
|
}
|
|
92
271
|
}
|
|
93
272
|
exports.TradeClient = TradeClient;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Requests use camelCase parameters in TypeScript (idiomatic), but the
|
|
5
5
|
* server wire format is snake_case, so we convert keys before serializing.
|
|
6
6
|
*/
|
|
7
|
-
import { keysToSnakeCase } from './case-convert';
|
|
7
|
+
import { keysToSnakeCase } from './case-convert.js';
|
|
8
8
|
/**
|
|
9
9
|
* Create an API request, serializing business parameters to JSON as bizContent.
|
|
10
10
|
* camelCase keys are automatically converted to snake_case to match the server.
|
|
@@ -13,7 +13,9 @@ export function camelToSnake(key) {
|
|
|
13
13
|
/**
|
|
14
14
|
* Recursively convert all object keys from camelCase to snake_case.
|
|
15
15
|
* Preserves arrays, primitives, and Date/null/undefined.
|
|
16
|
-
*
|
|
16
|
+
*
|
|
17
|
+
* Note: camelToSnake is idempotent for pure snake_case keys (no uppercase
|
|
18
|
+
* letters → no replacements), so no pre-check is needed.
|
|
17
19
|
*/
|
|
18
20
|
export function keysToSnakeCase(value) {
|
|
19
21
|
if (Array.isArray(value)) {
|
|
@@ -22,8 +24,7 @@ export function keysToSnakeCase(value) {
|
|
|
22
24
|
if (value && typeof value === 'object' && value.constructor === Object) {
|
|
23
25
|
const out = {};
|
|
24
26
|
for (const [k, v] of Object.entries(value)) {
|
|
25
|
-
|
|
26
|
-
out[newKey] = keysToSnakeCase(v);
|
|
27
|
+
out[camelToSnake(k)] = keysToSnakeCase(v);
|
|
27
28
|
}
|
|
28
29
|
return out;
|
|
29
30
|
}
|