@tigeropenapi/tigeropen 0.1.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/LICENSE +21 -0
- package/README.md +272 -0
- package/dist/cjs/client/api-request.js +26 -0
- package/dist/cjs/client/api-response.js +18 -0
- package/dist/cjs/client/errors.js +51 -0
- package/dist/cjs/client/http-client.js +149 -0
- package/dist/cjs/client/index.js +19 -0
- package/dist/cjs/client/retry.js +54 -0
- package/dist/cjs/config/client-config.js +114 -0
- package/dist/cjs/config/config-parser.js +142 -0
- package/dist/cjs/config/domain.js +97 -0
- package/dist/cjs/config/index.js +14 -0
- package/dist/cjs/config/token-manager.js +116 -0
- package/dist/cjs/index.js +21 -0
- package/dist/cjs/logger/index.js +20 -0
- package/dist/cjs/logger/logger.js +68 -0
- package/dist/cjs/model/contract-helpers.js +38 -0
- package/dist/cjs/model/contract.js +6 -0
- package/dist/cjs/model/enums.js +110 -0
- package/dist/cjs/model/order-helpers.js +104 -0
- package/dist/cjs/model/order.js +6 -0
- package/dist/cjs/model/position.js +6 -0
- package/dist/cjs/push/callbacks.js +2 -0
- package/dist/cjs/push/index.js +25 -0
- package/dist/cjs/push/push-client.js +423 -0
- package/dist/cjs/push/push-message.js +83 -0
- package/dist/cjs/quote/index.js +8 -0
- package/dist/cjs/quote/quote-client.js +110 -0
- package/dist/cjs/signer/index.js +12 -0
- package/dist/cjs/signer/sign-content.js +19 -0
- package/dist/cjs/signer/signer.js +93 -0
- package/dist/cjs/trade/index.js +8 -0
- package/dist/cjs/trade/trade-client.js +99 -0
- package/dist/esm/client/api-request.js +23 -0
- package/dist/esm/client/api-response.js +15 -0
- package/dist/esm/client/errors.js +46 -0
- package/dist/esm/client/http-client.js +145 -0
- package/dist/esm/client/index.js +8 -0
- package/dist/esm/client/retry.js +48 -0
- package/dist/esm/config/client-config.js +111 -0
- package/dist/esm/config/config-parser.js +105 -0
- package/dist/esm/config/domain.js +93 -0
- package/dist/esm/config/index.js +6 -0
- package/dist/esm/config/token-manager.js +112 -0
- package/dist/esm/index.js +18 -0
- package/dist/esm/logger/index.js +4 -0
- package/dist/esm/logger/logger.js +61 -0
- package/dist/esm/model/contract-helpers.js +29 -0
- package/dist/esm/model/contract.js +5 -0
- package/dist/esm/model/enums.js +107 -0
- package/dist/esm/model/order-helpers.js +93 -0
- package/dist/esm/model/order.js +5 -0
- package/dist/esm/model/position.js +5 -0
- package/dist/esm/push/callbacks.js +1 -0
- package/dist/esm/push/index.js +6 -0
- package/dist/esm/push/push-client.js +419 -0
- package/dist/esm/push/push-message.js +77 -0
- package/dist/esm/quote/index.js +4 -0
- package/dist/esm/quote/quote-client.js +106 -0
- package/dist/esm/signer/index.js +5 -0
- package/dist/esm/signer/sign-content.js +16 -0
- package/dist/esm/signer/signer.js +88 -0
- package/dist/esm/trade/index.js +4 -0
- package/dist/esm/trade/trade-client.js +95 -0
- package/dist/types/client/api-request.d.ts +18 -0
- package/dist/types/client/api-response.d.ts +16 -0
- package/dist/types/client/errors.d.ts +19 -0
- package/dist/types/client/http-client.d.ts +45 -0
- package/dist/types/client/index.d.ts +8 -0
- package/dist/types/client/retry.d.ts +37 -0
- package/dist/types/config/client-config.d.ts +43 -0
- package/dist/types/config/config-parser.d.ts +16 -0
- package/dist/types/config/domain.d.ts +18 -0
- package/dist/types/config/index.d.ts +7 -0
- package/dist/types/config/token-manager.d.ts +38 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/logger/index.d.ts +4 -0
- package/dist/types/logger/logger.d.ts +42 -0
- package/dist/types/model/contract-helpers.d.ts +18 -0
- package/dist/types/model/contract.d.ts +60 -0
- package/dist/types/model/enums.d.ts +97 -0
- package/dist/types/model/order-helpers.d.ts +22 -0
- package/dist/types/model/order.d.ts +95 -0
- package/dist/types/model/position.d.ts +39 -0
- package/dist/types/push/callbacks.d.ts +57 -0
- package/dist/types/push/index.d.ts +7 -0
- package/dist/types/push/push-client.d.ts +139 -0
- package/dist/types/push/push-message.d.ts +167 -0
- package/dist/types/quote/index.d.ts +4 -0
- package/dist/types/quote/quote-client.d.ts +58 -0
- package/dist/types/signer/index.d.ts +5 -0
- package/dist/types/signer/sign-content.d.ts +13 -0
- package/dist/types/signer/signer.d.ts +36 -0
- package/dist/types/trade/index.d.ts +4 -0
- package/dist/types/trade/trade-client.d.ts +48 -0
- package/package.json +54 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 推送消息类型定义和数据结构
|
|
3
|
+
*
|
|
4
|
+
* 定义 WebSocket 推送消息的类型、主题和数据结构,
|
|
5
|
+
* 使用 JSON 序列化/反序列化(简化替代 Protobuf)。
|
|
6
|
+
*/
|
|
7
|
+
/** 推送消息类型 */
|
|
8
|
+
export var MessageType;
|
|
9
|
+
(function (MessageType) {
|
|
10
|
+
// 连接相关
|
|
11
|
+
MessageType["Connect"] = "connect";
|
|
12
|
+
MessageType["Connected"] = "connected";
|
|
13
|
+
MessageType["Disconnect"] = "disconnect";
|
|
14
|
+
MessageType["Heartbeat"] = "heartbeat";
|
|
15
|
+
MessageType["Kickout"] = "kickout";
|
|
16
|
+
MessageType["Error"] = "error";
|
|
17
|
+
// 订阅相关
|
|
18
|
+
MessageType["Subscribe"] = "subscribe";
|
|
19
|
+
MessageType["Unsubscribe"] = "unsubscribe";
|
|
20
|
+
// 行情推送
|
|
21
|
+
MessageType["Quote"] = "quote";
|
|
22
|
+
MessageType["Tick"] = "tick";
|
|
23
|
+
MessageType["Depth"] = "depth";
|
|
24
|
+
MessageType["Option"] = "option";
|
|
25
|
+
MessageType["Future"] = "future";
|
|
26
|
+
MessageType["Kline"] = "kline";
|
|
27
|
+
MessageType["StockTop"] = "stock_top";
|
|
28
|
+
MessageType["OptionTop"] = "option_top";
|
|
29
|
+
MessageType["FullTick"] = "full_tick";
|
|
30
|
+
MessageType["QuoteBBO"] = "quote_bbo";
|
|
31
|
+
// 账户推送
|
|
32
|
+
MessageType["Asset"] = "asset";
|
|
33
|
+
MessageType["Position"] = "position";
|
|
34
|
+
MessageType["Order"] = "order";
|
|
35
|
+
MessageType["Transaction"] = "transaction";
|
|
36
|
+
})(MessageType || (MessageType = {}));
|
|
37
|
+
/** 订阅主题类型 */
|
|
38
|
+
export var SubjectType;
|
|
39
|
+
(function (SubjectType) {
|
|
40
|
+
SubjectType["Quote"] = "quote";
|
|
41
|
+
SubjectType["Tick"] = "tick";
|
|
42
|
+
SubjectType["Depth"] = "depth";
|
|
43
|
+
SubjectType["Option"] = "option";
|
|
44
|
+
SubjectType["Future"] = "future";
|
|
45
|
+
SubjectType["Kline"] = "kline";
|
|
46
|
+
SubjectType["StockTop"] = "stock_top";
|
|
47
|
+
SubjectType["OptionTop"] = "option_top";
|
|
48
|
+
SubjectType["FullTick"] = "full_tick";
|
|
49
|
+
SubjectType["QuoteBBO"] = "quote_bbo";
|
|
50
|
+
SubjectType["Asset"] = "asset";
|
|
51
|
+
SubjectType["Position"] = "position";
|
|
52
|
+
SubjectType["Order"] = "order";
|
|
53
|
+
SubjectType["Transaction"] = "transaction";
|
|
54
|
+
})(SubjectType || (SubjectType = {}));
|
|
55
|
+
/**
|
|
56
|
+
* 创建推送消息
|
|
57
|
+
*/
|
|
58
|
+
export function createPushMessage(type, subject, data) {
|
|
59
|
+
const msg = { type };
|
|
60
|
+
if (subject)
|
|
61
|
+
msg.subject = subject;
|
|
62
|
+
if (data !== undefined)
|
|
63
|
+
msg.data = data;
|
|
64
|
+
return msg;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 序列化推送消息为 JSON 字符串
|
|
68
|
+
*/
|
|
69
|
+
export function serializeMessage(msg) {
|
|
70
|
+
return JSON.stringify(msg);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 反序列化 JSON 字符串为推送消息
|
|
74
|
+
*/
|
|
75
|
+
export function deserializeMessage(data) {
|
|
76
|
+
return JSON.parse(data);
|
|
77
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createApiRequest } from '../client/api-request';
|
|
2
|
+
/**
|
|
3
|
+
* 行情查询客户端,封装所有行情相关 API。
|
|
4
|
+
*/
|
|
5
|
+
export class QuoteClient {
|
|
6
|
+
constructor(httpClient) {
|
|
7
|
+
this.httpClient = httpClient;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 内部通用方法:构造请求、发送、返回 data 字段
|
|
11
|
+
*/
|
|
12
|
+
async execute(method, bizParams) {
|
|
13
|
+
const request = createApiRequest(method, bizParams);
|
|
14
|
+
const response = await this.httpClient.executeRequest(request);
|
|
15
|
+
return response.data;
|
|
16
|
+
}
|
|
17
|
+
// === 基础行情方法 ===
|
|
18
|
+
/** 获取市场状态 */
|
|
19
|
+
async marketState(market) {
|
|
20
|
+
return this.execute('market_state', { market });
|
|
21
|
+
}
|
|
22
|
+
/** 获取实时报价 */
|
|
23
|
+
async quoteRealTime(symbols) {
|
|
24
|
+
return this.execute('quote_real_time', { symbols });
|
|
25
|
+
}
|
|
26
|
+
/** 获取 K 线数据 */
|
|
27
|
+
async kline(symbol, period) {
|
|
28
|
+
return this.execute('kline', { symbols: [symbol], period });
|
|
29
|
+
}
|
|
30
|
+
/** 获取分时数据 */
|
|
31
|
+
async timeline(symbols) {
|
|
32
|
+
return this.execute('timeline', { symbols });
|
|
33
|
+
}
|
|
34
|
+
/** 获取逐笔成交数据 */
|
|
35
|
+
async tradeTick(symbols) {
|
|
36
|
+
return this.execute('trade_tick', { symbols });
|
|
37
|
+
}
|
|
38
|
+
/** 获取深度行情 */
|
|
39
|
+
async quoteDepth(symbol) {
|
|
40
|
+
return this.execute('quote_depth', { symbol });
|
|
41
|
+
}
|
|
42
|
+
// === 期权行情方法 ===
|
|
43
|
+
/** 获取期权到期日 */
|
|
44
|
+
async optionExpiration(symbol) {
|
|
45
|
+
return this.execute('option_expiration', { symbols: [symbol] });
|
|
46
|
+
}
|
|
47
|
+
/** 获取期权链 */
|
|
48
|
+
async optionChain(symbol, expiry) {
|
|
49
|
+
return this.execute('option_chain', { symbol, expiry });
|
|
50
|
+
}
|
|
51
|
+
/** 获取期权报价 */
|
|
52
|
+
async optionBrief(identifiers) {
|
|
53
|
+
return this.execute('option_brief', { identifiers });
|
|
54
|
+
}
|
|
55
|
+
/** 获取期权 K 线 */
|
|
56
|
+
async optionKline(identifier, period) {
|
|
57
|
+
return this.execute('option_kline', { identifier, period });
|
|
58
|
+
}
|
|
59
|
+
// === 期货行情方法 ===
|
|
60
|
+
/** 获取期货交易所列表 */
|
|
61
|
+
async futureExchange() {
|
|
62
|
+
return this.execute('future_exchange', { sec_type: 'FUT' });
|
|
63
|
+
}
|
|
64
|
+
/** 获取期货合约列表 */
|
|
65
|
+
async futureContracts(exchange) {
|
|
66
|
+
return this.execute('future_contracts', { exchange });
|
|
67
|
+
}
|
|
68
|
+
/** 获取期货实时报价 */
|
|
69
|
+
async futureRealTimeQuote(symbols) {
|
|
70
|
+
return this.execute('future_real_time_quote', { symbols });
|
|
71
|
+
}
|
|
72
|
+
/** 获取期货 K 线 */
|
|
73
|
+
async futureKline(symbol, period) {
|
|
74
|
+
return this.execute('future_kline', { symbol, period });
|
|
75
|
+
}
|
|
76
|
+
// === 基本面和资金流向方法 ===
|
|
77
|
+
/** 获取财务日报 */
|
|
78
|
+
async financialDaily(symbol) {
|
|
79
|
+
return this.execute('financial_daily', { symbol });
|
|
80
|
+
}
|
|
81
|
+
/** 获取财务报告 */
|
|
82
|
+
async financialReport(symbol) {
|
|
83
|
+
return this.execute('financial_report', { symbol });
|
|
84
|
+
}
|
|
85
|
+
/** 获取公司行动 */
|
|
86
|
+
async corporateAction(symbol) {
|
|
87
|
+
return this.execute('corporate_action', { symbol });
|
|
88
|
+
}
|
|
89
|
+
/** 获取资金流向 */
|
|
90
|
+
async capitalFlow(symbol) {
|
|
91
|
+
return this.execute('capital_flow', { symbol });
|
|
92
|
+
}
|
|
93
|
+
/** 获取资金分布 */
|
|
94
|
+
async capitalDistribution(symbol) {
|
|
95
|
+
return this.execute('capital_distribution', { symbol });
|
|
96
|
+
}
|
|
97
|
+
// === 选股器和行情权限方法 ===
|
|
98
|
+
/** 选股器 */
|
|
99
|
+
async marketScanner(params) {
|
|
100
|
+
return this.execute('market_scanner', params);
|
|
101
|
+
}
|
|
102
|
+
/** 获取行情权限 */
|
|
103
|
+
async grabQuotePermission() {
|
|
104
|
+
return this.execute('grab_quote_permission');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 请求参数排序拼接模块
|
|
3
|
+
*
|
|
4
|
+
* 按参数名字母序排列所有参数,拼接为 key=value&key=value 格式,
|
|
5
|
+
* 用于构造 RSA 签名的待签名内容。
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 按参数名字母序排列所有参数,拼接为 key=value&key=value 格式。
|
|
9
|
+
*
|
|
10
|
+
* @param params - 参数名-值映射
|
|
11
|
+
* @returns 拼接后的字符串
|
|
12
|
+
*/
|
|
13
|
+
export function getSignContent(params) {
|
|
14
|
+
const keys = Object.keys(params).sort();
|
|
15
|
+
return keys.map((k) => `${k}=${params[k]}`).join('&');
|
|
16
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RSA 签名模块
|
|
3
|
+
*
|
|
4
|
+
* 提供 RSA 私钥加载、SHA1WithRSA 签名和验签功能。
|
|
5
|
+
* 支持 PKCS#1、PKCS#8 PEM 格式以及裸 Base64 编码。
|
|
6
|
+
*/
|
|
7
|
+
import { createSign, createVerify, createPrivateKey } from 'crypto';
|
|
8
|
+
/**
|
|
9
|
+
* 加载 RSA 私钥,支持以下格式:
|
|
10
|
+
* - PKCS#1 PEM(BEGIN RSA PRIVATE KEY)
|
|
11
|
+
* - PKCS#8 PEM(BEGIN PRIVATE KEY)
|
|
12
|
+
* - 裸 Base64 编码的 DER 数据(无 PEM 头尾)
|
|
13
|
+
*
|
|
14
|
+
* @param keyStr - 私钥字符串
|
|
15
|
+
* @returns KeyObject 私钥对象
|
|
16
|
+
* @throws 私钥为空或格式无效时抛出错误
|
|
17
|
+
*/
|
|
18
|
+
export function loadPrivateKey(keyStr) {
|
|
19
|
+
if (!keyStr) {
|
|
20
|
+
throw new Error('私钥不能为空');
|
|
21
|
+
}
|
|
22
|
+
// 尝试 PEM 格式(PKCS#1 或 PKCS#8)
|
|
23
|
+
if (keyStr.includes('-----BEGIN')) {
|
|
24
|
+
try {
|
|
25
|
+
return createPrivateKey(keyStr);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
throw new Error('无法解析私钥:PEM 格式无效');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// 非 PEM 格式,尝试作为裸 Base64 解码
|
|
32
|
+
// 先尝试 PKCS#1,再尝试 PKCS#8
|
|
33
|
+
const derBuffer = Buffer.from(keyStr, 'base64');
|
|
34
|
+
if (derBuffer.length === 0) {
|
|
35
|
+
throw new Error('无法解析私钥:不是有效的 PEM 或 Base64 格式');
|
|
36
|
+
}
|
|
37
|
+
// 尝试 PKCS#1 DER
|
|
38
|
+
try {
|
|
39
|
+
return createPrivateKey({
|
|
40
|
+
key: derBuffer,
|
|
41
|
+
format: 'der',
|
|
42
|
+
type: 'pkcs1',
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// 继续尝试 PKCS#8
|
|
47
|
+
}
|
|
48
|
+
// 尝试 PKCS#8 DER
|
|
49
|
+
try {
|
|
50
|
+
return createPrivateKey({
|
|
51
|
+
key: derBuffer,
|
|
52
|
+
format: 'der',
|
|
53
|
+
type: 'pkcs8',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
throw new Error('无法解析私钥:不是有效的 PKCS#1 或 PKCS#8 格式');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 使用 RSA 私钥对内容进行 SHA1WithRSA 签名,返回 Base64 编码的签名字符串。
|
|
62
|
+
*
|
|
63
|
+
* @param privateKeyStr - 私钥字符串(支持 PKCS#1/PKCS#8 PEM 或裸 Base64)
|
|
64
|
+
* @param content - 待签名内容
|
|
65
|
+
* @returns Base64 编码的签名字符串
|
|
66
|
+
* @throws 私钥无效或签名失败时抛出错误
|
|
67
|
+
*/
|
|
68
|
+
export function signWithRSA(privateKeyStr, content) {
|
|
69
|
+
const key = loadPrivateKey(privateKeyStr);
|
|
70
|
+
const sign = createSign('SHA1');
|
|
71
|
+
sign.update(content);
|
|
72
|
+
sign.end();
|
|
73
|
+
return sign.sign(key, 'base64');
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 使用 RSA 公钥验证 SHA1WithRSA 签名。
|
|
77
|
+
*
|
|
78
|
+
* @param publicKey - 公钥对象
|
|
79
|
+
* @param content - 原始内容
|
|
80
|
+
* @param signature - Base64 编码的签名字符串
|
|
81
|
+
* @returns 验签是否成功
|
|
82
|
+
*/
|
|
83
|
+
export function verifyWithRSA(publicKey, content, signature) {
|
|
84
|
+
const verify = createVerify('SHA1');
|
|
85
|
+
verify.update(content);
|
|
86
|
+
verify.end();
|
|
87
|
+
return verify.verify(publicKey, signature, 'base64');
|
|
88
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { createApiRequest } from '../client/api-request';
|
|
2
|
+
/**
|
|
3
|
+
* 交易客户端,封装所有交易相关 API。
|
|
4
|
+
*/
|
|
5
|
+
export class TradeClient {
|
|
6
|
+
constructor(httpClient, account) {
|
|
7
|
+
this.httpClient = httpClient;
|
|
8
|
+
this.account = account;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 内部通用方法:构造请求、发送、返回 data 字段
|
|
12
|
+
*/
|
|
13
|
+
async execute(method, bizParams) {
|
|
14
|
+
const request = createApiRequest(method, bizParams);
|
|
15
|
+
const response = await this.httpClient.executeRequest(request);
|
|
16
|
+
return response.data;
|
|
17
|
+
}
|
|
18
|
+
// === 合约查询方法 ===
|
|
19
|
+
/** 查询单个合约 */
|
|
20
|
+
async contract(symbol, secType) {
|
|
21
|
+
return this.execute('contract', {
|
|
22
|
+
account: this.account, symbol, secType,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/** 批量查询合约 */
|
|
26
|
+
async contracts(symbols, secType) {
|
|
27
|
+
return this.execute('contracts', {
|
|
28
|
+
account: this.account, symbols, secType,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/** 查询衍生品合约 */
|
|
32
|
+
async quoteContract(symbol, secType) {
|
|
33
|
+
return this.execute('quote_contract', {
|
|
34
|
+
account: this.account, symbol, secType,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// === 订单操作方法 ===
|
|
38
|
+
/** 下单 */
|
|
39
|
+
async placeOrder(order) {
|
|
40
|
+
const params = { ...order, account: this.account };
|
|
41
|
+
return this.execute('place_order', params);
|
|
42
|
+
}
|
|
43
|
+
/** 预览订单 */
|
|
44
|
+
async previewOrder(order) {
|
|
45
|
+
const params = { ...order, account: this.account };
|
|
46
|
+
return this.execute('preview_order', params);
|
|
47
|
+
}
|
|
48
|
+
/** 修改订单 */
|
|
49
|
+
async modifyOrder(id, order) {
|
|
50
|
+
const params = { ...order, account: this.account, id };
|
|
51
|
+
return this.execute('modify_order', params);
|
|
52
|
+
}
|
|
53
|
+
/** 取消订单 */
|
|
54
|
+
async cancelOrder(id) {
|
|
55
|
+
return this.execute('cancel_order', {
|
|
56
|
+
account: this.account, id,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// === 订单查询方法 ===
|
|
60
|
+
/** 查询全部订单 */
|
|
61
|
+
async orders() {
|
|
62
|
+
return this.execute('orders', { account: this.account });
|
|
63
|
+
}
|
|
64
|
+
/** 查询待成交订单 */
|
|
65
|
+
async activeOrders() {
|
|
66
|
+
return this.execute('active_orders', { account: this.account });
|
|
67
|
+
}
|
|
68
|
+
/** 查询已撤销订单 */
|
|
69
|
+
async inactiveOrders() {
|
|
70
|
+
return this.execute('inactive_orders', { account: this.account });
|
|
71
|
+
}
|
|
72
|
+
/** 查询已成交订单 */
|
|
73
|
+
async filledOrders() {
|
|
74
|
+
return this.execute('filled_orders', { account: this.account });
|
|
75
|
+
}
|
|
76
|
+
// === 持仓和资产查询方法 ===
|
|
77
|
+
/** 查询持仓 */
|
|
78
|
+
async positions() {
|
|
79
|
+
return this.execute('positions', { account: this.account });
|
|
80
|
+
}
|
|
81
|
+
/** 查询资产 */
|
|
82
|
+
async assets() {
|
|
83
|
+
return this.execute('assets', { account: this.account });
|
|
84
|
+
}
|
|
85
|
+
/** 查询综合账户资产 */
|
|
86
|
+
async primeAssets() {
|
|
87
|
+
return this.execute('prime_assets', { account: this.account });
|
|
88
|
+
}
|
|
89
|
+
/** 查询订单成交明细 */
|
|
90
|
+
async orderTransactions(id) {
|
|
91
|
+
return this.execute('order_transactions', {
|
|
92
|
+
account: this.account, id,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API 请求构造模块
|
|
3
|
+
*/
|
|
4
|
+
/** API 请求接口 */
|
|
5
|
+
export interface ApiRequest {
|
|
6
|
+
/** API 方法名(如 "market_state"、"place_order") */
|
|
7
|
+
method: string;
|
|
8
|
+
/** 业务参数 JSON 字符串 */
|
|
9
|
+
bizContent: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 创建 API 请求,将业务参数序列化为 JSON 字符串作为 bizContent。
|
|
13
|
+
*
|
|
14
|
+
* @param method - API 方法名
|
|
15
|
+
* @param bizParams - 业务参数(对象、字符串或 null)
|
|
16
|
+
* @returns ApiRequest 对象
|
|
17
|
+
*/
|
|
18
|
+
export declare function createApiRequest(method: string, bizParams: unknown): ApiRequest;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** API 响应接口 */
|
|
2
|
+
export interface ApiResponse {
|
|
3
|
+
/** 状态码(0=成功) */
|
|
4
|
+
code: number;
|
|
5
|
+
/** 状态描述 */
|
|
6
|
+
message: string;
|
|
7
|
+
/** 业务数据 */
|
|
8
|
+
data: unknown;
|
|
9
|
+
/** 服务器时间戳 */
|
|
10
|
+
timestamp: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 解析 API 响应 JSON 字符串。
|
|
14
|
+
* code 为 0 时返回 ApiResponse;code 不为 0 时抛出 TigerError。
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseApiResponse(body: string): ApiResponse;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 错误类型定义模块
|
|
3
|
+
*
|
|
4
|
+
* 定义 TigerError 及错误码分类逻辑。
|
|
5
|
+
*/
|
|
6
|
+
/** 错误分类 */
|
|
7
|
+
export type ErrorCategory = 'success' | 'common_param_error' | 'biz_param_error' | 'rate_limit' | 'trade_global_error' | 'trade_prime_error' | 'trade_simulation_error' | 'quote_stock_error' | 'quote_option_error' | 'quote_future_error' | 'token_error' | 'permission_error' | 'server_error' | 'unknown_error';
|
|
8
|
+
/**
|
|
9
|
+
* 根据错误码返回对应的错误分类
|
|
10
|
+
*/
|
|
11
|
+
export declare function classifyErrorCode(code: number): ErrorCategory;
|
|
12
|
+
/**
|
|
13
|
+
* TigerError - 统一错误类型
|
|
14
|
+
*/
|
|
15
|
+
export declare class TigerError extends Error {
|
|
16
|
+
code: number;
|
|
17
|
+
category: ErrorCategory;
|
|
18
|
+
constructor(code: number, message: string);
|
|
19
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HttpClient - HTTP 客户端
|
|
3
|
+
*
|
|
4
|
+
* 封装 HTTP 请求、签名、重试、超时。
|
|
5
|
+
* 使用 Node.js 内置 fetch(Node 18+)。
|
|
6
|
+
*/
|
|
7
|
+
import type { ClientConfig } from '../config/client-config';
|
|
8
|
+
import { RetryPolicy } from './retry';
|
|
9
|
+
import { type ApiResponse } from './api-response';
|
|
10
|
+
import type { ApiRequest } from './api-request';
|
|
11
|
+
/**
|
|
12
|
+
* HttpClient 封装 HTTP 请求、签名、重试、超时
|
|
13
|
+
*/
|
|
14
|
+
export declare class HttpClient {
|
|
15
|
+
private config;
|
|
16
|
+
private retryPolicy;
|
|
17
|
+
constructor(config: ClientConfig, retryPolicy?: RetryPolicy);
|
|
18
|
+
/**
|
|
19
|
+
* 构造公共请求参数
|
|
20
|
+
*/
|
|
21
|
+
private buildCommonParams;
|
|
22
|
+
/**
|
|
23
|
+
* 对参数进行签名
|
|
24
|
+
*/
|
|
25
|
+
private signParams;
|
|
26
|
+
/**
|
|
27
|
+
* 发送 HTTP POST 请求
|
|
28
|
+
*/
|
|
29
|
+
private doHttpPost;
|
|
30
|
+
/**
|
|
31
|
+
* 执行结构化 API 请求,返回解析后的 ApiResponse。
|
|
32
|
+
* 供 QuoteClient/TradeClient 内部使用。
|
|
33
|
+
*/
|
|
34
|
+
executeRequest(request: ApiRequest): Promise<ApiResponse>;
|
|
35
|
+
/**
|
|
36
|
+
* 通用 API 调用方法。
|
|
37
|
+
*
|
|
38
|
+
* @param apiMethod - API 方法名(如 "market_state"、"place_order")
|
|
39
|
+
* @param requestJson - 原始 biz_content JSON 字符串
|
|
40
|
+
* @returns 原始 response JSON 字符串,不做任何解析
|
|
41
|
+
*/
|
|
42
|
+
execute(apiMethod: string, requestJson: string): Promise<string>;
|
|
43
|
+
/** 延迟指定毫秒 */
|
|
44
|
+
private sleep;
|
|
45
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 传输层模块导出
|
|
3
|
+
*/
|
|
4
|
+
export { HttpClient } from './http-client';
|
|
5
|
+
export { TigerError, classifyErrorCode, type ErrorCategory } from './errors';
|
|
6
|
+
export { RetryPolicy, defaultRetryPolicy, isTradeOperation } from './retry';
|
|
7
|
+
export { type ApiRequest, createApiRequest } from './api-request';
|
|
8
|
+
export { type ApiResponse, parseApiResponse } from './api-response';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 重试策略模块
|
|
3
|
+
*
|
|
4
|
+
* 提供指数退避重试策略,交易操作(place_order/modify_order/cancel_order)跳过重试。
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* 判断是否为交易操作
|
|
8
|
+
*/
|
|
9
|
+
export declare function isTradeOperation(apiMethod: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* 重试策略
|
|
12
|
+
*/
|
|
13
|
+
export declare class RetryPolicy {
|
|
14
|
+
/** 最大重试次数,默认 5 */
|
|
15
|
+
maxRetries: number;
|
|
16
|
+
/** 最大重试总时间(毫秒),默认 60000 */
|
|
17
|
+
maxRetryTime: number;
|
|
18
|
+
/** 基础退避时间(毫秒),默认 1000 */
|
|
19
|
+
baseDelay: number;
|
|
20
|
+
/** 最大单次退避时间(毫秒),默认 16000 */
|
|
21
|
+
maxDelay: number;
|
|
22
|
+
constructor(options?: Partial<RetryPolicy>);
|
|
23
|
+
/**
|
|
24
|
+
* 判断指定的 API 方法是否应该重试。
|
|
25
|
+
* 交易操作跳过重试。
|
|
26
|
+
*/
|
|
27
|
+
shouldRetry(apiMethod: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* 计算第 n 次重试的退避等待时间(毫秒,从 0 开始计数)。
|
|
30
|
+
* 退避公式:min(2^n * baseDelay, maxDelay)
|
|
31
|
+
*/
|
|
32
|
+
calculateBackoff(retryCount: number): number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 返回默认重试策略
|
|
36
|
+
*/
|
|
37
|
+
export declare function defaultRetryPolicy(): RetryPolicy;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** 客户端配置接口 */
|
|
2
|
+
export interface ClientConfig {
|
|
3
|
+
tigerId: string;
|
|
4
|
+
privateKey: string;
|
|
5
|
+
account: string;
|
|
6
|
+
license?: string;
|
|
7
|
+
language: string;
|
|
8
|
+
timezone?: string;
|
|
9
|
+
timeout: number;
|
|
10
|
+
sandboxDebug: boolean;
|
|
11
|
+
token?: string;
|
|
12
|
+
tokenRefreshDuration?: number;
|
|
13
|
+
serverUrl: string;
|
|
14
|
+
}
|
|
15
|
+
/** 创建配置时的选项参数 */
|
|
16
|
+
export interface ClientConfigOptions {
|
|
17
|
+
tigerId?: string;
|
|
18
|
+
privateKey?: string;
|
|
19
|
+
account?: string;
|
|
20
|
+
license?: string;
|
|
21
|
+
language?: string;
|
|
22
|
+
timezone?: string;
|
|
23
|
+
timeout?: number;
|
|
24
|
+
sandboxDebug?: boolean;
|
|
25
|
+
token?: string;
|
|
26
|
+
tokenRefreshDuration?: number;
|
|
27
|
+
serverUrl?: string;
|
|
28
|
+
/** 是否启用动态域名获取(默认 true) */
|
|
29
|
+
enableDynamicDomain?: boolean;
|
|
30
|
+
/** properties 配置文件路径(同步读取) */
|
|
31
|
+
propertiesFilePath?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 创建客户端配置。
|
|
35
|
+
*
|
|
36
|
+
* 优先级:环境变量 > 代码设置(含配置文件) > 默认值。
|
|
37
|
+
* 必填字段 tigerId 和 privateKey 为空时抛出错误。
|
|
38
|
+
*
|
|
39
|
+
* @param options - 配置选项
|
|
40
|
+
* @returns 完整的客户端配置对象
|
|
41
|
+
* @throws tigerId 或 privateKey 为空时抛出错误
|
|
42
|
+
*/
|
|
43
|
+
export declare function createClientConfig(options: ClientConfigOptions): ClientConfig;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 解析 Java properties 格式的配置文件。
|
|
3
|
+
* 异步读取文件内容后调用 parsePropertiesString 解析。
|
|
4
|
+
*
|
|
5
|
+
* @param filePath - 配置文件路径
|
|
6
|
+
* @returns 键值对映射
|
|
7
|
+
* @throws 文件不存在或读取失败时抛出错误
|
|
8
|
+
*/
|
|
9
|
+
export declare function parsePropertiesFile(filePath: string): Promise<Record<string, string>>;
|
|
10
|
+
/**
|
|
11
|
+
* 解析 Java properties 格式的字符串内容。
|
|
12
|
+
*
|
|
13
|
+
* @param content - properties 格式的字符串
|
|
14
|
+
* @returns 键值对映射
|
|
15
|
+
*/
|
|
16
|
+
export declare function parsePropertiesString(content: string): Record<string, string>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 动态域名获取模块
|
|
3
|
+
*
|
|
4
|
+
* 从域名花园获取动态域名配置,用于 SDK 初始化时自动选择最优服务器地址。
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* 从域名花园获取动态域名配置。
|
|
8
|
+
* 失败时返回空对象(静默回退)。
|
|
9
|
+
*
|
|
10
|
+
* @param license - 牌照类型(如 "TBNZ")
|
|
11
|
+
* @returns 域名配置 map(key → URL)
|
|
12
|
+
*/
|
|
13
|
+
export declare function queryDomains(license?: string): Record<string, unknown>;
|
|
14
|
+
/**
|
|
15
|
+
* 根据动态域名配置和 license 解析服务器地址。
|
|
16
|
+
* 返回空字符串表示无法解析(应使用默认地址)。
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveDynamicServerUrl(domainConf: Record<string, unknown>, license?: string): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 配置层导出
|
|
3
|
+
*/
|
|
4
|
+
export { parsePropertiesFile, parsePropertiesString } from './config-parser';
|
|
5
|
+
export { createClientConfig } from './client-config';
|
|
6
|
+
export type { ClientConfig, ClientConfigOptions } from './client-config';
|
|
7
|
+
export { queryDomains, resolveDynamicServerUrl } from './domain';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** TokenManager 配置选项 */
|
|
2
|
+
export interface TokenManagerOptions {
|
|
3
|
+
filePath?: string;
|
|
4
|
+
refreshInterval?: number;
|
|
5
|
+
/** Token 刷新阈值(秒),0 表示不刷新,最小 30 秒 */
|
|
6
|
+
refreshDuration?: number;
|
|
7
|
+
}
|
|
8
|
+
/** Token 刷新函数类型 */
|
|
9
|
+
export type RefreshFn = () => Promise<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Token 管理器
|
|
12
|
+
*/
|
|
13
|
+
export declare class TokenManager {
|
|
14
|
+
private token;
|
|
15
|
+
private filePath;
|
|
16
|
+
private refreshInterval;
|
|
17
|
+
private refreshDuration;
|
|
18
|
+
private timer;
|
|
19
|
+
constructor(options?: TokenManagerOptions);
|
|
20
|
+
/** 从 properties 文件加载 Token */
|
|
21
|
+
loadToken(): string;
|
|
22
|
+
/** 获取当前 Token */
|
|
23
|
+
getToken(): string;
|
|
24
|
+
/** 设置 Token 并更新文件 */
|
|
25
|
+
setToken(token: string): void;
|
|
26
|
+
/** 将 Token 保存到 properties 文件 */
|
|
27
|
+
private saveTokenToFile;
|
|
28
|
+
/**
|
|
29
|
+
* 判断 Token 是否需要刷新。
|
|
30
|
+
* 解码 base64 token,提取前 27 字符中的 gen_ts,
|
|
31
|
+
* 当 (当前时间秒 - gen_ts/1000) > refreshDuration 时返回 true。
|
|
32
|
+
*/
|
|
33
|
+
shouldTokenRefresh(): boolean;
|
|
34
|
+
/** 启动后台定期刷新 */
|
|
35
|
+
startAutoRefresh(refreshFn: RefreshFn): void;
|
|
36
|
+
/** 停止后台刷新 */
|
|
37
|
+
stopAutoRefresh(): void;
|
|
38
|
+
}
|