@tigeropenapi/tigeropen 0.5.0 → 0.5.4
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/api-response.js +17 -15
- package/dist/cjs/client/token-methods.js +42 -0
- package/dist/cjs/config/client-config.js +59 -11
- package/dist/cjs/config/config-parser.js +19 -9
- package/dist/cjs/config/index.js +2 -1
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/model/enums.js +4 -0
- package/dist/cjs/model/order-helpers.js +126 -21
- package/dist/cjs/quote/quote-client.js +112 -21
- package/dist/cjs/trade/trade-client.js +74 -16
- package/dist/esm/client/api-response.js +17 -15
- package/dist/esm/client/token-methods.js +37 -0
- package/dist/esm/config/client-config.js +59 -12
- package/dist/esm/config/config-parser.js +19 -9
- package/dist/esm/config/index.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/model/enums.js +4 -0
- package/dist/esm/model/order-helpers.js +119 -20
- package/dist/esm/quote/quote-client.js +79 -21
- package/dist/esm/trade/trade-client.js +41 -16
- package/dist/types/client/api-response.d.ts +6 -5
- package/dist/types/client/token-methods.d.ts +34 -0
- package/dist/types/config/client-config.d.ts +2 -0
- package/dist/types/config/index.d.ts +1 -1
- package/dist/types/index.d.ts +3 -3
- package/dist/types/model/enums.d.ts +5 -1
- package/dist/types/model/order-helpers.d.ts +48 -8
- package/dist/types/model/order.d.ts +52 -1
- package/dist/types/model/quote.d.ts +56 -0
- package/dist/types/model/trade-requests.d.ts +41 -0
- package/dist/types/quote/quote-client.d.ts +31 -8
- package/dist/types/trade/trade-client.d.ts +19 -3
- package/package.json +1 -1
package/dist/esm/config/index.js
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* 配置层导出
|
|
3
3
|
*/
|
|
4
4
|
export { parsePropertiesFile, parsePropertiesString } from './config-parser.js';
|
|
5
|
-
export { createClientConfig, loadPropertiesFile } from './client-config.js';
|
|
5
|
+
export { createClientConfig, loadPropertiesFile, SANDBOX_TIGER_PUBLIC_KEY } from './client-config.js';
|
|
6
6
|
export { TokenManager } from './token-manager.js';
|
|
7
7
|
export { queryDomains, resolveDynamicServerUrl, resolveDynamicQuoteServerUrl } from './domain.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
/** SDK 版本号 */
|
|
18
18
|
export { SDK_VERSION as VERSION } from './version.js';
|
|
19
19
|
// Config
|
|
20
|
-
export { createClientConfig, loadPropertiesFile } from './config/index.js';
|
|
20
|
+
export { createClientConfig, loadPropertiesFile, SANDBOX_TIGER_PUBLIC_KEY } from './config/index.js';
|
|
21
21
|
export { TokenManager } from './config/index.js';
|
|
22
22
|
// Transport
|
|
23
23
|
export { HttpClient } from './client/index.js';
|
package/dist/esm/model/enums.js
CHANGED
|
@@ -146,6 +146,7 @@ export var TimeInForce;
|
|
|
146
146
|
(function (TimeInForce) {
|
|
147
147
|
TimeInForce["DAY"] = "DAY";
|
|
148
148
|
TimeInForce["GTC"] = "GTC";
|
|
149
|
+
TimeInForce["GTD"] = "GTD";
|
|
149
150
|
TimeInForce["OPG"] = "OPG";
|
|
150
151
|
})(TimeInForce || (TimeInForce = {}));
|
|
151
152
|
/** 订单排序字段 */
|
|
@@ -168,6 +169,9 @@ export var CorporateActionType;
|
|
|
168
169
|
CorporateActionType["Split"] = "split";
|
|
169
170
|
CorporateActionType["Dividend"] = "dividend";
|
|
170
171
|
CorporateActionType["Earning"] = "earning";
|
|
172
|
+
CorporateActionType["SymbolChange"] = "symbol_change";
|
|
173
|
+
CorporateActionType["Delisting"] = "delisting";
|
|
174
|
+
CorporateActionType["IPO"] = "ipo";
|
|
171
175
|
})(CorporateActionType || (CorporateActionType = {}));
|
|
172
176
|
/** 行业级别 (1~4 级) */
|
|
173
177
|
export var IndustryLevel;
|
|
@@ -88,26 +88,11 @@ export function algoOrder(account, symbol, secType, action, quantity, limitPrice
|
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
|
-
* Iceberg order
|
|
92
|
-
|
|
93
|
-
export function icebergOrder(account, symbol, secType, action, quantity, limitPrice, displaySize) {
|
|
94
|
-
return {
|
|
95
|
-
account, symbol, secType, action,
|
|
96
|
-
orderType: OrderType.ICEBERG,
|
|
97
|
-
totalQuantity: quantity,
|
|
98
|
-
limitPrice,
|
|
99
|
-
timeInForce: TimeInForce.DAY,
|
|
100
|
-
outsideRth: false,
|
|
101
|
-
displaySize,
|
|
102
|
-
priceType: PriceType.LIMIT_PRICE,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Iceberg order (full params).
|
|
107
|
-
* Pass `priceType` as empty string to use server default (LIMIT_PRICE).
|
|
91
|
+
* Iceberg order. `displaySize` is required; all other parameters are optional.
|
|
92
|
+
* Pass `priceType` as empty string to use the server default (LIMIT_PRICE).
|
|
108
93
|
* Pass `startTime` / `endTime` as 0 to omit the time window.
|
|
109
94
|
*/
|
|
110
|
-
export function
|
|
95
|
+
export function icebergOrder(account, symbol, secType, action, quantity, limitPrice, displaySize, minDisplaySize, checkIntervals, priceType, startTime, endTime) {
|
|
111
96
|
const req = {
|
|
112
97
|
account, symbol, secType, action,
|
|
113
98
|
orderType: OrderType.ICEBERG,
|
|
@@ -116,13 +101,12 @@ export function icebergOrderFull(account, symbol, secType, action, quantity, lim
|
|
|
116
101
|
timeInForce: TimeInForce.DAY,
|
|
117
102
|
outsideRth: false,
|
|
118
103
|
displaySize,
|
|
104
|
+
priceType: priceType || PriceType.LIMIT_PRICE,
|
|
119
105
|
};
|
|
120
106
|
if (minDisplaySize !== undefined && minDisplaySize > 0)
|
|
121
107
|
req.minDisplaySize = minDisplaySize;
|
|
122
108
|
if (checkIntervals !== undefined && checkIntervals > 0)
|
|
123
109
|
req.checkIntervals = checkIntervals;
|
|
124
|
-
if (priceType)
|
|
125
|
-
req.priceType = priceType;
|
|
126
110
|
if (startTime && startTime > 0)
|
|
127
111
|
req.startTime = startTime;
|
|
128
112
|
if (endTime && endTime > 0)
|
|
@@ -133,3 +117,118 @@ export function icebergOrderFull(account, symbol, secType, action, quantity, lim
|
|
|
133
117
|
export function orderLeg(legType, price, timeInForce) {
|
|
134
118
|
return { legType, price, timeInForce };
|
|
135
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Market order by cash amount (instead of quantity).
|
|
122
|
+
* Server uses `isQuantityByAmount=true` + `amount` field.
|
|
123
|
+
*/
|
|
124
|
+
export function marketOrderByAmount(account, symbol, secType, action, amount) {
|
|
125
|
+
return {
|
|
126
|
+
account, symbol, secType, action,
|
|
127
|
+
orderType: OrderType.MKT,
|
|
128
|
+
totalQuantity: 0,
|
|
129
|
+
cashAmount: amount,
|
|
130
|
+
timeInForce: TimeInForce.DAY,
|
|
131
|
+
outsideRth: false,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Limit order by cash amount (instead of quantity).
|
|
136
|
+
*/
|
|
137
|
+
export function limitOrderByAmount(account, symbol, secType, action, amount, limitPrice) {
|
|
138
|
+
return {
|
|
139
|
+
account, symbol, secType, action,
|
|
140
|
+
orderType: OrderType.LMT,
|
|
141
|
+
totalQuantity: 0,
|
|
142
|
+
cashAmount: amount,
|
|
143
|
+
limitPrice,
|
|
144
|
+
timeInForce: TimeInForce.DAY,
|
|
145
|
+
outsideRth: false,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Trailing stop order using a fixed price offset (auxPrice) instead of a percentage.
|
|
150
|
+
* Use `trailOrder()` for percentage-based trailing stops.
|
|
151
|
+
*/
|
|
152
|
+
export function trailOrderByPrice(account, symbol, secType, action, quantity, auxPrice) {
|
|
153
|
+
return {
|
|
154
|
+
account, symbol, secType, action,
|
|
155
|
+
orderType: OrderType.TRAIL,
|
|
156
|
+
totalQuantity: quantity,
|
|
157
|
+
auxPrice,
|
|
158
|
+
timeInForce: TimeInForce.DAY,
|
|
159
|
+
outsideRth: false,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Limit order with attached profit/loss legs (bracket order).
|
|
164
|
+
* At most 2 legs are supported.
|
|
165
|
+
*
|
|
166
|
+
* @param orderLegs - Array of `OrderLegRequest` (use `orderLeg()` helper)
|
|
167
|
+
*/
|
|
168
|
+
export function limitOrderWithLegs(account, symbol, secType, action, quantity, limitPrice, orderLegs) {
|
|
169
|
+
if (orderLegs.length === 0) {
|
|
170
|
+
throw new Error('At least 1 order leg is required for a bracket order');
|
|
171
|
+
}
|
|
172
|
+
if (orderLegs.length > 2) {
|
|
173
|
+
throw new Error('At most 2 order legs are supported');
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
account, symbol, secType, action,
|
|
177
|
+
orderType: OrderType.LMT,
|
|
178
|
+
totalQuantity: quantity,
|
|
179
|
+
limitPrice,
|
|
180
|
+
orderLegs,
|
|
181
|
+
timeInForce: TimeInForce.DAY,
|
|
182
|
+
outsideRth: false,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Multi-leg (combo/MLEG) order for options combos.
|
|
187
|
+
*
|
|
188
|
+
* @param contractLegs - Array of `ContractLegRequest` (use `contractLeg()` helper)
|
|
189
|
+
* @param comboType - e.g. `'MLEG'`
|
|
190
|
+
*/
|
|
191
|
+
export function comboOrder(account, action, quantity, orderType, contractLegs, comboType = 'MLEG', limitPrice, auxPrice, trailingPercent) {
|
|
192
|
+
return {
|
|
193
|
+
account,
|
|
194
|
+
symbol: '', // not used for combo orders
|
|
195
|
+
secType: 'MLEG',
|
|
196
|
+
action,
|
|
197
|
+
orderType,
|
|
198
|
+
totalQuantity: quantity,
|
|
199
|
+
limitPrice,
|
|
200
|
+
auxPrice,
|
|
201
|
+
trailingPercent,
|
|
202
|
+
contractLegs,
|
|
203
|
+
comboType,
|
|
204
|
+
timeInForce: TimeInForce.DAY,
|
|
205
|
+
outsideRth: false,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* OCA (One-Cancels-All) order.
|
|
210
|
+
* Server expects `orderType: 'OCA'` and an `ocaOrders` list.
|
|
211
|
+
*
|
|
212
|
+
* @param ocaOrders - The contained orders (use any order helper to build each)
|
|
213
|
+
*/
|
|
214
|
+
export function ocaOrder(account, symbol, secType, action, quantity, ocaOrders) {
|
|
215
|
+
return {
|
|
216
|
+
account, symbol, secType, action,
|
|
217
|
+
orderType: OrderType.OCA,
|
|
218
|
+
totalQuantity: quantity,
|
|
219
|
+
ocaOrders,
|
|
220
|
+
timeInForce: TimeInForce.DAY,
|
|
221
|
+
outsideRth: false,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Build a single leg for a multi-leg (MLEG / combo) order.
|
|
226
|
+
*
|
|
227
|
+
* @param symbol - Underlying symbol
|
|
228
|
+
* @param secType - Security type (e.g. `'OPT'`)
|
|
229
|
+
* @param action - `'BUY'` or `'SELL'`
|
|
230
|
+
* @param ratio - Number of contracts for this leg
|
|
231
|
+
*/
|
|
232
|
+
export function contractLeg(symbol, secType, action, ratio, expiry, strike, right) {
|
|
233
|
+
return { symbol, secType, action, ratio, expiry, strike, right };
|
|
234
|
+
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { HttpClient } from '../client/http-client.js';
|
|
9
9
|
import { createApiRequest } from '../client/api-request.js';
|
|
10
10
|
import { unmarshalData } from '../client/api-response.js';
|
|
11
|
+
import * as tokenMethods from '../client/token-methods.js';
|
|
11
12
|
/**
|
|
12
13
|
* resolveOptionTimezone returns the timezone string to use for expiry conversion.
|
|
13
14
|
* Explicit tz takes precedence; otherwise infer from symbol (.HK suffix → Asia/Hong_Kong, else America/New_York).
|
|
@@ -90,6 +91,25 @@ export class QuoteClient {
|
|
|
90
91
|
static fromConfig(config) {
|
|
91
92
|
return new QuoteClient(new HttpClient(config, undefined, { useQuoteServerUrl: true }));
|
|
92
93
|
}
|
|
94
|
+
// ── Token management ──────────────────────────────────────────────────────
|
|
95
|
+
/** Call the `user_token_refresh` API and return the new token. Read-only. */
|
|
96
|
+
async queryToken() {
|
|
97
|
+
return tokenMethods.queryToken(this.httpClient);
|
|
98
|
+
}
|
|
99
|
+
/** Refresh the token and update the in-memory config token. */
|
|
100
|
+
async refreshToken(tokenManager) {
|
|
101
|
+
return tokenMethods.refreshToken(this.httpClient, tokenManager);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Start background token auto-refresh. Returns a TokenManager to stop with `tm.stopAutoRefresh()`.
|
|
105
|
+
*
|
|
106
|
+
* @param refreshDurationSecs - Refresh threshold in seconds (minimum 30).
|
|
107
|
+
* @param checkIntervalMs - How often to check, in milliseconds (default 300 000 / 5 min).
|
|
108
|
+
* @param tokenWriter - Optional callback invoked after each successful refresh.
|
|
109
|
+
*/
|
|
110
|
+
startTokenAutoRefresh(refreshDurationSecs, checkIntervalMs, tokenWriter) {
|
|
111
|
+
return tokenMethods.startTokenAutoRefresh(this.httpClient, refreshDurationSecs, checkIntervalMs, tokenWriter);
|
|
112
|
+
}
|
|
93
113
|
async callInto(method, bizParams, version) {
|
|
94
114
|
const request = createApiRequest(method, bizParams, version);
|
|
95
115
|
const response = await this.httpClient.executeRequest(request);
|
|
@@ -151,8 +171,10 @@ export class QuoteClient {
|
|
|
151
171
|
*
|
|
152
172
|
* @param timezone - Optional IANA timezone for expiry conversion (e.g. 'America/New_York').
|
|
153
173
|
* If omitted, defaults to America/New_York for US symbols and Asia/Hong_Kong for .HK symbols.
|
|
174
|
+
* @param returnGreekValue - Whether to return Greeks (delta/gamma/theta/vega/rho).
|
|
175
|
+
* @param optionFilter - Optional filter for in-the-money status, IV range, open interest range, Greeks ranges.
|
|
154
176
|
*/
|
|
155
|
-
async getOptionChain(items, timezone) {
|
|
177
|
+
async getOptionChain(items, timezone, returnGreekValue, optionFilter) {
|
|
156
178
|
const optionBasic = items.map(([symbol, expiry]) => {
|
|
157
179
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(expiry)) {
|
|
158
180
|
throw new Error(`invalid expiry date, expected YYYY-MM-DD: ${expiry}`);
|
|
@@ -161,37 +183,27 @@ export class QuoteClient {
|
|
|
161
183
|
const expiryMs = localMidnightMs(expiry, tz);
|
|
162
184
|
return { symbol, expiry: expiryMs };
|
|
163
185
|
});
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
* If omitted, defaults to America/New_York for US symbols and Asia/Hong_Kong for .HK symbols.
|
|
171
|
-
*/
|
|
172
|
-
async getOptionQuote(identifiers, timezone) {
|
|
173
|
-
const optionBasic = identifiers.map((id) => {
|
|
174
|
-
const p = parseOptionIdentifier(id, timezone);
|
|
175
|
-
return { symbol: p.symbol, expiry: p.expiryMs, right: p.right, strike: p.strike };
|
|
176
|
-
});
|
|
177
|
-
return this.callInto('option_brief', { option_basic: optionBasic }, '2.0');
|
|
178
|
-
}
|
|
179
|
-
/** @deprecated Use getOptionQuote instead. */
|
|
180
|
-
async getOptionBrief(identifiers) {
|
|
181
|
-
return this.getOptionQuote(identifiers);
|
|
186
|
+
const body = { option_basic: optionBasic };
|
|
187
|
+
if (returnGreekValue !== undefined)
|
|
188
|
+
body['return_greek_value'] = returnGreekValue;
|
|
189
|
+
if (optionFilter !== undefined)
|
|
190
|
+
body['option_filter'] = optionFilter;
|
|
191
|
+
return this.callInto('option_chain', body, '3.0');
|
|
182
192
|
}
|
|
183
193
|
/**
|
|
184
194
|
* Option K-line by OCC-style identifier.
|
|
185
195
|
*
|
|
186
196
|
* @param timezone - Optional IANA timezone for expiry conversion (e.g. 'America/New_York').
|
|
187
197
|
* If omitted, defaults to America/New_York for US symbols and Asia/Hong_Kong for .HK symbols.
|
|
198
|
+
* @param limit - Maximum number of bars to return.
|
|
199
|
+
* @param sortDir - Sort direction ('asc' or 'desc').
|
|
188
200
|
*/
|
|
189
|
-
async getOptionKline(identifiers, period, beginTime = -1, endTime = -1, timezone) {
|
|
201
|
+
async getOptionKline(identifiers, period, beginTime = -1, endTime = -1, timezone, limit, sortDir) {
|
|
190
202
|
const resolvedBegin = beginTime === 0 ? -1 : beginTime;
|
|
191
203
|
const resolvedEnd = endTime === 0 ? -1 : endTime;
|
|
192
204
|
const optionQuery = identifiers.map((id) => {
|
|
193
205
|
const p = parseOptionIdentifier(id, timezone);
|
|
194
|
-
|
|
206
|
+
const entry = {
|
|
195
207
|
symbol: p.symbol,
|
|
196
208
|
expiry: p.expiryMs,
|
|
197
209
|
right: p.right,
|
|
@@ -200,9 +212,31 @@ export class QuoteClient {
|
|
|
200
212
|
begin_time: resolvedBegin,
|
|
201
213
|
end_time: resolvedEnd,
|
|
202
214
|
};
|
|
215
|
+
if (limit !== undefined && limit > 0)
|
|
216
|
+
entry['limit'] = limit;
|
|
217
|
+
if (sortDir !== undefined && sortDir !== '')
|
|
218
|
+
entry['sort_dir'] = sortDir;
|
|
219
|
+
return entry;
|
|
203
220
|
});
|
|
204
221
|
return this.callInto('option_kline', { option_query: optionQuery }, '2.0');
|
|
205
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Real-time option quotes by OCC-style identifier.
|
|
225
|
+
*
|
|
226
|
+
* @param timezone - Optional IANA timezone for expiry conversion (e.g. 'America/New_York').
|
|
227
|
+
* If omitted, defaults to America/New_York for US symbols and Asia/Hong_Kong for .HK symbols.
|
|
228
|
+
*/
|
|
229
|
+
async getOptionQuote(identifiers, timezone) {
|
|
230
|
+
const optionBasic = identifiers.map((id) => {
|
|
231
|
+
const p = parseOptionIdentifier(id, timezone);
|
|
232
|
+
return { symbol: p.symbol, expiry: p.expiryMs, right: p.right, strike: p.strike };
|
|
233
|
+
});
|
|
234
|
+
return this.callInto('option_brief', { option_basic: optionBasic }, '2.0');
|
|
235
|
+
}
|
|
236
|
+
/** @deprecated Use getOptionQuote instead. */
|
|
237
|
+
async getOptionBrief(identifiers) {
|
|
238
|
+
return this.getOptionQuote(identifiers);
|
|
239
|
+
}
|
|
206
240
|
// === Futures ===
|
|
207
241
|
async getFutureExchange() {
|
|
208
242
|
return this.callInto('future_exchange', { secType: 'FUT' });
|
|
@@ -520,6 +554,30 @@ export class QuoteClient {
|
|
|
520
554
|
return [];
|
|
521
555
|
return Object.values(grouped).flat();
|
|
522
556
|
}
|
|
557
|
+
/** Corporate symbol change (flattened). wire: corporate_action (action_type=symbol_change) */
|
|
558
|
+
async getCorporateSymbolChange(req) {
|
|
559
|
+
const body = { ...req, actionType: 'symbol_change' };
|
|
560
|
+
const grouped = await this.callInto('corporate_action', body);
|
|
561
|
+
if (!grouped || typeof grouped !== 'object')
|
|
562
|
+
return [];
|
|
563
|
+
return Object.values(grouped).flat();
|
|
564
|
+
}
|
|
565
|
+
/** Corporate delisting (flattened). wire: corporate_action (action_type=delisting) */
|
|
566
|
+
async getCorporateDelisting(req) {
|
|
567
|
+
const body = { ...req, actionType: 'delisting' };
|
|
568
|
+
const grouped = await this.callInto('corporate_action', body);
|
|
569
|
+
if (!grouped || typeof grouped !== 'object')
|
|
570
|
+
return [];
|
|
571
|
+
return Object.values(grouped).flat();
|
|
572
|
+
}
|
|
573
|
+
/** Corporate IPO (flattened). wire: corporate_action (action_type=ipo) */
|
|
574
|
+
async getCorporateIPO(req) {
|
|
575
|
+
const body = { ...req, actionType: 'ipo' };
|
|
576
|
+
const grouped = await this.callInto('corporate_action', body);
|
|
577
|
+
if (!grouped || typeof grouped !== 'object')
|
|
578
|
+
return [];
|
|
579
|
+
return Object.values(grouped).flat();
|
|
580
|
+
}
|
|
523
581
|
/** Financial currency per symbol. wire: financial_currency */
|
|
524
582
|
async getFinancialCurrency(req) {
|
|
525
583
|
return this.callInto('financial_currency', req);
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { HttpClient } from '../client/http-client.js';
|
|
11
11
|
import { createApiRequest } from '../client/api-request.js';
|
|
12
12
|
import { unmarshalData } from '../client/api-response.js';
|
|
13
|
+
import * as tokenMethods from '../client/token-methods.js';
|
|
13
14
|
import { normalizeOrderStatus } from '../model/order-status.js';
|
|
14
15
|
/** Normalize `Order.status` field in-place (handles int → string). */
|
|
15
16
|
function normalizeOrderInPlace(o) {
|
|
@@ -41,8 +42,42 @@ export class TradeClient {
|
|
|
41
42
|
static fromConfig(config, account, secretKey) {
|
|
42
43
|
return new TradeClient(new HttpClient(config), account, secretKey);
|
|
43
44
|
}
|
|
45
|
+
// ── Token management ──────────────────────────────────────────────────────
|
|
46
|
+
/** Call the `user_token_refresh` API and return the new token. Read-only. */
|
|
47
|
+
async queryToken() {
|
|
48
|
+
return tokenMethods.queryToken(this.httpClient);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Refresh the token: call the API, update the in-memory config token, and
|
|
52
|
+
* optionally persist via the provided TokenManager (file + writer callback).
|
|
53
|
+
*
|
|
54
|
+
* @param tokenManager - optional TokenManager for file persistence and writer callback
|
|
55
|
+
*/
|
|
56
|
+
async refreshToken(tokenManager) {
|
|
57
|
+
return tokenMethods.refreshToken(this.httpClient, tokenManager);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Start background token auto-refresh. Returns a TokenManager that can be
|
|
61
|
+
* used to stop the background task via `tm.stopAutoRefresh()`.
|
|
62
|
+
*
|
|
63
|
+
* @param refreshDurationSecs - Refresh threshold in seconds (minimum 30).
|
|
64
|
+
* @param checkIntervalMs - How often to check, in milliseconds (default 300 000 / 5 min).
|
|
65
|
+
* @param tokenWriter - Optional callback invoked after each successful refresh.
|
|
66
|
+
*/
|
|
67
|
+
startTokenAutoRefresh(refreshDurationSecs, checkIntervalMs, tokenWriter) {
|
|
68
|
+
return tokenMethods.startTokenAutoRefresh(this.httpClient, refreshDurationSecs, checkIntervalMs, tokenWriter);
|
|
69
|
+
}
|
|
44
70
|
async callInto(method, bizParams) {
|
|
45
|
-
|
|
71
|
+
// Inject secretKey into every request when available (institution accounts require it).
|
|
72
|
+
// Individual methods that already set secretKey will not be overwritten (|| not &&).
|
|
73
|
+
let params = bizParams;
|
|
74
|
+
if (this.secretKey && params !== null && typeof params === 'object' && !Array.isArray(params)) {
|
|
75
|
+
const p = params;
|
|
76
|
+
if (p['secretKey'] == null && p['secret_key'] == null) {
|
|
77
|
+
params = { ...p, secretKey: this.secretKey };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const request = createApiRequest(method, params);
|
|
46
81
|
const response = await this.httpClient.executeRequest(request);
|
|
47
82
|
return unmarshalData(response.data);
|
|
48
83
|
}
|
|
@@ -75,25 +110,18 @@ export class TradeClient {
|
|
|
75
110
|
}
|
|
76
111
|
// === Order operations ===
|
|
77
112
|
async placeOrder(order) {
|
|
78
|
-
|
|
79
|
-
if (!params.secretKey && this.secretKey)
|
|
80
|
-
params.secretKey = this.secretKey;
|
|
81
|
-
return this.callInto('place_order', params);
|
|
113
|
+
return this.callInto('place_order', { ...order, account: this.account });
|
|
82
114
|
}
|
|
83
115
|
async previewOrder(order) {
|
|
84
116
|
return this.callInto('preview_order', { ...order, account: this.account });
|
|
85
117
|
}
|
|
86
118
|
async modifyOrder(id, order) {
|
|
87
|
-
|
|
88
|
-
if (!params.secretKey && this.secretKey)
|
|
89
|
-
params.secretKey = this.secretKey;
|
|
90
|
-
return this.callInto('modify_order', params);
|
|
119
|
+
return this.callInto('modify_order', { ...order, account: this.account, id });
|
|
91
120
|
}
|
|
92
121
|
async cancelOrder(id, secretKey) {
|
|
93
|
-
const sk = secretKey ?? this.secretKey;
|
|
94
122
|
const params = { account: this.account, id };
|
|
95
|
-
if (
|
|
96
|
-
params.secretKey =
|
|
123
|
+
if (secretKey !== undefined)
|
|
124
|
+
params.secretKey = secretKey; // per-call override takes precedence; undefined means use config default
|
|
97
125
|
return this.callInto('cancel_order', params);
|
|
98
126
|
}
|
|
99
127
|
// === Order queries (BREAKING v0.4.0) ===
|
|
@@ -131,14 +159,11 @@ export class TradeClient {
|
|
|
131
159
|
}
|
|
132
160
|
/**
|
|
133
161
|
* Get a single order by ID (v0.4.0 new).
|
|
134
|
-
* Wire method: `orders` with id/order_id param; server returns a single Order object
|
|
135
|
-
* (not `{items:[]}` envelope).
|
|
136
|
-
*
|
|
137
162
|
* Returns `undefined` if no match.
|
|
138
163
|
*/
|
|
139
164
|
async getOrder(req) {
|
|
140
165
|
const merged = withAccount(req, this.account);
|
|
141
|
-
const out = await this.callInto('
|
|
166
|
+
const out = await this.callInto('order_no', merged);
|
|
142
167
|
if (!out || (!out.id && !out.orderId))
|
|
143
168
|
return undefined;
|
|
144
169
|
normalizeOrderInPlace(out);
|
|
@@ -12,14 +12,15 @@ export interface ApiResponse {
|
|
|
12
12
|
sign?: string;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* Parse the raw HTTP response body.
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* Parse the raw HTTP response body. Throws TigerError when code != 0.
|
|
16
|
+
*
|
|
17
|
+
* patchLargeIntegers is applied before JSON.parse to preserve int64 order IDs
|
|
18
|
+
* (e.g. 28868646234578944) as strings rather than losing precision.
|
|
18
19
|
*/
|
|
19
20
|
export declare function parseApiResponse(body: string): ApiResponse;
|
|
20
21
|
/**
|
|
21
22
|
* Decode an ApiResponse.data payload into a typed value.
|
|
22
|
-
* Handles
|
|
23
|
-
*
|
|
23
|
+
* Handles double-encoded JSON (where `data` is a JSON string wrapping JSON),
|
|
24
|
+
* seen on some trade endpoints.
|
|
24
25
|
*/
|
|
25
26
|
export declare function unmarshalData<T>(data: unknown): T | undefined;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared token management methods for TradeClient and QuoteClient.
|
|
3
|
+
* Both clients delegate to the underlying HttpClient; this module
|
|
4
|
+
* centralises the JSDoc so each client stays in sync automatically.
|
|
5
|
+
*/
|
|
6
|
+
import type { HttpClient } from './http-client';
|
|
7
|
+
import type { TokenManager } from '../config/token-manager';
|
|
8
|
+
/**
|
|
9
|
+
* Call the `user_token_refresh` API and return the new token string.
|
|
10
|
+
* Read-only: does NOT update the stored token.
|
|
11
|
+
* Use `refreshToken()` to also update the in-memory config and optionally persist.
|
|
12
|
+
*/
|
|
13
|
+
export declare function queryToken(httpClient: HttpClient): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Refresh the token: call the API, update the in-memory config token, and
|
|
16
|
+
* optionally persist via the provided TokenManager (file + writer callback).
|
|
17
|
+
*
|
|
18
|
+
* @param httpClient - The underlying HTTP client
|
|
19
|
+
* @param tokenManager - optional TokenManager for file persistence and writer callback
|
|
20
|
+
*/
|
|
21
|
+
export declare function refreshToken(httpClient: HttpClient, tokenManager?: TokenManager | null): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Start background token auto-refresh. Returns a TokenManager that can be
|
|
24
|
+
* used to stop the background task via `tm.stopAutoRefresh()`.
|
|
25
|
+
*
|
|
26
|
+
* @param httpClient - The underlying HTTP client
|
|
27
|
+
* @param refreshDurationSecs - Refresh threshold in seconds (minimum 30).
|
|
28
|
+
* When the token age exceeds this value the refresh is triggered.
|
|
29
|
+
* @param checkIntervalMs - How often to check whether a refresh is needed,
|
|
30
|
+
* in milliseconds. Defaults to 300 000 ms (5 minutes).
|
|
31
|
+
* @param tokenWriter - Optional callback invoked with the new token string
|
|
32
|
+
* after each successful refresh.
|
|
33
|
+
*/
|
|
34
|
+
export declare function startTokenAutoRefresh(httpClient: HttpClient, refreshDurationSecs: number, checkIntervalMs?: number, tokenWriter?: (token: string) => void): TokenManager;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 配置层导出
|
|
3
3
|
*/
|
|
4
4
|
export { parsePropertiesFile, parsePropertiesString } from './config-parser';
|
|
5
|
-
export { createClientConfig, loadPropertiesFile } from './client-config';
|
|
5
|
+
export { createClientConfig, loadPropertiesFile, SANDBOX_TIGER_PUBLIC_KEY } from './client-config';
|
|
6
6
|
export type { ClientConfig, ClientConfigOptions } from './client-config';
|
|
7
7
|
export { TokenManager } from './token-manager';
|
|
8
8
|
export type { TokenManagerOptions, RefreshFn } from './token-manager';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
/** SDK 版本号 */
|
|
18
18
|
export { SDK_VERSION as VERSION } from './version';
|
|
19
|
-
export { createClientConfig, loadPropertiesFile } from './config';
|
|
19
|
+
export { createClientConfig, loadPropertiesFile, SANDBOX_TIGER_PUBLIC_KEY } from './config';
|
|
20
20
|
export type { ClientConfig, ClientConfigOptions } from './config';
|
|
21
21
|
export { TokenManager } from './config';
|
|
22
22
|
export type { TokenManagerOptions, RefreshFn } from './config';
|
|
@@ -27,13 +27,13 @@ export { QuoteClient, parseOptionIdentifier } from './quote';
|
|
|
27
27
|
export { TradeClient } from './trade';
|
|
28
28
|
export { PushClient, ConnectionState, SubjectType } from './push';
|
|
29
29
|
export type { PushClientOptions } from './push';
|
|
30
|
-
export type { Order, OrderRequest } from './model/order';
|
|
30
|
+
export type { Order, OrderRequest, ContractLegRequest } from './model/order';
|
|
31
31
|
export { marketOrder, limitOrder, stopOrder, stopLimitOrder } from './model/order-helpers';
|
|
32
32
|
export { normalizeOrderStatus } from './model/order-status';
|
|
33
33
|
export type { Contract } from './model/contract';
|
|
34
34
|
export type { Position } from './model/position';
|
|
35
35
|
export type { Asset, AssetSegment, PrimeAsset, PreviewResult, PlaceOrderResult, OrderIdResult, Transaction, ManagedAccount, AnalyticsAsset, AggregateAssets, EstimateTradableQuantity, ForexOrderResult, SegmentFund, SegmentFundAvailableItem, SegmentFundHistoryItem, FundDetails, FundingHistoryItem, PositionTransferRecord, PositionTransferDetail, PositionTransferExternalRecord, OptionExerciseCheckResult, OptionExercisePositionPageResult, OptionExerciseRecordPageResult, } from './model/trade';
|
|
36
36
|
export type { OrdersRequest, GetOrderRequest, OrderTransactionsRequest, PositionsRequest, AssetsRequest, ManagedAccountsRequest, DerivativeContractsRequest, AnalyticsAssetRequest, AggregateAssetsRequest, EstimateTradableQuantityRequest, ForexOrderRequest, SegmentFundRequest, FundDetailsRequest, FundingHistoryRequest, PositionTransferRequest, PositionTransferRecordsRequest, PositionTransferDetailRequest, PositionTransferExternalRecordsRequest, OptionExerciseCheckRequest, OptionExercisePositionRequest, OptionExerciseSubmitRequest, OptionExerciseRecordsRequest, OptionExerciseCancelRequest, } from './model/trade-requests';
|
|
37
|
-
export type { MarketState, Brief, Kline, KlineItem, Timeline, TimelineItem, TradeTick, TradeTickItem, Depth, DepthLevel, OptionExpiration, OptionChain, OptionChainRow, OptionSymbol, FutureExchange, FutureContractInfo, FutureQuote, FutureKline, FutureKlineItem, FutureDepth, FutureTradeTickItem, FutureTradingTime, FinancialDailyItem, FinancialReportItem, CorporateAction, CapitalFlow, CapitalFlowItem, CapitalDistribution, ScannerResult, ScannerResultItem, QuotePermission, SymbolName, TradeMeta, StockDetail, StockBroker, StockBrokerItem, ShortInterest, StockIndustry, IndustryItem, IndustryStock, WarrantBrief, WarrantFilterResult, FundContractInfo, FundQuote, FundHistoryQuote, QuoteOvernight, KlineQuota, MarketScannerTag, MarketScannerTags, OptionAnalysis, OptionLeg, OptionVolatilityPoint, ExchangeRate, FinancialCurrency, BrokerDetail, TradingCalendarItem, FutureMainContractHistory, } from './model/quote';
|
|
37
|
+
export type { MarketState, Brief, Kline, KlineItem, Timeline, TimelineItem, TradeTick, TradeTickItem, Depth, DepthLevel, OptionExpiration, OptionChain, OptionChainRow, OptionSymbol, OptionChainFilter, OptionChainFilterGreeks, Range, FutureExchange, FutureContractInfo, FutureQuote, FutureKline, FutureKlineItem, FutureDepth, FutureTradeTickItem, FutureTradingTime, FinancialDailyItem, FinancialReportItem, CorporateAction, CorporateSymbolChange, CorporateDelisting, CorporateIPO, CapitalFlow, CapitalFlowItem, CapitalDistribution, ScannerResult, ScannerResultItem, QuotePermission, SymbolName, TradeMeta, StockDetail, StockBroker, StockBrokerItem, ShortInterest, StockIndustry, IndustryItem, IndustryStock, WarrantBrief, WarrantFilterResult, FundContractInfo, FundQuote, FundHistoryQuote, QuoteOvernight, KlineQuota, MarketScannerTag, MarketScannerTags, OptionAnalysis, OptionLeg, OptionVolatilityPoint, ExchangeRate, FinancialCurrency, BrokerDetail, TradingCalendarItem, FutureMainContractHistory, } from './model/quote';
|
|
38
38
|
export type { BriefRequest, DepthQuoteRequest, TradeTickRequest, KlineRequest, KlineByPageRequest, FutureBriefRequest, FutureKlineRequest, FutureKlineByPageRequest, FutureTradeTicksRequest, FutureDepthRequest, FutureContractSingleRequest, FutureContinuousContractsRequest, FutureHistoryMainContractRequest, FutureTradingTimesRequest, AllFutureContractsRequest, OptionTradeTicksRequest, OptionTimelineRequest, OptionDepthRequest, OptionSymbolsRequest, OptionAnalysisRequest, OptionQueryItem, ShortInterestRequest, StockBrokerRequest, StockDetailsRequest, StockFundamentalRequest, StockIndustryRequest, StockDelayBriefsRequest, SymbolsRequest, TradeMetasRequest, TradeRankRequest, TimelineHistoryRequest, TradingCalendarRequest, KlineQuotaRequest, QuotePermissionRequest, QuoteOvernightRequest, IndustryListRequest, IndustryStocksRequest, FundSymbolsRequest, FundContractsRequest, FundQuoteRequest, FundHistoryQuoteRequest, WarrantBriefsRequest, WarrantFilterRequest, MarketScannerTagsRequest, FinancialCurrencyRequest, FinancialExchangeRateRequest, } from './model/quote-requests';
|
|
39
39
|
export { OrderStatus, SecurityType, OrderType, TimeInForce, Market, Currency, QuoteRight, SegmentType, OrderSortBy, CorporateActionType, IndustryLevel, SortDirection, OptionAnalysisPeriod, FinancialReportPeriod, Language, License, BarPeriod, orderStatusCode, } from './model/enums';
|
|
@@ -115,6 +115,7 @@ export declare enum License {
|
|
|
115
115
|
export declare enum TimeInForce {
|
|
116
116
|
DAY = "DAY",
|
|
117
117
|
GTC = "GTC",
|
|
118
|
+
GTD = "GTD",
|
|
118
119
|
OPG = "OPG"
|
|
119
120
|
}
|
|
120
121
|
/** 订单排序字段 */
|
|
@@ -133,7 +134,10 @@ export declare enum SegmentType {
|
|
|
133
134
|
export declare enum CorporateActionType {
|
|
134
135
|
Split = "split",
|
|
135
136
|
Dividend = "dividend",
|
|
136
|
-
Earning = "earning"
|
|
137
|
+
Earning = "earning",
|
|
138
|
+
SymbolChange = "symbol_change",
|
|
139
|
+
Delisting = "delisting",
|
|
140
|
+
IPO = "ipo"
|
|
137
141
|
}
|
|
138
142
|
/** 行业级别 (1~4 级) */
|
|
139
143
|
export declare enum IndustryLevel {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Order construction helpers.
|
|
3
3
|
* All helpers return an `OrderRequest` with sensible defaults.
|
|
4
4
|
*/
|
|
5
|
-
import type { OrderRequest, OrderLegRequest, AlgoParamsRequest } from './order';
|
|
5
|
+
import type { OrderRequest, OrderLegRequest, AlgoParamsRequest, ContractLegRequest } from './order';
|
|
6
6
|
import { PriceType } from './enums';
|
|
7
7
|
/** Market order */
|
|
8
8
|
export declare function marketOrder(account: string, symbol: string, secType: string, action: string, quantity: number): OrderRequest;
|
|
@@ -21,14 +21,54 @@ export declare function auctionMarketOrder(account: string, symbol: string, secT
|
|
|
21
21
|
/** Algo order (TWAP / VWAP) */
|
|
22
22
|
export declare function algoOrder(account: string, symbol: string, secType: string, action: string, quantity: number, limitPrice: number, algoType: string, params: AlgoParamsRequest): OrderRequest;
|
|
23
23
|
/**
|
|
24
|
-
* Iceberg order
|
|
25
|
-
|
|
26
|
-
export declare function icebergOrder(account: string, symbol: string, secType: string, action: string, quantity: number, limitPrice: number, displaySize: number): OrderRequest;
|
|
27
|
-
/**
|
|
28
|
-
* Iceberg order (full params).
|
|
29
|
-
* Pass `priceType` as empty string to use server default (LIMIT_PRICE).
|
|
24
|
+
* Iceberg order. `displaySize` is required; all other parameters are optional.
|
|
25
|
+
* Pass `priceType` as empty string to use the server default (LIMIT_PRICE).
|
|
30
26
|
* Pass `startTime` / `endTime` as 0 to omit the time window.
|
|
31
27
|
*/
|
|
32
|
-
export declare function
|
|
28
|
+
export declare function icebergOrder(account: string, symbol: string, secType: string, action: string, quantity: number, limitPrice: number, displaySize: number, minDisplaySize?: number, checkIntervals?: number, priceType?: PriceType | string, startTime?: number, endTime?: number): OrderRequest;
|
|
33
29
|
/** Attached profit / loss leg */
|
|
34
30
|
export declare function orderLeg(legType: string, price: number, timeInForce: string): OrderLegRequest;
|
|
31
|
+
/**
|
|
32
|
+
* Market order by cash amount (instead of quantity).
|
|
33
|
+
* Server uses `isQuantityByAmount=true` + `amount` field.
|
|
34
|
+
*/
|
|
35
|
+
export declare function marketOrderByAmount(account: string, symbol: string, secType: string, action: string, amount: number): OrderRequest;
|
|
36
|
+
/**
|
|
37
|
+
* Limit order by cash amount (instead of quantity).
|
|
38
|
+
*/
|
|
39
|
+
export declare function limitOrderByAmount(account: string, symbol: string, secType: string, action: string, amount: number, limitPrice: number): OrderRequest;
|
|
40
|
+
/**
|
|
41
|
+
* Trailing stop order using a fixed price offset (auxPrice) instead of a percentage.
|
|
42
|
+
* Use `trailOrder()` for percentage-based trailing stops.
|
|
43
|
+
*/
|
|
44
|
+
export declare function trailOrderByPrice(account: string, symbol: string, secType: string, action: string, quantity: number, auxPrice: number): OrderRequest;
|
|
45
|
+
/**
|
|
46
|
+
* Limit order with attached profit/loss legs (bracket order).
|
|
47
|
+
* At most 2 legs are supported.
|
|
48
|
+
*
|
|
49
|
+
* @param orderLegs - Array of `OrderLegRequest` (use `orderLeg()` helper)
|
|
50
|
+
*/
|
|
51
|
+
export declare function limitOrderWithLegs(account: string, symbol: string, secType: string, action: string, quantity: number, limitPrice: number, orderLegs: OrderLegRequest[]): OrderRequest;
|
|
52
|
+
/**
|
|
53
|
+
* Multi-leg (combo/MLEG) order for options combos.
|
|
54
|
+
*
|
|
55
|
+
* @param contractLegs - Array of `ContractLegRequest` (use `contractLeg()` helper)
|
|
56
|
+
* @param comboType - e.g. `'MLEG'`
|
|
57
|
+
*/
|
|
58
|
+
export declare function comboOrder(account: string, action: string, quantity: number, orderType: string, contractLegs: ContractLegRequest[], comboType?: string, limitPrice?: number, auxPrice?: number, trailingPercent?: number): OrderRequest;
|
|
59
|
+
/**
|
|
60
|
+
* OCA (One-Cancels-All) order.
|
|
61
|
+
* Server expects `orderType: 'OCA'` and an `ocaOrders` list.
|
|
62
|
+
*
|
|
63
|
+
* @param ocaOrders - The contained orders (use any order helper to build each)
|
|
64
|
+
*/
|
|
65
|
+
export declare function ocaOrder(account: string, symbol: string, secType: string, action: string, quantity: number, ocaOrders: OrderRequest[]): OrderRequest;
|
|
66
|
+
/**
|
|
67
|
+
* Build a single leg for a multi-leg (MLEG / combo) order.
|
|
68
|
+
*
|
|
69
|
+
* @param symbol - Underlying symbol
|
|
70
|
+
* @param secType - Security type (e.g. `'OPT'`)
|
|
71
|
+
* @param action - `'BUY'` or `'SELL'`
|
|
72
|
+
* @param ratio - Number of contracts for this leg
|
|
73
|
+
*/
|
|
74
|
+
export declare function contractLeg(symbol: string, secType: string, action: string, ratio: number, expiry?: string, strike?: string, right?: string): ContractLegRequest;
|