okx-trade-cli 1.0.3 → 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 +1321 -290
- 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) {
|
|
@@ -533,6 +686,153 @@ function printKv(obj, indent = 0) {
|
|
|
533
686
|
}
|
|
534
687
|
|
|
535
688
|
// src/commands/market.ts
|
|
689
|
+
async function cmdMarketInstruments(client, opts) {
|
|
690
|
+
const params = { instType: opts.instType };
|
|
691
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
692
|
+
const res = await client.publicGet("/api/v5/public/instruments", params);
|
|
693
|
+
const items = res.data;
|
|
694
|
+
if (opts.json) return printJson(items);
|
|
695
|
+
printTable(
|
|
696
|
+
(items ?? []).slice(0, 50).map((t) => ({
|
|
697
|
+
instId: t["instId"],
|
|
698
|
+
ctVal: t["ctVal"],
|
|
699
|
+
lotSz: t["lotSz"],
|
|
700
|
+
minSz: t["minSz"],
|
|
701
|
+
tickSz: t["tickSz"],
|
|
702
|
+
state: t["state"]
|
|
703
|
+
}))
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
async function cmdMarketFundingRate(client, instId, opts) {
|
|
707
|
+
if (opts.history) {
|
|
708
|
+
const params = { instId };
|
|
709
|
+
if (opts.limit) params["limit"] = String(opts.limit);
|
|
710
|
+
const res = await client.publicGet("/api/v5/public/funding-rate-history", params);
|
|
711
|
+
const items = res.data;
|
|
712
|
+
if (opts.json) return printJson(items);
|
|
713
|
+
printTable(
|
|
714
|
+
(items ?? []).map((r) => ({
|
|
715
|
+
instId: r["instId"],
|
|
716
|
+
fundingRate: r["fundingRate"],
|
|
717
|
+
realizedRate: r["realizedRate"],
|
|
718
|
+
fundingTime: new Date(Number(r["fundingTime"])).toLocaleString()
|
|
719
|
+
}))
|
|
720
|
+
);
|
|
721
|
+
} else {
|
|
722
|
+
const res = await client.publicGet("/api/v5/public/funding-rate", { instId });
|
|
723
|
+
const items = res.data;
|
|
724
|
+
if (opts.json) return printJson(items);
|
|
725
|
+
const r = items?.[0];
|
|
726
|
+
if (!r) {
|
|
727
|
+
process.stdout.write("No data\n");
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
printKv({
|
|
731
|
+
instId: r["instId"],
|
|
732
|
+
fundingRate: r["fundingRate"],
|
|
733
|
+
nextFundingRate: r["nextFundingRate"],
|
|
734
|
+
fundingTime: new Date(Number(r["fundingTime"])).toLocaleString(),
|
|
735
|
+
nextFundingTime: new Date(Number(r["nextFundingTime"])).toLocaleString()
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
async function cmdMarketMarkPrice(client, opts) {
|
|
740
|
+
const params = { instType: opts.instType };
|
|
741
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
742
|
+
const res = await client.publicGet("/api/v5/public/mark-price", params);
|
|
743
|
+
const items = res.data;
|
|
744
|
+
if (opts.json) return printJson(items);
|
|
745
|
+
printTable(
|
|
746
|
+
(items ?? []).map((r) => ({
|
|
747
|
+
instId: r["instId"],
|
|
748
|
+
instType: r["instType"],
|
|
749
|
+
markPx: r["markPx"],
|
|
750
|
+
ts: new Date(Number(r["ts"])).toLocaleString()
|
|
751
|
+
}))
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
async function cmdMarketTrades(client, instId, opts) {
|
|
755
|
+
const params = { instId };
|
|
756
|
+
if (opts.limit) params["limit"] = String(opts.limit);
|
|
757
|
+
const res = await client.publicGet("/api/v5/market/trades", params);
|
|
758
|
+
const items = res.data;
|
|
759
|
+
if (opts.json) return printJson(items);
|
|
760
|
+
printTable(
|
|
761
|
+
(items ?? []).map((t) => ({
|
|
762
|
+
tradeId: t["tradeId"],
|
|
763
|
+
px: t["px"],
|
|
764
|
+
sz: t["sz"],
|
|
765
|
+
side: t["side"],
|
|
766
|
+
ts: new Date(Number(t["ts"])).toLocaleString()
|
|
767
|
+
}))
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
async function cmdMarketIndexTicker(client, opts) {
|
|
771
|
+
const params = {};
|
|
772
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
773
|
+
if (opts.quoteCcy) params["quoteCcy"] = opts.quoteCcy;
|
|
774
|
+
const res = await client.publicGet("/api/v5/market/index-tickers", params);
|
|
775
|
+
const items = res.data;
|
|
776
|
+
if (opts.json) return printJson(items);
|
|
777
|
+
printTable(
|
|
778
|
+
(items ?? []).map((t) => ({
|
|
779
|
+
instId: t["instId"],
|
|
780
|
+
idxPx: t["idxPx"],
|
|
781
|
+
high24h: t["high24h"],
|
|
782
|
+
low24h: t["low24h"],
|
|
783
|
+
ts: new Date(Number(t["ts"])).toLocaleString()
|
|
784
|
+
}))
|
|
785
|
+
);
|
|
786
|
+
}
|
|
787
|
+
async function cmdMarketIndexCandles(client, instId, opts) {
|
|
788
|
+
const path2 = opts.history ? "/api/v5/market/history-index-candles" : "/api/v5/market/index-candles";
|
|
789
|
+
const params = { instId };
|
|
790
|
+
if (opts.bar) params["bar"] = opts.bar;
|
|
791
|
+
if (opts.limit) params["limit"] = String(opts.limit);
|
|
792
|
+
const res = await client.publicGet(path2, params);
|
|
793
|
+
const candles = res.data;
|
|
794
|
+
if (opts.json) return printJson(candles);
|
|
795
|
+
printTable(
|
|
796
|
+
(candles ?? []).map(([ts, o, h, l, c]) => ({
|
|
797
|
+
time: new Date(Number(ts)).toLocaleString(),
|
|
798
|
+
open: o,
|
|
799
|
+
high: h,
|
|
800
|
+
low: l,
|
|
801
|
+
close: c
|
|
802
|
+
}))
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
async function cmdMarketPriceLimit(client, instId, json) {
|
|
806
|
+
const res = await client.publicGet("/api/v5/public/price-limit", { instId });
|
|
807
|
+
const items = res.data;
|
|
808
|
+
if (json) return printJson(items);
|
|
809
|
+
const r = items?.[0];
|
|
810
|
+
if (!r) {
|
|
811
|
+
process.stdout.write("No data\n");
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
printKv({
|
|
815
|
+
instId: r["instId"],
|
|
816
|
+
buyLmt: r["buyLmt"],
|
|
817
|
+
sellLmt: r["sellLmt"],
|
|
818
|
+
ts: new Date(Number(r["ts"])).toLocaleString()
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
async function cmdMarketOpenInterest(client, opts) {
|
|
822
|
+
const params = { instType: opts.instType };
|
|
823
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
824
|
+
const res = await client.publicGet("/api/v5/public/open-interest", params);
|
|
825
|
+
const items = res.data;
|
|
826
|
+
if (opts.json) return printJson(items);
|
|
827
|
+
printTable(
|
|
828
|
+
(items ?? []).map((r) => ({
|
|
829
|
+
instId: r["instId"],
|
|
830
|
+
oi: r["oi"],
|
|
831
|
+
oiCcy: r["oiCcy"],
|
|
832
|
+
ts: new Date(Number(r["ts"])).toLocaleString()
|
|
833
|
+
}))
|
|
834
|
+
);
|
|
835
|
+
}
|
|
536
836
|
async function cmdMarketTicker(client, instId, json) {
|
|
537
837
|
const res = await client.publicGet("/api/v5/market/ticker", { instId });
|
|
538
838
|
const items = res.data;
|
|
@@ -621,6 +921,187 @@ async function cmdAccountBalance(client, ccy, json) {
|
|
|
621
921
|
}))
|
|
622
922
|
);
|
|
623
923
|
}
|
|
924
|
+
async function cmdAccountAssetBalance(client, ccy, json) {
|
|
925
|
+
const params = {};
|
|
926
|
+
if (ccy) params["ccy"] = ccy;
|
|
927
|
+
const res = await client.privateGet("/api/v5/asset/balances", params);
|
|
928
|
+
const data = res.data;
|
|
929
|
+
if (json) return printJson(data);
|
|
930
|
+
printTable(
|
|
931
|
+
(data ?? []).filter((r) => Number(r["bal"]) > 0).map((r) => ({
|
|
932
|
+
ccy: r["ccy"],
|
|
933
|
+
bal: r["bal"],
|
|
934
|
+
availBal: r["availBal"],
|
|
935
|
+
frozenBal: r["frozenBal"]
|
|
936
|
+
}))
|
|
937
|
+
);
|
|
938
|
+
}
|
|
939
|
+
async function cmdAccountPositions(client, opts) {
|
|
940
|
+
const params = {};
|
|
941
|
+
if (opts.instType) params["instType"] = opts.instType;
|
|
942
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
943
|
+
const res = await client.privateGet("/api/v5/account/positions", params);
|
|
944
|
+
const positions = res.data;
|
|
945
|
+
if (opts.json) return printJson(positions);
|
|
946
|
+
const open = (positions ?? []).filter((p) => Number(p["pos"]) !== 0);
|
|
947
|
+
if (!open.length) {
|
|
948
|
+
process.stdout.write("No open positions\n");
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
printTable(
|
|
952
|
+
open.map((p) => ({
|
|
953
|
+
instId: p["instId"],
|
|
954
|
+
instType: p["instType"],
|
|
955
|
+
side: p["posSide"],
|
|
956
|
+
pos: p["pos"],
|
|
957
|
+
avgPx: p["avgPx"],
|
|
958
|
+
upl: p["upl"],
|
|
959
|
+
lever: p["lever"]
|
|
960
|
+
}))
|
|
961
|
+
);
|
|
962
|
+
}
|
|
963
|
+
async function cmdAccountBills(client, opts) {
|
|
964
|
+
const endpoint = opts.archive ? "/api/v5/account/bills-archive" : "/api/v5/account/bills";
|
|
965
|
+
const params = {};
|
|
966
|
+
if (opts.instType) params["instType"] = opts.instType;
|
|
967
|
+
if (opts.ccy) params["ccy"] = opts.ccy;
|
|
968
|
+
if (opts.limit) params["limit"] = String(opts.limit);
|
|
969
|
+
const res = await client.privateGet(endpoint, params);
|
|
970
|
+
const bills = res.data;
|
|
971
|
+
if (opts.json) return printJson(bills);
|
|
972
|
+
printTable(
|
|
973
|
+
(bills ?? []).map((b) => ({
|
|
974
|
+
billId: b["billId"],
|
|
975
|
+
instId: b["instId"],
|
|
976
|
+
type: b["type"],
|
|
977
|
+
ccy: b["ccy"],
|
|
978
|
+
balChg: b["balChg"],
|
|
979
|
+
bal: b["bal"],
|
|
980
|
+
ts: new Date(Number(b["ts"])).toLocaleString()
|
|
981
|
+
}))
|
|
982
|
+
);
|
|
983
|
+
}
|
|
984
|
+
async function cmdAccountFees(client, opts) {
|
|
985
|
+
const params = { instType: opts.instType };
|
|
986
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
987
|
+
const res = await client.privateGet("/api/v5/account/trade-fee", params);
|
|
988
|
+
const data = res.data;
|
|
989
|
+
if (opts.json) return printJson(data);
|
|
990
|
+
const fee = data?.[0];
|
|
991
|
+
if (!fee) {
|
|
992
|
+
process.stdout.write("No data\n");
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
printKv({
|
|
996
|
+
level: fee["level"],
|
|
997
|
+
maker: fee["maker"],
|
|
998
|
+
taker: fee["taker"],
|
|
999
|
+
makerU: fee["makerU"],
|
|
1000
|
+
takerU: fee["takerU"],
|
|
1001
|
+
ts: new Date(Number(fee["ts"])).toLocaleString()
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
async function cmdAccountConfig(client, json) {
|
|
1005
|
+
const res = await client.privateGet("/api/v5/account/config", {});
|
|
1006
|
+
const data = res.data;
|
|
1007
|
+
if (json) return printJson(data);
|
|
1008
|
+
const cfg = data?.[0];
|
|
1009
|
+
if (!cfg) {
|
|
1010
|
+
process.stdout.write("No data\n");
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
printKv({
|
|
1014
|
+
uid: cfg["uid"],
|
|
1015
|
+
acctLv: cfg["acctLv"],
|
|
1016
|
+
posMode: cfg["posMode"],
|
|
1017
|
+
autoLoan: cfg["autoLoan"],
|
|
1018
|
+
greeksType: cfg["greeksType"],
|
|
1019
|
+
level: cfg["level"],
|
|
1020
|
+
levelTmp: cfg["levelTmp"]
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
async function cmdAccountSetPositionMode(client, posMode, json) {
|
|
1024
|
+
const res = await client.privatePost("/api/v5/account/set-position-mode", { posMode });
|
|
1025
|
+
if (json) return printJson(res.data);
|
|
1026
|
+
const r = res.data[0];
|
|
1027
|
+
process.stdout.write(`Position mode set: ${r?.["posMode"]}
|
|
1028
|
+
`);
|
|
1029
|
+
}
|
|
1030
|
+
async function cmdAccountMaxSize(client, opts) {
|
|
1031
|
+
const params = { instId: opts.instId, tdMode: opts.tdMode };
|
|
1032
|
+
if (opts.px) params["px"] = opts.px;
|
|
1033
|
+
const res = await client.privateGet("/api/v5/account/max-size", params);
|
|
1034
|
+
const data = res.data;
|
|
1035
|
+
if (opts.json) return printJson(data);
|
|
1036
|
+
const r = data?.[0];
|
|
1037
|
+
if (!r) {
|
|
1038
|
+
process.stdout.write("No data\n");
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
printKv({ instId: r["instId"], maxBuy: r["maxBuy"], maxSell: r["maxSell"] });
|
|
1042
|
+
}
|
|
1043
|
+
async function cmdAccountMaxAvailSize(client, opts) {
|
|
1044
|
+
const res = await client.privateGet("/api/v5/account/max-avail-size", {
|
|
1045
|
+
instId: opts.instId,
|
|
1046
|
+
tdMode: opts.tdMode
|
|
1047
|
+
});
|
|
1048
|
+
const data = res.data;
|
|
1049
|
+
if (opts.json) return printJson(data);
|
|
1050
|
+
const r = data?.[0];
|
|
1051
|
+
if (!r) {
|
|
1052
|
+
process.stdout.write("No data\n");
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
printKv({ instId: r["instId"], availBuy: r["availBuy"], availSell: r["availSell"] });
|
|
1056
|
+
}
|
|
1057
|
+
async function cmdAccountMaxWithdrawal(client, ccy, json) {
|
|
1058
|
+
const params = {};
|
|
1059
|
+
if (ccy) params["ccy"] = ccy;
|
|
1060
|
+
const res = await client.privateGet("/api/v5/account/max-withdrawal", params);
|
|
1061
|
+
const data = res.data;
|
|
1062
|
+
if (json) return printJson(data);
|
|
1063
|
+
printTable(
|
|
1064
|
+
(data ?? []).map((r) => ({
|
|
1065
|
+
ccy: r["ccy"],
|
|
1066
|
+
maxWd: r["maxWd"],
|
|
1067
|
+
maxWdEx: r["maxWdEx"]
|
|
1068
|
+
}))
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
async function cmdAccountPositionsHistory(client, opts) {
|
|
1072
|
+
const params = {};
|
|
1073
|
+
if (opts.instType) params["instType"] = opts.instType;
|
|
1074
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
1075
|
+
if (opts.limit) params["limit"] = String(opts.limit);
|
|
1076
|
+
const res = await client.privateGet("/api/v5/account/positions-history", params);
|
|
1077
|
+
const data = res.data;
|
|
1078
|
+
if (opts.json) return printJson(data);
|
|
1079
|
+
printTable(
|
|
1080
|
+
(data ?? []).map((p) => ({
|
|
1081
|
+
instId: p["instId"],
|
|
1082
|
+
direction: p["direction"],
|
|
1083
|
+
openAvgPx: p["openAvgPx"],
|
|
1084
|
+
closeAvgPx: p["closeAvgPx"],
|
|
1085
|
+
realizedPnl: p["realizedPnl"],
|
|
1086
|
+
uTime: new Date(Number(p["uTime"])).toLocaleString()
|
|
1087
|
+
}))
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
async function cmdAccountTransfer(client, opts) {
|
|
1091
|
+
const body = {
|
|
1092
|
+
ccy: opts.ccy,
|
|
1093
|
+
amt: opts.amt,
|
|
1094
|
+
from: opts.from,
|
|
1095
|
+
to: opts.to
|
|
1096
|
+
};
|
|
1097
|
+
if (opts.transferType) body["type"] = opts.transferType;
|
|
1098
|
+
if (opts.subAcct) body["subAcct"] = opts.subAcct;
|
|
1099
|
+
const res = await client.privatePost("/api/v5/asset/transfer", body);
|
|
1100
|
+
if (opts.json) return printJson(res.data);
|
|
1101
|
+
const r = res.data[0];
|
|
1102
|
+
process.stdout.write(`Transfer: ${r?.["transId"]} (${r?.["ccy"]} ${r?.["amt"]})
|
|
1103
|
+
`);
|
|
1104
|
+
}
|
|
624
1105
|
|
|
625
1106
|
// src/commands/spot.ts
|
|
626
1107
|
async function cmdSpotOrders(client, opts) {
|
|
@@ -714,6 +1195,43 @@ async function cmdSpotAlgoCancel(client, instId, algoId, json) {
|
|
|
714
1195
|
`
|
|
715
1196
|
);
|
|
716
1197
|
}
|
|
1198
|
+
async function cmdSpotGet(client, opts) {
|
|
1199
|
+
const params = { instId: opts.instId };
|
|
1200
|
+
if (opts.ordId) params["ordId"] = opts.ordId;
|
|
1201
|
+
if (opts.clOrdId) params["clOrdId"] = opts.clOrdId;
|
|
1202
|
+
const res = await client.privateGet("/api/v5/trade/order", params);
|
|
1203
|
+
const data = res.data;
|
|
1204
|
+
if (opts.json) return printJson(data);
|
|
1205
|
+
const o = data?.[0];
|
|
1206
|
+
if (!o) {
|
|
1207
|
+
process.stdout.write("No data\n");
|
|
1208
|
+
return;
|
|
1209
|
+
}
|
|
1210
|
+
printKv({
|
|
1211
|
+
ordId: o["ordId"],
|
|
1212
|
+
instId: o["instId"],
|
|
1213
|
+
side: o["side"],
|
|
1214
|
+
ordType: o["ordType"],
|
|
1215
|
+
px: o["px"],
|
|
1216
|
+
sz: o["sz"],
|
|
1217
|
+
fillSz: o["fillSz"],
|
|
1218
|
+
avgPx: o["avgPx"],
|
|
1219
|
+
state: o["state"],
|
|
1220
|
+
cTime: new Date(Number(o["cTime"])).toLocaleString()
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1223
|
+
async function cmdSpotAmend(client, opts) {
|
|
1224
|
+
const body = { instId: opts.instId };
|
|
1225
|
+
if (opts.ordId) body["ordId"] = opts.ordId;
|
|
1226
|
+
if (opts.clOrdId) body["clOrdId"] = opts.clOrdId;
|
|
1227
|
+
if (opts.newSz) body["newSz"] = opts.newSz;
|
|
1228
|
+
if (opts.newPx) body["newPx"] = opts.newPx;
|
|
1229
|
+
const res = await client.privatePost("/api/v5/trade/amend-order", body);
|
|
1230
|
+
if (opts.json) return printJson(res.data);
|
|
1231
|
+
const r = res.data[0];
|
|
1232
|
+
process.stdout.write(`Order amended: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
1233
|
+
`);
|
|
1234
|
+
}
|
|
717
1235
|
async function cmdSpotAlgoOrders(client, opts) {
|
|
718
1236
|
const endpoint = opts.status === "history" ? "/api/v5/trade/orders-algo-history" : "/api/v5/trade/orders-algo-pending";
|
|
719
1237
|
const baseParams = { instType: "SPOT" };
|
|
@@ -946,6 +1464,80 @@ async function cmdSwapAlgoOrders(client, opts) {
|
|
|
946
1464
|
}))
|
|
947
1465
|
);
|
|
948
1466
|
}
|
|
1467
|
+
async function cmdSwapFills(client, opts) {
|
|
1468
|
+
const path2 = opts.archive ? "/api/v5/trade/fills-history" : "/api/v5/trade/fills";
|
|
1469
|
+
const params = { instType: "SWAP" };
|
|
1470
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
1471
|
+
if (opts.ordId) params["ordId"] = opts.ordId;
|
|
1472
|
+
const res = await client.privateGet(path2, params);
|
|
1473
|
+
const fills = res.data;
|
|
1474
|
+
if (opts.json) return printJson(fills);
|
|
1475
|
+
printTable(
|
|
1476
|
+
(fills ?? []).map((f) => ({
|
|
1477
|
+
instId: f["instId"],
|
|
1478
|
+
side: f["side"],
|
|
1479
|
+
fillPx: f["fillPx"],
|
|
1480
|
+
fillSz: f["fillSz"],
|
|
1481
|
+
fee: f["fee"],
|
|
1482
|
+
ts: new Date(Number(f["ts"])).toLocaleString()
|
|
1483
|
+
}))
|
|
1484
|
+
);
|
|
1485
|
+
}
|
|
1486
|
+
async function cmdSwapGet(client, opts) {
|
|
1487
|
+
const params = { instId: opts.instId };
|
|
1488
|
+
if (opts.ordId) params["ordId"] = opts.ordId;
|
|
1489
|
+
if (opts.clOrdId) params["clOrdId"] = opts.clOrdId;
|
|
1490
|
+
const res = await client.privateGet("/api/v5/trade/order", params);
|
|
1491
|
+
const data = res.data;
|
|
1492
|
+
if (opts.json) return printJson(data);
|
|
1493
|
+
const o = data?.[0];
|
|
1494
|
+
if (!o) {
|
|
1495
|
+
process.stdout.write("No data\n");
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1498
|
+
printKv({
|
|
1499
|
+
ordId: o["ordId"],
|
|
1500
|
+
instId: o["instId"],
|
|
1501
|
+
side: o["side"],
|
|
1502
|
+
posSide: o["posSide"],
|
|
1503
|
+
ordType: o["ordType"],
|
|
1504
|
+
px: o["px"],
|
|
1505
|
+
sz: o["sz"],
|
|
1506
|
+
fillSz: o["fillSz"],
|
|
1507
|
+
avgPx: o["avgPx"],
|
|
1508
|
+
state: o["state"],
|
|
1509
|
+
cTime: new Date(Number(o["cTime"])).toLocaleString()
|
|
1510
|
+
});
|
|
1511
|
+
}
|
|
1512
|
+
async function cmdSwapClose(client, opts) {
|
|
1513
|
+
const body = {
|
|
1514
|
+
instId: opts.instId,
|
|
1515
|
+
mgnMode: opts.mgnMode
|
|
1516
|
+
};
|
|
1517
|
+
if (opts.posSide) body["posSide"] = opts.posSide;
|
|
1518
|
+
if (opts.autoCxl !== void 0) body["autoCxl"] = String(opts.autoCxl);
|
|
1519
|
+
const res = await client.privatePost("/api/v5/trade/close-position", body);
|
|
1520
|
+
if (opts.json) return printJson(res.data);
|
|
1521
|
+
const r = res.data[0];
|
|
1522
|
+
process.stdout.write(`Position closed: ${r?.["instId"]} ${r?.["posSide"] ?? ""}
|
|
1523
|
+
`);
|
|
1524
|
+
}
|
|
1525
|
+
async function cmdSwapGetLeverage(client, opts) {
|
|
1526
|
+
const res = await client.privateGet("/api/v5/account/leverage-info", {
|
|
1527
|
+
instId: opts.instId,
|
|
1528
|
+
mgnMode: opts.mgnMode
|
|
1529
|
+
});
|
|
1530
|
+
const data = res.data;
|
|
1531
|
+
if (opts.json) return printJson(data);
|
|
1532
|
+
printTable(
|
|
1533
|
+
(data ?? []).map((r) => ({
|
|
1534
|
+
instId: r["instId"],
|
|
1535
|
+
mgnMode: r["mgnMode"],
|
|
1536
|
+
posSide: r["posSide"],
|
|
1537
|
+
lever: r["lever"]
|
|
1538
|
+
}))
|
|
1539
|
+
);
|
|
1540
|
+
}
|
|
949
1541
|
async function cmdSwapSetLeverage(client, opts) {
|
|
950
1542
|
const body = {
|
|
951
1543
|
instId: opts.instId,
|
|
@@ -960,29 +1552,141 @@ async function cmdSwapSetLeverage(client, opts) {
|
|
|
960
1552
|
`);
|
|
961
1553
|
}
|
|
962
1554
|
|
|
1555
|
+
// src/commands/futures.ts
|
|
1556
|
+
async function cmdFuturesOrders(client, opts) {
|
|
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";
|
|
1558
|
+
const params = { instType: "FUTURES" };
|
|
1559
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
1560
|
+
const res = await client.privateGet(path2, params);
|
|
1561
|
+
const orders = res.data;
|
|
1562
|
+
if (opts.json) return printJson(orders);
|
|
1563
|
+
printTable(
|
|
1564
|
+
(orders ?? []).map((o) => ({
|
|
1565
|
+
ordId: o["ordId"],
|
|
1566
|
+
instId: o["instId"],
|
|
1567
|
+
side: o["side"],
|
|
1568
|
+
posSide: o["posSide"],
|
|
1569
|
+
type: o["ordType"],
|
|
1570
|
+
price: o["px"],
|
|
1571
|
+
size: o["sz"],
|
|
1572
|
+
state: o["state"]
|
|
1573
|
+
}))
|
|
1574
|
+
);
|
|
1575
|
+
}
|
|
1576
|
+
async function cmdFuturesPositions(client, instId, json) {
|
|
1577
|
+
const params = { instType: "FUTURES" };
|
|
1578
|
+
if (instId) params["instId"] = instId;
|
|
1579
|
+
const res = await client.privateGet("/api/v5/account/positions", params);
|
|
1580
|
+
const positions = res.data;
|
|
1581
|
+
if (json) return printJson(positions);
|
|
1582
|
+
const open = (positions ?? []).filter((p) => Number(p["pos"]) !== 0);
|
|
1583
|
+
if (!open.length) {
|
|
1584
|
+
process.stdout.write("No open positions\n");
|
|
1585
|
+
return;
|
|
1586
|
+
}
|
|
1587
|
+
printTable(
|
|
1588
|
+
open.map((p) => ({
|
|
1589
|
+
instId: p["instId"],
|
|
1590
|
+
side: p["posSide"],
|
|
1591
|
+
pos: p["pos"],
|
|
1592
|
+
avgPx: p["avgPx"],
|
|
1593
|
+
upl: p["upl"],
|
|
1594
|
+
lever: p["lever"]
|
|
1595
|
+
}))
|
|
1596
|
+
);
|
|
1597
|
+
}
|
|
1598
|
+
async function cmdFuturesFills(client, opts) {
|
|
1599
|
+
const path2 = opts.archive ? "/api/v5/trade/fills-history" : "/api/v5/trade/fills";
|
|
1600
|
+
const params = { instType: "FUTURES" };
|
|
1601
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
1602
|
+
if (opts.ordId) params["ordId"] = opts.ordId;
|
|
1603
|
+
const res = await client.privateGet(path2, params);
|
|
1604
|
+
const fills = res.data;
|
|
1605
|
+
if (opts.json) return printJson(fills);
|
|
1606
|
+
printTable(
|
|
1607
|
+
(fills ?? []).map((f) => ({
|
|
1608
|
+
instId: f["instId"],
|
|
1609
|
+
side: f["side"],
|
|
1610
|
+
fillPx: f["fillPx"],
|
|
1611
|
+
fillSz: f["fillSz"],
|
|
1612
|
+
fee: f["fee"],
|
|
1613
|
+
ts: new Date(Number(f["ts"])).toLocaleString()
|
|
1614
|
+
}))
|
|
1615
|
+
);
|
|
1616
|
+
}
|
|
1617
|
+
async function cmdFuturesPlace(client, opts) {
|
|
1618
|
+
const body = {
|
|
1619
|
+
instId: opts.instId,
|
|
1620
|
+
tdMode: opts.tdMode,
|
|
1621
|
+
side: opts.side,
|
|
1622
|
+
ordType: opts.ordType,
|
|
1623
|
+
sz: opts.sz
|
|
1624
|
+
};
|
|
1625
|
+
if (opts.posSide) body["posSide"] = opts.posSide;
|
|
1626
|
+
if (opts.px) body["px"] = opts.px;
|
|
1627
|
+
if (opts.reduceOnly !== void 0) body["reduceOnly"] = String(opts.reduceOnly);
|
|
1628
|
+
const res = await client.privatePost("/api/v5/trade/order", body);
|
|
1629
|
+
if (opts.json) return printJson(res.data);
|
|
1630
|
+
const order = res.data[0];
|
|
1631
|
+
process.stdout.write(`Order placed: ${order?.["ordId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
1632
|
+
`);
|
|
1633
|
+
}
|
|
1634
|
+
async function cmdFuturesCancel(client, instId, ordId, json) {
|
|
1635
|
+
const res = await client.privatePost("/api/v5/trade/cancel-order", { instId, ordId });
|
|
1636
|
+
if (json) return printJson(res.data);
|
|
1637
|
+
const r = res.data[0];
|
|
1638
|
+
process.stdout.write(`Cancelled: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
1639
|
+
`);
|
|
1640
|
+
}
|
|
1641
|
+
async function cmdFuturesGet(client, opts) {
|
|
1642
|
+
const params = { instId: opts.instId };
|
|
1643
|
+
if (opts.ordId) params["ordId"] = opts.ordId;
|
|
1644
|
+
const res = await client.privateGet("/api/v5/trade/order", params);
|
|
1645
|
+
const data = res.data;
|
|
1646
|
+
if (opts.json) return printJson(data);
|
|
1647
|
+
const o = data?.[0];
|
|
1648
|
+
if (!o) {
|
|
1649
|
+
process.stdout.write("No data\n");
|
|
1650
|
+
return;
|
|
1651
|
+
}
|
|
1652
|
+
printKv({
|
|
1653
|
+
ordId: o["ordId"],
|
|
1654
|
+
instId: o["instId"],
|
|
1655
|
+
side: o["side"],
|
|
1656
|
+
posSide: o["posSide"],
|
|
1657
|
+
ordType: o["ordType"],
|
|
1658
|
+
px: o["px"],
|
|
1659
|
+
sz: o["sz"],
|
|
1660
|
+
fillSz: o["fillSz"],
|
|
1661
|
+
avgPx: o["avgPx"],
|
|
1662
|
+
state: o["state"],
|
|
1663
|
+
cTime: new Date(Number(o["cTime"])).toLocaleString()
|
|
1664
|
+
});
|
|
1665
|
+
}
|
|
1666
|
+
|
|
963
1667
|
// src/config/toml.ts
|
|
964
|
-
import { writeFileSync as
|
|
1668
|
+
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync4 } from "fs";
|
|
965
1669
|
import { stringify } from "smol-toml";
|
|
966
1670
|
function configDir() {
|
|
967
1671
|
return configFilePath().replace(/\/config\.toml$/, "");
|
|
968
1672
|
}
|
|
969
1673
|
function writeCliConfig(config) {
|
|
970
1674
|
const dir = configDir();
|
|
971
|
-
if (!
|
|
972
|
-
|
|
1675
|
+
if (!existsSync4(dir)) {
|
|
1676
|
+
mkdirSync3(dir, { recursive: true });
|
|
973
1677
|
}
|
|
974
|
-
|
|
1678
|
+
writeFileSync3(configFilePath(), stringify(config), "utf-8");
|
|
975
1679
|
}
|
|
976
1680
|
|
|
977
1681
|
// src/commands/config.ts
|
|
978
|
-
import { existsSync as
|
|
1682
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
|
|
979
1683
|
import { parse as parse2, stringify as stringify2 } from "smol-toml";
|
|
980
1684
|
import { createInterface } from "readline";
|
|
981
1685
|
import { spawnSync } from "child_process";
|
|
982
1686
|
function readFullConfig() {
|
|
983
|
-
const
|
|
984
|
-
if (!
|
|
985
|
-
const raw =
|
|
1687
|
+
const path2 = configFilePath();
|
|
1688
|
+
if (!existsSync5(path2)) return { profiles: {} };
|
|
1689
|
+
const raw = readFileSync4(path2, "utf-8");
|
|
986
1690
|
return parse2(raw);
|
|
987
1691
|
}
|
|
988
1692
|
function prompt(rl, question) {
|
|
@@ -1093,110 +1797,146 @@ async function cmdConfigInit() {
|
|
|
1093
1797
|
|
|
1094
1798
|
// src/commands/client-setup.ts
|
|
1095
1799
|
import * as fs from "fs";
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
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:
|
|
1815
|
+
`);
|
|
1816
|
+
for (const [id] of detected) {
|
|
1817
|
+
process.stdout.write(` ${id}
|
|
1818
|
+
`);
|
|
1819
|
+
}
|
|
1820
|
+
process.stdout.write(`
|
|
1821
|
+
`);
|
|
1114
1822
|
}
|
|
1115
|
-
|
|
1116
|
-
var MCP_ENTRY = {
|
|
1117
|
-
command: "okx-trade-mcp",
|
|
1118
|
-
args: ["--modules", "all"]
|
|
1119
|
-
};
|
|
1120
|
-
var MCP_SERVER_NAME = "okx-trade-mcp";
|
|
1121
|
-
function prompt2(rl, question) {
|
|
1122
|
-
return new Promise((resolve) => {
|
|
1123
|
-
rl.question(question, (answer) => {
|
|
1124
|
-
resolve(answer);
|
|
1125
|
-
});
|
|
1126
|
-
});
|
|
1823
|
+
printSetupUsage();
|
|
1127
1824
|
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1825
|
+
|
|
1826
|
+
// src/commands/bot.ts
|
|
1827
|
+
async function cmdGridOrders(client, opts) {
|
|
1828
|
+
const path2 = opts.status === "history" ? "/api/v5/tradingBot/grid/orders-algo-history" : "/api/v5/tradingBot/grid/orders-algo-pending";
|
|
1829
|
+
const params = { algoOrdType: opts.algoOrdType };
|
|
1830
|
+
if (opts.instId) params["instId"] = opts.instId;
|
|
1831
|
+
if (opts.algoId) params["algoId"] = opts.algoId;
|
|
1832
|
+
const res = await client.privateGet(path2, params);
|
|
1833
|
+
const orders = res.data ?? [];
|
|
1834
|
+
if (opts.json) return printJson(orders);
|
|
1835
|
+
if (!orders.length) {
|
|
1836
|
+
process.stdout.write("No grid bots\n");
|
|
1134
1837
|
return;
|
|
1135
1838
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1839
|
+
printTable(
|
|
1840
|
+
orders.map((o) => ({
|
|
1841
|
+
algoId: o["algoId"],
|
|
1842
|
+
instId: o["instId"],
|
|
1843
|
+
type: o["algoOrdType"],
|
|
1844
|
+
state: o["state"],
|
|
1845
|
+
pnl: o["pnlRatio"],
|
|
1846
|
+
gridNum: o["gridNum"],
|
|
1847
|
+
maxPx: o["maxPx"],
|
|
1848
|
+
minPx: o["minPx"],
|
|
1849
|
+
createdAt: new Date(Number(o["cTime"])).toLocaleString()
|
|
1850
|
+
}))
|
|
1851
|
+
);
|
|
1852
|
+
}
|
|
1853
|
+
async function cmdGridDetails(client, opts) {
|
|
1854
|
+
const res = await client.privateGet("/api/v5/tradingBot/grid/orders-algo-details", {
|
|
1855
|
+
algoOrdType: opts.algoOrdType,
|
|
1856
|
+
algoId: opts.algoId
|
|
1857
|
+
});
|
|
1858
|
+
const detail = (res.data ?? [])[0];
|
|
1859
|
+
if (!detail) {
|
|
1860
|
+
process.stdout.write("Bot not found\n");
|
|
1861
|
+
return;
|
|
1141
1862
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1863
|
+
if (opts.json) return printJson(detail);
|
|
1864
|
+
printKv({
|
|
1865
|
+
algoId: detail["algoId"],
|
|
1866
|
+
instId: detail["instId"],
|
|
1867
|
+
type: detail["algoOrdType"],
|
|
1868
|
+
state: detail["state"],
|
|
1869
|
+
maxPx: detail["maxPx"],
|
|
1870
|
+
minPx: detail["minPx"],
|
|
1871
|
+
gridNum: detail["gridNum"],
|
|
1872
|
+
runType: detail["runType"] === "1" ? "arithmetic" : "geometric",
|
|
1873
|
+
pnl: detail["pnl"],
|
|
1874
|
+
pnlRatio: detail["pnlRatio"],
|
|
1875
|
+
investAmt: detail["investAmt"],
|
|
1876
|
+
totalAnnRate: detail["totalAnnRate"],
|
|
1877
|
+
createdAt: new Date(Number(detail["cTime"])).toLocaleString()
|
|
1146
1878
|
});
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
data = JSON.parse(raw);
|
|
1160
|
-
} catch {
|
|
1161
|
-
process.stderr.write(
|
|
1162
|
-
` Error: Failed to parse JSON for ${client.name} at ${client.configPath}. Skipping.
|
|
1163
|
-
`
|
|
1164
|
-
);
|
|
1165
|
-
continue;
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
if (typeof data[client.mcpKey] !== "object" || data[client.mcpKey] === null) {
|
|
1169
|
-
data[client.mcpKey] = {};
|
|
1170
|
-
}
|
|
1171
|
-
const servers = data[client.mcpKey];
|
|
1172
|
-
if (Object.prototype.hasOwnProperty.call(servers, MCP_SERVER_NAME)) {
|
|
1173
|
-
process.stdout.write(` Already configured in ${client.name}. Skipping.
|
|
1174
|
-
`);
|
|
1175
|
-
continue;
|
|
1176
|
-
}
|
|
1177
|
-
servers[MCP_SERVER_NAME] = MCP_ENTRY;
|
|
1178
|
-
const jsonOutput = JSON.stringify(data, null, 2);
|
|
1179
|
-
try {
|
|
1180
|
-
fs.writeFileSync(client.configPath, jsonOutput, "utf-8");
|
|
1181
|
-
process.stdout.write(` Configured ${client.name} successfully.
|
|
1182
|
-
`);
|
|
1183
|
-
} catch (err) {
|
|
1184
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
1185
|
-
process.stderr.write(
|
|
1186
|
-
` Error: Failed to write config for ${client.name}: ${reason}
|
|
1187
|
-
Add the following to "${client.configPath}" manually:
|
|
1188
|
-
|
|
1189
|
-
"${MCP_SERVER_NAME}": ${JSON.stringify(MCP_ENTRY, null, 2).split("\n").join("\n ")}
|
|
1190
|
-
|
|
1191
|
-
`
|
|
1192
|
-
);
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
} finally {
|
|
1196
|
-
rl.close();
|
|
1879
|
+
}
|
|
1880
|
+
async function cmdGridSubOrders(client, opts) {
|
|
1881
|
+
const res = await client.privateGet("/api/v5/tradingBot/grid/sub-orders", {
|
|
1882
|
+
algoOrdType: opts.algoOrdType,
|
|
1883
|
+
algoId: opts.algoId,
|
|
1884
|
+
type: opts.type
|
|
1885
|
+
});
|
|
1886
|
+
const orders = res.data ?? [];
|
|
1887
|
+
if (opts.json) return printJson(orders);
|
|
1888
|
+
if (!orders.length) {
|
|
1889
|
+
process.stdout.write("No sub-orders\n");
|
|
1890
|
+
return;
|
|
1197
1891
|
}
|
|
1892
|
+
printTable(
|
|
1893
|
+
orders.map((o) => ({
|
|
1894
|
+
ordId: o["ordId"],
|
|
1895
|
+
side: o["side"],
|
|
1896
|
+
px: o["px"],
|
|
1897
|
+
sz: o["sz"],
|
|
1898
|
+
fillPx: o["fillPx"],
|
|
1899
|
+
fillSz: o["fillSz"],
|
|
1900
|
+
state: o["state"],
|
|
1901
|
+
fee: o["fee"]
|
|
1902
|
+
}))
|
|
1903
|
+
);
|
|
1904
|
+
}
|
|
1905
|
+
async function cmdGridCreate(client, opts) {
|
|
1906
|
+
const body = {
|
|
1907
|
+
instId: opts.instId,
|
|
1908
|
+
algoOrdType: opts.algoOrdType,
|
|
1909
|
+
maxPx: opts.maxPx,
|
|
1910
|
+
minPx: opts.minPx,
|
|
1911
|
+
gridNum: opts.gridNum
|
|
1912
|
+
};
|
|
1913
|
+
if (opts.runType) body["runType"] = opts.runType;
|
|
1914
|
+
if (opts.quoteSz) body["quoteSz"] = opts.quoteSz;
|
|
1915
|
+
if (opts.baseSz) body["baseSz"] = opts.baseSz;
|
|
1916
|
+
if (opts.direction) body["direction"] = opts.direction;
|
|
1917
|
+
if (opts.lever) body["lever"] = opts.lever;
|
|
1918
|
+
if (opts.sz) body["sz"] = opts.sz;
|
|
1919
|
+
const res = await client.privatePost("/api/v5/tradingBot/grid/order-algo", body);
|
|
1920
|
+
if (opts.json) return printJson(res.data);
|
|
1921
|
+
const r = res.data[0];
|
|
1198
1922
|
process.stdout.write(
|
|
1199
|
-
|
|
1923
|
+
`Grid bot created: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
1924
|
+
`
|
|
1925
|
+
);
|
|
1926
|
+
}
|
|
1927
|
+
async function cmdGridStop(client, opts) {
|
|
1928
|
+
const entry = {
|
|
1929
|
+
algoId: opts.algoId,
|
|
1930
|
+
algoOrdType: opts.algoOrdType,
|
|
1931
|
+
instId: opts.instId
|
|
1932
|
+
};
|
|
1933
|
+
if (opts.stopType) entry["stopType"] = opts.stopType;
|
|
1934
|
+
const res = await client.privatePost("/api/v5/tradingBot/grid/stop-order-algo", [entry]);
|
|
1935
|
+
if (opts.json) return printJson(res.data);
|
|
1936
|
+
const r = res.data[0];
|
|
1937
|
+
process.stdout.write(
|
|
1938
|
+
`Grid bot stopped: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
1939
|
+
`
|
|
1200
1940
|
);
|
|
1201
1941
|
}
|
|
1202
1942
|
|
|
@@ -1209,6 +1949,7 @@ Usage: okx [--profile <name>] [--json] <command> [args]
|
|
|
1209
1949
|
|
|
1210
1950
|
Global Options:
|
|
1211
1951
|
--profile <name> Use a named profile from ~/.okx/config.toml
|
|
1952
|
+
--demo Use simulated trading (demo) mode
|
|
1212
1953
|
--json Output raw JSON
|
|
1213
1954
|
--help Show this help
|
|
1214
1955
|
|
|
@@ -1217,12 +1958,33 @@ Commands:
|
|
|
1217
1958
|
market tickers <instType> (SPOT|SWAP|FUTURES|OPTION)
|
|
1218
1959
|
market orderbook <instId> [--sz <n>]
|
|
1219
1960
|
market candles <instId> [--bar <bar>] [--limit <n>]
|
|
1961
|
+
market instruments --instType <type> [--instId <id>]
|
|
1962
|
+
market funding-rate <instId> [--history] [--limit <n>]
|
|
1963
|
+
market mark-price --instType <MARGIN|SWAP|FUTURES|OPTION> [--instId <id>]
|
|
1964
|
+
market trades <instId> [--limit <n>]
|
|
1965
|
+
market index-ticker [--instId <id>] [--quoteCcy <ccy>]
|
|
1966
|
+
market index-candles <instId> [--bar <bar>] [--limit <n>] [--history]
|
|
1967
|
+
market price-limit <instId>
|
|
1968
|
+
market open-interest --instType <SWAP|FUTURES|OPTION> [--instId <id>]
|
|
1220
1969
|
|
|
1221
1970
|
account balance [<ccy>]
|
|
1971
|
+
account asset-balance [--ccy <ccy>]
|
|
1972
|
+
account positions [--instType <type>] [--instId <id>]
|
|
1973
|
+
account positions-history [--instType <type>] [--instId <id>] [--limit <n>]
|
|
1974
|
+
account bills [--instType <type>] [--ccy <ccy>] [--limit <n>] [--archive]
|
|
1975
|
+
account fees --instType <type> [--instId <id>]
|
|
1976
|
+
account config
|
|
1977
|
+
account set-position-mode --posMode <long_short_mode|net_mode>
|
|
1978
|
+
account max-size --instId <id> --tdMode <cross|isolated> [--px <price>]
|
|
1979
|
+
account max-avail-size --instId <id> --tdMode <cross|isolated|cash>
|
|
1980
|
+
account max-withdrawal [--ccy <ccy>]
|
|
1981
|
+
account transfer --ccy <ccy> --amt <n> --from <acct> --to <acct> [--transferType <0|1|2|3>]
|
|
1222
1982
|
|
|
1223
1983
|
spot orders [--instId <id>] [--history]
|
|
1984
|
+
spot get --instId <id> --ordId <id>
|
|
1224
1985
|
spot fills [--instId <id>] [--ordId <id>]
|
|
1225
1986
|
spot place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--px <price>]
|
|
1987
|
+
spot amend --instId <id> --ordId <id> [--newSz <n>] [--newPx <price>]
|
|
1226
1988
|
spot cancel <instId> --ordId <id>
|
|
1227
1989
|
spot algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]
|
|
1228
1990
|
spot algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]
|
|
@@ -1234,10 +1996,14 @@ Commands:
|
|
|
1234
1996
|
spot algo cancel --instId <id> --algoId <id>
|
|
1235
1997
|
|
|
1236
1998
|
swap positions [<instId>]
|
|
1237
|
-
swap orders [--instId <id>] [--history]
|
|
1999
|
+
swap orders [--instId <id>] [--history] [--archive]
|
|
2000
|
+
swap get --instId <id> --ordId <id>
|
|
2001
|
+
swap fills [--instId <id>] [--ordId <id>] [--archive]
|
|
1238
2002
|
swap place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--posSide <side>] [--px <price>] [--tdMode <cross|isolated>]
|
|
1239
2003
|
swap cancel <instId> --ordId <id>
|
|
2004
|
+
swap close --instId <id> --mgnMode <cross|isolated> [--posSide <net|long|short>] [--autoCxl]
|
|
1240
2005
|
swap leverage --instId <id> --lever <n> --mgnMode <cross|isolated> [--posSide <side>]
|
|
2006
|
+
swap get-leverage --instId <id> --mgnMode <cross|isolated>
|
|
1241
2007
|
swap algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]
|
|
1242
2008
|
swap algo trail --instId <id> --side <buy|sell> --sz <n> --callbackRatio <ratio>
|
|
1243
2009
|
[--activePx <price>] [--posSide <net|long|short>] [--tdMode <cross|isolated>] [--reduceOnly]
|
|
@@ -1250,20 +2016,399 @@ Commands:
|
|
|
1250
2016
|
[--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]
|
|
1251
2017
|
swap algo cancel --instId <id> --algoId <id>
|
|
1252
2018
|
|
|
2019
|
+
futures orders [--instId <id>] [--history] [--archive]
|
|
2020
|
+
futures positions [--instId <id>]
|
|
2021
|
+
futures fills [--instId <id>] [--ordId <id>] [--archive]
|
|
2022
|
+
futures place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--tdMode <cross|isolated>]
|
|
2023
|
+
[--posSide <net|long|short>] [--px <price>] [--reduceOnly]
|
|
2024
|
+
futures cancel <instId> --ordId <id>
|
|
2025
|
+
futures get --instId <id> --ordId <id>
|
|
2026
|
+
|
|
2027
|
+
bot grid orders --algoOrdType <grid|contract_grid|moon_grid> [--instId <id>] [--algoId <id>] [--history]
|
|
2028
|
+
bot grid details --algoOrdType <type> --algoId <id>
|
|
2029
|
+
bot grid sub-orders --algoOrdType <type> --algoId <id> [--live]
|
|
2030
|
+
bot grid create --instId <id> --algoOrdType <grid|contract_grid> --maxPx <px> --minPx <px> --gridNum <n>
|
|
2031
|
+
[--runType <1|2>] [--quoteSz <n>] [--baseSz <n>]
|
|
2032
|
+
[--direction <long|short|neutral>] [--lever <n>] [--sz <n>]
|
|
2033
|
+
bot grid stop --algoId <id> --algoOrdType <type> --instId <id> [--stopType <1|2|3|5|6>]
|
|
2034
|
+
|
|
1253
2035
|
config init
|
|
1254
2036
|
config show
|
|
1255
2037
|
config set <key> <value>
|
|
1256
2038
|
config setup-clients
|
|
2039
|
+
|
|
2040
|
+
setup --client <client> [--profile <name>] [--modules <list>]
|
|
2041
|
+
|
|
2042
|
+
Clients: ${SUPPORTED_CLIENTS.join(", ")}
|
|
1257
2043
|
`);
|
|
1258
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}
|
|
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);
|
|
2399
|
+
}
|
|
1259
2400
|
async function main() {
|
|
1260
2401
|
checkForUpdates("okx-trade-cli", CLI_VERSION);
|
|
1261
2402
|
const { values, positionals } = parseArgs({
|
|
1262
2403
|
args: process.argv.slice(2),
|
|
1263
2404
|
options: {
|
|
1264
2405
|
profile: { type: "string" },
|
|
2406
|
+
demo: { type: "boolean", default: false },
|
|
1265
2407
|
json: { type: "boolean", default: false },
|
|
1266
2408
|
help: { type: "boolean", default: false },
|
|
2409
|
+
// setup command
|
|
2410
|
+
client: { type: "string" },
|
|
2411
|
+
modules: { type: "string" },
|
|
1267
2412
|
// market candles
|
|
1268
2413
|
bar: { type: "string" },
|
|
1269
2414
|
limit: { type: "string" },
|
|
@@ -1297,7 +2442,34 @@ async function main() {
|
|
|
1297
2442
|
// trailing stop
|
|
1298
2443
|
callbackRatio: { type: "string" },
|
|
1299
2444
|
callbackSpread: { type: "string" },
|
|
1300
|
-
activePx: { type: "string" }
|
|
2445
|
+
activePx: { type: "string" },
|
|
2446
|
+
// grid bot
|
|
2447
|
+
algoOrdType: { type: "string" },
|
|
2448
|
+
gridNum: { type: "string" },
|
|
2449
|
+
maxPx: { type: "string" },
|
|
2450
|
+
minPx: { type: "string" },
|
|
2451
|
+
runType: { type: "string" },
|
|
2452
|
+
quoteSz: { type: "string" },
|
|
2453
|
+
baseSz: { type: "string" },
|
|
2454
|
+
direction: { type: "string" },
|
|
2455
|
+
stopType: { type: "string" },
|
|
2456
|
+
live: { type: "boolean", default: false },
|
|
2457
|
+
// market extras
|
|
2458
|
+
instType: { type: "string" },
|
|
2459
|
+
quoteCcy: { type: "string" },
|
|
2460
|
+
// account extras
|
|
2461
|
+
archive: { type: "boolean", default: false },
|
|
2462
|
+
posMode: { type: "string" },
|
|
2463
|
+
ccy: { type: "string" },
|
|
2464
|
+
from: { type: "string" },
|
|
2465
|
+
to: { type: "string" },
|
|
2466
|
+
transferType: { type: "string" },
|
|
2467
|
+
subAcct: { type: "string" },
|
|
2468
|
+
amt: { type: "string" },
|
|
2469
|
+
// swap/order extras
|
|
2470
|
+
autoCxl: { type: "boolean", default: false },
|
|
2471
|
+
clOrdId: { type: "string" },
|
|
2472
|
+
newPx: { type: "string" }
|
|
1301
2473
|
},
|
|
1302
2474
|
allowPositionals: true
|
|
1303
2475
|
});
|
|
@@ -1306,186 +2478,45 @@ async function main() {
|
|
|
1306
2478
|
return;
|
|
1307
2479
|
}
|
|
1308
2480
|
const [module, action, ...rest] = positionals;
|
|
1309
|
-
const
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
if (action === "setup-clients") return cmdSetupClients();
|
|
1315
|
-
process.stderr.write(`Unknown config command: ${action}
|
|
1316
|
-
`);
|
|
1317
|
-
process.exitCode = 1;
|
|
1318
|
-
return;
|
|
1319
|
-
}
|
|
1320
|
-
const config = loadProfileConfig({ profile: values.profile, 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}` });
|
|
1321
2486
|
const client = new OkxRestClient(config);
|
|
1322
|
-
if (module === "market")
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
return cmdMarketCandles(client, rest[0], {
|
|
1329
|
-
bar: values.bar,
|
|
1330
|
-
limit: values.limit ? Number(values.limit) : void 0,
|
|
1331
|
-
json
|
|
1332
|
-
});
|
|
1333
|
-
}
|
|
1334
|
-
if (module === "account") {
|
|
1335
|
-
if (action === "balance") return cmdAccountBalance(client, rest[0], json);
|
|
1336
|
-
}
|
|
1337
|
-
if (module === "spot") {
|
|
1338
|
-
if (action === "orders")
|
|
1339
|
-
return cmdSpotOrders(client, {
|
|
1340
|
-
instId: values.instId,
|
|
1341
|
-
status: values.history ? "history" : "open",
|
|
1342
|
-
json
|
|
1343
|
-
});
|
|
1344
|
-
if (action === "fills")
|
|
1345
|
-
return cmdSpotFills(client, { instId: values.instId, ordId: values.ordId, json });
|
|
1346
|
-
if (action === "place")
|
|
1347
|
-
return cmdSpotPlace(client, {
|
|
1348
|
-
instId: values.instId,
|
|
1349
|
-
side: values.side,
|
|
1350
|
-
ordType: values.ordType,
|
|
1351
|
-
sz: values.sz,
|
|
1352
|
-
px: values.px,
|
|
1353
|
-
json
|
|
1354
|
-
});
|
|
1355
|
-
if (action === "cancel")
|
|
1356
|
-
return cmdSpotCancel(client, rest[0], values.ordId, json);
|
|
1357
|
-
if (action === "algo") {
|
|
1358
|
-
const subAction = rest[0];
|
|
1359
|
-
if (subAction === "place")
|
|
1360
|
-
return cmdSpotAlgoPlace(client, {
|
|
1361
|
-
instId: values.instId,
|
|
1362
|
-
side: values.side,
|
|
1363
|
-
ordType: values.ordType ?? "conditional",
|
|
1364
|
-
sz: values.sz,
|
|
1365
|
-
tpTriggerPx: values.tpTriggerPx,
|
|
1366
|
-
tpOrdPx: values.tpOrdPx,
|
|
1367
|
-
slTriggerPx: values.slTriggerPx,
|
|
1368
|
-
slOrdPx: values.slOrdPx,
|
|
1369
|
-
json
|
|
1370
|
-
});
|
|
1371
|
-
if (subAction === "amend")
|
|
1372
|
-
return cmdSpotAlgoAmend(client, {
|
|
1373
|
-
instId: values.instId,
|
|
1374
|
-
algoId: values.algoId,
|
|
1375
|
-
newSz: values.newSz,
|
|
1376
|
-
newTpTriggerPx: values.newTpTriggerPx,
|
|
1377
|
-
newTpOrdPx: values.newTpOrdPx,
|
|
1378
|
-
newSlTriggerPx: values.newSlTriggerPx,
|
|
1379
|
-
newSlOrdPx: values.newSlOrdPx,
|
|
1380
|
-
json
|
|
1381
|
-
});
|
|
1382
|
-
if (subAction === "cancel")
|
|
1383
|
-
return cmdSpotAlgoCancel(client, values.instId, values.algoId, json);
|
|
1384
|
-
if (subAction === "orders")
|
|
1385
|
-
return cmdSpotAlgoOrders(client, {
|
|
1386
|
-
instId: values.instId,
|
|
1387
|
-
status: values.history ? "history" : "pending",
|
|
1388
|
-
ordType: values.ordType,
|
|
1389
|
-
json
|
|
1390
|
-
});
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1393
|
-
if (module === "swap") {
|
|
1394
|
-
if (action === "positions")
|
|
1395
|
-
return cmdSwapPositions(client, rest[0] ?? values.instId, json);
|
|
1396
|
-
if (action === "orders")
|
|
1397
|
-
return cmdSwapOrders(client, {
|
|
1398
|
-
instId: values.instId,
|
|
1399
|
-
status: values.history ? "history" : "open",
|
|
1400
|
-
json
|
|
1401
|
-
});
|
|
1402
|
-
if (action === "place")
|
|
1403
|
-
return cmdSwapPlace(client, {
|
|
1404
|
-
instId: values.instId,
|
|
1405
|
-
side: values.side,
|
|
1406
|
-
ordType: values.ordType,
|
|
1407
|
-
sz: values.sz,
|
|
1408
|
-
posSide: values.posSide,
|
|
1409
|
-
px: values.px,
|
|
1410
|
-
tdMode: values.tdMode ?? "cross",
|
|
1411
|
-
json
|
|
1412
|
-
});
|
|
1413
|
-
if (action === "cancel")
|
|
1414
|
-
return cmdSwapCancel(client, rest[0], values.ordId, json);
|
|
1415
|
-
if (action === "leverage")
|
|
1416
|
-
return cmdSwapSetLeverage(client, {
|
|
1417
|
-
instId: values.instId,
|
|
1418
|
-
lever: values.lever,
|
|
1419
|
-
mgnMode: values.mgnMode,
|
|
1420
|
-
posSide: values.posSide,
|
|
1421
|
-
json
|
|
1422
|
-
});
|
|
1423
|
-
if (action === "algo") {
|
|
1424
|
-
const subAction = rest[0];
|
|
1425
|
-
if (subAction === "trail")
|
|
1426
|
-
return cmdSwapAlgoTrailPlace(client, {
|
|
1427
|
-
instId: values.instId,
|
|
1428
|
-
side: values.side,
|
|
1429
|
-
sz: values.sz,
|
|
1430
|
-
callbackRatio: values.callbackRatio,
|
|
1431
|
-
callbackSpread: values.callbackSpread,
|
|
1432
|
-
activePx: values.activePx,
|
|
1433
|
-
posSide: values.posSide,
|
|
1434
|
-
tdMode: values.tdMode ?? "cross",
|
|
1435
|
-
reduceOnly: values.reduceOnly,
|
|
1436
|
-
json
|
|
1437
|
-
});
|
|
1438
|
-
if (subAction === "place")
|
|
1439
|
-
return cmdSwapAlgoPlace(client, {
|
|
1440
|
-
instId: values.instId,
|
|
1441
|
-
side: values.side,
|
|
1442
|
-
ordType: values.ordType ?? "conditional",
|
|
1443
|
-
sz: values.sz,
|
|
1444
|
-
posSide: values.posSide,
|
|
1445
|
-
tdMode: values.tdMode ?? "cross",
|
|
1446
|
-
tpTriggerPx: values.tpTriggerPx,
|
|
1447
|
-
tpOrdPx: values.tpOrdPx,
|
|
1448
|
-
slTriggerPx: values.slTriggerPx,
|
|
1449
|
-
slOrdPx: values.slOrdPx,
|
|
1450
|
-
reduceOnly: values.reduceOnly,
|
|
1451
|
-
json
|
|
1452
|
-
});
|
|
1453
|
-
if (subAction === "amend")
|
|
1454
|
-
return cmdSwapAlgoAmend(client, {
|
|
1455
|
-
instId: values.instId,
|
|
1456
|
-
algoId: values.algoId,
|
|
1457
|
-
newSz: values.newSz,
|
|
1458
|
-
newTpTriggerPx: values.newTpTriggerPx,
|
|
1459
|
-
newTpOrdPx: values.newTpOrdPx,
|
|
1460
|
-
newSlTriggerPx: values.newSlTriggerPx,
|
|
1461
|
-
newSlOrdPx: values.newSlOrdPx,
|
|
1462
|
-
json
|
|
1463
|
-
});
|
|
1464
|
-
if (subAction === "cancel")
|
|
1465
|
-
return cmdSwapAlgoCancel(client, values.instId, values.algoId, json);
|
|
1466
|
-
if (subAction === "orders")
|
|
1467
|
-
return cmdSwapAlgoOrders(client, {
|
|
1468
|
-
instId: values.instId,
|
|
1469
|
-
status: values.history ? "history" : "pending",
|
|
1470
|
-
ordType: values.ordType,
|
|
1471
|
-
json
|
|
1472
|
-
});
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
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);
|
|
1475
2493
|
process.stderr.write(`Unknown command: ${module} ${action ?? ""}
|
|
1476
2494
|
`);
|
|
1477
2495
|
process.exitCode = 1;
|
|
1478
2496
|
}
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
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}
|
|
1482
2501
|
`);
|
|
1483
|
-
|
|
2502
|
+
if (payload.traceId) process.stderr.write(`TraceId: ${payload.traceId}
|
|
1484
2503
|
`);
|
|
1485
|
-
|
|
2504
|
+
if (payload.suggestion) process.stderr.write(`Hint: ${payload.suggestion}
|
|
1486
2505
|
`);
|
|
1487
|
-
|
|
2506
|
+
process.stderr.write(`Version: okx-trade-cli@${CLI_VERSION}
|
|
1488
2507
|
`);
|
|
1489
|
-
|
|
1490
|
-
});
|
|
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
|
+
};
|
|
1491
2522
|
//# sourceMappingURL=index.js.map
|