okx-trade-cli 1.0.4 → 1.0.5
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 +596 -474
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { parseArgs } from "util";
|
|
5
5
|
import { createRequire } from "module";
|
|
6
|
+
import { pathToFileURL } from "url";
|
|
6
7
|
|
|
7
8
|
// ../core/dist/index.js
|
|
8
9
|
import { createHmac } from "crypto";
|
|
@@ -15,6 +16,10 @@ import { parse } from "smol-toml";
|
|
|
15
16
|
import { readFileSync as readFileSync2, writeFileSync, mkdirSync, existsSync as existsSync2 } from "fs";
|
|
16
17
|
import { join as join2 } from "path";
|
|
17
18
|
import { homedir as homedir2 } from "os";
|
|
19
|
+
import * as fs3 from "fs";
|
|
20
|
+
import * as path3 from "path";
|
|
21
|
+
import * as os3 from "os";
|
|
22
|
+
import { execFileSync } from "child_process";
|
|
18
23
|
function getNow() {
|
|
19
24
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
20
25
|
}
|
|
@@ -156,6 +161,34 @@ var RateLimiter = class {
|
|
|
156
161
|
bucket.lastRefillMs = now;
|
|
157
162
|
}
|
|
158
163
|
};
|
|
164
|
+
var OKX_CODE_BEHAVIORS = {
|
|
165
|
+
// Rate limit → throw RateLimitError
|
|
166
|
+
"50011": { retry: true, suggestion: "Rate limited. Back off and retry after a delay." },
|
|
167
|
+
"50061": { retry: true, suggestion: "Too many connections. Reduce request frequency and retry." },
|
|
168
|
+
// Server temporarily unavailable → retryable
|
|
169
|
+
"50001": { retry: true, suggestion: "OKX system upgrade in progress. Retry in a few minutes." },
|
|
170
|
+
"50004": { retry: true, suggestion: "Endpoint temporarily unavailable. Retry later." },
|
|
171
|
+
"50013": { retry: true, suggestion: "System busy. Retry after 1-2 seconds." },
|
|
172
|
+
"50026": { retry: true, suggestion: "Order book system upgrading. Retry in a few minutes." },
|
|
173
|
+
// Region / compliance restriction → do not retry
|
|
174
|
+
"51155": { retry: false, suggestion: "Feature unavailable in your region. Do not retry." },
|
|
175
|
+
"51734": { retry: false, suggestion: "Feature not supported for your KYC country. Do not retry." },
|
|
176
|
+
// Account issues → do not retry
|
|
177
|
+
"50007": { retry: false, suggestion: "Account suspended. Contact OKX support. Do not retry." },
|
|
178
|
+
"50009": { retry: false, suggestion: "Account blocked by risk control. Contact OKX support. Do not retry." },
|
|
179
|
+
"51009": { retry: false, suggestion: "Account mode not supported for this operation. Check account settings." },
|
|
180
|
+
// API key permission / expiry → do not retry
|
|
181
|
+
"50100": { retry: false, suggestion: "API key lacks required permissions. Update API key permissions." },
|
|
182
|
+
"50110": { retry: false, suggestion: "API key expired. Generate a new API key." },
|
|
183
|
+
// Insufficient funds / margin → do not retry
|
|
184
|
+
"51008": { retry: false, suggestion: "Insufficient balance. Top up account before retrying." },
|
|
185
|
+
"51119": { retry: false, suggestion: "Insufficient margin. Add margin before retrying." },
|
|
186
|
+
"51127": { retry: false, suggestion: "Insufficient available margin. Reduce position or add margin." },
|
|
187
|
+
// Instrument unavailable → do not retry
|
|
188
|
+
"51021": { retry: false, suggestion: "Instrument does not exist. Check instId." },
|
|
189
|
+
"51022": { retry: false, suggestion: "Instrument not available for trading." },
|
|
190
|
+
"51027": { retry: false, suggestion: "Contract has expired." }
|
|
191
|
+
};
|
|
159
192
|
function isDefined(value) {
|
|
160
193
|
return value !== void 0 && value !== null;
|
|
161
194
|
}
|
|
@@ -188,28 +221,28 @@ var OkxRestClient = class {
|
|
|
188
221
|
constructor(config) {
|
|
189
222
|
this.config = config;
|
|
190
223
|
}
|
|
191
|
-
async publicGet(
|
|
224
|
+
async publicGet(path4, query, rateLimit) {
|
|
192
225
|
return this.request({
|
|
193
226
|
method: "GET",
|
|
194
|
-
path:
|
|
227
|
+
path: path4,
|
|
195
228
|
auth: "public",
|
|
196
229
|
query,
|
|
197
230
|
rateLimit
|
|
198
231
|
});
|
|
199
232
|
}
|
|
200
|
-
async privateGet(
|
|
233
|
+
async privateGet(path4, query, rateLimit) {
|
|
201
234
|
return this.request({
|
|
202
235
|
method: "GET",
|
|
203
|
-
path:
|
|
236
|
+
path: path4,
|
|
204
237
|
auth: "private",
|
|
205
238
|
query,
|
|
206
239
|
rateLimit
|
|
207
240
|
});
|
|
208
241
|
}
|
|
209
|
-
async privatePost(
|
|
242
|
+
async privatePost(path4, body, rateLimit) {
|
|
210
243
|
return this.request({
|
|
211
244
|
method: "POST",
|
|
212
|
-
path:
|
|
245
|
+
path: path4,
|
|
213
246
|
auth: "private",
|
|
214
247
|
body,
|
|
215
248
|
rateLimit
|
|
@@ -307,17 +340,23 @@ var OkxRestClient = class {
|
|
|
307
340
|
const responseCode = parsed.code;
|
|
308
341
|
if (responseCode && responseCode !== "0") {
|
|
309
342
|
const message = parsed.msg ?? "OKX API request failed.";
|
|
343
|
+
const endpoint = `${config.method} ${config.path}`;
|
|
310
344
|
if (responseCode === "50111" || responseCode === "50112" || responseCode === "50113") {
|
|
311
345
|
throw new AuthenticationError(
|
|
312
346
|
message,
|
|
313
347
|
"Check API key, secret, passphrase and permissions.",
|
|
314
|
-
|
|
348
|
+
endpoint,
|
|
315
349
|
traceId
|
|
316
350
|
);
|
|
317
351
|
}
|
|
352
|
+
const behavior = OKX_CODE_BEHAVIORS[responseCode];
|
|
353
|
+
if (responseCode === "50011" || responseCode === "50061") {
|
|
354
|
+
throw new RateLimitError(message, behavior?.suggestion, endpoint, traceId);
|
|
355
|
+
}
|
|
318
356
|
throw new OkxApiError(message, {
|
|
319
357
|
code: responseCode,
|
|
320
|
-
endpoint
|
|
358
|
+
endpoint,
|
|
359
|
+
suggestion: behavior?.suggestion,
|
|
321
360
|
traceId
|
|
322
361
|
});
|
|
323
362
|
}
|
|
@@ -344,9 +383,9 @@ function configFilePath() {
|
|
|
344
383
|
return join(homedir(), ".okx", "config.toml");
|
|
345
384
|
}
|
|
346
385
|
function readTomlProfile(profileName) {
|
|
347
|
-
const
|
|
348
|
-
if (!existsSync(
|
|
349
|
-
const raw = readFileSync(
|
|
386
|
+
const path4 = configFilePath();
|
|
387
|
+
if (!existsSync(path4)) return {};
|
|
388
|
+
const raw = readFileSync(path4, "utf-8");
|
|
350
389
|
const config = parse(raw);
|
|
351
390
|
const name = profileName ?? config.default_profile ?? "default";
|
|
352
391
|
return config.profiles?.[name] ?? {};
|
|
@@ -484,6 +523,120 @@ Run: npm install -g ${packageName}
|
|
|
484
523
|
refreshCacheInBackground(packageName);
|
|
485
524
|
}
|
|
486
525
|
}
|
|
526
|
+
var CLIENT_NAMES = {
|
|
527
|
+
"claude-desktop": "Claude Desktop",
|
|
528
|
+
cursor: "Cursor",
|
|
529
|
+
windsurf: "Windsurf",
|
|
530
|
+
vscode: "VS Code",
|
|
531
|
+
"claude-code": "Claude Code CLI"
|
|
532
|
+
};
|
|
533
|
+
var SUPPORTED_CLIENTS = Object.keys(CLIENT_NAMES);
|
|
534
|
+
function appData() {
|
|
535
|
+
return process.env.APPDATA ?? path3.join(os3.homedir(), "AppData", "Roaming");
|
|
536
|
+
}
|
|
537
|
+
function getConfigPath(client) {
|
|
538
|
+
const home = os3.homedir();
|
|
539
|
+
const win = process.platform === "win32";
|
|
540
|
+
switch (client) {
|
|
541
|
+
case "claude-desktop":
|
|
542
|
+
return win ? path3.join(appData(), "Claude", "claude_desktop_config.json") : path3.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
543
|
+
case "cursor":
|
|
544
|
+
return path3.join(home, ".cursor", "mcp.json");
|
|
545
|
+
case "windsurf":
|
|
546
|
+
return path3.join(home, ".codeium", "windsurf", "mcp_config.json");
|
|
547
|
+
case "vscode":
|
|
548
|
+
return path3.join(process.cwd(), ".mcp.json");
|
|
549
|
+
case "claude-code":
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
function buildEntry(client, args) {
|
|
554
|
+
if (client === "vscode") {
|
|
555
|
+
return { type: "stdio", command: "okx-trade-mcp", args };
|
|
556
|
+
}
|
|
557
|
+
return { command: "okx-trade-mcp", args };
|
|
558
|
+
}
|
|
559
|
+
function buildArgs(options) {
|
|
560
|
+
const args = [];
|
|
561
|
+
if (options.profile) args.push("--profile", options.profile);
|
|
562
|
+
args.push("--modules", options.modules ?? "all");
|
|
563
|
+
return args;
|
|
564
|
+
}
|
|
565
|
+
function mergeJsonConfig(configPath, serverName, entry) {
|
|
566
|
+
const dir = path3.dirname(configPath);
|
|
567
|
+
if (!fs3.existsSync(dir)) fs3.mkdirSync(dir, { recursive: true });
|
|
568
|
+
let data = {};
|
|
569
|
+
if (fs3.existsSync(configPath)) {
|
|
570
|
+
const raw = fs3.readFileSync(configPath, "utf-8");
|
|
571
|
+
try {
|
|
572
|
+
data = JSON.parse(raw);
|
|
573
|
+
} catch {
|
|
574
|
+
throw new Error(`Failed to parse existing config at ${configPath}`);
|
|
575
|
+
}
|
|
576
|
+
const backupPath = configPath + ".bak";
|
|
577
|
+
fs3.copyFileSync(configPath, backupPath);
|
|
578
|
+
process.stdout.write(` Backup \u2192 ${backupPath}
|
|
579
|
+
`);
|
|
580
|
+
}
|
|
581
|
+
if (typeof data.mcpServers !== "object" || data.mcpServers === null) {
|
|
582
|
+
data.mcpServers = {};
|
|
583
|
+
}
|
|
584
|
+
data.mcpServers[serverName] = entry;
|
|
585
|
+
fs3.writeFileSync(configPath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
586
|
+
}
|
|
587
|
+
function printSetupUsage() {
|
|
588
|
+
process.stdout.write(
|
|
589
|
+
`Usage: okx-trade-mcp setup --client <client> [--profile <name>] [--modules <list>]
|
|
590
|
+
|
|
591
|
+
Clients:
|
|
592
|
+
` + SUPPORTED_CLIENTS.map((id) => ` ${id.padEnd(16)} ${CLIENT_NAMES[id]}`).join("\n") + `
|
|
593
|
+
|
|
594
|
+
Options:
|
|
595
|
+
--profile <name> Profile from ~/.okx/config.toml (default: uses default_profile)
|
|
596
|
+
--modules <list> Comma-separated modules or "all" (default: all)
|
|
597
|
+
`
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
function runSetup(options) {
|
|
601
|
+
const { client } = options;
|
|
602
|
+
const name = CLIENT_NAMES[client];
|
|
603
|
+
const args = buildArgs(options);
|
|
604
|
+
const serverName = options.profile ? `okx-trade-mcp-${options.profile}` : "okx-trade-mcp";
|
|
605
|
+
if (client === "claude-code") {
|
|
606
|
+
const claudeArgs = [
|
|
607
|
+
"mcp",
|
|
608
|
+
"add",
|
|
609
|
+
"--transport",
|
|
610
|
+
"stdio",
|
|
611
|
+
serverName,
|
|
612
|
+
"--",
|
|
613
|
+
"okx-trade-mcp",
|
|
614
|
+
...args
|
|
615
|
+
];
|
|
616
|
+
process.stdout.write(`Running: claude ${claudeArgs.join(" ")}
|
|
617
|
+
`);
|
|
618
|
+
execFileSync("claude", claudeArgs, { stdio: "inherit" });
|
|
619
|
+
process.stdout.write(`\u2713 Configured ${name}
|
|
620
|
+
`);
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
const configPath = getConfigPath(client);
|
|
624
|
+
if (!configPath) {
|
|
625
|
+
throw new Error(`${name} is not supported on this platform`);
|
|
626
|
+
}
|
|
627
|
+
const entry = buildEntry(client, args);
|
|
628
|
+
mergeJsonConfig(configPath, serverName, entry);
|
|
629
|
+
process.stdout.write(
|
|
630
|
+
`\u2713 Configured ${name}
|
|
631
|
+
${configPath}
|
|
632
|
+
Server args: ${args.join(" ")}
|
|
633
|
+
`
|
|
634
|
+
);
|
|
635
|
+
if (client !== "vscode") {
|
|
636
|
+
process.stdout.write(` Restart ${name} to apply changes.
|
|
637
|
+
`);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
487
640
|
|
|
488
641
|
// src/config/loader.ts
|
|
489
642
|
function loadProfileConfig(opts) {
|
|
@@ -632,11 +785,11 @@ async function cmdMarketIndexTicker(client, opts) {
|
|
|
632
785
|
);
|
|
633
786
|
}
|
|
634
787
|
async function cmdMarketIndexCandles(client, instId, opts) {
|
|
635
|
-
const
|
|
788
|
+
const path2 = opts.history ? "/api/v5/market/history-index-candles" : "/api/v5/market/index-candles";
|
|
636
789
|
const params = { instId };
|
|
637
790
|
if (opts.bar) params["bar"] = opts.bar;
|
|
638
791
|
if (opts.limit) params["limit"] = String(opts.limit);
|
|
639
|
-
const res = await client.publicGet(
|
|
792
|
+
const res = await client.publicGet(path2, params);
|
|
640
793
|
const candles = res.data;
|
|
641
794
|
if (opts.json) return printJson(candles);
|
|
642
795
|
printTable(
|
|
@@ -1312,11 +1465,11 @@ async function cmdSwapAlgoOrders(client, opts) {
|
|
|
1312
1465
|
);
|
|
1313
1466
|
}
|
|
1314
1467
|
async function cmdSwapFills(client, opts) {
|
|
1315
|
-
const
|
|
1468
|
+
const path2 = opts.archive ? "/api/v5/trade/fills-history" : "/api/v5/trade/fills";
|
|
1316
1469
|
const params = { instType: "SWAP" };
|
|
1317
1470
|
if (opts.instId) params["instId"] = opts.instId;
|
|
1318
1471
|
if (opts.ordId) params["ordId"] = opts.ordId;
|
|
1319
|
-
const res = await client.privateGet(
|
|
1472
|
+
const res = await client.privateGet(path2, params);
|
|
1320
1473
|
const fills = res.data;
|
|
1321
1474
|
if (opts.json) return printJson(fills);
|
|
1322
1475
|
printTable(
|
|
@@ -1401,10 +1554,10 @@ async function cmdSwapSetLeverage(client, opts) {
|
|
|
1401
1554
|
|
|
1402
1555
|
// src/commands/futures.ts
|
|
1403
1556
|
async function cmdFuturesOrders(client, opts) {
|
|
1404
|
-
const
|
|
1557
|
+
const path2 = opts.status === "archive" ? "/api/v5/trade/orders-history-archive" : opts.status === "history" ? "/api/v5/trade/orders-history" : "/api/v5/trade/orders-pending";
|
|
1405
1558
|
const params = { instType: "FUTURES" };
|
|
1406
1559
|
if (opts.instId) params["instId"] = opts.instId;
|
|
1407
|
-
const res = await client.privateGet(
|
|
1560
|
+
const res = await client.privateGet(path2, params);
|
|
1408
1561
|
const orders = res.data;
|
|
1409
1562
|
if (opts.json) return printJson(orders);
|
|
1410
1563
|
printTable(
|
|
@@ -1443,11 +1596,11 @@ async function cmdFuturesPositions(client, instId, json) {
|
|
|
1443
1596
|
);
|
|
1444
1597
|
}
|
|
1445
1598
|
async function cmdFuturesFills(client, opts) {
|
|
1446
|
-
const
|
|
1599
|
+
const path2 = opts.archive ? "/api/v5/trade/fills-history" : "/api/v5/trade/fills";
|
|
1447
1600
|
const params = { instType: "FUTURES" };
|
|
1448
1601
|
if (opts.instId) params["instId"] = opts.instId;
|
|
1449
1602
|
if (opts.ordId) params["ordId"] = opts.ordId;
|
|
1450
|
-
const res = await client.privateGet(
|
|
1603
|
+
const res = await client.privateGet(path2, params);
|
|
1451
1604
|
const fills = res.data;
|
|
1452
1605
|
if (opts.json) return printJson(fills);
|
|
1453
1606
|
printTable(
|
|
@@ -1512,28 +1665,28 @@ async function cmdFuturesGet(client, opts) {
|
|
|
1512
1665
|
}
|
|
1513
1666
|
|
|
1514
1667
|
// src/config/toml.ts
|
|
1515
|
-
import { writeFileSync as
|
|
1668
|
+
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync4 } from "fs";
|
|
1516
1669
|
import { stringify } from "smol-toml";
|
|
1517
1670
|
function configDir() {
|
|
1518
1671
|
return configFilePath().replace(/\/config\.toml$/, "");
|
|
1519
1672
|
}
|
|
1520
1673
|
function writeCliConfig(config) {
|
|
1521
1674
|
const dir = configDir();
|
|
1522
|
-
if (!
|
|
1523
|
-
|
|
1675
|
+
if (!existsSync4(dir)) {
|
|
1676
|
+
mkdirSync3(dir, { recursive: true });
|
|
1524
1677
|
}
|
|
1525
|
-
|
|
1678
|
+
writeFileSync3(configFilePath(), stringify(config), "utf-8");
|
|
1526
1679
|
}
|
|
1527
1680
|
|
|
1528
1681
|
// src/commands/config.ts
|
|
1529
|
-
import { existsSync as
|
|
1682
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
|
|
1530
1683
|
import { parse as parse2, stringify as stringify2 } from "smol-toml";
|
|
1531
1684
|
import { createInterface } from "readline";
|
|
1532
1685
|
import { spawnSync } from "child_process";
|
|
1533
1686
|
function readFullConfig() {
|
|
1534
|
-
const
|
|
1535
|
-
if (!
|
|
1536
|
-
const raw =
|
|
1687
|
+
const path2 = configFilePath();
|
|
1688
|
+
if (!existsSync5(path2)) return { profiles: {} };
|
|
1689
|
+
const raw = readFileSync4(path2, "utf-8");
|
|
1537
1690
|
return parse2(raw);
|
|
1538
1691
|
}
|
|
1539
1692
|
function prompt(rl, question) {
|
|
@@ -1644,120 +1797,39 @@ async function cmdConfigInit() {
|
|
|
1644
1797
|
|
|
1645
1798
|
// src/commands/client-setup.ts
|
|
1646
1799
|
import * as fs from "fs";
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
name: "Windsurf",
|
|
1663
|
-
configPath: path2.join(os2.homedir(), ".codeium/windsurf/mcp_config.json"),
|
|
1664
|
-
mcpKey: "mcpServers"
|
|
1665
|
-
}
|
|
1666
|
-
];
|
|
1667
|
-
var MCP_ENTRY = {
|
|
1668
|
-
command: "okx-trade-mcp",
|
|
1669
|
-
args: ["--modules", "all"]
|
|
1670
|
-
};
|
|
1671
|
-
var MCP_SERVER_NAME = "okx-trade-mcp";
|
|
1672
|
-
function prompt2(rl, question) {
|
|
1673
|
-
return new Promise((resolve) => {
|
|
1674
|
-
rl.question(question, (answer) => {
|
|
1675
|
-
resolve(answer);
|
|
1676
|
-
});
|
|
1677
|
-
});
|
|
1678
|
-
}
|
|
1679
|
-
async function cmdSetupClients() {
|
|
1680
|
-
const detected = CLIENTS.filter((c) => fs.existsSync(c.configPath));
|
|
1681
|
-
if (detected.length === 0) {
|
|
1682
|
-
process.stdout.write(
|
|
1683
|
-
"No supported IDE/client installations detected.\nChecked:\n" + CLIENTS.map((c) => ` - ${c.name}: ${c.configPath}`).join("\n") + "\n"
|
|
1684
|
-
);
|
|
1685
|
-
return;
|
|
1686
|
-
}
|
|
1687
|
-
process.stdout.write(`Detected ${detected.length} client(s):
|
|
1688
|
-
`);
|
|
1689
|
-
for (const c of detected) {
|
|
1690
|
-
process.stdout.write(` - ${c.name}
|
|
1691
|
-
`);
|
|
1692
|
-
}
|
|
1693
|
-
process.stdout.write("\n");
|
|
1694
|
-
const rl = readline.createInterface({
|
|
1695
|
-
input: process.stdin,
|
|
1696
|
-
output: process.stdout
|
|
1697
|
-
});
|
|
1698
|
-
try {
|
|
1699
|
-
for (const client of detected) {
|
|
1700
|
-
const answer = await prompt2(rl, `Configure ${client.name}? (y/N) `);
|
|
1701
|
-
if (answer.trim().toLowerCase() !== "y") {
|
|
1702
|
-
process.stdout.write(` Skipped ${client.name}.
|
|
1703
|
-
`);
|
|
1704
|
-
continue;
|
|
1705
|
-
}
|
|
1706
|
-
let data = { [client.mcpKey]: {} };
|
|
1707
|
-
if (fs.existsSync(client.configPath)) {
|
|
1708
|
-
const raw = fs.readFileSync(client.configPath, "utf-8");
|
|
1709
|
-
try {
|
|
1710
|
-
data = JSON.parse(raw);
|
|
1711
|
-
} catch {
|
|
1712
|
-
process.stderr.write(
|
|
1713
|
-
` Error: Failed to parse JSON for ${client.name} at ${client.configPath}. Skipping.
|
|
1714
|
-
`
|
|
1715
|
-
);
|
|
1716
|
-
continue;
|
|
1717
|
-
}
|
|
1718
|
-
}
|
|
1719
|
-
if (typeof data[client.mcpKey] !== "object" || data[client.mcpKey] === null) {
|
|
1720
|
-
data[client.mcpKey] = {};
|
|
1721
|
-
}
|
|
1722
|
-
const servers = data[client.mcpKey];
|
|
1723
|
-
if (Object.prototype.hasOwnProperty.call(servers, MCP_SERVER_NAME)) {
|
|
1724
|
-
process.stdout.write(` Already configured in ${client.name}. Skipping.
|
|
1800
|
+
function cmdSetupClient(options) {
|
|
1801
|
+
runSetup(options);
|
|
1802
|
+
}
|
|
1803
|
+
function cmdSetupClients() {
|
|
1804
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
1805
|
+
const detectedPaths = {
|
|
1806
|
+
"claude-desktop": `${home}/Library/Application Support/Claude/claude_desktop_config.json`,
|
|
1807
|
+
cursor: `${home}/.cursor/mcp.json`,
|
|
1808
|
+
windsurf: `${home}/.codeium/windsurf/mcp_config.json`
|
|
1809
|
+
};
|
|
1810
|
+
const detected = Object.entries(detectedPaths).filter(
|
|
1811
|
+
([, p]) => fs.existsSync(p)
|
|
1812
|
+
);
|
|
1813
|
+
if (detected.length > 0) {
|
|
1814
|
+
process.stdout.write(`Detected clients:
|
|
1725
1815
|
`);
|
|
1726
|
-
|
|
1727
|
-
}
|
|
1728
|
-
servers[MCP_SERVER_NAME] = MCP_ENTRY;
|
|
1729
|
-
const jsonOutput = JSON.stringify(data, null, 2);
|
|
1730
|
-
try {
|
|
1731
|
-
fs.writeFileSync(client.configPath, jsonOutput, "utf-8");
|
|
1732
|
-
process.stdout.write(` Configured ${client.name} successfully.
|
|
1816
|
+
for (const [id] of detected) {
|
|
1817
|
+
process.stdout.write(` ${id}
|
|
1733
1818
|
`);
|
|
1734
|
-
} catch (err) {
|
|
1735
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
1736
|
-
process.stderr.write(
|
|
1737
|
-
` Error: Failed to write config for ${client.name}: ${reason}
|
|
1738
|
-
Add the following to "${client.configPath}" manually:
|
|
1739
|
-
|
|
1740
|
-
"${MCP_SERVER_NAME}": ${JSON.stringify(MCP_ENTRY, null, 2).split("\n").join("\n ")}
|
|
1741
|
-
|
|
1742
|
-
`
|
|
1743
|
-
);
|
|
1744
|
-
}
|
|
1745
1819
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1820
|
+
process.stdout.write(`
|
|
1821
|
+
`);
|
|
1748
1822
|
}
|
|
1749
|
-
|
|
1750
|
-
"\nDone. Please restart any configured IDE/client for the changes to take effect.\n"
|
|
1751
|
-
);
|
|
1823
|
+
printSetupUsage();
|
|
1752
1824
|
}
|
|
1753
1825
|
|
|
1754
1826
|
// src/commands/bot.ts
|
|
1755
1827
|
async function cmdGridOrders(client, opts) {
|
|
1756
|
-
const
|
|
1828
|
+
const path2 = opts.status === "history" ? "/api/v5/tradingBot/grid/orders-algo-history" : "/api/v5/tradingBot/grid/orders-algo-pending";
|
|
1757
1829
|
const params = { algoOrdType: opts.algoOrdType };
|
|
1758
1830
|
if (opts.instId) params["instId"] = opts.instId;
|
|
1759
1831
|
if (opts.algoId) params["algoId"] = opts.algoId;
|
|
1760
|
-
const res = await client.privateGet(
|
|
1832
|
+
const res = await client.privateGet(path2, params);
|
|
1761
1833
|
const orders = res.data ?? [];
|
|
1762
1834
|
if (opts.json) return printJson(orders);
|
|
1763
1835
|
if (!orders.length) {
|
|
@@ -1964,7 +2036,366 @@ Commands:
|
|
|
1964
2036
|
config show
|
|
1965
2037
|
config set <key> <value>
|
|
1966
2038
|
config setup-clients
|
|
2039
|
+
|
|
2040
|
+
setup --client <client> [--profile <name>] [--modules <list>]
|
|
2041
|
+
|
|
2042
|
+
Clients: ${SUPPORTED_CLIENTS.join(", ")}
|
|
2043
|
+
`);
|
|
2044
|
+
}
|
|
2045
|
+
function handleConfigCommand(action, rest, json) {
|
|
2046
|
+
if (action === "init") return cmdConfigInit();
|
|
2047
|
+
if (action === "show") return cmdConfigShow(json);
|
|
2048
|
+
if (action === "set") return cmdConfigSet(rest[0], rest[1]);
|
|
2049
|
+
if (action === "setup-clients") return cmdSetupClients();
|
|
2050
|
+
process.stderr.write(`Unknown config command: ${action}
|
|
1967
2051
|
`);
|
|
2052
|
+
process.exitCode = 1;
|
|
2053
|
+
}
|
|
2054
|
+
function handleSetupCommand(v) {
|
|
2055
|
+
if (!v.client) {
|
|
2056
|
+
printSetupUsage();
|
|
2057
|
+
return;
|
|
2058
|
+
}
|
|
2059
|
+
if (!SUPPORTED_CLIENTS.includes(v.client)) {
|
|
2060
|
+
process.stderr.write(
|
|
2061
|
+
`Unknown client: "${v.client}"
|
|
2062
|
+
Supported: ${SUPPORTED_CLIENTS.join(", ")}
|
|
2063
|
+
`
|
|
2064
|
+
);
|
|
2065
|
+
process.exitCode = 1;
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
cmdSetupClient({
|
|
2069
|
+
client: v.client,
|
|
2070
|
+
profile: v.profile,
|
|
2071
|
+
modules: v.modules
|
|
2072
|
+
});
|
|
2073
|
+
}
|
|
2074
|
+
function handleMarketPublicCommand(client, action, rest, v, json) {
|
|
2075
|
+
if (action === "ticker") return cmdMarketTicker(client, rest[0], json);
|
|
2076
|
+
if (action === "tickers") return cmdMarketTickers(client, rest[0], json);
|
|
2077
|
+
if (action === "instruments")
|
|
2078
|
+
return cmdMarketInstruments(client, { instType: v.instType, instId: v.instId, json });
|
|
2079
|
+
if (action === "mark-price")
|
|
2080
|
+
return cmdMarketMarkPrice(client, { instType: v.instType, instId: v.instId, json });
|
|
2081
|
+
if (action === "index-ticker")
|
|
2082
|
+
return cmdMarketIndexTicker(client, { instId: v.instId, quoteCcy: v.quoteCcy, json });
|
|
2083
|
+
if (action === "price-limit") return cmdMarketPriceLimit(client, rest[0], json);
|
|
2084
|
+
if (action === "open-interest")
|
|
2085
|
+
return cmdMarketOpenInterest(client, { instType: v.instType, instId: v.instId, json });
|
|
2086
|
+
}
|
|
2087
|
+
function handleMarketDataCommand(client, action, rest, v, json) {
|
|
2088
|
+
const limit = v.limit !== void 0 ? Number(v.limit) : void 0;
|
|
2089
|
+
if (action === "orderbook")
|
|
2090
|
+
return cmdMarketOrderbook(client, rest[0], v.sz !== void 0 ? Number(v.sz) : void 0, json);
|
|
2091
|
+
if (action === "candles")
|
|
2092
|
+
return cmdMarketCandles(client, rest[0], { bar: v.bar, limit, json });
|
|
2093
|
+
if (action === "funding-rate")
|
|
2094
|
+
return cmdMarketFundingRate(client, rest[0], { history: v.history ?? false, limit, json });
|
|
2095
|
+
if (action === "trades")
|
|
2096
|
+
return cmdMarketTrades(client, rest[0], { limit, json });
|
|
2097
|
+
if (action === "index-candles")
|
|
2098
|
+
return cmdMarketIndexCandles(client, rest[0], { bar: v.bar, limit, history: v.history ?? false, json });
|
|
2099
|
+
}
|
|
2100
|
+
function handleMarketCommand(client, action, rest, v, json) {
|
|
2101
|
+
return handleMarketPublicCommand(client, action, rest, v, json) ?? handleMarketDataCommand(client, action, rest, v, json);
|
|
2102
|
+
}
|
|
2103
|
+
function handleAccountWriteCommand(client, action, v, json) {
|
|
2104
|
+
if (action === "set-position-mode")
|
|
2105
|
+
return cmdAccountSetPositionMode(client, v.posMode, json);
|
|
2106
|
+
if (action === "max-size")
|
|
2107
|
+
return cmdAccountMaxSize(client, { instId: v.instId, tdMode: v.tdMode, px: v.px, json });
|
|
2108
|
+
if (action === "max-avail-size")
|
|
2109
|
+
return cmdAccountMaxAvailSize(client, { instId: v.instId, tdMode: v.tdMode, json });
|
|
2110
|
+
if (action === "max-withdrawal") return cmdAccountMaxWithdrawal(client, v.ccy, json);
|
|
2111
|
+
if (action === "transfer")
|
|
2112
|
+
return cmdAccountTransfer(client, {
|
|
2113
|
+
ccy: v.ccy,
|
|
2114
|
+
amt: v.amt,
|
|
2115
|
+
from: v.from,
|
|
2116
|
+
to: v.to,
|
|
2117
|
+
transferType: v.transferType,
|
|
2118
|
+
subAcct: v.subAcct,
|
|
2119
|
+
json
|
|
2120
|
+
});
|
|
2121
|
+
}
|
|
2122
|
+
function handleAccountCommand(client, action, rest, v, json) {
|
|
2123
|
+
const limit = v.limit !== void 0 ? Number(v.limit) : void 0;
|
|
2124
|
+
if (action === "balance") return cmdAccountBalance(client, rest[0], json);
|
|
2125
|
+
if (action === "asset-balance") return cmdAccountAssetBalance(client, v.ccy, json);
|
|
2126
|
+
if (action === "positions")
|
|
2127
|
+
return cmdAccountPositions(client, { instType: v.instType, instId: v.instId, json });
|
|
2128
|
+
if (action === "positions-history")
|
|
2129
|
+
return cmdAccountPositionsHistory(client, {
|
|
2130
|
+
instType: v.instType,
|
|
2131
|
+
instId: v.instId,
|
|
2132
|
+
limit,
|
|
2133
|
+
json
|
|
2134
|
+
});
|
|
2135
|
+
if (action === "bills")
|
|
2136
|
+
return cmdAccountBills(client, {
|
|
2137
|
+
archive: v.archive ?? false,
|
|
2138
|
+
instType: v.instType,
|
|
2139
|
+
ccy: v.ccy,
|
|
2140
|
+
limit,
|
|
2141
|
+
json
|
|
2142
|
+
});
|
|
2143
|
+
if (action === "fees")
|
|
2144
|
+
return cmdAccountFees(client, { instType: v.instType, instId: v.instId, json });
|
|
2145
|
+
if (action === "config") return cmdAccountConfig(client, json);
|
|
2146
|
+
return handleAccountWriteCommand(client, action, v, json);
|
|
2147
|
+
}
|
|
2148
|
+
function handleSpotAlgoCommand(client, subAction, v, json) {
|
|
2149
|
+
if (subAction === "place")
|
|
2150
|
+
return cmdSpotAlgoPlace(client, {
|
|
2151
|
+
instId: v.instId,
|
|
2152
|
+
side: v.side,
|
|
2153
|
+
ordType: v.ordType ?? "conditional",
|
|
2154
|
+
sz: v.sz,
|
|
2155
|
+
tpTriggerPx: v.tpTriggerPx,
|
|
2156
|
+
tpOrdPx: v.tpOrdPx,
|
|
2157
|
+
slTriggerPx: v.slTriggerPx,
|
|
2158
|
+
slOrdPx: v.slOrdPx,
|
|
2159
|
+
json
|
|
2160
|
+
});
|
|
2161
|
+
if (subAction === "amend")
|
|
2162
|
+
return cmdSpotAlgoAmend(client, {
|
|
2163
|
+
instId: v.instId,
|
|
2164
|
+
algoId: v.algoId,
|
|
2165
|
+
newSz: v.newSz,
|
|
2166
|
+
newTpTriggerPx: v.newTpTriggerPx,
|
|
2167
|
+
newTpOrdPx: v.newTpOrdPx,
|
|
2168
|
+
newSlTriggerPx: v.newSlTriggerPx,
|
|
2169
|
+
newSlOrdPx: v.newSlOrdPx,
|
|
2170
|
+
json
|
|
2171
|
+
});
|
|
2172
|
+
if (subAction === "cancel")
|
|
2173
|
+
return cmdSpotAlgoCancel(client, v.instId, v.algoId, json);
|
|
2174
|
+
if (subAction === "orders")
|
|
2175
|
+
return cmdSpotAlgoOrders(client, {
|
|
2176
|
+
instId: v.instId,
|
|
2177
|
+
status: v.history ? "history" : "pending",
|
|
2178
|
+
ordType: v.ordType,
|
|
2179
|
+
json
|
|
2180
|
+
});
|
|
2181
|
+
}
|
|
2182
|
+
function handleSpotCommand(client, action, rest, v, json) {
|
|
2183
|
+
if (action === "orders")
|
|
2184
|
+
return cmdSpotOrders(client, {
|
|
2185
|
+
instId: v.instId,
|
|
2186
|
+
status: v.history ? "history" : "open",
|
|
2187
|
+
json
|
|
2188
|
+
});
|
|
2189
|
+
if (action === "get")
|
|
2190
|
+
return cmdSpotGet(client, { instId: v.instId, ordId: v.ordId, clOrdId: v.clOrdId, json });
|
|
2191
|
+
if (action === "fills")
|
|
2192
|
+
return cmdSpotFills(client, { instId: v.instId, ordId: v.ordId, json });
|
|
2193
|
+
if (action === "amend")
|
|
2194
|
+
return cmdSpotAmend(client, {
|
|
2195
|
+
instId: v.instId,
|
|
2196
|
+
ordId: v.ordId,
|
|
2197
|
+
clOrdId: v.clOrdId,
|
|
2198
|
+
newSz: v.newSz,
|
|
2199
|
+
newPx: v.newPx,
|
|
2200
|
+
json
|
|
2201
|
+
});
|
|
2202
|
+
if (action === "place")
|
|
2203
|
+
return cmdSpotPlace(client, {
|
|
2204
|
+
instId: v.instId,
|
|
2205
|
+
side: v.side,
|
|
2206
|
+
ordType: v.ordType,
|
|
2207
|
+
sz: v.sz,
|
|
2208
|
+
px: v.px,
|
|
2209
|
+
json
|
|
2210
|
+
});
|
|
2211
|
+
if (action === "cancel")
|
|
2212
|
+
return cmdSpotCancel(client, rest[0], v.ordId, json);
|
|
2213
|
+
if (action === "algo")
|
|
2214
|
+
return handleSpotAlgoCommand(client, rest[0], v, json);
|
|
2215
|
+
}
|
|
2216
|
+
function handleSwapAlgoCommand(client, subAction, v, json) {
|
|
2217
|
+
if (subAction === "trail")
|
|
2218
|
+
return cmdSwapAlgoTrailPlace(client, {
|
|
2219
|
+
instId: v.instId,
|
|
2220
|
+
side: v.side,
|
|
2221
|
+
sz: v.sz,
|
|
2222
|
+
callbackRatio: v.callbackRatio,
|
|
2223
|
+
callbackSpread: v.callbackSpread,
|
|
2224
|
+
activePx: v.activePx,
|
|
2225
|
+
posSide: v.posSide,
|
|
2226
|
+
tdMode: v.tdMode ?? "cross",
|
|
2227
|
+
reduceOnly: v.reduceOnly,
|
|
2228
|
+
json
|
|
2229
|
+
});
|
|
2230
|
+
if (subAction === "place")
|
|
2231
|
+
return cmdSwapAlgoPlace(client, {
|
|
2232
|
+
instId: v.instId,
|
|
2233
|
+
side: v.side,
|
|
2234
|
+
ordType: v.ordType ?? "conditional",
|
|
2235
|
+
sz: v.sz,
|
|
2236
|
+
posSide: v.posSide,
|
|
2237
|
+
tdMode: v.tdMode ?? "cross",
|
|
2238
|
+
tpTriggerPx: v.tpTriggerPx,
|
|
2239
|
+
tpOrdPx: v.tpOrdPx,
|
|
2240
|
+
slTriggerPx: v.slTriggerPx,
|
|
2241
|
+
slOrdPx: v.slOrdPx,
|
|
2242
|
+
reduceOnly: v.reduceOnly,
|
|
2243
|
+
json
|
|
2244
|
+
});
|
|
2245
|
+
if (subAction === "amend")
|
|
2246
|
+
return cmdSwapAlgoAmend(client, {
|
|
2247
|
+
instId: v.instId,
|
|
2248
|
+
algoId: v.algoId,
|
|
2249
|
+
newSz: v.newSz,
|
|
2250
|
+
newTpTriggerPx: v.newTpTriggerPx,
|
|
2251
|
+
newTpOrdPx: v.newTpOrdPx,
|
|
2252
|
+
newSlTriggerPx: v.newSlTriggerPx,
|
|
2253
|
+
newSlOrdPx: v.newSlOrdPx,
|
|
2254
|
+
json
|
|
2255
|
+
});
|
|
2256
|
+
if (subAction === "cancel")
|
|
2257
|
+
return cmdSwapAlgoCancel(client, v.instId, v.algoId, json);
|
|
2258
|
+
if (subAction === "orders")
|
|
2259
|
+
return cmdSwapAlgoOrders(client, {
|
|
2260
|
+
instId: v.instId,
|
|
2261
|
+
status: v.history ? "history" : "pending",
|
|
2262
|
+
ordType: v.ordType,
|
|
2263
|
+
json
|
|
2264
|
+
});
|
|
2265
|
+
}
|
|
2266
|
+
function handleSwapCommand(client, action, rest, v, json) {
|
|
2267
|
+
if (action === "positions")
|
|
2268
|
+
return cmdSwapPositions(client, rest[0] ?? v.instId, json);
|
|
2269
|
+
if (action === "orders")
|
|
2270
|
+
return cmdSwapOrders(client, {
|
|
2271
|
+
instId: v.instId,
|
|
2272
|
+
status: v.history ? "history" : "open",
|
|
2273
|
+
json
|
|
2274
|
+
});
|
|
2275
|
+
if (action === "get")
|
|
2276
|
+
return cmdSwapGet(client, { instId: v.instId, ordId: v.ordId, clOrdId: v.clOrdId, json });
|
|
2277
|
+
if (action === "fills")
|
|
2278
|
+
return cmdSwapFills(client, {
|
|
2279
|
+
instId: v.instId,
|
|
2280
|
+
ordId: v.ordId,
|
|
2281
|
+
archive: v.archive ?? false,
|
|
2282
|
+
json
|
|
2283
|
+
});
|
|
2284
|
+
if (action === "close")
|
|
2285
|
+
return cmdSwapClose(client, {
|
|
2286
|
+
instId: v.instId,
|
|
2287
|
+
mgnMode: v.mgnMode,
|
|
2288
|
+
posSide: v.posSide,
|
|
2289
|
+
autoCxl: v.autoCxl,
|
|
2290
|
+
json
|
|
2291
|
+
});
|
|
2292
|
+
if (action === "get-leverage")
|
|
2293
|
+
return cmdSwapGetLeverage(client, { instId: v.instId, mgnMode: v.mgnMode, json });
|
|
2294
|
+
if (action === "place")
|
|
2295
|
+
return cmdSwapPlace(client, {
|
|
2296
|
+
instId: v.instId,
|
|
2297
|
+
side: v.side,
|
|
2298
|
+
ordType: v.ordType,
|
|
2299
|
+
sz: v.sz,
|
|
2300
|
+
posSide: v.posSide,
|
|
2301
|
+
px: v.px,
|
|
2302
|
+
tdMode: v.tdMode ?? "cross",
|
|
2303
|
+
json
|
|
2304
|
+
});
|
|
2305
|
+
if (action === "cancel")
|
|
2306
|
+
return cmdSwapCancel(client, rest[0], v.ordId, json);
|
|
2307
|
+
if (action === "leverage")
|
|
2308
|
+
return cmdSwapSetLeverage(client, {
|
|
2309
|
+
instId: v.instId,
|
|
2310
|
+
lever: v.lever,
|
|
2311
|
+
mgnMode: v.mgnMode,
|
|
2312
|
+
posSide: v.posSide,
|
|
2313
|
+
json
|
|
2314
|
+
});
|
|
2315
|
+
if (action === "algo")
|
|
2316
|
+
return handleSwapAlgoCommand(client, rest[0], v, json);
|
|
2317
|
+
}
|
|
2318
|
+
function handleFuturesCommand(client, action, rest, v, json) {
|
|
2319
|
+
if (action === "orders") {
|
|
2320
|
+
let status = "open";
|
|
2321
|
+
if (v.archive) status = "archive";
|
|
2322
|
+
else if (v.history) status = "history";
|
|
2323
|
+
return cmdFuturesOrders(client, { instId: v.instId, status, json });
|
|
2324
|
+
}
|
|
2325
|
+
if (action === "positions") return cmdFuturesPositions(client, v.instId, json);
|
|
2326
|
+
if (action === "fills")
|
|
2327
|
+
return cmdFuturesFills(client, {
|
|
2328
|
+
instId: v.instId,
|
|
2329
|
+
ordId: v.ordId,
|
|
2330
|
+
archive: v.archive ?? false,
|
|
2331
|
+
json
|
|
2332
|
+
});
|
|
2333
|
+
if (action === "place")
|
|
2334
|
+
return cmdFuturesPlace(client, {
|
|
2335
|
+
instId: v.instId,
|
|
2336
|
+
side: v.side,
|
|
2337
|
+
ordType: v.ordType,
|
|
2338
|
+
sz: v.sz,
|
|
2339
|
+
tdMode: v.tdMode ?? "cross",
|
|
2340
|
+
posSide: v.posSide,
|
|
2341
|
+
px: v.px,
|
|
2342
|
+
reduceOnly: v.reduceOnly,
|
|
2343
|
+
json
|
|
2344
|
+
});
|
|
2345
|
+
if (action === "cancel")
|
|
2346
|
+
return cmdFuturesCancel(client, rest[0] ?? v.instId, v.ordId, json);
|
|
2347
|
+
if (action === "get")
|
|
2348
|
+
return cmdFuturesGet(client, { instId: rest[0] ?? v.instId, ordId: v.ordId, json });
|
|
2349
|
+
}
|
|
2350
|
+
function handleBotGridCommand(client, v, rest, json) {
|
|
2351
|
+
const subAction = rest[0];
|
|
2352
|
+
if (subAction === "orders")
|
|
2353
|
+
return cmdGridOrders(client, {
|
|
2354
|
+
algoOrdType: v.algoOrdType,
|
|
2355
|
+
instId: v.instId,
|
|
2356
|
+
algoId: v.algoId,
|
|
2357
|
+
status: v.history ? "history" : "active",
|
|
2358
|
+
json
|
|
2359
|
+
});
|
|
2360
|
+
if (subAction === "details")
|
|
2361
|
+
return cmdGridDetails(client, {
|
|
2362
|
+
algoOrdType: v.algoOrdType,
|
|
2363
|
+
algoId: v.algoId,
|
|
2364
|
+
json
|
|
2365
|
+
});
|
|
2366
|
+
if (subAction === "sub-orders")
|
|
2367
|
+
return cmdGridSubOrders(client, {
|
|
2368
|
+
algoOrdType: v.algoOrdType,
|
|
2369
|
+
algoId: v.algoId,
|
|
2370
|
+
type: v.live ? "live" : "filled",
|
|
2371
|
+
json
|
|
2372
|
+
});
|
|
2373
|
+
if (subAction === "create")
|
|
2374
|
+
return cmdGridCreate(client, {
|
|
2375
|
+
instId: v.instId,
|
|
2376
|
+
algoOrdType: v.algoOrdType,
|
|
2377
|
+
maxPx: v.maxPx,
|
|
2378
|
+
minPx: v.minPx,
|
|
2379
|
+
gridNum: v.gridNum,
|
|
2380
|
+
runType: v.runType,
|
|
2381
|
+
quoteSz: v.quoteSz,
|
|
2382
|
+
baseSz: v.baseSz,
|
|
2383
|
+
direction: v.direction,
|
|
2384
|
+
lever: v.lever,
|
|
2385
|
+
sz: v.sz,
|
|
2386
|
+
json
|
|
2387
|
+
});
|
|
2388
|
+
if (subAction === "stop")
|
|
2389
|
+
return cmdGridStop(client, {
|
|
2390
|
+
algoId: v.algoId,
|
|
2391
|
+
algoOrdType: v.algoOrdType,
|
|
2392
|
+
instId: v.instId,
|
|
2393
|
+
stopType: v.stopType,
|
|
2394
|
+
json
|
|
2395
|
+
});
|
|
2396
|
+
}
|
|
2397
|
+
function handleBotCommand(client, action, rest, v, json) {
|
|
2398
|
+
if (action === "grid") return handleBotGridCommand(client, v, rest, json);
|
|
1968
2399
|
}
|
|
1969
2400
|
async function main() {
|
|
1970
2401
|
checkForUpdates("okx-trade-cli", CLI_VERSION);
|
|
@@ -1975,6 +2406,9 @@ async function main() {
|
|
|
1975
2406
|
demo: { type: "boolean", default: false },
|
|
1976
2407
|
json: { type: "boolean", default: false },
|
|
1977
2408
|
help: { type: "boolean", default: false },
|
|
2409
|
+
// setup command
|
|
2410
|
+
client: { type: "string" },
|
|
2411
|
+
modules: { type: "string" },
|
|
1978
2412
|
// market candles
|
|
1979
2413
|
bar: { type: "string" },
|
|
1980
2414
|
limit: { type: "string" },
|
|
@@ -2044,357 +2478,45 @@ async function main() {
|
|
|
2044
2478
|
return;
|
|
2045
2479
|
}
|
|
2046
2480
|
const [module, action, ...rest] = positionals;
|
|
2047
|
-
const
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
if (action === "setup-clients") return cmdSetupClients();
|
|
2053
|
-
process.stderr.write(`Unknown config command: ${action}
|
|
2054
|
-
`);
|
|
2055
|
-
process.exitCode = 1;
|
|
2056
|
-
return;
|
|
2057
|
-
}
|
|
2058
|
-
const config = loadProfileConfig({ profile: values.profile, demo: values.demo, userAgent: `okx-trade-cli/${CLI_VERSION}` });
|
|
2481
|
+
const v = values;
|
|
2482
|
+
const json = v.json ?? false;
|
|
2483
|
+
if (module === "config") return handleConfigCommand(action, rest, json);
|
|
2484
|
+
if (module === "setup") return handleSetupCommand(v);
|
|
2485
|
+
const config = loadProfileConfig({ profile: v.profile, demo: v.demo, userAgent: `okx-trade-cli/${CLI_VERSION}` });
|
|
2059
2486
|
const client = new OkxRestClient(config);
|
|
2060
|
-
if (module === "market")
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
return cmdMarketCandles(client, rest[0], {
|
|
2067
|
-
bar: values.bar,
|
|
2068
|
-
limit: values.limit ? Number(values.limit) : void 0,
|
|
2069
|
-
json
|
|
2070
|
-
});
|
|
2071
|
-
if (action === "instruments")
|
|
2072
|
-
return cmdMarketInstruments(client, { instType: values.instType, instId: values.instId, json });
|
|
2073
|
-
if (action === "funding-rate")
|
|
2074
|
-
return cmdMarketFundingRate(client, rest[0], {
|
|
2075
|
-
history: values.history,
|
|
2076
|
-
limit: values.limit ? Number(values.limit) : void 0,
|
|
2077
|
-
json
|
|
2078
|
-
});
|
|
2079
|
-
if (action === "mark-price")
|
|
2080
|
-
return cmdMarketMarkPrice(client, { instType: values.instType, instId: values.instId, json });
|
|
2081
|
-
if (action === "trades")
|
|
2082
|
-
return cmdMarketTrades(client, rest[0], {
|
|
2083
|
-
limit: values.limit ? Number(values.limit) : void 0,
|
|
2084
|
-
json
|
|
2085
|
-
});
|
|
2086
|
-
if (action === "index-ticker")
|
|
2087
|
-
return cmdMarketIndexTicker(client, { instId: values.instId, quoteCcy: values.quoteCcy, json });
|
|
2088
|
-
if (action === "index-candles")
|
|
2089
|
-
return cmdMarketIndexCandles(client, rest[0], {
|
|
2090
|
-
bar: values.bar,
|
|
2091
|
-
limit: values.limit ? Number(values.limit) : void 0,
|
|
2092
|
-
history: values.history,
|
|
2093
|
-
json
|
|
2094
|
-
});
|
|
2095
|
-
if (action === "price-limit") return cmdMarketPriceLimit(client, rest[0], json);
|
|
2096
|
-
if (action === "open-interest")
|
|
2097
|
-
return cmdMarketOpenInterest(client, { instType: values.instType, instId: values.instId, json });
|
|
2098
|
-
}
|
|
2099
|
-
if (module === "account") {
|
|
2100
|
-
if (action === "balance") return cmdAccountBalance(client, rest[0], json);
|
|
2101
|
-
if (action === "asset-balance") return cmdAccountAssetBalance(client, values.ccy, json);
|
|
2102
|
-
if (action === "positions")
|
|
2103
|
-
return cmdAccountPositions(client, { instType: values.instType, instId: values.instId, json });
|
|
2104
|
-
if (action === "positions-history")
|
|
2105
|
-
return cmdAccountPositionsHistory(client, {
|
|
2106
|
-
instType: values.instType,
|
|
2107
|
-
instId: values.instId,
|
|
2108
|
-
limit: values.limit ? Number(values.limit) : void 0,
|
|
2109
|
-
json
|
|
2110
|
-
});
|
|
2111
|
-
if (action === "bills")
|
|
2112
|
-
return cmdAccountBills(client, {
|
|
2113
|
-
archive: values.archive,
|
|
2114
|
-
instType: values.instType,
|
|
2115
|
-
ccy: values.ccy,
|
|
2116
|
-
limit: values.limit ? Number(values.limit) : void 0,
|
|
2117
|
-
json
|
|
2118
|
-
});
|
|
2119
|
-
if (action === "fees")
|
|
2120
|
-
return cmdAccountFees(client, { instType: values.instType, instId: values.instId, json });
|
|
2121
|
-
if (action === "config") return cmdAccountConfig(client, json);
|
|
2122
|
-
if (action === "set-position-mode")
|
|
2123
|
-
return cmdAccountSetPositionMode(client, values.posMode, json);
|
|
2124
|
-
if (action === "max-size")
|
|
2125
|
-
return cmdAccountMaxSize(client, { instId: values.instId, tdMode: values.tdMode, px: values.px, json });
|
|
2126
|
-
if (action === "max-avail-size")
|
|
2127
|
-
return cmdAccountMaxAvailSize(client, { instId: values.instId, tdMode: values.tdMode, json });
|
|
2128
|
-
if (action === "max-withdrawal") return cmdAccountMaxWithdrawal(client, values.ccy, json);
|
|
2129
|
-
if (action === "transfer")
|
|
2130
|
-
return cmdAccountTransfer(client, {
|
|
2131
|
-
ccy: values.ccy,
|
|
2132
|
-
amt: values.amt,
|
|
2133
|
-
from: values.from,
|
|
2134
|
-
to: values.to,
|
|
2135
|
-
transferType: values.transferType,
|
|
2136
|
-
subAcct: values.subAcct,
|
|
2137
|
-
json
|
|
2138
|
-
});
|
|
2139
|
-
}
|
|
2140
|
-
if (module === "spot") {
|
|
2141
|
-
if (action === "orders")
|
|
2142
|
-
return cmdSpotOrders(client, {
|
|
2143
|
-
instId: values.instId,
|
|
2144
|
-
status: values.history ? "history" : "open",
|
|
2145
|
-
json
|
|
2146
|
-
});
|
|
2147
|
-
if (action === "get")
|
|
2148
|
-
return cmdSpotGet(client, { instId: values.instId, ordId: values.ordId, clOrdId: values.clOrdId, json });
|
|
2149
|
-
if (action === "fills")
|
|
2150
|
-
return cmdSpotFills(client, { instId: values.instId, ordId: values.ordId, json });
|
|
2151
|
-
if (action === "amend")
|
|
2152
|
-
return cmdSpotAmend(client, {
|
|
2153
|
-
instId: values.instId,
|
|
2154
|
-
ordId: values.ordId,
|
|
2155
|
-
clOrdId: values.clOrdId,
|
|
2156
|
-
newSz: values.newSz,
|
|
2157
|
-
newPx: values.newPx,
|
|
2158
|
-
json
|
|
2159
|
-
});
|
|
2160
|
-
if (action === "place")
|
|
2161
|
-
return cmdSpotPlace(client, {
|
|
2162
|
-
instId: values.instId,
|
|
2163
|
-
side: values.side,
|
|
2164
|
-
ordType: values.ordType,
|
|
2165
|
-
sz: values.sz,
|
|
2166
|
-
px: values.px,
|
|
2167
|
-
json
|
|
2168
|
-
});
|
|
2169
|
-
if (action === "cancel")
|
|
2170
|
-
return cmdSpotCancel(client, rest[0], values.ordId, json);
|
|
2171
|
-
if (action === "algo") {
|
|
2172
|
-
const subAction = rest[0];
|
|
2173
|
-
if (subAction === "place")
|
|
2174
|
-
return cmdSpotAlgoPlace(client, {
|
|
2175
|
-
instId: values.instId,
|
|
2176
|
-
side: values.side,
|
|
2177
|
-
ordType: values.ordType ?? "conditional",
|
|
2178
|
-
sz: values.sz,
|
|
2179
|
-
tpTriggerPx: values.tpTriggerPx,
|
|
2180
|
-
tpOrdPx: values.tpOrdPx,
|
|
2181
|
-
slTriggerPx: values.slTriggerPx,
|
|
2182
|
-
slOrdPx: values.slOrdPx,
|
|
2183
|
-
json
|
|
2184
|
-
});
|
|
2185
|
-
if (subAction === "amend")
|
|
2186
|
-
return cmdSpotAlgoAmend(client, {
|
|
2187
|
-
instId: values.instId,
|
|
2188
|
-
algoId: values.algoId,
|
|
2189
|
-
newSz: values.newSz,
|
|
2190
|
-
newTpTriggerPx: values.newTpTriggerPx,
|
|
2191
|
-
newTpOrdPx: values.newTpOrdPx,
|
|
2192
|
-
newSlTriggerPx: values.newSlTriggerPx,
|
|
2193
|
-
newSlOrdPx: values.newSlOrdPx,
|
|
2194
|
-
json
|
|
2195
|
-
});
|
|
2196
|
-
if (subAction === "cancel")
|
|
2197
|
-
return cmdSpotAlgoCancel(client, values.instId, values.algoId, json);
|
|
2198
|
-
if (subAction === "orders")
|
|
2199
|
-
return cmdSpotAlgoOrders(client, {
|
|
2200
|
-
instId: values.instId,
|
|
2201
|
-
status: values.history ? "history" : "pending",
|
|
2202
|
-
ordType: values.ordType,
|
|
2203
|
-
json
|
|
2204
|
-
});
|
|
2205
|
-
}
|
|
2206
|
-
}
|
|
2207
|
-
if (module === "swap") {
|
|
2208
|
-
if (action === "positions")
|
|
2209
|
-
return cmdSwapPositions(client, rest[0] ?? values.instId, json);
|
|
2210
|
-
if (action === "orders")
|
|
2211
|
-
return cmdSwapOrders(client, {
|
|
2212
|
-
instId: values.instId,
|
|
2213
|
-
status: values.history ? "history" : "open",
|
|
2214
|
-
json
|
|
2215
|
-
});
|
|
2216
|
-
if (action === "get")
|
|
2217
|
-
return cmdSwapGet(client, { instId: values.instId, ordId: values.ordId, clOrdId: values.clOrdId, json });
|
|
2218
|
-
if (action === "fills")
|
|
2219
|
-
return cmdSwapFills(client, { instId: values.instId, ordId: values.ordId, archive: values.archive, json });
|
|
2220
|
-
if (action === "close")
|
|
2221
|
-
return cmdSwapClose(client, {
|
|
2222
|
-
instId: values.instId,
|
|
2223
|
-
mgnMode: values.mgnMode,
|
|
2224
|
-
posSide: values.posSide,
|
|
2225
|
-
autoCxl: values.autoCxl,
|
|
2226
|
-
json
|
|
2227
|
-
});
|
|
2228
|
-
if (action === "get-leverage")
|
|
2229
|
-
return cmdSwapGetLeverage(client, { instId: values.instId, mgnMode: values.mgnMode, json });
|
|
2230
|
-
if (action === "place")
|
|
2231
|
-
return cmdSwapPlace(client, {
|
|
2232
|
-
instId: values.instId,
|
|
2233
|
-
side: values.side,
|
|
2234
|
-
ordType: values.ordType,
|
|
2235
|
-
sz: values.sz,
|
|
2236
|
-
posSide: values.posSide,
|
|
2237
|
-
px: values.px,
|
|
2238
|
-
tdMode: values.tdMode ?? "cross",
|
|
2239
|
-
json
|
|
2240
|
-
});
|
|
2241
|
-
if (action === "cancel")
|
|
2242
|
-
return cmdSwapCancel(client, rest[0], values.ordId, json);
|
|
2243
|
-
if (action === "leverage")
|
|
2244
|
-
return cmdSwapSetLeverage(client, {
|
|
2245
|
-
instId: values.instId,
|
|
2246
|
-
lever: values.lever,
|
|
2247
|
-
mgnMode: values.mgnMode,
|
|
2248
|
-
posSide: values.posSide,
|
|
2249
|
-
json
|
|
2250
|
-
});
|
|
2251
|
-
if (action === "algo") {
|
|
2252
|
-
const subAction = rest[0];
|
|
2253
|
-
if (subAction === "trail")
|
|
2254
|
-
return cmdSwapAlgoTrailPlace(client, {
|
|
2255
|
-
instId: values.instId,
|
|
2256
|
-
side: values.side,
|
|
2257
|
-
sz: values.sz,
|
|
2258
|
-
callbackRatio: values.callbackRatio,
|
|
2259
|
-
callbackSpread: values.callbackSpread,
|
|
2260
|
-
activePx: values.activePx,
|
|
2261
|
-
posSide: values.posSide,
|
|
2262
|
-
tdMode: values.tdMode ?? "cross",
|
|
2263
|
-
reduceOnly: values.reduceOnly,
|
|
2264
|
-
json
|
|
2265
|
-
});
|
|
2266
|
-
if (subAction === "place")
|
|
2267
|
-
return cmdSwapAlgoPlace(client, {
|
|
2268
|
-
instId: values.instId,
|
|
2269
|
-
side: values.side,
|
|
2270
|
-
ordType: values.ordType ?? "conditional",
|
|
2271
|
-
sz: values.sz,
|
|
2272
|
-
posSide: values.posSide,
|
|
2273
|
-
tdMode: values.tdMode ?? "cross",
|
|
2274
|
-
tpTriggerPx: values.tpTriggerPx,
|
|
2275
|
-
tpOrdPx: values.tpOrdPx,
|
|
2276
|
-
slTriggerPx: values.slTriggerPx,
|
|
2277
|
-
slOrdPx: values.slOrdPx,
|
|
2278
|
-
reduceOnly: values.reduceOnly,
|
|
2279
|
-
json
|
|
2280
|
-
});
|
|
2281
|
-
if (subAction === "amend")
|
|
2282
|
-
return cmdSwapAlgoAmend(client, {
|
|
2283
|
-
instId: values.instId,
|
|
2284
|
-
algoId: values.algoId,
|
|
2285
|
-
newSz: values.newSz,
|
|
2286
|
-
newTpTriggerPx: values.newTpTriggerPx,
|
|
2287
|
-
newTpOrdPx: values.newTpOrdPx,
|
|
2288
|
-
newSlTriggerPx: values.newSlTriggerPx,
|
|
2289
|
-
newSlOrdPx: values.newSlOrdPx,
|
|
2290
|
-
json
|
|
2291
|
-
});
|
|
2292
|
-
if (subAction === "cancel")
|
|
2293
|
-
return cmdSwapAlgoCancel(client, values.instId, values.algoId, json);
|
|
2294
|
-
if (subAction === "orders")
|
|
2295
|
-
return cmdSwapAlgoOrders(client, {
|
|
2296
|
-
instId: values.instId,
|
|
2297
|
-
status: values.history ? "history" : "pending",
|
|
2298
|
-
ordType: values.ordType,
|
|
2299
|
-
json
|
|
2300
|
-
});
|
|
2301
|
-
}
|
|
2302
|
-
}
|
|
2303
|
-
if (module === "futures") {
|
|
2304
|
-
if (action === "orders")
|
|
2305
|
-
return cmdFuturesOrders(client, {
|
|
2306
|
-
instId: values.instId,
|
|
2307
|
-
status: values.archive ? "archive" : values.history ? "history" : "open",
|
|
2308
|
-
json
|
|
2309
|
-
});
|
|
2310
|
-
if (action === "positions") return cmdFuturesPositions(client, values.instId, json);
|
|
2311
|
-
if (action === "fills")
|
|
2312
|
-
return cmdFuturesFills(client, {
|
|
2313
|
-
instId: values.instId,
|
|
2314
|
-
ordId: values.ordId,
|
|
2315
|
-
archive: values.archive,
|
|
2316
|
-
json
|
|
2317
|
-
});
|
|
2318
|
-
if (action === "place")
|
|
2319
|
-
return cmdFuturesPlace(client, {
|
|
2320
|
-
instId: values.instId,
|
|
2321
|
-
side: values.side,
|
|
2322
|
-
ordType: values.ordType,
|
|
2323
|
-
sz: values.sz,
|
|
2324
|
-
tdMode: values.tdMode ?? "cross",
|
|
2325
|
-
posSide: values.posSide,
|
|
2326
|
-
px: values.px,
|
|
2327
|
-
reduceOnly: values.reduceOnly,
|
|
2328
|
-
json
|
|
2329
|
-
});
|
|
2330
|
-
if (action === "cancel")
|
|
2331
|
-
return cmdFuturesCancel(client, rest[0] ?? values.instId, values.ordId, json);
|
|
2332
|
-
if (action === "get")
|
|
2333
|
-
return cmdFuturesGet(client, { instId: rest[0] ?? values.instId, ordId: values.ordId, json });
|
|
2334
|
-
}
|
|
2335
|
-
if (module === "bot") {
|
|
2336
|
-
const subAction = rest[0];
|
|
2337
|
-
if (action === "grid") {
|
|
2338
|
-
if (subAction === "orders")
|
|
2339
|
-
return cmdGridOrders(client, {
|
|
2340
|
-
algoOrdType: values.algoOrdType,
|
|
2341
|
-
instId: values.instId,
|
|
2342
|
-
algoId: values.algoId,
|
|
2343
|
-
status: values.history ? "history" : "active",
|
|
2344
|
-
json
|
|
2345
|
-
});
|
|
2346
|
-
if (subAction === "details")
|
|
2347
|
-
return cmdGridDetails(client, {
|
|
2348
|
-
algoOrdType: values.algoOrdType,
|
|
2349
|
-
algoId: values.algoId,
|
|
2350
|
-
json
|
|
2351
|
-
});
|
|
2352
|
-
if (subAction === "sub-orders")
|
|
2353
|
-
return cmdGridSubOrders(client, {
|
|
2354
|
-
algoOrdType: values.algoOrdType,
|
|
2355
|
-
algoId: values.algoId,
|
|
2356
|
-
type: values.live ? "live" : "filled",
|
|
2357
|
-
json
|
|
2358
|
-
});
|
|
2359
|
-
if (subAction === "create")
|
|
2360
|
-
return cmdGridCreate(client, {
|
|
2361
|
-
instId: values.instId,
|
|
2362
|
-
algoOrdType: values.algoOrdType,
|
|
2363
|
-
maxPx: values.maxPx,
|
|
2364
|
-
minPx: values.minPx,
|
|
2365
|
-
gridNum: values.gridNum,
|
|
2366
|
-
runType: values.runType,
|
|
2367
|
-
quoteSz: values.quoteSz,
|
|
2368
|
-
baseSz: values.baseSz,
|
|
2369
|
-
direction: values.direction,
|
|
2370
|
-
lever: values.lever,
|
|
2371
|
-
sz: values.sz,
|
|
2372
|
-
json
|
|
2373
|
-
});
|
|
2374
|
-
if (subAction === "stop")
|
|
2375
|
-
return cmdGridStop(client, {
|
|
2376
|
-
algoId: values.algoId,
|
|
2377
|
-
algoOrdType: values.algoOrdType,
|
|
2378
|
-
instId: values.instId,
|
|
2379
|
-
stopType: values.stopType,
|
|
2380
|
-
json
|
|
2381
|
-
});
|
|
2382
|
-
}
|
|
2383
|
-
}
|
|
2487
|
+
if (module === "market") return handleMarketCommand(client, action, rest, v, json);
|
|
2488
|
+
if (module === "account") return handleAccountCommand(client, action, rest, v, json);
|
|
2489
|
+
if (module === "spot") return handleSpotCommand(client, action, rest, v, json);
|
|
2490
|
+
if (module === "swap") return handleSwapCommand(client, action, rest, v, json);
|
|
2491
|
+
if (module === "futures") return handleFuturesCommand(client, action, rest, v, json);
|
|
2492
|
+
if (module === "bot") return handleBotCommand(client, action, rest, v, json);
|
|
2384
2493
|
process.stderr.write(`Unknown command: ${module} ${action ?? ""}
|
|
2385
2494
|
`);
|
|
2386
2495
|
process.exitCode = 1;
|
|
2387
2496
|
}
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2497
|
+
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
2498
|
+
main().catch((error) => {
|
|
2499
|
+
const payload = toToolErrorPayload(error);
|
|
2500
|
+
process.stderr.write(`Error: ${payload.message}
|
|
2391
2501
|
`);
|
|
2392
|
-
|
|
2502
|
+
if (payload.traceId) process.stderr.write(`TraceId: ${payload.traceId}
|
|
2393
2503
|
`);
|
|
2394
|
-
|
|
2504
|
+
if (payload.suggestion) process.stderr.write(`Hint: ${payload.suggestion}
|
|
2395
2505
|
`);
|
|
2396
|
-
|
|
2506
|
+
process.stderr.write(`Version: okx-trade-cli@${CLI_VERSION}
|
|
2397
2507
|
`);
|
|
2398
|
-
|
|
2399
|
-
});
|
|
2508
|
+
process.exitCode = 1;
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
export {
|
|
2512
|
+
handleAccountWriteCommand,
|
|
2513
|
+
handleBotCommand,
|
|
2514
|
+
handleBotGridCommand,
|
|
2515
|
+
handleConfigCommand,
|
|
2516
|
+
handleMarketCommand,
|
|
2517
|
+
handleMarketDataCommand,
|
|
2518
|
+
handleMarketPublicCommand,
|
|
2519
|
+
handleSetupCommand,
|
|
2520
|
+
printHelp
|
|
2521
|
+
};
|
|
2400
2522
|
//# sourceMappingURL=index.js.map
|