@okx_ai/okx-trade-cli 1.1.7 → 1.1.9
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 +153 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2452,7 +2452,7 @@ function registerGridTools() {
|
|
|
2452
2452
|
{
|
|
2453
2453
|
name: "grid_create_order",
|
|
2454
2454
|
module: "bot.grid",
|
|
2455
|
-
description: "Create a new grid trading bot. [CAUTION] Executes real trades and locks funds. Supports Spot Grid ('grid') and Contract Grid ('contract_grid'). For spot grid, provide quoteSz (invest in quote currency) or baseSz (invest in base currency). For contract grids, provide direction, lever, and sz (
|
|
2455
|
+
description: "Create a new grid trading bot. [CAUTION] Executes real trades and locks funds. Supports Spot Grid ('grid') and Contract Grid ('contract_grid'). For spot grid, provide quoteSz (invest in quote currency) or baseSz (invest in base currency). For contract grids, provide direction, lever, and sz (investment amount in margin currency, e.g. USDT for USDT-margined contracts). Private endpoint. Rate limit: 20 req/2s per UID.",
|
|
2456
2456
|
isWrite: true,
|
|
2457
2457
|
inputSchema: {
|
|
2458
2458
|
type: "object",
|
|
@@ -2502,7 +2502,11 @@ function registerGridTools() {
|
|
|
2502
2502
|
},
|
|
2503
2503
|
sz: {
|
|
2504
2504
|
type: "string",
|
|
2505
|
-
description: "
|
|
2505
|
+
description: "Investment amount in margin currency (e.g. USDT for USDT-margined contracts). Required for contract_grid."
|
|
2506
|
+
},
|
|
2507
|
+
basePos: {
|
|
2508
|
+
type: "boolean",
|
|
2509
|
+
description: "Whether to open a base position for contract grid. Ignored for neutral direction and spot grid. Default: true"
|
|
2506
2510
|
}
|
|
2507
2511
|
},
|
|
2508
2512
|
required: ["instId", "algoOrdType", "maxPx", "minPx", "gridNum"]
|
|
@@ -2525,6 +2529,7 @@ function registerGridTools() {
|
|
|
2525
2529
|
});
|
|
2526
2530
|
if (algoOrdType === "contract_grid") {
|
|
2527
2531
|
body.triggerParams = [{ triggerAction: "start", triggerStrategy: "instant" }];
|
|
2532
|
+
body.basePos = readBoolean(args, "basePos") ?? true;
|
|
2528
2533
|
}
|
|
2529
2534
|
const response = await context.client.privatePost(
|
|
2530
2535
|
"/api/v5/tradingBot/grid/order-algo",
|
|
@@ -6207,8 +6212,8 @@ var HELP_TREE = {
|
|
|
6207
6212
|
description: "List sub-orders of a grid bot (filled or live)"
|
|
6208
6213
|
},
|
|
6209
6214
|
create: {
|
|
6210
|
-
usage: "okx bot grid create --instId <id> --algoOrdType <grid|contract_grid> --maxPx <px> --minPx <px> --gridNum <n>\n [--runType <1|2>] [--quoteSz <n>] [--baseSz <n>]\n [--direction <long|short|neutral>] [--lever <n>] [--sz <n>]",
|
|
6211
|
-
description: "Create a new grid bot order"
|
|
6215
|
+
usage: "okx bot grid create --instId <id> --algoOrdType <grid|contract_grid> --maxPx <px> --minPx <px> --gridNum <n>\n [--runType <1|2>] [--quoteSz <n>] [--baseSz <n>]\n [--direction <long|short|neutral>] [--lever <n>] [--sz <n>] [--basePos] [--no-basePos]",
|
|
6216
|
+
description: "Create a new grid bot order (contract grid opens base position by default)"
|
|
6212
6217
|
},
|
|
6213
6218
|
stop: {
|
|
6214
6219
|
usage: "okx bot grid stop --algoId <id> --algoOrdType <type> --instId <id> [--stopType <1|2|3|5|6>]",
|
|
@@ -6447,6 +6452,7 @@ var CLI_OPTIONS = {
|
|
|
6447
6452
|
quoteSz: { type: "string" },
|
|
6448
6453
|
baseSz: { type: "string" },
|
|
6449
6454
|
direction: { type: "string" },
|
|
6455
|
+
basePos: { type: "boolean", default: true },
|
|
6450
6456
|
stopType: { type: "string" },
|
|
6451
6457
|
live: { type: "boolean", default: false },
|
|
6452
6458
|
// market extras
|
|
@@ -6488,14 +6494,30 @@ var CLI_OPTIONS = {
|
|
|
6488
6494
|
orders: { type: "string" },
|
|
6489
6495
|
// audit
|
|
6490
6496
|
since: { type: "string" },
|
|
6491
|
-
tool: { type: "string" }
|
|
6497
|
+
tool: { type: "string" },
|
|
6498
|
+
// config profile
|
|
6499
|
+
force: { type: "boolean", default: false }
|
|
6492
6500
|
};
|
|
6493
6501
|
function parseCli(argv) {
|
|
6502
|
+
const negated = /* @__PURE__ */ new Set();
|
|
6503
|
+
const filtered = argv.filter((arg) => {
|
|
6504
|
+
if (arg.startsWith("--no-")) {
|
|
6505
|
+
const key = arg.slice(5);
|
|
6506
|
+
if (key in CLI_OPTIONS && CLI_OPTIONS[key].type === "boolean") {
|
|
6507
|
+
negated.add(key);
|
|
6508
|
+
return false;
|
|
6509
|
+
}
|
|
6510
|
+
}
|
|
6511
|
+
return true;
|
|
6512
|
+
});
|
|
6494
6513
|
const { values, positionals } = parseArgs({
|
|
6495
|
-
args:
|
|
6514
|
+
args: filtered,
|
|
6496
6515
|
options: CLI_OPTIONS,
|
|
6497
6516
|
allowPositionals: true
|
|
6498
6517
|
});
|
|
6518
|
+
for (const key of negated) {
|
|
6519
|
+
values[key] = false;
|
|
6520
|
+
}
|
|
6499
6521
|
return { values, positionals };
|
|
6500
6522
|
}
|
|
6501
6523
|
|
|
@@ -7855,7 +7877,7 @@ function cmdConfigShow(json) {
|
|
|
7855
7877
|
process.stdout.write(`[${name}]
|
|
7856
7878
|
`);
|
|
7857
7879
|
printKv({
|
|
7858
|
-
api_key: profile.api_key ?
|
|
7880
|
+
api_key: profile.api_key ? maskSecret(profile.api_key) : "(not set)",
|
|
7859
7881
|
demo: profile.demo ?? false,
|
|
7860
7882
|
base_url: profile.base_url ?? "(default)"
|
|
7861
7883
|
}, 2);
|
|
@@ -7876,10 +7898,24 @@ function cmdConfigSet(key, value) {
|
|
|
7876
7898
|
}
|
|
7877
7899
|
}
|
|
7878
7900
|
function parseSiteKey(raw) {
|
|
7879
|
-
|
|
7880
|
-
if (raw === "
|
|
7901
|
+
const lower = raw.toLowerCase();
|
|
7902
|
+
if (lower === "eea" || raw === "2") return "eea";
|
|
7903
|
+
if (lower === "us" || raw === "3") return "us";
|
|
7904
|
+
if (lower === "global" || raw === "1") return "global";
|
|
7881
7905
|
return "global";
|
|
7882
7906
|
}
|
|
7907
|
+
function inferSiteFromBaseUrl(baseUrl) {
|
|
7908
|
+
if (!baseUrl) return "global";
|
|
7909
|
+
for (const id of SITE_IDS) {
|
|
7910
|
+
const site = OKX_SITES[id];
|
|
7911
|
+
if (baseUrl === site.apiBaseUrl || baseUrl === site.webUrl) return id;
|
|
7912
|
+
}
|
|
7913
|
+
return "global";
|
|
7914
|
+
}
|
|
7915
|
+
function maskSecret(value) {
|
|
7916
|
+
if (!value || value.length < 4) return "****";
|
|
7917
|
+
return "***" + value.slice(-4);
|
|
7918
|
+
}
|
|
7883
7919
|
function buildApiUrl(siteKey, demo) {
|
|
7884
7920
|
const query = demo ? "?go-demo-trading=1" : "?go-live-trading=1";
|
|
7885
7921
|
return `${OKX_SITES[siteKey].webUrl}/account/my-api${query}`;
|
|
@@ -7979,6 +8015,105 @@ async function cmdConfigInit(lang = "en") {
|
|
|
7979
8015
|
rl.close();
|
|
7980
8016
|
}
|
|
7981
8017
|
}
|
|
8018
|
+
function cmdConfigAddProfile(kvPairs, force) {
|
|
8019
|
+
const params = {};
|
|
8020
|
+
for (const pair of kvPairs) {
|
|
8021
|
+
const eqIdx = pair.indexOf("=");
|
|
8022
|
+
if (eqIdx === -1) continue;
|
|
8023
|
+
const key = pair.slice(0, eqIdx).trim();
|
|
8024
|
+
const value = pair.slice(eqIdx + 1);
|
|
8025
|
+
params[key.toUpperCase()] = value;
|
|
8026
|
+
}
|
|
8027
|
+
const ak = params["AK"];
|
|
8028
|
+
const sk = params["SK"];
|
|
8029
|
+
const pp = params["PP"];
|
|
8030
|
+
const missing = [];
|
|
8031
|
+
if (!ak) missing.push("AK");
|
|
8032
|
+
if (!sk) missing.push("SK");
|
|
8033
|
+
if (!pp) missing.push("PP");
|
|
8034
|
+
if (missing.length > 0) {
|
|
8035
|
+
process.stderr.write(`Error: missing required parameter(s): ${missing.join(", ")}
|
|
8036
|
+
`);
|
|
8037
|
+
process.stderr.write("Usage: okx config add-profile AK=<key> SK=<secret> PP=<passphrase> [site=global|eea|us] [demo=true|false] [name=<name>] [--force]\n");
|
|
8038
|
+
process.exitCode = 1;
|
|
8039
|
+
return;
|
|
8040
|
+
}
|
|
8041
|
+
const siteKey = parseSiteKey(params["SITE"] ?? "");
|
|
8042
|
+
const demo = params["DEMO"] !== void 0 ? params["DEMO"].toLowerCase() !== "false" : true;
|
|
8043
|
+
const defaultName = demo ? "demo" : "live";
|
|
8044
|
+
const profileName = params["NAME"] ?? defaultName;
|
|
8045
|
+
const config = readFullConfig();
|
|
8046
|
+
if (config.profiles[profileName] && !force) {
|
|
8047
|
+
process.stderr.write(`Error: profile "${profileName}" already exists. Use --force to overwrite.
|
|
8048
|
+
`);
|
|
8049
|
+
process.exitCode = 1;
|
|
8050
|
+
return;
|
|
8051
|
+
}
|
|
8052
|
+
const entry = buildProfileEntry(siteKey, ak, sk, pp, demo);
|
|
8053
|
+
entry.site = siteKey;
|
|
8054
|
+
config.profiles[profileName] = entry;
|
|
8055
|
+
config.default_profile = profileName;
|
|
8056
|
+
writeCliConfig(config);
|
|
8057
|
+
process.stdout.write(`Profile "${profileName}" saved to ${configFilePath()}
|
|
8058
|
+
`);
|
|
8059
|
+
process.stdout.write(`Default profile set to: ${profileName}
|
|
8060
|
+
`);
|
|
8061
|
+
}
|
|
8062
|
+
function cmdConfigListProfile() {
|
|
8063
|
+
const config = readFullConfig();
|
|
8064
|
+
const entries = Object.entries(config.profiles);
|
|
8065
|
+
if (entries.length === 0) {
|
|
8066
|
+
process.stdout.write("No profiles found. Run: okx config add-profile AK=<key> SK=<secret> PP=<passphrase>\n");
|
|
8067
|
+
return;
|
|
8068
|
+
}
|
|
8069
|
+
process.stdout.write(`Config: ${configFilePath()}
|
|
8070
|
+
|
|
8071
|
+
`);
|
|
8072
|
+
for (const [name, profile] of entries) {
|
|
8073
|
+
const isDefault = name === config.default_profile;
|
|
8074
|
+
const marker = isDefault ? " *" : "";
|
|
8075
|
+
const site = profile.site ?? inferSiteFromBaseUrl(profile.base_url);
|
|
8076
|
+
const mode = profile.demo !== false ? "demo (\u6A21\u62DF\u76D8)" : "live (\u5B9E\u76D8)";
|
|
8077
|
+
process.stdout.write(`[${name}]${marker}
|
|
8078
|
+
`);
|
|
8079
|
+
process.stdout.write(` api_key: ${maskSecret(profile.api_key)}
|
|
8080
|
+
`);
|
|
8081
|
+
process.stdout.write(` secret_key: ${maskSecret(profile.secret_key)}
|
|
8082
|
+
`);
|
|
8083
|
+
process.stdout.write(` passphrase: ${maskSecret(profile.passphrase)}
|
|
8084
|
+
`);
|
|
8085
|
+
process.stdout.write(` site: ${site}
|
|
8086
|
+
`);
|
|
8087
|
+
process.stdout.write(` mode: ${mode}
|
|
8088
|
+
`);
|
|
8089
|
+
process.stdout.write("\n");
|
|
8090
|
+
}
|
|
8091
|
+
}
|
|
8092
|
+
function cmdConfigUse(profileName) {
|
|
8093
|
+
if (!profileName) {
|
|
8094
|
+
process.stderr.write("Error: profile name is required.\nUsage: okx config use <profile-name>\n");
|
|
8095
|
+
process.exitCode = 1;
|
|
8096
|
+
return;
|
|
8097
|
+
}
|
|
8098
|
+
const config = readFullConfig();
|
|
8099
|
+
const available = Object.keys(config.profiles);
|
|
8100
|
+
if (!config.profiles[profileName]) {
|
|
8101
|
+
process.stderr.write(`Error: profile "${profileName}" does not exist.
|
|
8102
|
+
`);
|
|
8103
|
+
if (available.length > 0) {
|
|
8104
|
+
process.stderr.write(`Available profiles: ${available.join(", ")}
|
|
8105
|
+
`);
|
|
8106
|
+
} else {
|
|
8107
|
+
process.stderr.write("No profiles configured. Run: okx config add-profile AK=<key> SK=<secret> PP=<passphrase>\n");
|
|
8108
|
+
}
|
|
8109
|
+
process.exitCode = 1;
|
|
8110
|
+
return;
|
|
8111
|
+
}
|
|
8112
|
+
config.default_profile = profileName;
|
|
8113
|
+
writeCliConfig(config);
|
|
8114
|
+
process.stdout.write(`Default profile set to: "${profileName}"
|
|
8115
|
+
`);
|
|
8116
|
+
}
|
|
7982
8117
|
|
|
7983
8118
|
// src/commands/bot.ts
|
|
7984
8119
|
function getData7(result) {
|
|
@@ -8075,7 +8210,8 @@ async function cmdGridCreate(run, opts) {
|
|
|
8075
8210
|
baseSz: opts.baseSz,
|
|
8076
8211
|
direction: opts.direction,
|
|
8077
8212
|
lever: opts.lever,
|
|
8078
|
-
sz: opts.sz
|
|
8213
|
+
sz: opts.sz,
|
|
8214
|
+
basePos: opts.basePos
|
|
8079
8215
|
});
|
|
8080
8216
|
const data = getData7(result);
|
|
8081
8217
|
if (opts.json) return printJson(data);
|
|
@@ -8251,12 +8387,15 @@ async function cmdDcaSubOrders(run, opts) {
|
|
|
8251
8387
|
// src/index.ts
|
|
8252
8388
|
var _require = createRequire(import.meta.url);
|
|
8253
8389
|
var CLI_VERSION = _require("../package.json").version;
|
|
8254
|
-
var GIT_HASH = true ? "
|
|
8255
|
-
function handleConfigCommand(action, rest, json, lang) {
|
|
8390
|
+
var GIT_HASH = true ? "9eed480" : "dev";
|
|
8391
|
+
function handleConfigCommand(action, rest, json, lang, force) {
|
|
8256
8392
|
if (action === "init") return cmdConfigInit(lang === "zh" ? "zh" : "en");
|
|
8257
8393
|
if (action === "show") return cmdConfigShow(json);
|
|
8258
8394
|
if (action === "set") return cmdConfigSet(rest[0], rest[1]);
|
|
8259
8395
|
if (action === "setup-clients") return cmdSetupClients();
|
|
8396
|
+
if (action === "add-profile") return cmdConfigAddProfile(rest, force ?? false);
|
|
8397
|
+
if (action === "list-profile") return cmdConfigListProfile();
|
|
8398
|
+
if (action === "use") return cmdConfigUse(rest[0]);
|
|
8260
8399
|
process.stderr.write(`Unknown config command: ${action}
|
|
8261
8400
|
`);
|
|
8262
8401
|
process.exitCode = 1;
|
|
@@ -8653,6 +8792,7 @@ function handleBotGridCommand(run, v, rest, json) {
|
|
|
8653
8792
|
direction: v.direction,
|
|
8654
8793
|
lever: v.lever,
|
|
8655
8794
|
sz: v.sz,
|
|
8795
|
+
basePos: v.basePos,
|
|
8656
8796
|
json
|
|
8657
8797
|
});
|
|
8658
8798
|
if (subAction === "stop")
|
|
@@ -8720,7 +8860,7 @@ async function main() {
|
|
|
8720
8860
|
const [module, action, ...rest] = positionals;
|
|
8721
8861
|
const v = values;
|
|
8722
8862
|
const json = v.json ?? false;
|
|
8723
|
-
if (module === "config") return handleConfigCommand(action, rest, json, v.lang);
|
|
8863
|
+
if (module === "config") return handleConfigCommand(action, rest, json, v.lang, v.force);
|
|
8724
8864
|
if (module === "setup") return handleSetupCommand(v);
|
|
8725
8865
|
const config = loadProfileConfig({ profile: v.profile, demo: v.demo, userAgent: `okx-trade-cli/${CLI_VERSION}` });
|
|
8726
8866
|
const client = new OkxRestClient(config);
|