@dshtrading/connector-okx 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.d.ts +13 -1
- package/lib/index.js +46 -9
- package/package.json +4 -4
package/lib/index.d.ts
CHANGED
|
@@ -120,6 +120,15 @@ declare class OkxTradeService extends Service implements TradeService {
|
|
|
120
120
|
private auth;
|
|
121
121
|
/** 规格(带 TTL 缓存;demo/live 分桶)。查不到 → TRADING_UNSUPPORTED_SYMBOL。 */
|
|
122
122
|
private getInstrument;
|
|
123
|
+
/** 从上游行集收集 instId(只读账户面三个入口共用的预取键;非 SWAP 由 prefetch 内部过滤)。 */
|
|
124
|
+
private instIdsOf;
|
|
125
|
+
/**
|
|
126
|
+
* 规格并发预取(只读账户面冷启动热路径):getPositions/listOpenOrders/listTradeFills 每个
|
|
127
|
+
* 不同 SWAP instId 都要一次 /public/instruments 解析 ctVal;逐行 await 会把 N 个不同标的
|
|
128
|
+
* 放大成 N 次串行往返。这里先按上限并发解析并把成功结果回传,逐行同步取用。
|
|
129
|
+
* 返回 Map 只含成功项:查不到的 instId 缺席,调用点按原语义保留张数原值(不再逐行重试)。
|
|
130
|
+
*/
|
|
131
|
+
private prefetchInstruments;
|
|
123
132
|
/**
|
|
124
133
|
* 下单(api TradeService 契约)。
|
|
125
134
|
*
|
|
@@ -157,7 +166,10 @@ declare class OkxTradeService extends Service implements TradeService {
|
|
|
157
166
|
getPositions(): Promise<Position[]>;
|
|
158
167
|
/** 只读余额(TradeService 契约外扩展,crypto_get_balance 工具消费)。 */
|
|
159
168
|
getBalances(): Promise<AccountBalance[]>;
|
|
160
|
-
/**
|
|
169
|
+
/**
|
|
170
|
+
* SWAP 的 sz/accFillSz/fillSz(张)→ base 币数(非 SWAP 原值)。传入已预取的规格 Map
|
|
171
|
+
* 时纯内存查表(缺席即回退原值,不触网);未传时回退单条 getInstrument(带缓存)。
|
|
172
|
+
*/
|
|
161
173
|
private toCoins;
|
|
162
174
|
/** 当前挂单(TradeService 可选契约,issue #40;只读、需凭证)。 */
|
|
163
175
|
listOpenOrders(symbol?: string): Promise<Order[]>;
|
package/lib/index.js
CHANGED
|
@@ -191,6 +191,8 @@ var OkxMarketDataService = class extends Service {
|
|
|
191
191
|
}
|
|
192
192
|
};
|
|
193
193
|
const INSTRUMENT_TTL_MS = 36e5;
|
|
194
|
+
/** 规格并发预取上限:账户只读面冷缓存时最多同时打这么多 /public/instruments(公共面有限频,取保守并发)。 */
|
|
195
|
+
const INSTRUMENT_PREFETCH_CONCURRENCY = 8;
|
|
194
196
|
var OkxTradeService = class extends Service {
|
|
195
197
|
client;
|
|
196
198
|
config;
|
|
@@ -237,6 +239,31 @@ var OkxTradeService = class extends Service {
|
|
|
237
239
|
});
|
|
238
240
|
return row;
|
|
239
241
|
}
|
|
242
|
+
/** 从上游行集收集 instId(只读账户面三个入口共用的预取键;非 SWAP 由 prefetch 内部过滤)。 */
|
|
243
|
+
instIdsOf(rows) {
|
|
244
|
+
const ids = [];
|
|
245
|
+
for (const row of rows) {
|
|
246
|
+
const instId = row.instId;
|
|
247
|
+
if (typeof instId === "string") ids.push(instId);
|
|
248
|
+
}
|
|
249
|
+
return ids;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* 规格并发预取(只读账户面冷启动热路径):getPositions/listOpenOrders/listTradeFills 每个
|
|
253
|
+
* 不同 SWAP instId 都要一次 /public/instruments 解析 ctVal;逐行 await 会把 N 个不同标的
|
|
254
|
+
* 放大成 N 次串行往返。这里先按上限并发解析并把成功结果回传,逐行同步取用。
|
|
255
|
+
* 返回 Map 只含成功项:查不到的 instId 缺席,调用点按原语义保留张数原值(不再逐行重试)。
|
|
256
|
+
*/
|
|
257
|
+
async prefetchInstruments(instIds) {
|
|
258
|
+
const distinct = [...new Set([...instIds].filter((id) => id.endsWith("-SWAP")))];
|
|
259
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
260
|
+
for (let i = 0; i < distinct.length; i += INSTRUMENT_PREFETCH_CONCURRENCY) await Promise.all(distinct.slice(i, i + INSTRUMENT_PREFETCH_CONCURRENCY).map(async (id) => {
|
|
261
|
+
try {
|
|
262
|
+
resolved.set(id, await this.getInstrument(id));
|
|
263
|
+
} catch {}
|
|
264
|
+
}));
|
|
265
|
+
return resolved;
|
|
266
|
+
}
|
|
240
267
|
/**
|
|
241
268
|
* 下单(api TradeService 契约)。
|
|
242
269
|
*
|
|
@@ -367,6 +394,7 @@ var OkxTradeService = class extends Service {
|
|
|
367
394
|
async getPositions() {
|
|
368
395
|
const credentials = await this.getCredentials();
|
|
369
396
|
const rows = await this.client.getPositions(this.auth(credentials));
|
|
397
|
+
const instruments = await this.prefetchInstruments(this.instIdsOf(rows));
|
|
370
398
|
const positions = [];
|
|
371
399
|
for (const row of rows) {
|
|
372
400
|
const d = row;
|
|
@@ -374,10 +402,10 @@ var OkxTradeService = class extends Service {
|
|
|
374
402
|
const pos = typeof d.pos === "string" || typeof d.pos === "number" ? Number(d.pos) : NaN;
|
|
375
403
|
if (instId === void 0 || !Number.isFinite(pos)) continue;
|
|
376
404
|
let size = Math.abs(pos);
|
|
377
|
-
if (instId.endsWith("-SWAP"))
|
|
378
|
-
const instrument =
|
|
379
|
-
if (instrument
|
|
380
|
-
}
|
|
405
|
+
if (instId.endsWith("-SWAP")) {
|
|
406
|
+
const instrument = instruments.get(instId);
|
|
407
|
+
if (instrument?.ctVal !== void 0) size = size * instrument.ctVal;
|
|
408
|
+
}
|
|
381
409
|
const posSide = d.posSide === "long" || d.posSide === "short" ? d.posSide : "net";
|
|
382
410
|
const side = posSide === "net" ? pos >= 0 ? "long" : "short" : posSide;
|
|
383
411
|
const entryPrice = typeof d.avgPx === "string" ? Number(d.avgPx) : void 0;
|
|
@@ -421,11 +449,18 @@ var OkxTradeService = class extends Service {
|
|
|
421
449
|
}
|
|
422
450
|
return balances;
|
|
423
451
|
}
|
|
424
|
-
/**
|
|
425
|
-
|
|
452
|
+
/**
|
|
453
|
+
* SWAP 的 sz/accFillSz/fillSz(张)→ base 币数(非 SWAP 原值)。传入已预取的规格 Map
|
|
454
|
+
* 时纯内存查表(缺席即回退原值,不触网);未传时回退单条 getInstrument(带缓存)。
|
|
455
|
+
*/
|
|
456
|
+
async toCoins(instId, exchangeAmount, instruments) {
|
|
426
457
|
const n = typeof exchangeAmount === "string" || typeof exchangeAmount === "number" ? Number(exchangeAmount) : NaN;
|
|
427
458
|
if (!Number.isFinite(n)) return void 0;
|
|
428
459
|
if (!instId.endsWith("-SWAP")) return n;
|
|
460
|
+
if (instruments !== void 0) {
|
|
461
|
+
const instrument = instruments.get(instId);
|
|
462
|
+
return instrument?.ctVal !== void 0 ? n * instrument.ctVal : n;
|
|
463
|
+
}
|
|
429
464
|
try {
|
|
430
465
|
const instrument = await this.getInstrument(instId);
|
|
431
466
|
return instrument.ctVal !== void 0 ? n * instrument.ctVal : n;
|
|
@@ -438,15 +473,16 @@ var OkxTradeService = class extends Service {
|
|
|
438
473
|
const instId = symbol !== void 0 && symbol !== "" ? normalizeOkxSymbol(symbol) : void 0;
|
|
439
474
|
const credentials = await this.getCredentials();
|
|
440
475
|
const rows = await this.client.listPendingOrders(instId, this.auth(credentials));
|
|
476
|
+
const instruments = await this.prefetchInstruments(this.instIdsOf(rows));
|
|
441
477
|
const orders = [];
|
|
442
478
|
for (const row of rows) {
|
|
443
479
|
const d = row;
|
|
444
480
|
const ordId = typeof d.ordId === "string" ? d.ordId : void 0;
|
|
445
481
|
const rawInstId = typeof d.instId === "string" ? d.instId : void 0;
|
|
446
482
|
if (ordId === void 0 || rawInstId === void 0) continue;
|
|
447
|
-
const quantity = await this.toCoins(rawInstId, d.sz);
|
|
483
|
+
const quantity = await this.toCoins(rawInstId, d.sz, instruments);
|
|
448
484
|
if (quantity === void 0) continue;
|
|
449
|
-
const filledQuantity = await this.toCoins(rawInstId, d.accFillSz);
|
|
485
|
+
const filledQuantity = await this.toCoins(rawInstId, d.accFillSz, instruments);
|
|
450
486
|
const price = typeof d.px === "string" && d.px !== "" ? Number(d.px) : typeof d.avgPx === "string" && d.avgPx !== "" ? Number(d.avgPx) : void 0;
|
|
451
487
|
const state = typeof d.state === "string" ? d.state : "";
|
|
452
488
|
const timestamp = typeof d.uTime === "string" ? Number(d.uTime) : typeof d.cTime === "string" ? Number(d.cTime) : Date.now();
|
|
@@ -471,13 +507,14 @@ var OkxTradeService = class extends Service {
|
|
|
471
507
|
const capped = Math.max(1, Math.min(Math.floor(limit) || 50, 100));
|
|
472
508
|
const credentials = await this.getCredentials();
|
|
473
509
|
const rows = await this.client.listFillsHistory(instId, capped, this.auth(credentials));
|
|
510
|
+
const instruments = await this.prefetchInstruments(this.instIdsOf(rows));
|
|
474
511
|
const fills = [];
|
|
475
512
|
for (const row of rows) {
|
|
476
513
|
const d = row;
|
|
477
514
|
const rawInstId = typeof d.instId === "string" ? d.instId : void 0;
|
|
478
515
|
const price = pickNumber(d.fillPx);
|
|
479
516
|
if (rawInstId === void 0 || price === void 0) continue;
|
|
480
|
-
const amount = await this.toCoins(rawInstId, d.fillSz);
|
|
517
|
+
const amount = await this.toCoins(rawInstId, d.fillSz, instruments);
|
|
481
518
|
if (amount === void 0) continue;
|
|
482
519
|
const fee = pickNumber(d.fee);
|
|
483
520
|
const feeAsset = typeof d.feeCcy === "string" && d.feeCcy !== "" ? d.feeCcy : void 0;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dshtrading/connector-okx",
|
|
3
3
|
"description": "OKX market connector plugin for dsh-trading: public market data + signed demo/live trading (R1-R3), mutual-exclusion activation with connector-binance",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "./lib/index.d.ts",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
],
|
|
22
22
|
"license": "PolyForm-Noncommercial-1.0.0",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@dshtrading/api": "^0.
|
|
25
|
-
"@dshtrading/indicators": "^0.
|
|
24
|
+
"@dshtrading/api": "^0.4.0",
|
|
25
|
+
"@dshtrading/indicators": "^0.4.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@deepseek-ai/cordis": ">=4.0.0",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"tsdown": "^0.22.0",
|
|
34
34
|
"vitest": "^3.0.0",
|
|
35
|
-
"@dshtrading/connector-binance": "^0.
|
|
35
|
+
"@dshtrading/connector-binance": "^0.4.0"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "tsdown",
|