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 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(path3, query, rateLimit) {
224
+ async publicGet(path4, query, rateLimit) {
192
225
  return this.request({
193
226
  method: "GET",
194
- path: path3,
227
+ path: path4,
195
228
  auth: "public",
196
229
  query,
197
230
  rateLimit
198
231
  });
199
232
  }
200
- async privateGet(path3, query, rateLimit) {
233
+ async privateGet(path4, query, rateLimit) {
201
234
  return this.request({
202
235
  method: "GET",
203
- path: path3,
236
+ path: path4,
204
237
  auth: "private",
205
238
  query,
206
239
  rateLimit
207
240
  });
208
241
  }
209
- async privatePost(path3, body, rateLimit) {
242
+ async privatePost(path4, body, rateLimit) {
210
243
  return this.request({
211
244
  method: "POST",
212
- path: path3,
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
- `${config.method} ${config.path}`,
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: `${config.method} ${config.path}`,
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 path3 = configFilePath();
348
- if (!existsSync(path3)) return {};
349
- const raw = readFileSync(path3, "utf-8");
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 writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync3 } from "fs";
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 (!existsSync3(dir)) {
972
- mkdirSync2(dir, { recursive: true });
1675
+ if (!existsSync4(dir)) {
1676
+ mkdirSync3(dir, { recursive: true });
973
1677
  }
974
- writeFileSync2(configFilePath(), stringify(config), "utf-8");
1678
+ writeFileSync3(configFilePath(), stringify(config), "utf-8");
975
1679
  }
976
1680
 
977
1681
  // src/commands/config.ts
978
- import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
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 path3 = configFilePath();
984
- if (!existsSync4(path3)) return { profiles: {} };
985
- const raw = readFileSync3(path3, "utf-8");
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
- import * as path2 from "path";
1097
- import * as os2 from "os";
1098
- import * as readline from "readline";
1099
- var CLIENTS = [
1100
- {
1101
- name: "Claude Desktop",
1102
- configPath: path2.join(os2.homedir(), "Library/Application Support/Claude/claude_desktop_config.json"),
1103
- mcpKey: "mcpServers"
1104
- },
1105
- {
1106
- name: "Cursor",
1107
- configPath: path2.join(os2.homedir(), ".cursor/mcp.json"),
1108
- mcpKey: "mcpServers"
1109
- },
1110
- {
1111
- name: "Windsurf",
1112
- configPath: path2.join(os2.homedir(), ".codeium/windsurf/mcp_config.json"),
1113
- mcpKey: "mcpServers"
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
- async function cmdSetupClients() {
1129
- const detected = CLIENTS.filter((c) => fs.existsSync(c.configPath));
1130
- if (detected.length === 0) {
1131
- process.stdout.write(
1132
- "No supported IDE/client installations detected.\nChecked:\n" + CLIENTS.map((c) => ` - ${c.name}: ${c.configPath}`).join("\n") + "\n"
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
- process.stdout.write(`Detected ${detected.length} client(s):
1137
- `);
1138
- for (const c of detected) {
1139
- process.stdout.write(` - ${c.name}
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
- process.stdout.write("\n");
1143
- const rl = readline.createInterface({
1144
- input: process.stdin,
1145
- output: process.stdout
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
- try {
1148
- for (const client of detected) {
1149
- const answer = await prompt2(rl, `Configure ${client.name}? (y/N) `);
1150
- if (answer.trim().toLowerCase() !== "y") {
1151
- process.stdout.write(` Skipped ${client.name}.
1152
- `);
1153
- continue;
1154
- }
1155
- let data = { [client.mcpKey]: {} };
1156
- if (fs.existsSync(client.configPath)) {
1157
- const raw = fs.readFileSync(client.configPath, "utf-8");
1158
- try {
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
- "\nDone. Please restart any configured IDE/client for the changes to take effect.\n"
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 json = values.json ?? false;
1310
- if (module === "config") {
1311
- if (action === "init") return cmdConfigInit();
1312
- if (action === "show") return cmdConfigShow(json);
1313
- if (action === "set") return cmdConfigSet(rest[0], rest[1]);
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
- if (action === "ticker") return cmdMarketTicker(client, rest[0], json);
1324
- if (action === "tickers") return cmdMarketTickers(client, rest[0], json);
1325
- if (action === "orderbook")
1326
- return cmdMarketOrderbook(client, rest[0], values.sz ? Number(values.sz) : void 0, json);
1327
- if (action === "candles")
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
- main().catch((error) => {
1480
- const payload = toToolErrorPayload(error);
1481
- process.stderr.write(`Error: ${payload.message}
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
- if (payload.traceId) process.stderr.write(`TraceId: ${payload.traceId}
2502
+ if (payload.traceId) process.stderr.write(`TraceId: ${payload.traceId}
1484
2503
  `);
1485
- if (payload.suggestion) process.stderr.write(`Hint: ${payload.suggestion}
2504
+ if (payload.suggestion) process.stderr.write(`Hint: ${payload.suggestion}
1486
2505
  `);
1487
- process.stderr.write(`Version: okx-trade-cli@${CLI_VERSION}
2506
+ process.stderr.write(`Version: okx-trade-cli@${CLI_VERSION}
1488
2507
  `);
1489
- process.exitCode = 1;
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