@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.
- package/README.md +475 -104
- package/dist/cjs/client/api-request.js +16 -10
- package/dist/cjs/client/api-response.js +23 -3
- package/dist/cjs/client/case-convert.js +35 -0
- package/dist/cjs/client/http-client.js +47 -21
- package/dist/cjs/client/index.js +6 -2
- package/dist/cjs/config/client-config.js +130 -49
- package/dist/cjs/config/domain.js +21 -2
- package/dist/cjs/config/index.js +3 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/model/contract.js +1 -2
- package/dist/cjs/model/enums.js +89 -7
- package/dist/cjs/model/order-helpers.js +9 -9
- package/dist/cjs/model/order-status.js +46 -0
- package/dist/cjs/model/order.js +5 -2
- package/dist/cjs/model/position.js +1 -2
- package/dist/cjs/model/quote-requests.js +11 -0
- package/dist/cjs/model/quote.js +7 -0
- package/dist/cjs/model/trade-requests.js +13 -0
- package/dist/cjs/model/trade.js +2 -0
- package/dist/cjs/push/index.js +6 -3
- package/dist/cjs/push/pb/AssetData.js +208 -0
- package/dist/cjs/push/pb/KlineData.js +184 -0
- package/dist/cjs/push/pb/OptionTopData.js +427 -0
- package/dist/cjs/push/pb/OrderStatusData.js +592 -0
- package/dist/cjs/push/pb/OrderTransactionData.js +256 -0
- package/dist/cjs/push/pb/PositionData.js +316 -0
- package/dist/cjs/push/pb/PushData.js +219 -0
- package/dist/cjs/push/pb/QuoteBBOData.js +160 -0
- package/dist/cjs/push/pb/QuoteBasicData.js +329 -0
- package/dist/cjs/push/pb/QuoteData.js +507 -0
- package/dist/cjs/push/pb/QuoteDepthData.js +220 -0
- package/dist/cjs/push/pb/Request.js +278 -0
- package/dist/cjs/push/pb/Response.js +97 -0
- package/dist/cjs/push/pb/SocketCommon.js +86 -0
- package/dist/cjs/push/pb/StockTopData.js +199 -0
- package/dist/cjs/push/pb/TickData.js +202 -0
- package/dist/cjs/push/pb/TradeTickData.js +308 -0
- package/dist/cjs/push/pb/index.js +49 -0
- package/dist/cjs/push/proto-message.js +135 -0
- package/dist/cjs/push/push-client.js +361 -163
- package/dist/cjs/push/push-message.js +8 -60
- package/dist/cjs/push/varint.js +76 -0
- package/dist/cjs/quote/index.js +3 -2
- package/dist/cjs/quote/quote-client.js +440 -94
- package/dist/cjs/signer/signer.js +10 -10
- package/dist/cjs/trade/trade-client.js +197 -62
- package/dist/esm/client/api-request.js +14 -8
- package/dist/esm/client/api-response.js +22 -3
- package/dist/esm/client/case-convert.js +31 -0
- package/dist/esm/client/http-client.js +48 -22
- package/dist/esm/client/index.js +3 -2
- package/dist/esm/config/client-config.js +131 -51
- package/dist/esm/config/domain.js +20 -2
- package/dist/esm/config/index.js +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/model/contract.js +1 -2
- package/dist/esm/model/enums.js +87 -6
- package/dist/esm/model/order-helpers.js +9 -9
- package/dist/esm/model/order-status.js +43 -0
- package/dist/esm/model/order.js +5 -2
- package/dist/esm/model/position.js +1 -2
- package/dist/esm/model/quote-requests.js +10 -0
- package/dist/esm/model/quote.js +6 -0
- package/dist/esm/model/trade-requests.js +12 -0
- package/dist/esm/model/trade.js +1 -0
- package/dist/esm/push/index.js +4 -2
- package/dist/esm/push/pb/AssetData.js +205 -0
- package/dist/esm/push/pb/KlineData.js +181 -0
- package/dist/esm/push/pb/OptionTopData.js +424 -0
- package/dist/esm/push/pb/OrderStatusData.js +589 -0
- package/dist/esm/push/pb/OrderTransactionData.js +253 -0
- package/dist/esm/push/pb/PositionData.js +313 -0
- package/dist/esm/push/pb/PushData.js +216 -0
- package/dist/esm/push/pb/QuoteBBOData.js +157 -0
- package/dist/esm/push/pb/QuoteBasicData.js +326 -0
- package/dist/esm/push/pb/QuoteData.js +504 -0
- package/dist/esm/push/pb/QuoteDepthData.js +217 -0
- package/dist/esm/push/pb/Request.js +275 -0
- package/dist/esm/push/pb/Response.js +94 -0
- package/dist/esm/push/pb/SocketCommon.js +83 -0
- package/dist/esm/push/pb/StockTopData.js +196 -0
- package/dist/esm/push/pb/TickData.js +199 -0
- package/dist/esm/push/pb/TradeTickData.js +305 -0
- package/dist/esm/push/pb/index.js +25 -0
- package/dist/esm/push/proto-message.js +127 -0
- package/dist/esm/push/push-client.js +329 -164
- package/dist/esm/push/push-message.js +7 -56
- package/dist/esm/push/varint.js +72 -0
- package/dist/esm/quote/index.js +2 -2
- package/dist/esm/quote/quote-client.js +439 -94
- package/dist/esm/signer/signer.js +10 -10
- package/dist/esm/trade/trade-client.js +197 -62
- package/dist/types/client/api-request.d.ts +12 -11
- package/dist/types/client/api-response.d.ts +15 -7
- package/dist/types/client/case-convert.d.ts +16 -0
- package/dist/types/client/http-client.d.ts +26 -14
- package/dist/types/client/index.d.ts +3 -2
- package/dist/types/config/client-config.d.ts +29 -13
- package/dist/types/config/domain.d.ts +9 -0
- package/dist/types/config/index.d.ts +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/model/contract.d.ts +13 -29
- package/dist/types/model/enums.d.ts +60 -6
- package/dist/types/model/order-helpers.d.ts +21 -20
- package/dist/types/model/order-status.d.ts +14 -0
- package/dist/types/model/order.d.ts +101 -55
- package/dist/types/model/position.d.ts +26 -24
- package/dist/types/model/quote-requests.d.ts +344 -0
- package/dist/types/model/quote.d.ts +572 -0
- package/dist/types/model/trade-requests.d.ts +195 -0
- package/dist/types/model/trade.d.ts +235 -0
- package/dist/types/push/callbacks.d.ts +32 -51
- package/dist/types/push/index.d.ts +5 -3
- package/dist/types/push/pb/AssetData.d.ts +47 -0
- package/dist/types/push/pb/KlineData.d.ts +43 -0
- package/dist/types/push/pb/OptionTopData.d.ts +76 -0
- package/dist/types/push/pb/OrderStatusData.d.ts +100 -0
- package/dist/types/push/pb/OrderTransactionData.d.ts +51 -0
- package/dist/types/push/pb/PositionData.d.ts +63 -0
- package/dist/types/push/pb/PushData.d.ts +46 -0
- package/dist/types/push/pb/QuoteBBOData.d.ts +35 -0
- package/dist/types/push/pb/QuoteBasicData.d.ts +66 -0
- package/dist/types/push/pb/QuoteData.d.ts +94 -0
- package/dist/types/push/pb/QuoteDepthData.d.ts +37 -0
- package/dist/types/push/pb/Request.d.ts +44 -0
- package/dist/types/push/pb/Response.d.ts +30 -0
- package/dist/types/push/pb/SocketCommon.d.ts +64 -0
- package/dist/types/push/pb/StockTopData.d.ts +37 -0
- package/dist/types/push/pb/TickData.d.ts +44 -0
- package/dist/types/push/pb/TradeTickData.d.ts +53 -0
- package/dist/types/push/pb/index.d.ts +39 -0
- package/dist/types/push/proto-message.d.ts +33 -0
- package/dist/types/push/push-client.d.ts +100 -68
- package/dist/types/push/push-message.d.ts +7 -147
- package/dist/types/push/varint.d.ts +23 -0
- package/dist/types/quote/index.d.ts +2 -2
- package/dist/types/quote/quote-client.d.ts +154 -47
- package/dist/types/signer/signer.d.ts +6 -6
- package/dist/types/trade/trade-client.d.ts +106 -38
- package/package.json +11 -6
|
@@ -1,95 +1,230 @@
|
|
|
1
1
|
import { createApiRequest } from '../client/api-request';
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
56
|
-
account: this.account, id,
|
|
57
|
-
});
|
|
72
|
+
return this.callInto('cancel_order', { account: this.account, id });
|
|
58
73
|
}
|
|
59
|
-
// ===
|
|
60
|
-
/**
|
|
61
|
-
|
|
62
|
-
|
|
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
|
|
66
|
-
return this.
|
|
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
|
|
70
|
-
return this.
|
|
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
|
-
|
|
74
|
-
|
|
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
|
-
|
|
79
|
-
|
|
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
|
-
|
|
83
|
-
|
|
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
|
-
|
|
87
|
-
|
|
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
|
|
91
|
-
return this.
|
|
92
|
-
|
|
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
|
|
3
|
+
/** API method name (e.g. "market_state", "place_order") */
|
|
7
4
|
method: string;
|
|
8
|
-
/**
|
|
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
|
-
*
|
|
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 -
|
|
16
|
-
* @
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
14
|
-
*
|
|
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
|
-
*
|
|
5
|
-
*
|
|
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
|
|
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
|
-
|
|
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
|
-
*
|
|
31
|
+
* Send HTTP POST request
|
|
28
32
|
*/
|
|
29
33
|
private doHttpPost;
|
|
30
34
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
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
|
-
*
|
|
40
|
+
* General-purpose API call method.
|
|
37
41
|
*
|
|
38
|
-
* @param apiMethod - API
|
|
39
|
-
* @param requestJson -
|
|
40
|
-
* @returns
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
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
|
|
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
|
|
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';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
}
|