@tigeropenapi/tigeropen 0.4.5 → 0.4.7
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 +2 -2
- package/dist/cjs/client/api-response.js +21 -2
- package/dist/cjs/config/client-config.js +7 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/model/enums.js +14 -1
- package/dist/cjs/model/order-helpers.js +44 -0
- package/dist/cjs/trade/trade-client.js +17 -6
- package/dist/esm/client/api-response.js +21 -2
- package/dist/esm/config/client-config.js +7 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/model/enums.js +13 -0
- package/dist/esm/model/order-helpers.js +43 -1
- package/dist/esm/trade/trade-client.js +17 -6
- package/dist/types/client/api-response.d.ts +1 -0
- package/dist/types/config/client-config.d.ts +4 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/model/enums.d.ts +13 -1
- package/dist/types/model/order-helpers.d.ts +11 -0
- package/dist/types/model/order.d.ts +17 -2
- package/dist/types/model/trade.d.ts +6 -4
- package/dist/types/trade/trade-client.d.ts +4 -3
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -312,7 +312,7 @@ const { createClientConfig } = require('@tigeropenapi/tigeropen');
|
|
|
312
312
|
## References
|
|
313
313
|
|
|
314
314
|
- [TypeScript SDK Documentation](https://docs.itigerup.com/docs/typescript)
|
|
315
|
-
- [Tiger Brokers OpenAPI Docs](https://
|
|
315
|
+
- [Tiger Brokers OpenAPI Docs](https://docs-en.itigerup.com/docs/)
|
|
316
316
|
- [npm package](https://www.npmjs.com/package/@tigeropenapi/tigeropen)
|
|
317
317
|
|
|
318
318
|
## License
|
|
@@ -635,7 +635,7 @@ const { createClientConfig } = require('@tigeropenapi/tigeropen');
|
|
|
635
635
|
## 参考链接
|
|
636
636
|
|
|
637
637
|
- [TypeScript SDK 文档](https://docs.itigerup.com/docs/typescript)
|
|
638
|
-
- [老虎证券 OpenAPI 文档](https://
|
|
638
|
+
- [老虎证券 OpenAPI 文档](https://docs.itigerup.com/docs/)
|
|
639
639
|
- [npm 包](https://www.npmjs.com/package/@tigeropenapi/tigeropen)
|
|
640
640
|
|
|
641
641
|
## 许可证
|
|
@@ -6,9 +6,27 @@ exports.unmarshalData = unmarshalData;
|
|
|
6
6
|
* API response parsing.
|
|
7
7
|
*/
|
|
8
8
|
const errors_1 = require("./errors");
|
|
9
|
+
/**
|
|
10
|
+
* Replace bare integers (not inside JSON string values) that exceed
|
|
11
|
+
* Number.MAX_SAFE_INTEGER (> 15 digits) with quoted string equivalents,
|
|
12
|
+
* so that int64 order IDs survive JSON.parse without precision loss.
|
|
13
|
+
*/
|
|
14
|
+
function patchLargeIntegers(text) {
|
|
15
|
+
// Mask all existing JSON string values so their content isn't touched.
|
|
16
|
+
const strings = [];
|
|
17
|
+
const masked = text.replace(/"(?:[^"\\]|\\.)*"/g, (match) => {
|
|
18
|
+
strings.push(match);
|
|
19
|
+
return '\x01' + (strings.length - 1) + '\x01';
|
|
20
|
+
});
|
|
21
|
+
// Quote any bare integer with >15 digits.
|
|
22
|
+
const patched = masked.replace(/-?\d{16,}/g, (m) => '"' + m + '"');
|
|
23
|
+
// Restore original string values.
|
|
24
|
+
return patched.replace(/\x01(\d+)\x01/g, (_, i) => strings[parseInt(i, 10)]);
|
|
25
|
+
}
|
|
9
26
|
/**
|
|
10
27
|
* Parse the raw HTTP response body.
|
|
11
28
|
* Throws TigerError when code != 0.
|
|
29
|
+
* Large integers in the outer envelope are not an issue (only inner `data` contains int64 IDs).
|
|
12
30
|
*/
|
|
13
31
|
function parseApiResponse(body) {
|
|
14
32
|
const resp = JSON.parse(body);
|
|
@@ -26,9 +44,10 @@ function unmarshalData(data) {
|
|
|
26
44
|
if (data == null)
|
|
27
45
|
return undefined;
|
|
28
46
|
if (typeof data === 'string') {
|
|
29
|
-
// Attempt to parse JSON string (double-encoded case)
|
|
47
|
+
// Attempt to parse JSON string (double-encoded case).
|
|
48
|
+
// Patch large integers before parsing so int64 IDs survive as strings.
|
|
30
49
|
try {
|
|
31
|
-
return JSON.parse(data);
|
|
50
|
+
return JSON.parse(patchLargeIntegers(data));
|
|
32
51
|
}
|
|
33
52
|
catch {
|
|
34
53
|
return data;
|
|
@@ -30,6 +30,7 @@ const TIGER_PUBLIC_KEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNF3G8SoEcCZh2rs
|
|
|
30
30
|
const ENV_TIGER_ID = 'TIGEROPEN_TIGER_ID';
|
|
31
31
|
const ENV_PRIVATE_KEY = 'TIGEROPEN_PRIVATE_KEY';
|
|
32
32
|
const ENV_ACCOUNT = 'TIGEROPEN_ACCOUNT';
|
|
33
|
+
const ENV_SECRET_KEY = 'TIGEROPEN_SECRET_KEY';
|
|
33
34
|
const ENV_TOKEN = 'TIGEROPEN_TOKEN';
|
|
34
35
|
const ENV_TOKEN_FILE = 'TIGEROPEN_TOKEN_FILE';
|
|
35
36
|
/**
|
|
@@ -128,6 +129,7 @@ function createClientConfig(options) {
|
|
|
128
129
|
let tigerId = opts.tigerId || fileProps['tiger_id'] || '';
|
|
129
130
|
let privateKey = opts.privateKey || resolvePrivateKey(fileProps) || '';
|
|
130
131
|
let account = opts.account || fileProps['account'] || '';
|
|
132
|
+
let secretKey = opts.secretKey || fileProps['secret_key'] || undefined;
|
|
131
133
|
let token = opts.token || fileProps['token'];
|
|
132
134
|
const license = opts.license || fileProps['license'];
|
|
133
135
|
const language = opts.language || fileProps['language'] || DEFAULT_LANGUAGE;
|
|
@@ -136,6 +138,7 @@ function createClientConfig(options) {
|
|
|
136
138
|
const envTigerId = process.env[ENV_TIGER_ID];
|
|
137
139
|
const envPrivateKey = process.env[ENV_PRIVATE_KEY];
|
|
138
140
|
const envAccount = process.env[ENV_ACCOUNT];
|
|
141
|
+
const envSecretKey = process.env[ENV_SECRET_KEY];
|
|
139
142
|
const envToken = process.env[ENV_TOKEN];
|
|
140
143
|
if (envTigerId) {
|
|
141
144
|
tigerId = envTigerId;
|
|
@@ -146,6 +149,9 @@ function createClientConfig(options) {
|
|
|
146
149
|
if (envAccount) {
|
|
147
150
|
account = envAccount;
|
|
148
151
|
}
|
|
152
|
+
if (envSecretKey) {
|
|
153
|
+
secretKey = envSecretKey;
|
|
154
|
+
}
|
|
149
155
|
if (envToken) {
|
|
150
156
|
token = envToken;
|
|
151
157
|
}
|
|
@@ -215,6 +221,7 @@ function createClientConfig(options) {
|
|
|
215
221
|
tigerId,
|
|
216
222
|
privateKey,
|
|
217
223
|
account,
|
|
224
|
+
secretKey: secretKey || undefined,
|
|
218
225
|
license,
|
|
219
226
|
language,
|
|
220
227
|
timezone,
|
package/dist/cjs/index.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.orderStatusCode = exports.BarPeriod = exports.License = exports.Language = exports.FinancialReportPeriod = exports.OptionAnalysisPeriod = exports.SortDirection = exports.IndustryLevel = exports.CorporateActionType = exports.OrderSortBy = exports.SegmentType = exports.QuoteRight = exports.Currency = exports.Market = exports.TimeInForce = exports.OrderType = exports.SecurityType = exports.OrderStatus = exports.normalizeOrderStatus = exports.stopLimitOrder = exports.stopOrder = exports.limitOrder = exports.marketOrder = exports.SubjectType = exports.ConnectionState = exports.PushClient = exports.TradeClient = exports.parseOptionIdentifier = exports.QuoteClient = exports.classifyErrorCode = exports.TigerError = exports.HttpClient = exports.TokenManager = exports.loadPropertiesFile = exports.createClientConfig = exports.VERSION = void 0;
|
|
20
20
|
/** SDK 版本号 */
|
|
21
|
-
exports.VERSION = '0.4.
|
|
21
|
+
exports.VERSION = '0.4.6';
|
|
22
22
|
// Config
|
|
23
23
|
var config_1 = require("./config");
|
|
24
24
|
Object.defineProperty(exports, "createClientConfig", { enumerable: true, get: function () { return config_1.createClientConfig; } });
|
package/dist/cjs/model/enums.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 所有枚举值与 API JSON 保持一致
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.FinancialReportPeriod = exports.OptionAnalysisPeriod = exports.SortDirection = exports.IndustryLevel = exports.CorporateActionType = exports.SegmentType = exports.OrderSortBy = exports.TimeInForce = exports.License = exports.QuoteRight = exports.Language = exports.BarPeriod = exports.OrderStatus = exports.OrderType = exports.Currency = exports.SecurityType = exports.Market = void 0;
|
|
7
|
+
exports.FinancialReportPeriod = exports.OptionAnalysisPeriod = exports.SortDirection = exports.IndustryLevel = exports.CorporateActionType = exports.SegmentType = exports.OrderSortBy = exports.TimeInForce = exports.License = exports.QuoteRight = exports.Language = exports.BarPeriod = exports.OrderStatus = exports.PriceType = exports.OrderType = exports.Currency = exports.SecurityType = exports.Market = void 0;
|
|
8
8
|
exports.orderStatusCode = orderStatusCode;
|
|
9
9
|
/** 市场枚举 */
|
|
10
10
|
var Market;
|
|
@@ -51,7 +51,20 @@ var OrderType;
|
|
|
51
51
|
OrderType["TWAP"] = "TWAP";
|
|
52
52
|
OrderType["VWAP"] = "VWAP";
|
|
53
53
|
OrderType["OCA"] = "OCA";
|
|
54
|
+
OrderType["ICEBERG"] = "ICEBERG";
|
|
54
55
|
})(OrderType || (exports.OrderType = OrderType = {}));
|
|
56
|
+
/** 冰山单价格类型 */
|
|
57
|
+
var PriceType;
|
|
58
|
+
(function (PriceType) {
|
|
59
|
+
/** 限价 */
|
|
60
|
+
PriceType["LIMIT_PRICE"] = "LIMIT_PRICE";
|
|
61
|
+
/** 卖一价 */
|
|
62
|
+
PriceType["ASK_PRICE"] = "ASK_PRICE";
|
|
63
|
+
/** 买一价 */
|
|
64
|
+
PriceType["BID_PRICE"] = "BID_PRICE";
|
|
65
|
+
/** 最新价 */
|
|
66
|
+
PriceType["LATEST_PRICE"] = "LATEST_PRICE";
|
|
67
|
+
})(PriceType || (exports.PriceType = PriceType = {}));
|
|
55
68
|
/**
|
|
56
69
|
* 订单状态枚举。对齐 Java SDK OrderStatus 定义。
|
|
57
70
|
*
|
|
@@ -8,6 +8,8 @@ exports.trailOrder = trailOrder;
|
|
|
8
8
|
exports.auctionLimitOrder = auctionLimitOrder;
|
|
9
9
|
exports.auctionMarketOrder = auctionMarketOrder;
|
|
10
10
|
exports.algoOrder = algoOrder;
|
|
11
|
+
exports.icebergOrder = icebergOrder;
|
|
12
|
+
exports.icebergOrderFull = icebergOrderFull;
|
|
11
13
|
exports.orderLeg = orderLeg;
|
|
12
14
|
const enums_1 = require("./enums");
|
|
13
15
|
/** Market order */
|
|
@@ -98,6 +100,48 @@ function algoOrder(account, symbol, secType, action, quantity, limitPrice, algoT
|
|
|
98
100
|
outsideRth: false,
|
|
99
101
|
};
|
|
100
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Iceberg order (basic) — only displaySize required.
|
|
105
|
+
*/
|
|
106
|
+
function icebergOrder(account, symbol, secType, action, quantity, limitPrice, displaySize) {
|
|
107
|
+
return {
|
|
108
|
+
account, symbol, secType, action,
|
|
109
|
+
orderType: enums_1.OrderType.ICEBERG,
|
|
110
|
+
totalQuantity: quantity,
|
|
111
|
+
limitPrice,
|
|
112
|
+
timeInForce: enums_1.TimeInForce.DAY,
|
|
113
|
+
outsideRth: false,
|
|
114
|
+
displaySize,
|
|
115
|
+
priceType: enums_1.PriceType.LIMIT_PRICE,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Iceberg order (full params).
|
|
120
|
+
* Pass `priceType` as empty string to use server default (LIMIT_PRICE).
|
|
121
|
+
* Pass `startTime` / `endTime` as 0 to omit the time window.
|
|
122
|
+
*/
|
|
123
|
+
function icebergOrderFull(account, symbol, secType, action, quantity, limitPrice, displaySize, minDisplaySize, checkIntervals, priceType, startTime, endTime) {
|
|
124
|
+
const req = {
|
|
125
|
+
account, symbol, secType, action,
|
|
126
|
+
orderType: enums_1.OrderType.ICEBERG,
|
|
127
|
+
totalQuantity: quantity,
|
|
128
|
+
limitPrice,
|
|
129
|
+
timeInForce: enums_1.TimeInForce.DAY,
|
|
130
|
+
outsideRth: false,
|
|
131
|
+
displaySize,
|
|
132
|
+
};
|
|
133
|
+
if (minDisplaySize !== undefined && minDisplaySize > 0)
|
|
134
|
+
req.minDisplaySize = minDisplaySize;
|
|
135
|
+
if (checkIntervals !== undefined && checkIntervals > 0)
|
|
136
|
+
req.checkIntervals = checkIntervals;
|
|
137
|
+
if (priceType)
|
|
138
|
+
req.priceType = priceType;
|
|
139
|
+
if (startTime && startTime > 0)
|
|
140
|
+
req.startTime = startTime;
|
|
141
|
+
if (endTime && endTime > 0)
|
|
142
|
+
req.endTime = endTime;
|
|
143
|
+
return req;
|
|
144
|
+
}
|
|
101
145
|
/** Attached profit / loss leg */
|
|
102
146
|
function orderLeg(legType, price, timeInForce) {
|
|
103
147
|
return { legType, price, timeInForce };
|
|
@@ -25,9 +25,10 @@ function withAccount(req, account) {
|
|
|
25
25
|
}
|
|
26
26
|
/** Trading client wrapping all trade-related APIs. */
|
|
27
27
|
class TradeClient {
|
|
28
|
-
constructor(httpClient, account) {
|
|
28
|
+
constructor(httpClient, account, secretKey) {
|
|
29
29
|
this.httpClient = httpClient;
|
|
30
30
|
this.account = account;
|
|
31
|
+
this.secretKey = secretKey;
|
|
31
32
|
}
|
|
32
33
|
async callInto(method, bizParams) {
|
|
33
34
|
const request = (0, api_request_1.createApiRequest)(method, bizParams);
|
|
@@ -63,16 +64,26 @@ class TradeClient {
|
|
|
63
64
|
}
|
|
64
65
|
// === Order operations ===
|
|
65
66
|
async placeOrder(order) {
|
|
66
|
-
|
|
67
|
+
const params = { ...order, account: this.account };
|
|
68
|
+
if (!params.secretKey && this.secretKey)
|
|
69
|
+
params.secretKey = this.secretKey;
|
|
70
|
+
return this.callInto('place_order', params);
|
|
67
71
|
}
|
|
68
72
|
async previewOrder(order) {
|
|
69
73
|
return this.callInto('preview_order', { ...order, account: this.account });
|
|
70
74
|
}
|
|
71
75
|
async modifyOrder(id, order) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return this.callInto('
|
|
76
|
+
const params = { ...order, account: this.account, id };
|
|
77
|
+
if (!params.secretKey && this.secretKey)
|
|
78
|
+
params.secretKey = this.secretKey;
|
|
79
|
+
return this.callInto('modify_order', params);
|
|
80
|
+
}
|
|
81
|
+
async cancelOrder(id, secretKey) {
|
|
82
|
+
const sk = secretKey ?? this.secretKey;
|
|
83
|
+
const params = { account: this.account, id };
|
|
84
|
+
if (sk)
|
|
85
|
+
params.secretKey = sk;
|
|
86
|
+
return this.callInto('cancel_order', params);
|
|
76
87
|
}
|
|
77
88
|
// === Order queries (BREAKING v0.4.0) ===
|
|
78
89
|
/**
|
|
@@ -2,9 +2,27 @@
|
|
|
2
2
|
* API response parsing.
|
|
3
3
|
*/
|
|
4
4
|
import { TigerError } from './errors.js';
|
|
5
|
+
/**
|
|
6
|
+
* Replace bare integers (not inside JSON string values) that exceed
|
|
7
|
+
* Number.MAX_SAFE_INTEGER (> 15 digits) with quoted string equivalents,
|
|
8
|
+
* so that int64 order IDs survive JSON.parse without precision loss.
|
|
9
|
+
*/
|
|
10
|
+
function patchLargeIntegers(text) {
|
|
11
|
+
// Mask all existing JSON string values so their content isn't touched.
|
|
12
|
+
const strings = [];
|
|
13
|
+
const masked = text.replace(/"(?:[^"\\]|\\.)*"/g, (match) => {
|
|
14
|
+
strings.push(match);
|
|
15
|
+
return '\x01' + (strings.length - 1) + '\x01';
|
|
16
|
+
});
|
|
17
|
+
// Quote any bare integer with >15 digits.
|
|
18
|
+
const patched = masked.replace(/-?\d{16,}/g, (m) => '"' + m + '"');
|
|
19
|
+
// Restore original string values.
|
|
20
|
+
return patched.replace(/\x01(\d+)\x01/g, (_, i) => strings[parseInt(i, 10)]);
|
|
21
|
+
}
|
|
5
22
|
/**
|
|
6
23
|
* Parse the raw HTTP response body.
|
|
7
24
|
* Throws TigerError when code != 0.
|
|
25
|
+
* Large integers in the outer envelope are not an issue (only inner `data` contains int64 IDs).
|
|
8
26
|
*/
|
|
9
27
|
export function parseApiResponse(body) {
|
|
10
28
|
const resp = JSON.parse(body);
|
|
@@ -22,9 +40,10 @@ export function unmarshalData(data) {
|
|
|
22
40
|
if (data == null)
|
|
23
41
|
return undefined;
|
|
24
42
|
if (typeof data === 'string') {
|
|
25
|
-
// Attempt to parse JSON string (double-encoded case)
|
|
43
|
+
// Attempt to parse JSON string (double-encoded case).
|
|
44
|
+
// Patch large integers before parsing so int64 IDs survive as strings.
|
|
26
45
|
try {
|
|
27
|
-
return JSON.parse(data);
|
|
46
|
+
return JSON.parse(patchLargeIntegers(data));
|
|
28
47
|
}
|
|
29
48
|
catch {
|
|
30
49
|
return data;
|
|
@@ -26,6 +26,7 @@ const TIGER_PUBLIC_KEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNF3G8SoEcCZh2rs
|
|
|
26
26
|
const ENV_TIGER_ID = 'TIGEROPEN_TIGER_ID';
|
|
27
27
|
const ENV_PRIVATE_KEY = 'TIGEROPEN_PRIVATE_KEY';
|
|
28
28
|
const ENV_ACCOUNT = 'TIGEROPEN_ACCOUNT';
|
|
29
|
+
const ENV_SECRET_KEY = 'TIGEROPEN_SECRET_KEY';
|
|
29
30
|
const ENV_TOKEN = 'TIGEROPEN_TOKEN';
|
|
30
31
|
const ENV_TOKEN_FILE = 'TIGEROPEN_TOKEN_FILE';
|
|
31
32
|
/**
|
|
@@ -124,6 +125,7 @@ export function createClientConfig(options) {
|
|
|
124
125
|
let tigerId = opts.tigerId || fileProps['tiger_id'] || '';
|
|
125
126
|
let privateKey = opts.privateKey || resolvePrivateKey(fileProps) || '';
|
|
126
127
|
let account = opts.account || fileProps['account'] || '';
|
|
128
|
+
let secretKey = opts.secretKey || fileProps['secret_key'] || undefined;
|
|
127
129
|
let token = opts.token || fileProps['token'];
|
|
128
130
|
const license = opts.license || fileProps['license'];
|
|
129
131
|
const language = opts.language || fileProps['language'] || DEFAULT_LANGUAGE;
|
|
@@ -132,6 +134,7 @@ export function createClientConfig(options) {
|
|
|
132
134
|
const envTigerId = process.env[ENV_TIGER_ID];
|
|
133
135
|
const envPrivateKey = process.env[ENV_PRIVATE_KEY];
|
|
134
136
|
const envAccount = process.env[ENV_ACCOUNT];
|
|
137
|
+
const envSecretKey = process.env[ENV_SECRET_KEY];
|
|
135
138
|
const envToken = process.env[ENV_TOKEN];
|
|
136
139
|
if (envTigerId) {
|
|
137
140
|
tigerId = envTigerId;
|
|
@@ -142,6 +145,9 @@ export function createClientConfig(options) {
|
|
|
142
145
|
if (envAccount) {
|
|
143
146
|
account = envAccount;
|
|
144
147
|
}
|
|
148
|
+
if (envSecretKey) {
|
|
149
|
+
secretKey = envSecretKey;
|
|
150
|
+
}
|
|
145
151
|
if (envToken) {
|
|
146
152
|
token = envToken;
|
|
147
153
|
}
|
|
@@ -211,6 +217,7 @@ export function createClientConfig(options) {
|
|
|
211
217
|
tigerId,
|
|
212
218
|
privateKey,
|
|
213
219
|
account,
|
|
220
|
+
secretKey: secretKey || undefined,
|
|
214
221
|
license,
|
|
215
222
|
language,
|
|
216
223
|
timezone,
|
package/dist/esm/index.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* @packageDocumentation
|
|
16
16
|
*/
|
|
17
17
|
/** SDK 版本号 */
|
|
18
|
-
export const VERSION = '0.4.
|
|
18
|
+
export const VERSION = '0.4.6';
|
|
19
19
|
// Config
|
|
20
20
|
export { createClientConfig, loadPropertiesFile } from './config/index.js';
|
|
21
21
|
export { TokenManager } from './config/index.js';
|
package/dist/esm/model/enums.js
CHANGED
|
@@ -47,7 +47,20 @@ export var OrderType;
|
|
|
47
47
|
OrderType["TWAP"] = "TWAP";
|
|
48
48
|
OrderType["VWAP"] = "VWAP";
|
|
49
49
|
OrderType["OCA"] = "OCA";
|
|
50
|
+
OrderType["ICEBERG"] = "ICEBERG";
|
|
50
51
|
})(OrderType || (OrderType = {}));
|
|
52
|
+
/** 冰山单价格类型 */
|
|
53
|
+
export var PriceType;
|
|
54
|
+
(function (PriceType) {
|
|
55
|
+
/** 限价 */
|
|
56
|
+
PriceType["LIMIT_PRICE"] = "LIMIT_PRICE";
|
|
57
|
+
/** 卖一价 */
|
|
58
|
+
PriceType["ASK_PRICE"] = "ASK_PRICE";
|
|
59
|
+
/** 买一价 */
|
|
60
|
+
PriceType["BID_PRICE"] = "BID_PRICE";
|
|
61
|
+
/** 最新价 */
|
|
62
|
+
PriceType["LATEST_PRICE"] = "LATEST_PRICE";
|
|
63
|
+
})(PriceType || (PriceType = {}));
|
|
51
64
|
/**
|
|
52
65
|
* 订单状态枚举。对齐 Java SDK OrderStatus 定义。
|
|
53
66
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OrderType, TimeInForce } from './enums.js';
|
|
1
|
+
import { OrderType, TimeInForce, PriceType } from './enums.js';
|
|
2
2
|
/** Market order */
|
|
3
3
|
export function marketOrder(account, symbol, secType, action, quantity) {
|
|
4
4
|
return {
|
|
@@ -87,6 +87,48 @@ export function algoOrder(account, symbol, secType, action, quantity, limitPrice
|
|
|
87
87
|
outsideRth: false,
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Iceberg order (basic) — only displaySize required.
|
|
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).
|
|
108
|
+
* Pass `startTime` / `endTime` as 0 to omit the time window.
|
|
109
|
+
*/
|
|
110
|
+
export function icebergOrderFull(account, symbol, secType, action, quantity, limitPrice, displaySize, minDisplaySize, checkIntervals, priceType, startTime, endTime) {
|
|
111
|
+
const req = {
|
|
112
|
+
account, symbol, secType, action,
|
|
113
|
+
orderType: OrderType.ICEBERG,
|
|
114
|
+
totalQuantity: quantity,
|
|
115
|
+
limitPrice,
|
|
116
|
+
timeInForce: TimeInForce.DAY,
|
|
117
|
+
outsideRth: false,
|
|
118
|
+
displaySize,
|
|
119
|
+
};
|
|
120
|
+
if (minDisplaySize !== undefined && minDisplaySize > 0)
|
|
121
|
+
req.minDisplaySize = minDisplaySize;
|
|
122
|
+
if (checkIntervals !== undefined && checkIntervals > 0)
|
|
123
|
+
req.checkIntervals = checkIntervals;
|
|
124
|
+
if (priceType)
|
|
125
|
+
req.priceType = priceType;
|
|
126
|
+
if (startTime && startTime > 0)
|
|
127
|
+
req.startTime = startTime;
|
|
128
|
+
if (endTime && endTime > 0)
|
|
129
|
+
req.endTime = endTime;
|
|
130
|
+
return req;
|
|
131
|
+
}
|
|
90
132
|
/** Attached profit / loss leg */
|
|
91
133
|
export function orderLeg(legType, price, timeInForce) {
|
|
92
134
|
return { legType, price, timeInForce };
|
|
@@ -22,9 +22,10 @@ function withAccount(req, account) {
|
|
|
22
22
|
}
|
|
23
23
|
/** Trading client wrapping all trade-related APIs. */
|
|
24
24
|
export class TradeClient {
|
|
25
|
-
constructor(httpClient, account) {
|
|
25
|
+
constructor(httpClient, account, secretKey) {
|
|
26
26
|
this.httpClient = httpClient;
|
|
27
27
|
this.account = account;
|
|
28
|
+
this.secretKey = secretKey;
|
|
28
29
|
}
|
|
29
30
|
async callInto(method, bizParams) {
|
|
30
31
|
const request = createApiRequest(method, bizParams);
|
|
@@ -60,16 +61,26 @@ export class TradeClient {
|
|
|
60
61
|
}
|
|
61
62
|
// === Order operations ===
|
|
62
63
|
async placeOrder(order) {
|
|
63
|
-
|
|
64
|
+
const params = { ...order, account: this.account };
|
|
65
|
+
if (!params.secretKey && this.secretKey)
|
|
66
|
+
params.secretKey = this.secretKey;
|
|
67
|
+
return this.callInto('place_order', params);
|
|
64
68
|
}
|
|
65
69
|
async previewOrder(order) {
|
|
66
70
|
return this.callInto('preview_order', { ...order, account: this.account });
|
|
67
71
|
}
|
|
68
72
|
async modifyOrder(id, order) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return this.callInto('
|
|
73
|
+
const params = { ...order, account: this.account, id };
|
|
74
|
+
if (!params.secretKey && this.secretKey)
|
|
75
|
+
params.secretKey = this.secretKey;
|
|
76
|
+
return this.callInto('modify_order', params);
|
|
77
|
+
}
|
|
78
|
+
async cancelOrder(id, secretKey) {
|
|
79
|
+
const sk = secretKey ?? this.secretKey;
|
|
80
|
+
const params = { account: this.account, id };
|
|
81
|
+
if (sk)
|
|
82
|
+
params.secretKey = sk;
|
|
83
|
+
return this.callInto('cancel_order', params);
|
|
73
84
|
}
|
|
74
85
|
// === Order queries (BREAKING v0.4.0) ===
|
|
75
86
|
/**
|
|
@@ -14,6 +14,7 @@ export interface ApiResponse {
|
|
|
14
14
|
/**
|
|
15
15
|
* Parse the raw HTTP response body.
|
|
16
16
|
* Throws TigerError when code != 0.
|
|
17
|
+
* Large integers in the outer envelope are not an issue (only inner `data` contains int64 IDs).
|
|
17
18
|
*/
|
|
18
19
|
export declare function parseApiResponse(body: string): ApiResponse;
|
|
19
20
|
/**
|
|
@@ -3,6 +3,8 @@ export interface ClientConfig {
|
|
|
3
3
|
tigerId: string;
|
|
4
4
|
privateKey: string;
|
|
5
5
|
account: string;
|
|
6
|
+
/** Institution secret key for trade authentication (institution accounts only) */
|
|
7
|
+
secretKey?: string;
|
|
6
8
|
license?: string;
|
|
7
9
|
language: string;
|
|
8
10
|
timezone?: string;
|
|
@@ -27,6 +29,8 @@ export interface ClientConfigOptions {
|
|
|
27
29
|
tigerId?: string;
|
|
28
30
|
privateKey?: string;
|
|
29
31
|
account?: string;
|
|
32
|
+
/** Institution secret key for trade authentication (institution accounts only) */
|
|
33
|
+
secretKey?: string;
|
|
30
34
|
license?: string;
|
|
31
35
|
language?: string;
|
|
32
36
|
timezone?: string;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* @packageDocumentation
|
|
16
16
|
*/
|
|
17
17
|
/** SDK 版本号 */
|
|
18
|
-
export declare const VERSION = "0.4.
|
|
18
|
+
export declare const VERSION = "0.4.6";
|
|
19
19
|
export { createClientConfig, loadPropertiesFile } from './config';
|
|
20
20
|
export type { ClientConfig, ClientConfigOptions } from './config';
|
|
21
21
|
export { TokenManager } from './config';
|
|
@@ -42,7 +42,19 @@ export declare enum OrderType {
|
|
|
42
42
|
AL = "AL",
|
|
43
43
|
TWAP = "TWAP",
|
|
44
44
|
VWAP = "VWAP",
|
|
45
|
-
OCA = "OCA"
|
|
45
|
+
OCA = "OCA",
|
|
46
|
+
ICEBERG = "ICEBERG"
|
|
47
|
+
}
|
|
48
|
+
/** 冰山单价格类型 */
|
|
49
|
+
export declare enum PriceType {
|
|
50
|
+
/** 限价 */
|
|
51
|
+
LIMIT_PRICE = "LIMIT_PRICE",
|
|
52
|
+
/** 卖一价 */
|
|
53
|
+
ASK_PRICE = "ASK_PRICE",
|
|
54
|
+
/** 买一价 */
|
|
55
|
+
BID_PRICE = "BID_PRICE",
|
|
56
|
+
/** 最新价 */
|
|
57
|
+
LATEST_PRICE = "LATEST_PRICE"
|
|
46
58
|
}
|
|
47
59
|
/**
|
|
48
60
|
* 订单状态枚举。对齐 Java SDK OrderStatus 定义。
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* All helpers return an `OrderRequest` with sensible defaults.
|
|
4
4
|
*/
|
|
5
5
|
import type { OrderRequest, OrderLegRequest, AlgoParamsRequest } from './order';
|
|
6
|
+
import { PriceType } from './enums';
|
|
6
7
|
/** Market order */
|
|
7
8
|
export declare function marketOrder(account: string, symbol: string, secType: string, action: string, quantity: number): OrderRequest;
|
|
8
9
|
/** Limit order */
|
|
@@ -19,5 +20,15 @@ export declare function auctionLimitOrder(account: string, symbol: string, secTy
|
|
|
19
20
|
export declare function auctionMarketOrder(account: string, symbol: string, secType: string, action: string, quantity: number): OrderRequest;
|
|
20
21
|
/** Algo order (TWAP / VWAP) */
|
|
21
22
|
export declare function algoOrder(account: string, symbol: string, secType: string, action: string, quantity: number, limitPrice: number, algoType: string, params: AlgoParamsRequest): OrderRequest;
|
|
23
|
+
/**
|
|
24
|
+
* Iceberg order (basic) — only displaySize required.
|
|
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).
|
|
30
|
+
* Pass `startTime` / `endTime` as 0 to omit the time window.
|
|
31
|
+
*/
|
|
32
|
+
export declare function icebergOrderFull(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;
|
|
22
33
|
/** Attached profit / loss leg */
|
|
23
34
|
export declare function orderLeg(legType: string, price: number, timeInForce: string): OrderLegRequest;
|
|
@@ -22,8 +22,9 @@ export interface AlgoParams {
|
|
|
22
22
|
/** Order response model (returned by order query methods). */
|
|
23
23
|
export interface Order {
|
|
24
24
|
account?: string;
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
/** int64 order ID — may be a string when it exceeds Number.MAX_SAFE_INTEGER */
|
|
26
|
+
id?: number | string;
|
|
27
|
+
orderId?: number | string;
|
|
27
28
|
externalId?: string;
|
|
28
29
|
action?: string;
|
|
29
30
|
orderType?: string;
|
|
@@ -82,6 +83,8 @@ export interface OrderRequest {
|
|
|
82
83
|
account?: string;
|
|
83
84
|
/** Global order ID (required for modify) */
|
|
84
85
|
id?: number;
|
|
86
|
+
/** Institutional account trading key (client fills it in automatically if set) */
|
|
87
|
+
secretKey?: string;
|
|
85
88
|
/** Account-level order ID */
|
|
86
89
|
orderId?: number;
|
|
87
90
|
/** BUY / SELL */
|
|
@@ -124,6 +127,18 @@ export interface OrderRequest {
|
|
|
124
127
|
remark?: string;
|
|
125
128
|
/** User mark */
|
|
126
129
|
userMark?: string;
|
|
130
|
+
/** 冰山单:展示数量 */
|
|
131
|
+
displaySize?: number;
|
|
132
|
+
/** 冰山单:最小展示数量 */
|
|
133
|
+
minDisplaySize?: number;
|
|
134
|
+
/** 冰山单:价检间隔(秒) */
|
|
135
|
+
checkIntervals?: number;
|
|
136
|
+
/** 冰山单:价格类型(LIMIT_PRICE / ASK_PRICE / BID_PRICE / LATEST_PRICE) */
|
|
137
|
+
priceType?: string;
|
|
138
|
+
/** 冰山单:生效开始时间(epoch ms) */
|
|
139
|
+
startTime?: number;
|
|
140
|
+
/** 冰山单:生效结束时间(epoch ms) */
|
|
141
|
+
endTime?: number;
|
|
127
142
|
}
|
|
128
143
|
/** Attached leg for request side */
|
|
129
144
|
export interface OrderLegRequest {
|
|
@@ -84,14 +84,16 @@ export interface PreviewResult {
|
|
|
84
84
|
message?: string;
|
|
85
85
|
}
|
|
86
86
|
export interface PlaceOrderResult {
|
|
87
|
-
|
|
87
|
+
/** int64 order ID — may be a string when it exceeds Number.MAX_SAFE_INTEGER */
|
|
88
|
+
id: number | string;
|
|
88
89
|
/** Account-level order ID; the server returns snake_case `order_id` */
|
|
89
|
-
order_id?: number;
|
|
90
|
-
subIds?: number[];
|
|
90
|
+
order_id?: number | string;
|
|
91
|
+
subIds?: (number | string)[];
|
|
91
92
|
orders?: Order[];
|
|
92
93
|
}
|
|
93
94
|
export interface OrderIdResult {
|
|
94
|
-
|
|
95
|
+
/** int64 order ID — may be a string when it exceeds Number.MAX_SAFE_INTEGER */
|
|
96
|
+
id: number | string;
|
|
95
97
|
}
|
|
96
98
|
export interface Transaction {
|
|
97
99
|
id?: number;
|
|
@@ -17,7 +17,8 @@ import type { OrdersRequest, GetOrderRequest, OrderTransactionsRequest, Position
|
|
|
17
17
|
export declare class TradeClient {
|
|
18
18
|
private httpClient;
|
|
19
19
|
private account;
|
|
20
|
-
|
|
20
|
+
private secretKey?;
|
|
21
|
+
constructor(httpClient: HttpClient, account: string, secretKey?: string);
|
|
21
22
|
private callInto;
|
|
22
23
|
/** Strip `{items: [...]}` envelope used by most trade read endpoints. */
|
|
23
24
|
private callIntoItems;
|
|
@@ -30,8 +31,8 @@ export declare class TradeClient {
|
|
|
30
31
|
getQuoteContract(symbol: string, secType: string, expiry: string): Promise<Contract[]>;
|
|
31
32
|
placeOrder(order: OrderRequest): Promise<PlaceOrderResult | undefined>;
|
|
32
33
|
previewOrder(order: OrderRequest): Promise<PreviewResult | undefined>;
|
|
33
|
-
modifyOrder(id: number, order: OrderRequest): Promise<OrderIdResult | undefined>;
|
|
34
|
-
cancelOrder(id: number): Promise<OrderIdResult | undefined>;
|
|
34
|
+
modifyOrder(id: number | string, order: OrderRequest): Promise<OrderIdResult | undefined>;
|
|
35
|
+
cancelOrder(id: number | string, secretKey?: string): Promise<OrderIdResult | undefined>;
|
|
35
36
|
/**
|
|
36
37
|
* Query all historical orders. v0.4.0: optional OrdersRequest for filtering.
|
|
37
38
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tigeropenapi/tigeropen",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
4
4
|
"description": "Tiger Brokers OpenAPI TypeScript SDK for market data, trading, and real-time push",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"@types/node": "^25.6.0",
|
|
51
51
|
"fast-check": "^3.15.0",
|
|
52
52
|
"ts-proto": "^2.11.6",
|
|
53
|
+
"tsx": "^4.22.4",
|
|
53
54
|
"typescript": "^5.3.0",
|
|
54
55
|
"vitest": "^1.2.0"
|
|
55
56
|
},
|