@okx_ai/okx-trade-cli 1.2.8 → 1.2.9-beta.2
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/index.js +118 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall-download.js +152 -0
package/dist/index.js
CHANGED
|
@@ -2191,6 +2191,59 @@ function registerAccountTools() {
|
|
|
2191
2191
|
}
|
|
2192
2192
|
];
|
|
2193
2193
|
}
|
|
2194
|
+
async function resolveQuoteCcySz(instId, sz, tgtCcy, instType, client) {
|
|
2195
|
+
if (tgtCcy !== "quote_ccy") {
|
|
2196
|
+
return { sz, tgtCcy, conversionNote: void 0 };
|
|
2197
|
+
}
|
|
2198
|
+
const [instrumentsRes, tickerRes] = await Promise.all([
|
|
2199
|
+
client.publicGet("/api/v5/public/instruments", {
|
|
2200
|
+
instType,
|
|
2201
|
+
instId
|
|
2202
|
+
}),
|
|
2203
|
+
client.publicGet("/api/v5/market/ticker", { instId })
|
|
2204
|
+
]);
|
|
2205
|
+
const instruments = Array.isArray(instrumentsRes.data) ? instrumentsRes.data : [];
|
|
2206
|
+
if (instruments.length === 0) {
|
|
2207
|
+
throw new Error(
|
|
2208
|
+
`Failed to fetch instrument info for ${instId}: empty instrument list. Cannot determine ctVal for quote_ccy conversion.`
|
|
2209
|
+
);
|
|
2210
|
+
}
|
|
2211
|
+
const ctValStr = String(instruments[0].ctVal ?? "");
|
|
2212
|
+
const ctVal = parseFloat(ctValStr);
|
|
2213
|
+
if (!isFinite(ctVal) || ctVal <= 0) {
|
|
2214
|
+
throw new Error(
|
|
2215
|
+
`Invalid ctVal "${ctValStr}" for ${instId}. ctVal must be a positive number for quote_ccy conversion.`
|
|
2216
|
+
);
|
|
2217
|
+
}
|
|
2218
|
+
const tickers = Array.isArray(tickerRes.data) ? tickerRes.data : [];
|
|
2219
|
+
if (tickers.length === 0) {
|
|
2220
|
+
throw new Error(
|
|
2221
|
+
`Failed to fetch ticker price for ${instId}: empty ticker response. Cannot determine last price for quote_ccy conversion.`
|
|
2222
|
+
);
|
|
2223
|
+
}
|
|
2224
|
+
const lastStr = String(tickers[0].last ?? "");
|
|
2225
|
+
const lastPx = parseFloat(lastStr);
|
|
2226
|
+
if (!isFinite(lastPx) || lastPx <= 0) {
|
|
2227
|
+
throw new Error(
|
|
2228
|
+
`Invalid last price "${lastStr}" for ${instId}. Last price must be a positive number for quote_ccy conversion.`
|
|
2229
|
+
);
|
|
2230
|
+
}
|
|
2231
|
+
const usdtAmount = parseFloat(sz);
|
|
2232
|
+
const contractValue = ctVal * lastPx;
|
|
2233
|
+
const contracts = Math.floor(usdtAmount / contractValue);
|
|
2234
|
+
if (contracts <= 0) {
|
|
2235
|
+
const minUsdt = contractValue.toFixed(2);
|
|
2236
|
+
throw new Error(
|
|
2237
|
+
`sz=${sz} USDT is too small to buy even 1 contract of ${instId}. Minimum amount required is at least ${minUsdt} USDT (ctVal=${ctValStr}, lastPx=${lastStr}, 1 contract = ${minUsdt} USDT).`
|
|
2238
|
+
);
|
|
2239
|
+
}
|
|
2240
|
+
const conversionNote = `Converting ${sz} USDT \u2192 ${contracts} contracts (ctVal=${ctValStr}, lastPx=${lastStr}, formula: floor(${sz} / (${ctValStr} \xD7 ${lastStr})) = ${contracts})`;
|
|
2241
|
+
return {
|
|
2242
|
+
sz: String(contracts),
|
|
2243
|
+
tgtCcy: void 0,
|
|
2244
|
+
conversionNote
|
|
2245
|
+
};
|
|
2246
|
+
}
|
|
2194
2247
|
function registerAlgoTradeTools() {
|
|
2195
2248
|
return [
|
|
2196
2249
|
{
|
|
@@ -2286,6 +2339,13 @@ function registerAlgoTradeTools() {
|
|
|
2286
2339
|
handler: async (rawArgs, context) => {
|
|
2287
2340
|
const args = asRecord(rawArgs);
|
|
2288
2341
|
const reduceOnly = args.reduceOnly;
|
|
2342
|
+
const resolved = await resolveQuoteCcySz(
|
|
2343
|
+
requireString(args, "instId"),
|
|
2344
|
+
requireString(args, "sz"),
|
|
2345
|
+
readString(args, "tgtCcy"),
|
|
2346
|
+
"SWAP",
|
|
2347
|
+
context.client
|
|
2348
|
+
);
|
|
2289
2349
|
const response = await context.client.privatePost(
|
|
2290
2350
|
"/api/v5/trade/order-algo",
|
|
2291
2351
|
compactObject({
|
|
@@ -2294,8 +2354,8 @@ function registerAlgoTradeTools() {
|
|
|
2294
2354
|
side: requireString(args, "side"),
|
|
2295
2355
|
posSide: readString(args, "posSide"),
|
|
2296
2356
|
ordType: requireString(args, "ordType"),
|
|
2297
|
-
sz:
|
|
2298
|
-
tgtCcy:
|
|
2357
|
+
sz: resolved.sz,
|
|
2358
|
+
tgtCcy: resolved.tgtCcy,
|
|
2299
2359
|
tpTriggerPx: readString(args, "tpTriggerPx"),
|
|
2300
2360
|
tpOrdPx: readString(args, "tpOrdPx"),
|
|
2301
2361
|
tpTriggerPxType: readString(args, "tpTriggerPxType"),
|
|
@@ -2311,7 +2371,11 @@ function registerAlgoTradeTools() {
|
|
|
2311
2371
|
}),
|
|
2312
2372
|
privateRateLimit("swap_place_algo_order", 20)
|
|
2313
2373
|
);
|
|
2314
|
-
|
|
2374
|
+
const result = normalizeResponse(response);
|
|
2375
|
+
if (resolved.conversionNote) {
|
|
2376
|
+
result._conversion = resolved.conversionNote;
|
|
2377
|
+
}
|
|
2378
|
+
return result;
|
|
2315
2379
|
}
|
|
2316
2380
|
},
|
|
2317
2381
|
{
|
|
@@ -2619,6 +2683,13 @@ function registerFuturesAlgoTools() {
|
|
|
2619
2683
|
handler: async (rawArgs, context) => {
|
|
2620
2684
|
const args = asRecord(rawArgs);
|
|
2621
2685
|
const reduceOnly = args.reduceOnly;
|
|
2686
|
+
const resolved = await resolveQuoteCcySz(
|
|
2687
|
+
requireString(args, "instId"),
|
|
2688
|
+
requireString(args, "sz"),
|
|
2689
|
+
readString(args, "tgtCcy"),
|
|
2690
|
+
"FUTURES",
|
|
2691
|
+
context.client
|
|
2692
|
+
);
|
|
2622
2693
|
const response = await context.client.privatePost(
|
|
2623
2694
|
"/api/v5/trade/order-algo",
|
|
2624
2695
|
compactObject({
|
|
@@ -2627,8 +2698,8 @@ function registerFuturesAlgoTools() {
|
|
|
2627
2698
|
side: requireString(args, "side"),
|
|
2628
2699
|
posSide: readString(args, "posSide"),
|
|
2629
2700
|
ordType: requireString(args, "ordType"),
|
|
2630
|
-
sz:
|
|
2631
|
-
tgtCcy:
|
|
2701
|
+
sz: resolved.sz,
|
|
2702
|
+
tgtCcy: resolved.tgtCcy,
|
|
2632
2703
|
tpTriggerPx: readString(args, "tpTriggerPx"),
|
|
2633
2704
|
tpOrdPx: readString(args, "tpOrdPx"),
|
|
2634
2705
|
tpTriggerPxType: readString(args, "tpTriggerPxType"),
|
|
@@ -2644,7 +2715,11 @@ function registerFuturesAlgoTools() {
|
|
|
2644
2715
|
}),
|
|
2645
2716
|
privateRateLimit("futures_place_algo_order", 20)
|
|
2646
2717
|
);
|
|
2647
|
-
|
|
2718
|
+
const result = normalizeResponse(response);
|
|
2719
|
+
if (resolved.conversionNote) {
|
|
2720
|
+
result._conversion = resolved.conversionNote;
|
|
2721
|
+
}
|
|
2722
|
+
return result;
|
|
2648
2723
|
}
|
|
2649
2724
|
},
|
|
2650
2725
|
{
|
|
@@ -3209,7 +3284,7 @@ function registerSkillsTools() {
|
|
|
3209
3284
|
{
|
|
3210
3285
|
name: "skills_download",
|
|
3211
3286
|
module: "skills",
|
|
3212
|
-
description: "Download a skill zip file from OKX Skills Marketplace to a local directory. Always call skills_search first to confirm the skill name exists. Downloads the latest approved version. NOTE:
|
|
3287
|
+
description: "Download a skill zip file from OKX Skills Marketplace to a local directory. Always call skills_search first to confirm the skill name exists. Downloads the latest approved version. NOTE: Downloads third-party developer content as a zip \u2014 does NOT install to agents. For full installation use CLI: okx skill add <name>. Use when the user wants to inspect or manually install a skill package.",
|
|
3213
3288
|
inputSchema: {
|
|
3214
3289
|
type: "object",
|
|
3215
3290
|
properties: {
|
|
@@ -4730,6 +4805,13 @@ function buildContractTradeTools(cfg) {
|
|
|
4730
4805
|
const args = asRecord(rawArgs);
|
|
4731
4806
|
const reduceOnly = args.reduceOnly;
|
|
4732
4807
|
const attachAlgoOrds = buildAttachAlgoOrds(args);
|
|
4808
|
+
const resolved = await resolveQuoteCcySz(
|
|
4809
|
+
requireString(args, "instId"),
|
|
4810
|
+
requireString(args, "sz"),
|
|
4811
|
+
readString(args, "tgtCcy"),
|
|
4812
|
+
defaultType,
|
|
4813
|
+
context.client
|
|
4814
|
+
);
|
|
4733
4815
|
const response = await context.client.privatePost(
|
|
4734
4816
|
"/api/v5/trade/order",
|
|
4735
4817
|
compactObject({
|
|
@@ -4738,8 +4820,8 @@ function buildContractTradeTools(cfg) {
|
|
|
4738
4820
|
side: requireString(args, "side"),
|
|
4739
4821
|
posSide: readString(args, "posSide"),
|
|
4740
4822
|
ordType: requireString(args, "ordType"),
|
|
4741
|
-
sz:
|
|
4742
|
-
tgtCcy:
|
|
4823
|
+
sz: resolved.sz,
|
|
4824
|
+
tgtCcy: resolved.tgtCcy,
|
|
4743
4825
|
px: readString(args, "px"),
|
|
4744
4826
|
reduceOnly: typeof reduceOnly === "boolean" ? String(reduceOnly) : void 0,
|
|
4745
4827
|
clOrdId: readString(args, "clOrdId"),
|
|
@@ -4748,7 +4830,11 @@ function buildContractTradeTools(cfg) {
|
|
|
4748
4830
|
}),
|
|
4749
4831
|
privateRateLimit(n("place_order"), 60)
|
|
4750
4832
|
);
|
|
4751
|
-
|
|
4833
|
+
const result = normalizeResponse(response);
|
|
4834
|
+
if (resolved.conversionNote) {
|
|
4835
|
+
result._conversion = resolved.conversionNote;
|
|
4836
|
+
}
|
|
4837
|
+
return result;
|
|
4752
4838
|
}
|
|
4753
4839
|
},
|
|
4754
4840
|
// ── cancel_order ─────────────────────────────────────────────────────────
|
|
@@ -5823,7 +5909,7 @@ function registerOptionAlgoTools() {
|
|
|
5823
5909
|
tgtCcy: {
|
|
5824
5910
|
type: "string",
|
|
5825
5911
|
enum: ["base_ccy", "quote_ccy"],
|
|
5826
|
-
description: "Size unit. base_ccy(default): sz in contracts, quote_ccy: sz in USDT (
|
|
5912
|
+
description: "Size unit. base_ccy(default): sz in contracts, quote_ccy: sz in USDT (auto-converted to contracts)"
|
|
5827
5913
|
},
|
|
5828
5914
|
reduceOnly: {
|
|
5829
5915
|
type: "boolean",
|
|
@@ -5839,6 +5925,13 @@ function registerOptionAlgoTools() {
|
|
|
5839
5925
|
handler: async (rawArgs, context) => {
|
|
5840
5926
|
const args = asRecord(rawArgs);
|
|
5841
5927
|
const reduceOnly = readBoolean(args, "reduceOnly");
|
|
5928
|
+
const resolved = await resolveQuoteCcySz(
|
|
5929
|
+
requireString(args, "instId"),
|
|
5930
|
+
requireString(args, "sz"),
|
|
5931
|
+
readString(args, "tgtCcy"),
|
|
5932
|
+
"OPTION",
|
|
5933
|
+
context.client
|
|
5934
|
+
);
|
|
5842
5935
|
const response = await context.client.privatePost(
|
|
5843
5936
|
"/api/v5/trade/order-algo",
|
|
5844
5937
|
compactObject({
|
|
@@ -5846,8 +5939,8 @@ function registerOptionAlgoTools() {
|
|
|
5846
5939
|
tdMode: requireString(args, "tdMode"),
|
|
5847
5940
|
side: requireString(args, "side"),
|
|
5848
5941
|
ordType: requireString(args, "ordType"),
|
|
5849
|
-
sz:
|
|
5850
|
-
tgtCcy:
|
|
5942
|
+
sz: resolved.sz,
|
|
5943
|
+
tgtCcy: resolved.tgtCcy,
|
|
5851
5944
|
tpTriggerPx: readString(args, "tpTriggerPx"),
|
|
5852
5945
|
tpOrdPx: readString(args, "tpOrdPx"),
|
|
5853
5946
|
tpTriggerPxType: readString(args, "tpTriggerPxType"),
|
|
@@ -8248,7 +8341,7 @@ async function cmdDiagnoseMcp(options = {}) {
|
|
|
8248
8341
|
|
|
8249
8342
|
// src/commands/diagnose.ts
|
|
8250
8343
|
var CLI_VERSION = readCliVersion();
|
|
8251
|
-
var GIT_HASH = true ? "
|
|
8344
|
+
var GIT_HASH = true ? "5f833a2" : "dev";
|
|
8252
8345
|
function maskKey2(key) {
|
|
8253
8346
|
if (!key) return "(not set)";
|
|
8254
8347
|
if (key.length <= 8) return "****";
|
|
@@ -12270,6 +12363,7 @@ function resolveNpx() {
|
|
|
12270
12363
|
if (existsSync7(sibling)) return sibling;
|
|
12271
12364
|
return "npx";
|
|
12272
12365
|
}
|
|
12366
|
+
var THIRD_PARTY_INSTALL_NOTICE = "Note: This skill was created by a third-party developer, not by OKX. Review SKILL.md before use.";
|
|
12273
12367
|
async function cmdSkillSearch(run, opts) {
|
|
12274
12368
|
const args = {};
|
|
12275
12369
|
if (opts.keyword) args.keyword = opts.keyword;
|
|
@@ -12345,11 +12439,7 @@ async function cmdSkillAdd(name, config, json) {
|
|
|
12345
12439
|
throw e;
|
|
12346
12440
|
}
|
|
12347
12441
|
upsertSkillRecord(meta);
|
|
12348
|
-
|
|
12349
|
-
outputLine(JSON.stringify({ name: meta.name, version: meta.version, status: "installed" }, null, 2));
|
|
12350
|
-
} else {
|
|
12351
|
-
outputLine(`\u2713 Skill "${meta.name}" v${meta.version} installed`);
|
|
12352
|
-
}
|
|
12442
|
+
printSkillInstallResult(meta, json);
|
|
12353
12443
|
} finally {
|
|
12354
12444
|
rmSync(tmpBase, { recursive: true, force: true });
|
|
12355
12445
|
}
|
|
@@ -12442,11 +12532,19 @@ function cmdSkillList(json) {
|
|
|
12442
12532
|
outputLine("");
|
|
12443
12533
|
outputLine(`${skills.length} skills installed.`);
|
|
12444
12534
|
}
|
|
12535
|
+
function printSkillInstallResult(meta, json) {
|
|
12536
|
+
if (json) {
|
|
12537
|
+
outputLine(JSON.stringify({ name: meta.name, version: meta.version, status: "installed" }, null, 2));
|
|
12538
|
+
} else {
|
|
12539
|
+
outputLine(`\u2713 Skill "${meta.name}" v${meta.version} installed`);
|
|
12540
|
+
outputLine(` ${THIRD_PARTY_INSTALL_NOTICE}`);
|
|
12541
|
+
}
|
|
12542
|
+
}
|
|
12445
12543
|
|
|
12446
12544
|
// src/index.ts
|
|
12447
12545
|
var _require3 = createRequire3(import.meta.url);
|
|
12448
12546
|
var CLI_VERSION2 = _require3("../package.json").version;
|
|
12449
|
-
var GIT_HASH2 = true ? "
|
|
12547
|
+
var GIT_HASH2 = true ? "5f833a2" : "dev";
|
|
12450
12548
|
function handleConfigCommand(action, rest, json, lang, force) {
|
|
12451
12549
|
if (action === "init") return cmdConfigInit(lang === "zh" ? "zh" : "en");
|
|
12452
12550
|
if (action === "show") return cmdConfigShow(json);
|