@dshtrading/connector-okx 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/lib/rest.d.ts ADDED
@@ -0,0 +1,238 @@
1
+ import { DerivativesPoint, Interval, Kline, Orderbook, Ticker, TradeTick, TradingErrorCode } from "@dshtrading/api";
2
+ //#region src/rest.d.ts
3
+ /** api 包 TradingError 契约的运行时 Error 实现(connector-binance 同款)。 */
4
+ declare class TradingServiceError extends Error {
5
+ readonly code: TradingErrorCode;
6
+ constructor(code: TradingErrorCode, message: string, cause?: unknown);
7
+ }
8
+ /**
9
+ * 拼接签名 prehash:`timestamp + METHOD + requestPath + body`(调研 §1)。
10
+ * GET 的 query 必须已并入 requestPath;无 body 时省略(传 undefined)。
11
+ */
12
+ declare function signaturePrehash(timestamp: string, method: 'GET' | 'POST', requestPath: string, body?: string): string;
13
+ /** OK-ACCESS-SIGN:Base64(HMAC-SHA256(secret, prehash))。 */
14
+ declare function signPayload(secret: string, prehash: string): string;
15
+ /** OK-ACCESS-TIMESTAMP:UTC ISO 8601 毫秒精度(Date.toISOString 即该形态)。 */
16
+ declare function isoTimestamp(epochMs: number): string;
17
+ /** OKX 三值凭证(BYOK:由插件层每次操作从 ctx.credentials 解析,绝不落盘/打日志)。 */
18
+ interface OkxCredentials {
19
+ readonly key: string;
20
+ readonly secret: string;
21
+ readonly passphrase: string;
22
+ }
23
+ /** 签名请求的鉴权参数:三值凭证 + 是否打模拟盘。 */
24
+ interface SignedAuth {
25
+ readonly credentials: OkxCredentials;
26
+ /** true → 附加 `x-simulated-trading: 1`(模拟盘头级开关,调研 §2)。 */
27
+ readonly simulated: boolean;
28
+ }
29
+ /** 四头 + 模拟盘头的构造(导出供单测断言头部集合)。 */
30
+ declare function buildAuthHeaders(auth: SignedAuth, timestamp: string, method: 'GET' | 'POST', requestPath: string, body?: string): Record<string, string>;
31
+ /**
32
+ * api Interval(Binance 词汇)→ OKX bar 词汇。
33
+ *
34
+ * **1d → 1Dutc(口径裁决,回应调研待验证 #3)**:OKX `1D` 按 UTC+8 零点开盘
35
+ * (用户实证记忆:1D 日线边界对齐 UTC+8),而本仓 `Interval` 的 `1d` 语义继承自
36
+ * Binance = UTC 零点。crypto 24/7 交易、UTC 是跨所通用口径,取 `1Dutc` 才能与
37
+ * connector-binance 的日线对齐同一日界;`1D`(UTC+8)会导致同一标的跨连接器日 K
38
+ * 错位 8 小时,故不取。6h/12h/3d/1w/1M 同理取 utc 变体。
39
+ *
40
+ * **8h 无映射**:OKX bar 词汇没有 8 小时档(1m..4H、6Hutc、12Hutc、1Dutc、2Dutc、
41
+ * 3Dutc、1Wutc、1Mutc、3Mutc),8h 请求返回 TRADING_UNSUPPORTED_INTERVAL。
42
+ */
43
+ declare const BAR_MAP: Readonly<Record<string, string>>;
44
+ /** 支持的 interval 词汇(工具 enum 用;8h 刻意缺席,见 BAR_MAP 注释)。 */
45
+ declare const OKX_INTERVAL_VOCABULARY: readonly string[];
46
+ /** bar → 毫秒时长(closeTime 补算用;UTC 变体与本地变体时长相同)。 */
47
+ declare function barDurationMs(bar: string): number;
48
+ /** Interval → OKX bar;不支持(含 8h)抛 TRADING_UNSUPPORTED_INTERVAL。 */
49
+ declare function toBar(interval: Interval): string;
50
+ interface OkxRestOptions {
51
+ /** 覆盖 API base(测试/反代用),末尾不带斜杠。 */
52
+ readonly baseUrl?: string;
53
+ /** 单请求超时(ms),默认 10s。 */
54
+ readonly timeoutMs?: number;
55
+ /** 注入 fetch 实现;缺省用全局 fetch(Node 22+ 内置)。 */
56
+ readonly fetchImpl?: typeof fetch;
57
+ /** 禁用自动对时(离线单测);缺省 true。 */
58
+ readonly clockSync?: boolean;
59
+ /** 注入当前墙钟(ms);缺省 Date.now(单测固定时间用)。 */
60
+ readonly now?: () => number;
61
+ /** 预置服务器偏移(ms);设置后跳过网络对时。 */
62
+ readonly clockOffsetMs?: number;
63
+ }
64
+ /** OKX 资金费率快照(GET /api/v5/public/funding-rate,SWAP 专用)。 */
65
+ interface OkxFundingRate {
66
+ readonly instId: string;
67
+ readonly fundingRate: number;
68
+ readonly nextFundingRate?: number;
69
+ readonly fundingTime: number;
70
+ readonly nextFundingTime?: number;
71
+ }
72
+ /** OKX 未平仓合约量快照(GET /api/v5/public/open-interest,SWAP 专用)。 */
73
+ interface OkxOpenInterest {
74
+ readonly instId: string;
75
+ /** 持仓量(张)。 */
76
+ readonly oi: number;
77
+ /** 持仓量(base 币数;= 张数 × ctVal,OKX 直接回填)。 */
78
+ readonly oiCcy?: number;
79
+ /** 持仓量价值(USD 计价)。 */
80
+ readonly oiUsd?: number;
81
+ readonly ts: number;
82
+ }
83
+ /** OKX 合约/币对规格(GET /api/v5/public/instruments;sz 单位纪律的依据,调研 §4)。 */
84
+ interface OkxInstrument {
85
+ readonly instId: string;
86
+ readonly instType: string;
87
+ /** 数量步进(SPOT=base 币;SWAP=张)。 */
88
+ readonly lotSz: number;
89
+ /** 最小下单量(单位同 lotSz)。 */
90
+ readonly minSz: number;
91
+ /** 价格步进。 */
92
+ readonly tickSz: number;
93
+ /** 一张合约含多少币(仅 SWAP/FUTURES;SPOT 无此字段)。 */
94
+ readonly ctVal?: number;
95
+ readonly ctValCcy?: string;
96
+ readonly settleCcy?: string;
97
+ readonly baseCcy?: string;
98
+ readonly quoteCcy?: string;
99
+ }
100
+ /** POST /api/v5/trade/order 请求体词汇(R3 只做 market/limit;tdMode 现货=cash、永续=cross)。 */
101
+ interface OkxPlaceOrderParams {
102
+ readonly instId: string;
103
+ readonly tdMode: 'cash' | 'cross';
104
+ readonly side: 'buy' | 'sell';
105
+ readonly ordType: 'market' | 'limit';
106
+ /** 字符串数量:SPOT=base 币数(market 单显式 tgtCcy=base_ccy);SWAP=张(=coins/ctVal)。 */
107
+ readonly sz: string;
108
+ readonly px?: string;
109
+ readonly tgtCcy?: 'base_ccy' | 'quote_ccy';
110
+ }
111
+ /** 客户端侧 sz 纪律校验结果:换算后的交易所数量字符串 + 提示(index.ts 组装请求体)。 */
112
+ interface NormalizedSize {
113
+ /** 发给交易所的 sz 字符串(SPOT=币数;SWAP=张)。 */
114
+ readonly sz: string;
115
+ /** 现货市价单显式 tgtCcy=base_ccy(消除「buy 缺省按计价币金额」的坑,调研 §4)。 */
116
+ readonly tgtCcy?: 'base_ccy';
117
+ }
118
+ /** 把 api 语义的 base 币数量换算成 OKX sz(本地精度校验:minSz/lotSz,省一次 51000 往返)。 */
119
+ declare function normalizeSize(instId: string, instrument: OkxInstrument, quantityCoins: number): NormalizedSize;
120
+ declare class OkxRestClient {
121
+ #private;
122
+ private readonly baseUrl;
123
+ private readonly timeoutMs;
124
+ private readonly fetchImpl;
125
+ private readonly clockSyncEnabled;
126
+ private readonly now;
127
+ /** 服务器偏移缓存(server - local,ms);null = 未对时。 */
128
+ private clockOffsetMs;
129
+ constructor(options?: OkxRestOptions);
130
+ /** 当前对时后的墙钟(ms)。clockOffsetMs 预置或已缓存时直接用;否则按需对时。 */
131
+ private timestampMs;
132
+ /** 使缓存偏移失效(50102 重试路径)。 */
133
+ invalidateClock(): void;
134
+ /**
135
+ * 统一请求:query 拼 URL 与签名 requestPath;签名头经 buildAuthHeaders;
136
+ * envelope code!=='0'(含 '1' 失败 / '2' 部分成功——本客户端只发单条操作)映射为
137
+ * 结构化错误;50102(时差)重对时重试一次。
138
+ */
139
+ private request;
140
+ /** envelope/HTTP 状态处理:code==='0' → data;单行 trade 端点的 sCode 非 0 → 失败。 */
141
+ private processEnvelope;
142
+ /** 最新行情:GET /api/v5/market/ticker。 */
143
+ getTicker(instId: string): Promise<Ticker>;
144
+ /** K 线:GET /api/v5/market/candles(单请求上限 300,超出走 after 游标翻页;响应新→旧,翻转为旧→新)。 */
145
+ getKlines(instId: string, interval: Interval, limit?: number): Promise<Kline[]>;
146
+ /** 资金费率:GET /api/v5/public/funding-rate(仅 SWAP;10 次/2s)。 */
147
+ getFundingRate(instId: string): Promise<OkxFundingRate>;
148
+ /** 标记价格:GET /api/v5/public/mark-price(仅 SWAP;2026-09-03 真实网络实证)。 */
149
+ getMarkPrice(instId: string): Promise<{
150
+ instId: string;
151
+ markPrice: number;
152
+ ts: number;
153
+ }>;
154
+ /**
155
+ * 指数价格:GET /api/v5/market/index-tickers(现货指数成分 instId,如 HYPE-USDT;
156
+ * 与永续 markPx 配对算基差。2026-09-03 真实网络实证)。
157
+ */
158
+ getIndexPrice(instId: string): Promise<{
159
+ instId: string;
160
+ indexPrice: number;
161
+ ts: number;
162
+ }>;
163
+ /** 资金费率历史:GET /api/v5/public/funding-rate-history(响应新→旧 → 反转为升序)。 */
164
+ getFundingRateHistory(instId: string, limit?: number): Promise<DerivativesPoint[]>;
165
+ /**
166
+ * OI 历史:GET /api/v5/rubik/stat/contracts/open-interest-history(period=1D)。
167
+ * 响应是时间序列行 `[ts, oi张, oiCcy币, oiUsd]`(字符串数值,新→旧;
168
+ * 2026-09-03 真实网络实证);取值列与快照同纪律——优先币数(oiCcy),退张数。
169
+ */
170
+ getOpenInterestHistory(instId: string, limit?: number): Promise<DerivativesPoint[]>;
171
+ /** 盘口快照:GET /api/v5/market/books(sz=20 档;bids 降序 / asks 升序,OKX 原生序)。 */
172
+ getOrderbook(instId: string): Promise<Orderbook>;
173
+ /** 最近逐笔成交:GET /api/v5/market/trades(响应新→旧 → 反转为时间升序)。 */
174
+ getRecentTrades(instId: string, limit?: number): Promise<TradeTick[]>;
175
+ /** 未平仓合约量:GET /api/v5/public/open-interest(仅 SWAP;oi=张、oiCcy=币、oiUsd=USD)。 */ getOpenInterest(instId: string): Promise<OkxOpenInterest>;
176
+ /**
177
+ * 多空账户人数比:GET /api/v5/rubik/stat/contracts/long-short-account-ratio(ccy=base 资产,period=1H)。
178
+ * 响应是时间序列行 `[ts, ratio]`(字符串数值,新→旧;2026-09-02 真实网络实证,
179
+ * spikes/impl-crypto-derivatives),取最新一行。
180
+ */
181
+ getLongShortAccountRatio(ccy: string): Promise<{
182
+ ccy: string;
183
+ ratio: number;
184
+ ts?: number;
185
+ }>;
186
+ /**
187
+ * 合约主动买卖量:GET /api/v5/rubik/stat/taker-volume(ccy=base 资产,instType=CONTRACTS)。
188
+ * 响应是时间序列行 `[ts, buyVol, sellVol]`(字符串数值,新→旧;2026-09-02 真实网络
189
+ * 实证,spikes/impl-crypto-derivatives),取最新一行。
190
+ */
191
+ getContractTakerVolume(ccy: string): Promise<{
192
+ ccy: string;
193
+ buyVol: number;
194
+ sellVol: number;
195
+ }>;
196
+ /** 合约/币对规格:GET /api/v5/public/instruments(sz 纪律的 ctVal/lotSz/minSz 来源)。 */
197
+ getInstruments(instType: 'SPOT' | 'SWAP', instId?: string): Promise<OkxInstrument[]>;
198
+ /**
199
+ * 全部可交易现货标的名册(GET /api/v5/public/instruments?instType=SPOT,Issue #15)。
200
+ * 输出 symbol 归一化为市场规范形(BTC-USDT → BTCUSDT),name 为 baseCcy/quoteCcy。
201
+ */
202
+ listInstruments(): Promise<Array<{
203
+ symbol: string;
204
+ name?: string;
205
+ }>>;
206
+ /** 只读余额:GET /api/v5/account/balance(ccy 可选,逗号分隔 ≤20)。 */
207
+ getBalance(auth: SignedAuth, ccy?: string): Promise<unknown[]>;
208
+ /** 只读持仓:GET /api/v5/account/positions(instId 可选过滤)。 */
209
+ getPositions(auth: SignedAuth, instId?: string): Promise<unknown[]>;
210
+ /** 下单:POST /api/v5/trade/order(60 次/2s)。 */
211
+ placeOrder(params: OkxPlaceOrderParams, auth: SignedAuth): Promise<unknown[]>;
212
+ /** 撤单:POST /api/v5/trade/cancel-order(ordId 优先于 clOrdId,本切片只支持 ordId)。 */
213
+ cancelOrder(instId: string, ordId: string, auth: SignedAuth): Promise<unknown[]>;
214
+ /** 查单:GET /api/v5/trade/order(query 属于签名 requestPath)。 */
215
+ getOrder(instId: string, ordId: string, auth: SignedAuth): Promise<unknown[]>;
216
+ /** 当前挂单:GET /api/v5/trade/orders-pending(instId 可选过滤;issue #40 交易台)。 */
217
+ listPendingOrders(instId: string | undefined, auth: SignedAuth): Promise<unknown[]>;
218
+ /** 最近成交明细:GET /api/v5/trade/fills-history(instId/limit 可选;issue #40 交易台)。 */
219
+ listFillsHistory(instId: string | undefined, limit: number | undefined, auth: SignedAuth): Promise<unknown[]>;
220
+ }
221
+ /**
222
+ * 输入归一 → OKX 原生 instId。接受规范形(BTCUSDT / BTCUSDT-SWAP)与原生形
223
+ *(BTC-USDT / BTC-USDT-SWAP);都解析不出才报 TRADING_UNSUPPORTED_SYMBOL。
224
+ */
225
+ declare function normalizeOkxSymbol(input: string): string;
226
+ /**
227
+ * 输出归一 → 规范形(下游永远看到市场规范词汇)。原生 BTC-USDT → BTCUSDT;
228
+ * BTC-USDT-SWAP → BTCUSDT-SWAP;已是规范形则原样返回。
229
+ */
230
+ declare function toCanonicalOkxSymbol(symbol: string): string;
231
+ /**
232
+ * 衍生品端点输入归一:现货与合约输入一律升到永续 SWAP instId——
233
+ * BTCUSDT / BTC-USDT / BTCUSDT-SWAP / BTC-USDT-SWAP → BTC-USDT-SWAP。
234
+ * (GUI 选中的现货标的也要能看到对应合约的衍生品指标,issue #38。)
235
+ */
236
+ declare function toOkxSwapInstId(input: string): string;
237
+ //#endregion
238
+ export { BAR_MAP, NormalizedSize, OKX_INTERVAL_VOCABULARY, OkxCredentials, OkxFundingRate, OkxInstrument, OkxOpenInterest, OkxPlaceOrderParams, OkxRestClient, OkxRestOptions, SignedAuth, TradingServiceError, barDurationMs, buildAuthHeaders, isoTimestamp, normalizeOkxSymbol, normalizeSize, signPayload, signaturePrehash, toBar, toCanonicalOkxSymbol, toOkxSwapInstId };