@okx_ai/okx-trade-cli 1.1.6 → 1.1.8

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
@@ -1232,7 +1232,7 @@ var MODULES = [
1232
1232
  "account",
1233
1233
  ...BOT_SUB_MODULE_IDS
1234
1234
  ];
1235
- var DEFAULT_MODULES = ["spot", "swap", "account", ...BOT_DEFAULT_SUB_MODULES];
1235
+ var DEFAULT_MODULES = ["spot", "swap", "option", "account", ...BOT_DEFAULT_SUB_MODULES];
1236
1236
  function asRecord(value) {
1237
1237
  if (!value || typeof value !== "object" || Array.isArray(value)) {
1238
1238
  return {};
@@ -2503,6 +2503,10 @@ function registerGridTools() {
2503
2503
  sz: {
2504
2504
  type: "string",
2505
2505
  description: "Contracts to invest. Required for contract_grid."
2506
+ },
2507
+ basePos: {
2508
+ type: "boolean",
2509
+ description: "Whether to open a base position for contract grid. Ignored for neutral direction and spot grid. Default: true"
2506
2510
  }
2507
2511
  },
2508
2512
  required: ["instId", "algoOrdType", "maxPx", "minPx", "gridNum"]
@@ -2525,6 +2529,7 @@ function registerGridTools() {
2525
2529
  });
2526
2530
  if (algoOrdType === "contract_grid") {
2527
2531
  body.triggerParams = [{ triggerAction: "start", triggerStrategy: "instant" }];
2532
+ body.basePos = readBoolean(args, "basePos") ?? true;
2528
2533
  }
2529
2534
  const response = await context.client.privatePost(
2530
2535
  "/api/v5/tradingBot/grid/order-algo",
@@ -5541,7 +5546,7 @@ function parseModuleList(rawModules) {
5541
5546
  }
5542
5547
  const trimmed = rawModules.trim().toLowerCase();
5543
5548
  if (trimmed === "all") {
5544
- return [...BASE_MODULES, ...BOT_DEFAULT_SUB_MODULES];
5549
+ return [...BASE_MODULES, ...BOT_SUB_MODULE_IDS];
5545
5550
  }
5546
5551
  const requested = trimmed.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
5547
5552
  if (requested.length === 0) {
@@ -5871,128 +5876,526 @@ function cmdSetupClients() {
5871
5876
  }
5872
5877
 
5873
5878
  // src/help.ts
5874
- function printHelp() {
5875
- process.stdout.write(`
5876
- Usage: okx [--profile <name>] [--json] <command> [args]
5877
-
5878
- Global Options:
5879
- --profile <name> Use a named profile from ${configFilePath()}
5880
- --demo Use simulated trading (demo) mode
5881
- --json Output raw JSON
5882
- --version, -v Show version
5883
- --help Show this help
5884
-
5885
- Commands:
5886
- market ticker <instId>
5887
- market tickers <instType> (SPOT|SWAP|FUTURES|OPTION)
5888
- market orderbook <instId> [--sz <n>]
5889
- market candles <instId> [--bar <bar>] [--limit <n>]
5890
- market instruments --instType <type> [--instId <id>]
5891
- market funding-rate <instId> [--history] [--limit <n>]
5892
- market mark-price --instType <MARGIN|SWAP|FUTURES|OPTION> [--instId <id>]
5893
- market trades <instId> [--limit <n>]
5894
- market index-ticker [--instId <id>] [--quoteCcy <ccy>]
5895
- market index-candles <instId> [--bar <bar>] [--limit <n>] [--history]
5896
- market price-limit <instId>
5897
- market open-interest --instType <SWAP|FUTURES|OPTION> [--instId <id>]
5898
-
5899
- account balance [<ccy>]
5900
- account asset-balance [--ccy <ccy>]
5901
- account positions [--instType <type>] [--instId <id>]
5902
- account positions-history [--instType <type>] [--instId <id>] [--limit <n>]
5903
- account bills [--instType <type>] [--ccy <ccy>] [--limit <n>] [--archive]
5904
- account fees --instType <type> [--instId <id>]
5905
- account config
5906
- account set-position-mode --posMode <long_short_mode|net_mode>
5907
- account max-size --instId <id> --tdMode <cross|isolated> [--px <price>]
5908
- account max-avail-size --instId <id> --tdMode <cross|isolated|cash>
5909
- account max-withdrawal [--ccy <ccy>]
5910
- account transfer --ccy <ccy> --amt <n> --from <acct> --to <acct> [--transferType <0|1|2|3>]
5911
- account audit [--tool <name>] [--since <ISO-date>] [--limit <n>]
5912
-
5913
- spot orders [--instId <id>] [--history]
5914
- spot get --instId <id> --ordId <id>
5915
- spot fills [--instId <id>] [--ordId <id>]
5916
- spot place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--px <price>] [--tdMode <cash|cross|isolated>]
5917
- spot amend --instId <id> --ordId <id> [--newSz <n>] [--newPx <price>]
5918
- spot cancel <instId> --ordId <id>
5919
- spot algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]
5920
- spot algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]
5921
- [--tpTriggerPx <price>] [--tpOrdPx <price|-1>]
5922
- [--slTriggerPx <price>] [--slOrdPx <price|-1>] [--tdMode <cash|cross|isolated>]
5923
- spot algo amend --instId <id> --algoId <id> [--newSz <n>]
5924
- [--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]
5925
- [--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]
5926
- spot algo cancel --instId <id> --algoId <id>
5927
- spot batch --action <place|amend|cancel> --orders '<json>'
5928
-
5929
- swap positions [<instId>]
5930
- swap orders [--instId <id>] [--history] [--archive]
5931
- swap get --instId <id> --ordId <id>
5932
- swap fills [--instId <id>] [--ordId <id>] [--archive]
5933
- swap place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--posSide <side>] [--px <price>] [--tdMode <cross|isolated>]
5934
- swap cancel <instId> --ordId <id>
5935
- swap amend --instId <id> --ordId <id> [--newSz <n>] [--newPx <price>]
5936
- swap close --instId <id> --mgnMode <cross|isolated> [--posSide <net|long|short>] [--autoCxl]
5937
- swap leverage --instId <id> --lever <n> --mgnMode <cross|isolated> [--posSide <side>]
5938
- swap get-leverage --instId <id> --mgnMode <cross|isolated>
5939
- swap algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]
5940
- swap algo trail --instId <id> --side <buy|sell> --sz <n> --callbackRatio <ratio>
5941
- [--activePx <price>] [--posSide <net|long|short>] [--tdMode <cross|isolated>] [--reduceOnly]
5942
- swap algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]
5943
- [--tpTriggerPx <price>] [--tpOrdPx <price|-1>]
5944
- [--slTriggerPx <price>] [--slOrdPx <price|-1>]
5945
- [--posSide <net|long|short>] [--tdMode <cross|isolated>] [--reduceOnly]
5946
- swap algo amend --instId <id> --algoId <id> [--newSz <n>]
5947
- [--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]
5948
- [--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]
5949
- swap algo cancel --instId <id> --algoId <id>
5950
- swap batch --action <place|amend|cancel> --orders '<json>'
5951
-
5952
- futures orders [--instId <id>] [--history] [--archive]
5953
- futures positions [--instId <id>]
5954
- futures fills [--instId <id>] [--ordId <id>] [--archive]
5955
- futures place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--tdMode <cross|isolated>]
5956
- [--posSide <net|long|short>] [--px <price>] [--reduceOnly]
5957
- futures cancel <instId> --ordId <id>
5958
- futures get --instId <id> --ordId <id>
5959
-
5960
- option orders [--instId <id>] [--uly <uly>] [--history] [--archive]
5961
- option get --instId <id> [--ordId <id>] [--clOrdId <id>]
5962
- option positions [--instId <id>] [--uly <uly>]
5963
- option fills [--instId <id>] [--ordId <id>] [--archive]
5964
- option instruments --uly <uly> [--expTime <date>]
5965
- option greeks --uly <uly> [--expTime <date>]
5966
- option place --instId <id> --tdMode <cash|cross|isolated> --side <buy|sell> --ordType <type> --sz <n> [--px <price>] [--reduceOnly] [--clOrdId <id>]
5967
- option cancel --instId <id> [--ordId <id>] [--clOrdId <id>]
5968
- option amend --instId <id> [--ordId <id>] [--clOrdId <id>] [--newSz <n>] [--newPx <price>]
5969
- option batch-cancel --orders '<json>'
5970
-
5971
- bot grid orders --algoOrdType <grid|contract_grid|moon_grid> [--instId <id>] [--algoId <id>] [--history]
5972
- bot grid details --algoOrdType <type> --algoId <id>
5973
- bot grid sub-orders --algoOrdType <type> --algoId <id> [--live]
5974
- bot grid create --instId <id> --algoOrdType <grid|contract_grid> --maxPx <px> --minPx <px> --gridNum <n>
5975
- [--runType <1|2>] [--quoteSz <n>] [--baseSz <n>]
5976
- [--direction <long|short|neutral>] [--lever <n>] [--sz <n>]
5977
- bot grid stop --algoId <id> --algoOrdType <type> --instId <id> [--stopType <1|2|3|5|6>]
5978
-
5979
- bot dca orders [--type <spot|contract>] [--history]
5980
- bot dca details [--type <spot|contract>] --algoId <id>
5981
- bot dca sub-orders [--type <spot|contract>] --algoId <id> [--live] [--cycleId <id>]
5982
- bot dca create --instId <id> --initOrdAmt <n> --safetyOrdAmt <n> --maxSafetyOrds <n>
5983
- --pxSteps <n> --pxStepsMult <n> --volMult <n> --tpPct <n> [--slPct <n>]
5984
- [--type <spot|contract>] [--triggerType <1|2>] [--lever <n>] [--side <buy|sell>]
5985
- bot dca stop [--type <spot|contract>] --algoId <id> --instId <id> [--stopType <1|2>]
5986
-
5987
- config init [--lang zh]
5988
- config show
5989
- config set <key> <value>
5990
- config setup-clients
5991
-
5992
- setup --client <client> [--profile <name>] [--modules <list>]
5993
-
5994
- Clients: ${SUPPORTED_CLIENTS.join(", ")}
5879
+ var HELP_TREE = {
5880
+ market: {
5881
+ description: "Market data (ticker, orderbook, candles, trades)",
5882
+ commands: {
5883
+ ticker: {
5884
+ usage: "okx market ticker <instId>",
5885
+ description: "Get latest ticker data for an instrument"
5886
+ },
5887
+ tickers: {
5888
+ usage: "okx market tickers <instType>",
5889
+ description: "Get all tickers for an instrument type (SPOT|SWAP|FUTURES|OPTION)"
5890
+ },
5891
+ orderbook: {
5892
+ usage: "okx market orderbook <instId> [--sz <n>]",
5893
+ description: "Get order book depth for an instrument"
5894
+ },
5895
+ candles: {
5896
+ usage: "okx market candles <instId> [--bar <bar>] [--limit <n>]",
5897
+ description: "Get candlestick (OHLCV) data"
5898
+ },
5899
+ instruments: {
5900
+ usage: "okx market instruments --instType <type> [--instId <id>]",
5901
+ description: "List tradable instruments of a given type"
5902
+ },
5903
+ "funding-rate": {
5904
+ usage: "okx market funding-rate <instId> [--history] [--limit <n>]",
5905
+ description: "Get current or historical funding rate for perpetual swaps"
5906
+ },
5907
+ "mark-price": {
5908
+ usage: "okx market mark-price --instType <MARGIN|SWAP|FUTURES|OPTION> [--instId <id>]",
5909
+ description: "Get mark price for instruments"
5910
+ },
5911
+ trades: {
5912
+ usage: "okx market trades <instId> [--limit <n>]",
5913
+ description: "Get recent trades for an instrument"
5914
+ },
5915
+ "index-ticker": {
5916
+ usage: "okx market index-ticker [--instId <id>] [--quoteCcy <ccy>]",
5917
+ description: "Get index ticker data"
5918
+ },
5919
+ "index-candles": {
5920
+ usage: "okx market index-candles <instId> [--bar <bar>] [--limit <n>] [--history]",
5921
+ description: "Get index candlestick data"
5922
+ },
5923
+ "price-limit": {
5924
+ usage: "okx market price-limit <instId>",
5925
+ description: "Get price limit for an instrument"
5926
+ },
5927
+ "open-interest": {
5928
+ usage: "okx market open-interest --instType <SWAP|FUTURES|OPTION> [--instId <id>]",
5929
+ description: "Get open interest for instruments"
5930
+ }
5931
+ }
5932
+ },
5933
+ account: {
5934
+ description: "Account balance, positions, bills, and configuration",
5935
+ commands: {
5936
+ balance: {
5937
+ usage: "okx account balance [<ccy>]",
5938
+ description: "Get trading account balance"
5939
+ },
5940
+ "asset-balance": {
5941
+ usage: "okx account asset-balance [--ccy <ccy>]",
5942
+ description: "Get funding account asset balance"
5943
+ },
5944
+ positions: {
5945
+ usage: "okx account positions [--instType <type>] [--instId <id>]",
5946
+ description: "Get current open positions"
5947
+ },
5948
+ "positions-history": {
5949
+ usage: "okx account positions-history [--instType <type>] [--instId <id>] [--limit <n>]",
5950
+ description: "Get historical positions"
5951
+ },
5952
+ bills: {
5953
+ usage: "okx account bills [--instType <type>] [--ccy <ccy>] [--limit <n>] [--archive]",
5954
+ description: "Get account bill history"
5955
+ },
5956
+ fees: {
5957
+ usage: "okx account fees --instType <type> [--instId <id>]",
5958
+ description: "Get trading fee rates"
5959
+ },
5960
+ config: {
5961
+ usage: "okx account config",
5962
+ description: "Get account configuration"
5963
+ },
5964
+ "set-position-mode": {
5965
+ usage: "okx account set-position-mode --posMode <long_short_mode|net_mode>",
5966
+ description: "Set position mode (long/short or net)"
5967
+ },
5968
+ "max-size": {
5969
+ usage: "okx account max-size --instId <id> --tdMode <cross|isolated> [--px <price>]",
5970
+ description: "Get maximum order size for an instrument"
5971
+ },
5972
+ "max-avail-size": {
5973
+ usage: "okx account max-avail-size --instId <id> --tdMode <cross|isolated|cash>",
5974
+ description: "Get maximum available tradable amount"
5975
+ },
5976
+ "max-withdrawal": {
5977
+ usage: "okx account max-withdrawal [--ccy <ccy>]",
5978
+ description: "Get maximum withdrawable amount"
5979
+ },
5980
+ transfer: {
5981
+ usage: "okx account transfer --ccy <ccy> --amt <n> --from <acct> --to <acct> [--transferType <0|1|2|3>]",
5982
+ description: "Transfer funds between accounts"
5983
+ },
5984
+ audit: {
5985
+ usage: "okx account audit [--tool <name>] [--since <ISO-date>] [--limit <n>]",
5986
+ description: "Audit account activity and tool call history"
5987
+ }
5988
+ }
5989
+ },
5990
+ spot: {
5991
+ description: "Spot trading (orders, algo orders)",
5992
+ commands: {
5993
+ orders: {
5994
+ usage: "okx spot orders [--instId <id>] [--history]",
5995
+ description: "List open or historical spot orders"
5996
+ },
5997
+ get: {
5998
+ usage: "okx spot get --instId <id> --ordId <id>",
5999
+ description: "Get details of a specific spot order"
6000
+ },
6001
+ fills: {
6002
+ usage: "okx spot fills [--instId <id>] [--ordId <id>]",
6003
+ description: "Get trade fill history for spot orders"
6004
+ },
6005
+ place: {
6006
+ usage: "okx spot place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--px <price>] [--tdMode <cash|cross|isolated>]",
6007
+ description: "Place a new spot order"
6008
+ },
6009
+ amend: {
6010
+ usage: "okx spot amend --instId <id> --ordId <id> [--newSz <n>] [--newPx <price>]",
6011
+ description: "Amend a pending spot order"
6012
+ },
6013
+ cancel: {
6014
+ usage: "okx spot cancel <instId> --ordId <id>",
6015
+ description: "Cancel a pending spot order"
6016
+ },
6017
+ batch: {
6018
+ usage: "okx spot batch --action <place|amend|cancel> --orders '<json>'",
6019
+ description: "Batch place, amend, or cancel spot orders"
6020
+ }
6021
+ },
6022
+ subgroups: {
6023
+ algo: {
6024
+ description: "Spot algo orders (conditional, OCO, take-profit/stop-loss)",
6025
+ commands: {
6026
+ orders: {
6027
+ usage: "okx spot algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]",
6028
+ description: "List spot algo orders"
6029
+ },
6030
+ place: {
6031
+ usage: "okx spot algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]\n [--tpTriggerPx <price>] [--tpOrdPx <price|-1>]\n [--slTriggerPx <price>] [--slOrdPx <price|-1>] [--tdMode <cash|cross|isolated>]",
6032
+ description: "Place a spot algo order (take-profit/stop-loss)"
6033
+ },
6034
+ amend: {
6035
+ usage: "okx spot algo amend --instId <id> --algoId <id> [--newSz <n>]\n [--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]\n [--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]",
6036
+ description: "Amend a pending spot algo order"
6037
+ },
6038
+ cancel: {
6039
+ usage: "okx spot algo cancel --instId <id> --algoId <id>",
6040
+ description: "Cancel a pending spot algo order"
6041
+ }
6042
+ }
6043
+ }
6044
+ }
6045
+ },
6046
+ swap: {
6047
+ description: "Perpetual swap trading (orders, algo orders)",
6048
+ commands: {
6049
+ positions: {
6050
+ usage: "okx swap positions [<instId>]",
6051
+ description: "Get current perpetual swap positions"
6052
+ },
6053
+ orders: {
6054
+ usage: "okx swap orders [--instId <id>] [--history] [--archive]",
6055
+ description: "List open or historical swap orders"
6056
+ },
6057
+ get: {
6058
+ usage: "okx swap get --instId <id> --ordId <id>",
6059
+ description: "Get details of a specific swap order"
6060
+ },
6061
+ fills: {
6062
+ usage: "okx swap fills [--instId <id>] [--ordId <id>] [--archive]",
6063
+ description: "Get trade fill history for swap orders"
6064
+ },
6065
+ place: {
6066
+ usage: "okx swap place --instId <id> --side <buy|sell> --ordType <type> --sz <n> [--posSide <side>] [--px <price>] [--tdMode <cross|isolated>]",
6067
+ description: "Place a new perpetual swap order"
6068
+ },
6069
+ cancel: {
6070
+ usage: "okx swap cancel <instId> --ordId <id>",
6071
+ description: "Cancel a pending swap order"
6072
+ },
6073
+ amend: {
6074
+ usage: "okx swap amend --instId <id> --ordId <id> [--newSz <n>] [--newPx <price>]",
6075
+ description: "Amend a pending swap order"
6076
+ },
6077
+ close: {
6078
+ usage: "okx swap close --instId <id> --mgnMode <cross|isolated> [--posSide <net|long|short>] [--autoCxl]",
6079
+ description: "Close a swap position"
6080
+ },
6081
+ leverage: {
6082
+ usage: "okx swap leverage --instId <id> --lever <n> --mgnMode <cross|isolated> [--posSide <side>]",
6083
+ description: "Set leverage for a swap instrument"
6084
+ },
6085
+ "get-leverage": {
6086
+ usage: "okx swap get-leverage --instId <id> --mgnMode <cross|isolated>",
6087
+ description: "Get current leverage setting for a swap instrument"
6088
+ },
6089
+ batch: {
6090
+ usage: "okx swap batch --action <place|amend|cancel> --orders '<json>'",
6091
+ description: "Batch place, amend, or cancel swap orders"
6092
+ }
6093
+ },
6094
+ subgroups: {
6095
+ algo: {
6096
+ description: "Perpetual swap algo orders (trailing stop, conditional, OCO)",
6097
+ commands: {
6098
+ orders: {
6099
+ usage: "okx swap algo orders [--instId <id>] [--history] [--ordType <conditional|oco>]",
6100
+ description: "List swap algo orders"
6101
+ },
6102
+ trail: {
6103
+ usage: "okx swap algo trail --instId <id> --side <buy|sell> --sz <n> --callbackRatio <ratio>\n [--activePx <price>] [--posSide <net|long|short>] [--tdMode <cross|isolated>] [--reduceOnly]",
6104
+ description: "Place a trailing stop algo order for perpetual swap"
6105
+ },
6106
+ place: {
6107
+ usage: "okx swap algo place --instId <id> --side <buy|sell> --sz <n> [--ordType <conditional|oco>]\n [--tpTriggerPx <price>] [--tpOrdPx <price|-1>]\n [--slTriggerPx <price>] [--slOrdPx <price|-1>]\n [--posSide <net|long|short>] [--tdMode <cross|isolated>] [--reduceOnly]",
6108
+ description: "Place a swap algo order (take-profit/stop-loss)"
6109
+ },
6110
+ amend: {
6111
+ usage: "okx swap algo amend --instId <id> --algoId <id> [--newSz <n>]\n [--newTpTriggerPx <price>] [--newTpOrdPx <price|-1>]\n [--newSlTriggerPx <price>] [--newSlOrdPx <price|-1>]",
6112
+ description: "Amend a pending swap algo order"
6113
+ },
6114
+ cancel: {
6115
+ usage: "okx swap algo cancel --instId <id> --algoId <id>",
6116
+ description: "Cancel a pending swap algo order"
6117
+ }
6118
+ }
6119
+ }
6120
+ }
6121
+ },
6122
+ futures: {
6123
+ description: "Futures trading (orders, positions)",
6124
+ commands: {
6125
+ orders: {
6126
+ usage: "okx futures orders [--instId <id>] [--history] [--archive]",
6127
+ description: "List open or historical futures orders"
6128
+ },
6129
+ positions: {
6130
+ usage: "okx futures positions [--instId <id>]",
6131
+ description: "Get current futures positions"
6132
+ },
6133
+ fills: {
6134
+ usage: "okx futures fills [--instId <id>] [--ordId <id>] [--archive]",
6135
+ description: "Get trade fill history for futures orders"
6136
+ },
6137
+ place: {
6138
+ usage: "okx futures place --instId <id> --side <buy|sell> --ordType <type> --sz <n>\n [--tdMode <cross|isolated>] [--posSide <net|long|short>] [--px <price>] [--reduceOnly]",
6139
+ description: "Place a new futures order"
6140
+ },
6141
+ cancel: {
6142
+ usage: "okx futures cancel <instId> --ordId <id>",
6143
+ description: "Cancel a pending futures order"
6144
+ },
6145
+ get: {
6146
+ usage: "okx futures get --instId <id> --ordId <id>",
6147
+ description: "Get details of a specific futures order"
6148
+ }
6149
+ }
6150
+ },
6151
+ option: {
6152
+ description: "Options trading (orders, positions, greeks)",
6153
+ commands: {
6154
+ orders: {
6155
+ usage: "okx option orders [--instId <id>] [--uly <uly>] [--history] [--archive]",
6156
+ description: "List open or historical option orders"
6157
+ },
6158
+ get: {
6159
+ usage: "okx option get --instId <id> [--ordId <id>] [--clOrdId <id>]",
6160
+ description: "Get details of a specific option order"
6161
+ },
6162
+ positions: {
6163
+ usage: "okx option positions [--instId <id>] [--uly <uly>]",
6164
+ description: "Get current option positions"
6165
+ },
6166
+ fills: {
6167
+ usage: "okx option fills [--instId <id>] [--ordId <id>] [--archive]",
6168
+ description: "Get trade fill history for option orders"
6169
+ },
6170
+ instruments: {
6171
+ usage: "okx option instruments --uly <uly> [--expTime <date>]",
6172
+ description: "List tradable option instruments for an underlying"
6173
+ },
6174
+ greeks: {
6175
+ usage: "okx option greeks --uly <uly> [--expTime <date>]",
6176
+ description: "Get option greeks (delta, gamma, theta, vega)"
6177
+ },
6178
+ place: {
6179
+ usage: "okx option place --instId <id> --tdMode <cash|cross|isolated> --side <buy|sell> --ordType <type> --sz <n>\n [--px <price>] [--reduceOnly] [--clOrdId <id>]",
6180
+ description: "Place a new option order"
6181
+ },
6182
+ cancel: {
6183
+ usage: "okx option cancel --instId <id> [--ordId <id>] [--clOrdId <id>]",
6184
+ description: "Cancel a pending option order"
6185
+ },
6186
+ amend: {
6187
+ usage: "okx option amend --instId <id> [--ordId <id>] [--clOrdId <id>] [--newSz <n>] [--newPx <price>]",
6188
+ description: "Amend a pending option order"
6189
+ },
6190
+ "batch-cancel": {
6191
+ usage: "okx option batch-cancel --orders '<json>'",
6192
+ description: "Batch cancel option orders"
6193
+ }
6194
+ }
6195
+ },
6196
+ bot: {
6197
+ description: "Trading bot strategies (grid, dca)",
6198
+ subgroups: {
6199
+ grid: {
6200
+ description: "Grid trading bot \u2014 create, monitor, and stop grid orders",
6201
+ commands: {
6202
+ orders: {
6203
+ usage: "okx bot grid orders --algoOrdType <grid|contract_grid|moon_grid> [--instId <id>] [--algoId <id>] [--history]",
6204
+ description: "List active or historical grid bot orders"
6205
+ },
6206
+ details: {
6207
+ usage: "okx bot grid details --algoOrdType <type> --algoId <id>",
6208
+ description: "Get details of a specific grid bot order"
6209
+ },
6210
+ "sub-orders": {
6211
+ usage: "okx bot grid sub-orders --algoOrdType <type> --algoId <id> [--live]",
6212
+ description: "List sub-orders of a grid bot (filled or live)"
6213
+ },
6214
+ create: {
6215
+ usage: "okx bot grid create --instId <id> --algoOrdType <grid|contract_grid> --maxPx <px> --minPx <px> --gridNum <n>\n [--runType <1|2>] [--quoteSz <n>] [--baseSz <n>]\n [--direction <long|short|neutral>] [--lever <n>] [--sz <n>] [--basePos] [--no-basePos]",
6216
+ description: "Create a new grid bot order (contract grid opens base position by default)"
6217
+ },
6218
+ stop: {
6219
+ usage: "okx bot grid stop --algoId <id> --algoOrdType <type> --instId <id> [--stopType <1|2|3|5|6>]",
6220
+ description: "Stop a running grid bot order"
6221
+ }
6222
+ }
6223
+ },
6224
+ dca: {
6225
+ description: "DCA (Dollar Cost Averaging) bot \u2014 automated recurring buys",
6226
+ commands: {
6227
+ orders: {
6228
+ usage: "okx bot dca orders [--type <spot|contract>] [--history]",
6229
+ description: "List active or historical DCA bot orders"
6230
+ },
6231
+ details: {
6232
+ usage: "okx bot dca details [--type <spot|contract>] --algoId <id>",
6233
+ description: "Get details of a specific DCA bot order"
6234
+ },
6235
+ "sub-orders": {
6236
+ usage: "okx bot dca sub-orders [--type <spot|contract>] --algoId <id> [--live] [--cycleId <id>]",
6237
+ description: "List sub-orders of a DCA bot"
6238
+ },
6239
+ create: {
6240
+ usage: "okx bot dca create --instId <id> --initOrdAmt <n> --safetyOrdAmt <n> --maxSafetyOrds <n>\n --pxSteps <n> --pxStepsMult <n> --volMult <n> --tpPct <n> [--slPct <n>]\n [--type <spot|contract>] [--triggerType <1|2>] [--lever <n>] [--side <buy|sell>]\n [--reserveFunds <true|false>]",
6241
+ description: "Create a new DCA bot order"
6242
+ },
6243
+ stop: {
6244
+ usage: "okx bot dca stop [--type <spot|contract>] --algoId <id> --instId <id> [--stopType <1|2>]",
6245
+ description: "Stop a running DCA bot order"
6246
+ }
6247
+ }
6248
+ }
6249
+ }
6250
+ },
6251
+ config: {
6252
+ description: "Manage CLI configuration profiles",
6253
+ commands: {
6254
+ init: {
6255
+ usage: "okx config init [--lang zh]",
6256
+ description: "Initialize a new configuration profile interactively"
6257
+ },
6258
+ show: {
6259
+ usage: "okx config show",
6260
+ description: `Show current configuration (file: ${configFilePath()})`
6261
+ },
6262
+ set: {
6263
+ usage: "okx config set <key> <value>",
6264
+ description: "Set a configuration value"
6265
+ },
6266
+ "setup-clients": {
6267
+ usage: "okx config setup-clients",
6268
+ description: "Set up MCP client integrations (Cursor, Windsurf, etc.)"
6269
+ }
6270
+ }
6271
+ },
6272
+ setup: {
6273
+ description: "Set up client integrations (Cursor, Windsurf, Claude, etc.)",
6274
+ usage: `okx setup --client <${SUPPORTED_CLIENTS.join("|")}> [--profile <name>] [--modules <list>]`
6275
+ }
6276
+ };
6277
+ function printGlobalHelp() {
6278
+ const lines = [
6279
+ "",
6280
+ `Usage: okx [--profile <name>] [--demo] [--json] <module> <action> [args...]`,
6281
+ "",
6282
+ "Global Options:",
6283
+ ` --profile <name> Use a named profile from ${configFilePath()}`,
6284
+ " --demo Use simulated trading (demo) mode",
6285
+ " --json Output raw JSON",
6286
+ " --version, -v Show version",
6287
+ " --help Show this help",
6288
+ "",
6289
+ "Modules:"
6290
+ ];
6291
+ const colWidth = 12;
6292
+ for (const [name, group] of Object.entries(HELP_TREE)) {
6293
+ lines.push(` ${name.padEnd(colWidth)}${group.description}`);
6294
+ }
6295
+ lines.push("", 'Run "okx <module> --help" for module details.', "");
6296
+ process.stdout.write(lines.join("\n"));
6297
+ }
6298
+ function printModuleHelp(moduleName) {
6299
+ const group = HELP_TREE[moduleName];
6300
+ if (!group) {
6301
+ process.stderr.write(`Unknown module: ${moduleName}
6302
+ `);
6303
+ process.exitCode = 1;
6304
+ return;
6305
+ }
6306
+ const hasSubgroups = group.subgroups && Object.keys(group.subgroups).length > 0;
6307
+ const hasCommands = group.commands && Object.keys(group.commands).length > 0;
6308
+ const lines = [""];
6309
+ if (hasSubgroups && !hasCommands) {
6310
+ const subgroupNames = Object.keys(group.subgroups);
6311
+ lines.push(`Usage: okx ${moduleName} <strategy> <action> [args...]`);
6312
+ lines.push("", `${group.description}.`, "");
6313
+ lines.push("Strategies:");
6314
+ const colWidth = Math.max(...subgroupNames.map((n) => n.length)) + 4;
6315
+ for (const [sgName, sg] of Object.entries(group.subgroups)) {
6316
+ lines.push(` ${sgName.padEnd(colWidth)}${sg.description}`);
6317
+ }
6318
+ lines.push("", `Run "okx ${moduleName} <strategy> --help" for details.`);
6319
+ } else if (hasSubgroups && hasCommands) {
6320
+ lines.push(`Usage: okx ${moduleName} <action> [args...]`);
6321
+ lines.push("", `${group.description}.`, "", "Commands:");
6322
+ printCommandList(lines, group.commands);
6323
+ lines.push("", "Subgroups:");
6324
+ const subgroupEntries = Object.entries(group.subgroups);
6325
+ const colWidth = Math.max(...subgroupEntries.map(([n]) => n.length)) + 4;
6326
+ for (const [sgName, sg] of subgroupEntries) {
6327
+ lines.push(` ${sgName.padEnd(colWidth)}${sg.description}`);
6328
+ }
6329
+ lines.push("", `Run "okx ${moduleName} <subgroup> --help" for subgroup details.`);
6330
+ } else if (hasCommands) {
6331
+ lines.push(`Usage: okx ${moduleName} <action> [args...]`);
6332
+ lines.push("", `${group.description}.`, "", "Commands:");
6333
+ printCommandList(lines, group.commands);
6334
+ } else if (group.usage) {
6335
+ lines.push(`Usage: ${group.usage}`);
6336
+ lines.push("", `${group.description}.`);
6337
+ if (group.commands) {
6338
+ lines.push("");
6339
+ for (const cmd of Object.values(group.commands)) {
6340
+ lines.push(` ${cmd.description}`);
6341
+ lines.push(` Usage: ${cmd.usage}`);
6342
+ }
6343
+ }
6344
+ }
6345
+ lines.push("");
6346
+ process.stdout.write(lines.join("\n"));
6347
+ }
6348
+ function printSubgroupHelp(moduleName, subgroupName) {
6349
+ const group = HELP_TREE[moduleName];
6350
+ if (!group) {
6351
+ process.stderr.write(`Unknown module: ${moduleName}
6352
+ `);
6353
+ process.exitCode = 1;
6354
+ return;
6355
+ }
6356
+ const subgroup = group.subgroups?.[subgroupName];
6357
+ if (!subgroup) {
6358
+ process.stderr.write(`Unknown subgroup: ${moduleName} ${subgroupName}
5995
6359
  `);
6360
+ process.exitCode = 1;
6361
+ return;
6362
+ }
6363
+ const lines = [
6364
+ "",
6365
+ `Usage: okx ${moduleName} ${subgroupName} <action> [args...]`,
6366
+ "",
6367
+ `${subgroup.description}.`,
6368
+ "",
6369
+ "Commands:"
6370
+ ];
6371
+ if (subgroup.commands) {
6372
+ printCommandList(lines, subgroup.commands);
6373
+ }
6374
+ lines.push("");
6375
+ process.stdout.write(lines.join("\n"));
6376
+ }
6377
+ function printCommandList(lines, commands) {
6378
+ const names = Object.keys(commands);
6379
+ const colWidth = Math.max(...names.map((n) => n.length)) + 4;
6380
+ for (const [name, cmd] of Object.entries(commands)) {
6381
+ lines.push(` ${name.padEnd(colWidth)}${cmd.description}`);
6382
+ const usageLines = cmd.usage.split("\n");
6383
+ lines.push(` ${" ".repeat(colWidth)}Usage: ${usageLines[0]}`);
6384
+ for (const extra of usageLines.slice(1)) {
6385
+ lines.push(` ${" ".repeat(colWidth)} ${extra.trimStart()}`);
6386
+ }
6387
+ lines.push("");
6388
+ }
6389
+ }
6390
+ function printHelp(...path4) {
6391
+ const [moduleName, subgroupName] = path4;
6392
+ if (!moduleName) {
6393
+ printGlobalHelp();
6394
+ } else if (!subgroupName) {
6395
+ printModuleHelp(moduleName);
6396
+ } else {
6397
+ printSubgroupHelp(moduleName, subgroupName);
6398
+ }
5996
6399
  }
5997
6400
 
5998
6401
  // src/parser.ts
@@ -6049,6 +6452,7 @@ var CLI_OPTIONS = {
6049
6452
  quoteSz: { type: "string" },
6050
6453
  baseSz: { type: "string" },
6051
6454
  direction: { type: "string" },
6455
+ basePos: { type: "boolean", default: true },
6052
6456
  stopType: { type: "string" },
6053
6457
  live: { type: "boolean", default: false },
6054
6458
  // market extras
@@ -6090,14 +6494,30 @@ var CLI_OPTIONS = {
6090
6494
  orders: { type: "string" },
6091
6495
  // audit
6092
6496
  since: { type: "string" },
6093
- tool: { type: "string" }
6497
+ tool: { type: "string" },
6498
+ // config profile
6499
+ force: { type: "boolean", default: false }
6094
6500
  };
6095
6501
  function parseCli(argv) {
6502
+ const negated = /* @__PURE__ */ new Set();
6503
+ const filtered = argv.filter((arg) => {
6504
+ if (arg.startsWith("--no-")) {
6505
+ const key = arg.slice(5);
6506
+ if (key in CLI_OPTIONS && CLI_OPTIONS[key].type === "boolean") {
6507
+ negated.add(key);
6508
+ return false;
6509
+ }
6510
+ }
6511
+ return true;
6512
+ });
6096
6513
  const { values, positionals } = parseArgs({
6097
- args: argv,
6514
+ args: filtered,
6098
6515
  options: CLI_OPTIONS,
6099
6516
  allowPositionals: true
6100
6517
  });
6518
+ for (const key of negated) {
6519
+ values[key] = false;
6520
+ }
6101
6521
  return { values, positionals };
6102
6522
  }
6103
6523
 
@@ -7457,7 +7877,7 @@ function cmdConfigShow(json) {
7457
7877
  process.stdout.write(`[${name}]
7458
7878
  `);
7459
7879
  printKv({
7460
- api_key: profile.api_key ? "***" + profile.api_key.slice(-4) : "(not set)",
7880
+ api_key: profile.api_key ? maskSecret(profile.api_key) : "(not set)",
7461
7881
  demo: profile.demo ?? false,
7462
7882
  base_url: profile.base_url ?? "(default)"
7463
7883
  }, 2);
@@ -7478,10 +7898,24 @@ function cmdConfigSet(key, value) {
7478
7898
  }
7479
7899
  }
7480
7900
  function parseSiteKey(raw) {
7481
- if (raw === "2") return "eea";
7482
- if (raw === "3") return "us";
7901
+ const lower = raw.toLowerCase();
7902
+ if (lower === "eea" || raw === "2") return "eea";
7903
+ if (lower === "us" || raw === "3") return "us";
7904
+ if (lower === "global" || raw === "1") return "global";
7483
7905
  return "global";
7484
7906
  }
7907
+ function inferSiteFromBaseUrl(baseUrl) {
7908
+ if (!baseUrl) return "global";
7909
+ for (const id of SITE_IDS) {
7910
+ const site = OKX_SITES[id];
7911
+ if (baseUrl === site.apiBaseUrl || baseUrl === site.webUrl) return id;
7912
+ }
7913
+ return "global";
7914
+ }
7915
+ function maskSecret(value) {
7916
+ if (!value || value.length < 4) return "****";
7917
+ return "***" + value.slice(-4);
7918
+ }
7485
7919
  function buildApiUrl(siteKey, demo) {
7486
7920
  const query = demo ? "?go-demo-trading=1" : "?go-live-trading=1";
7487
7921
  return `${OKX_SITES[siteKey].webUrl}/account/my-api${query}`;
@@ -7581,6 +8015,105 @@ async function cmdConfigInit(lang = "en") {
7581
8015
  rl.close();
7582
8016
  }
7583
8017
  }
8018
+ function cmdConfigAddProfile(kvPairs, force) {
8019
+ const params = {};
8020
+ for (const pair of kvPairs) {
8021
+ const eqIdx = pair.indexOf("=");
8022
+ if (eqIdx === -1) continue;
8023
+ const key = pair.slice(0, eqIdx).trim();
8024
+ const value = pair.slice(eqIdx + 1);
8025
+ params[key.toUpperCase()] = value;
8026
+ }
8027
+ const ak = params["AK"];
8028
+ const sk = params["SK"];
8029
+ const pp = params["PP"];
8030
+ const missing = [];
8031
+ if (!ak) missing.push("AK");
8032
+ if (!sk) missing.push("SK");
8033
+ if (!pp) missing.push("PP");
8034
+ if (missing.length > 0) {
8035
+ process.stderr.write(`Error: missing required parameter(s): ${missing.join(", ")}
8036
+ `);
8037
+ process.stderr.write("Usage: okx config add-profile AK=<key> SK=<secret> PP=<passphrase> [site=global|eea|us] [demo=true|false] [name=<name>] [--force]\n");
8038
+ process.exitCode = 1;
8039
+ return;
8040
+ }
8041
+ const siteKey = parseSiteKey(params["SITE"] ?? "");
8042
+ const demo = params["DEMO"] !== void 0 ? params["DEMO"].toLowerCase() !== "false" : true;
8043
+ const defaultName = demo ? "demo" : "live";
8044
+ const profileName = params["NAME"] ?? defaultName;
8045
+ const config = readFullConfig();
8046
+ if (config.profiles[profileName] && !force) {
8047
+ process.stderr.write(`Error: profile "${profileName}" already exists. Use --force to overwrite.
8048
+ `);
8049
+ process.exitCode = 1;
8050
+ return;
8051
+ }
8052
+ const entry = buildProfileEntry(siteKey, ak, sk, pp, demo);
8053
+ entry.site = siteKey;
8054
+ config.profiles[profileName] = entry;
8055
+ config.default_profile = profileName;
8056
+ writeCliConfig(config);
8057
+ process.stdout.write(`Profile "${profileName}" saved to ${configFilePath()}
8058
+ `);
8059
+ process.stdout.write(`Default profile set to: ${profileName}
8060
+ `);
8061
+ }
8062
+ function cmdConfigListProfile() {
8063
+ const config = readFullConfig();
8064
+ const entries = Object.entries(config.profiles);
8065
+ if (entries.length === 0) {
8066
+ process.stdout.write("No profiles found. Run: okx config add-profile AK=<key> SK=<secret> PP=<passphrase>\n");
8067
+ return;
8068
+ }
8069
+ process.stdout.write(`Config: ${configFilePath()}
8070
+
8071
+ `);
8072
+ for (const [name, profile] of entries) {
8073
+ const isDefault = name === config.default_profile;
8074
+ const marker = isDefault ? " *" : "";
8075
+ const site = profile.site ?? inferSiteFromBaseUrl(profile.base_url);
8076
+ const mode = profile.demo !== false ? "demo (\u6A21\u62DF\u76D8)" : "live (\u5B9E\u76D8)";
8077
+ process.stdout.write(`[${name}]${marker}
8078
+ `);
8079
+ process.stdout.write(` api_key: ${maskSecret(profile.api_key)}
8080
+ `);
8081
+ process.stdout.write(` secret_key: ${maskSecret(profile.secret_key)}
8082
+ `);
8083
+ process.stdout.write(` passphrase: ${maskSecret(profile.passphrase)}
8084
+ `);
8085
+ process.stdout.write(` site: ${site}
8086
+ `);
8087
+ process.stdout.write(` mode: ${mode}
8088
+ `);
8089
+ process.stdout.write("\n");
8090
+ }
8091
+ }
8092
+ function cmdConfigUse(profileName) {
8093
+ if (!profileName) {
8094
+ process.stderr.write("Error: profile name is required.\nUsage: okx config use <profile-name>\n");
8095
+ process.exitCode = 1;
8096
+ return;
8097
+ }
8098
+ const config = readFullConfig();
8099
+ const available = Object.keys(config.profiles);
8100
+ if (!config.profiles[profileName]) {
8101
+ process.stderr.write(`Error: profile "${profileName}" does not exist.
8102
+ `);
8103
+ if (available.length > 0) {
8104
+ process.stderr.write(`Available profiles: ${available.join(", ")}
8105
+ `);
8106
+ } else {
8107
+ process.stderr.write("No profiles configured. Run: okx config add-profile AK=<key> SK=<secret> PP=<passphrase>\n");
8108
+ }
8109
+ process.exitCode = 1;
8110
+ return;
8111
+ }
8112
+ config.default_profile = profileName;
8113
+ writeCliConfig(config);
8114
+ process.stdout.write(`Default profile set to: "${profileName}"
8115
+ `);
8116
+ }
7584
8117
 
7585
8118
  // src/commands/bot.ts
7586
8119
  function getData7(result) {
@@ -7677,7 +8210,8 @@ async function cmdGridCreate(run, opts) {
7677
8210
  baseSz: opts.baseSz,
7678
8211
  direction: opts.direction,
7679
8212
  lever: opts.lever,
7680
- sz: opts.sz
8213
+ sz: opts.sz,
8214
+ basePos: opts.basePos
7681
8215
  });
7682
8216
  const data = getData7(result);
7683
8217
  if (opts.json) return printJson(data);
@@ -7853,11 +8387,15 @@ async function cmdDcaSubOrders(run, opts) {
7853
8387
  // src/index.ts
7854
8388
  var _require = createRequire(import.meta.url);
7855
8389
  var CLI_VERSION = _require("../package.json").version;
7856
- function handleConfigCommand(action, rest, json, lang) {
8390
+ var GIT_HASH = true ? "53a7589" : "dev";
8391
+ function handleConfigCommand(action, rest, json, lang, force) {
7857
8392
  if (action === "init") return cmdConfigInit(lang === "zh" ? "zh" : "en");
7858
8393
  if (action === "show") return cmdConfigShow(json);
7859
8394
  if (action === "set") return cmdConfigSet(rest[0], rest[1]);
7860
8395
  if (action === "setup-clients") return cmdSetupClients();
8396
+ if (action === "add-profile") return cmdConfigAddProfile(rest, force ?? false);
8397
+ if (action === "list-profile") return cmdConfigListProfile();
8398
+ if (action === "use") return cmdConfigUse(rest[0]);
7861
8399
  process.stderr.write(`Unknown config command: ${action}
7862
8400
  `);
7863
8401
  process.exitCode = 1;
@@ -8254,6 +8792,7 @@ function handleBotGridCommand(run, v, rest, json) {
8254
8792
  direction: v.direction,
8255
8793
  lever: v.lever,
8256
8794
  sz: v.sz,
8795
+ basePos: v.basePos,
8257
8796
  json
8258
8797
  });
8259
8798
  if (subAction === "stop")
@@ -8303,18 +8842,25 @@ async function main() {
8303
8842
  checkForUpdates("@okx_ai/okx-trade-cli", CLI_VERSION);
8304
8843
  const { values, positionals } = parseCli(process.argv.slice(2));
8305
8844
  if (values.version) {
8306
- process.stdout.write(`${CLI_VERSION}
8845
+ process.stdout.write(`${CLI_VERSION} (${GIT_HASH})
8307
8846
  `);
8308
8847
  return;
8309
8848
  }
8310
8849
  if (values.help || positionals.length === 0) {
8311
- printHelp();
8850
+ const [module2, subgroup] = positionals;
8851
+ if (!module2) {
8852
+ printHelp();
8853
+ } else if (!subgroup) {
8854
+ printHelp(module2);
8855
+ } else {
8856
+ printHelp(module2, subgroup);
8857
+ }
8312
8858
  return;
8313
8859
  }
8314
8860
  const [module, action, ...rest] = positionals;
8315
8861
  const v = values;
8316
8862
  const json = v.json ?? false;
8317
- if (module === "config") return handleConfigCommand(action, rest, json, v.lang);
8863
+ if (module === "config") return handleConfigCommand(action, rest, json, v.lang, v.force);
8318
8864
  if (module === "setup") return handleSetupCommand(v);
8319
8865
  const config = loadProfileConfig({ profile: v.profile, demo: v.demo, userAgent: `okx-trade-cli/${CLI_VERSION}` });
8320
8866
  const client = new OkxRestClient(config);