@pionex/pionex-ai-kit 0.2.19 → 0.2.21

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/README.md CHANGED
@@ -13,6 +13,10 @@ npm install -g @pionex/pionex-ai-kit
13
13
  - **pionex-ai-kit onboard** — Interactive wizard: API Key, API Secret, profile name. Writes `~/.pionex/config.toml`.
14
14
  - **pionex-ai-kit setup** — Register MCP servers for supported clients.
15
15
  - **pionex-ai-kit help** — Show help.
16
+ - **pionex market ...** — Public market data commands.
17
+ - **pionex account ...** — Account balance command.
18
+ - **pionex orders ...** — Spot order lifecycle commands.
19
+ - **pionex bot ...** — Futures grid bot lifecycle commands (`get/create/adjust/reduce/cancel`).
16
20
 
17
21
  The MCP server (**@pionex/pionex-trade-mcp**) reads from the same file. After init, run:
18
22
 
package/dist/index.js CHANGED
@@ -987,8 +987,8 @@ function runSetup(options) {
987
987
  );
988
988
  }
989
989
  var PIONEX_API_DEFAULT_BASE_URL = "https://api.pionex.com";
990
- var MODULES = ["market", "account", "orders"];
991
- var DEFAULT_MODULES = ["market", "account", "orders"];
990
+ var MODULES = ["market", "account", "orders", "bot"];
991
+ var DEFAULT_MODULES = ["market", "account", "orders", "bot"];
992
992
  var ConfigError = class extends Error {
993
993
  suggestion;
994
994
  constructor(message, suggestion) {
@@ -1480,8 +1480,318 @@ function registerOrdersTools() {
1480
1480
  }
1481
1481
  ];
1482
1482
  }
1483
+ function asNonEmptyString(value, field) {
1484
+ if (typeof value !== "string" || value.trim().length === 0) {
1485
+ throw new Error(`Invalid "${field}": expected non-empty string.`);
1486
+ }
1487
+ return value.trim();
1488
+ }
1489
+ function asFiniteNumber(value, field) {
1490
+ if (typeof value !== "number" || !Number.isFinite(value)) {
1491
+ throw new Error(`Invalid "${field}": expected finite number.`);
1492
+ }
1493
+ return value;
1494
+ }
1495
+ function asPositiveNumber(value, field) {
1496
+ const n = asFiniteNumber(value, field);
1497
+ if (n <= 0) throw new Error(`Invalid "${field}": expected number > 0.`);
1498
+ return n;
1499
+ }
1500
+ function asPositiveInteger(value, field) {
1501
+ const n = asPositiveNumber(value, field);
1502
+ if (!Number.isInteger(n)) {
1503
+ throw new Error(`Invalid "${field}": expected positive integer.`);
1504
+ }
1505
+ return n;
1506
+ }
1507
+ function asBoolean(value, field) {
1508
+ if (typeof value !== "boolean") {
1509
+ throw new Error(`Invalid "${field}": expected boolean.`);
1510
+ }
1511
+ return value;
1512
+ }
1513
+ function assertEnum(value, field, allowed) {
1514
+ if (!allowed.includes(value)) {
1515
+ throw new Error(`Invalid "${field}": expected one of ${allowed.join(", ")}.`);
1516
+ }
1517
+ }
1518
+ function asObject(value, field) {
1519
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1520
+ throw new Error(`Invalid "${field}": expected JSON object.`);
1521
+ }
1522
+ return value;
1523
+ }
1524
+ function asPositiveDecimalString(value, field) {
1525
+ const s = asNonEmptyString(value, field);
1526
+ if (!/^\d+(\.\d+)?$/.test(s)) {
1527
+ throw new Error(`Invalid "${field}": expected positive decimal string.`);
1528
+ }
1529
+ const n = Number(s);
1530
+ if (!Number.isFinite(n) || n <= 0) {
1531
+ throw new Error(`Invalid "${field}": expected positive decimal string.`);
1532
+ }
1533
+ return s;
1534
+ }
1535
+ function registerBotTools() {
1536
+ return [
1537
+ {
1538
+ name: "pionex_bot_get_futures_grid_order",
1539
+ module: "bot",
1540
+ isWrite: false,
1541
+ description: "Get one futures grid bot order by buOrderId.",
1542
+ inputSchema: {
1543
+ type: "object",
1544
+ additionalProperties: false,
1545
+ properties: {
1546
+ buOrderId: { type: "string", description: "Futures grid bot order id." },
1547
+ lang: { type: "string", description: "Optional language code." }
1548
+ },
1549
+ required: ["buOrderId"]
1550
+ },
1551
+ async handler(args, { client }) {
1552
+ const buOrderId = String(args.buOrderId);
1553
+ const q = { buOrderId };
1554
+ if (args.lang != null) q.lang = String(args.lang);
1555
+ return (await client.signedGet("/api/v1/bot/orders/futuresGrid/order", q)).data;
1556
+ }
1557
+ },
1558
+ {
1559
+ name: "pionex_bot_create_futures_grid_order",
1560
+ module: "bot",
1561
+ isWrite: true,
1562
+ description: "Create a futures grid bot order.",
1563
+ inputSchema: {
1564
+ type: "object",
1565
+ additionalProperties: false,
1566
+ properties: {
1567
+ keyId: { type: "string" },
1568
+ exchange: { type: "string", description: "e.g. pionex.v2" },
1569
+ base: { type: "string", description: "e.g. BTC" },
1570
+ quote: { type: "string", description: "e.g. USDT" },
1571
+ copyFrom: { type: "string" },
1572
+ copyType: { type: "string" },
1573
+ groupId: { type: "string" },
1574
+ copyBotOrderId: { type: "string" },
1575
+ lang: { type: "string" },
1576
+ buOrderData: {
1577
+ type: "object",
1578
+ additionalProperties: true,
1579
+ description: "CreateFuturesGridOrderData payload from openapi_bot.yaml."
1580
+ }
1581
+ },
1582
+ required: ["keyId", "exchange", "base", "quote", "buOrderData"]
1583
+ },
1584
+ async handler(args, { client, config }) {
1585
+ if (config.readOnly) {
1586
+ throw new Error("Server is running in --read-only mode; bot create is disabled.");
1587
+ }
1588
+ const keyId = asNonEmptyString(args.keyId, "keyId");
1589
+ const exchange = asNonEmptyString(args.exchange, "exchange");
1590
+ const base = asNonEmptyString(args.base, "base");
1591
+ const quote = asNonEmptyString(args.quote, "quote");
1592
+ const buOrderData = asObject(args.buOrderData, "buOrderData");
1593
+ const top = asPositiveDecimalString(buOrderData.top, "buOrderData.top");
1594
+ const bottom = asPositiveDecimalString(buOrderData.bottom, "buOrderData.bottom");
1595
+ if (Number(top) <= Number(bottom)) {
1596
+ throw new Error('Invalid "buOrderData.top": expected top > bottom.');
1597
+ }
1598
+ const row = asPositiveInteger(buOrderData.row, "buOrderData.row");
1599
+ const gridType = asNonEmptyString(buOrderData.grid_type, "buOrderData.grid_type");
1600
+ assertEnum(gridType, "buOrderData.grid_type", ["arithmetic", "geometric"]);
1601
+ const openPrice = asPositiveDecimalString(buOrderData.openPrice, "buOrderData.openPrice");
1602
+ const trend = asNonEmptyString(buOrderData.trend, "buOrderData.trend");
1603
+ assertEnum(trend, "buOrderData.trend", ["long", "short", "no_trend"]);
1604
+ const leverage = asPositiveNumber(buOrderData.leverage, "buOrderData.leverage");
1605
+ const extraMargin = asPositiveDecimalString(buOrderData.extraMargin, "buOrderData.extraMargin");
1606
+ const quoteInvestment = asPositiveDecimalString(buOrderData.quoteInvestment, "buOrderData.quoteInvestment");
1607
+ const body = {
1608
+ keyId,
1609
+ exchange,
1610
+ base,
1611
+ quote,
1612
+ buOrderData: {
1613
+ ...buOrderData,
1614
+ top,
1615
+ bottom,
1616
+ row,
1617
+ grid_type: gridType,
1618
+ openPrice,
1619
+ trend,
1620
+ leverage,
1621
+ extraMargin,
1622
+ quoteInvestment
1623
+ }
1624
+ };
1625
+ if (args.copyFrom != null) body.copyFrom = String(args.copyFrom);
1626
+ if (args.copyType != null) body.copyType = String(args.copyType);
1627
+ if (args.groupId != null) body.groupId = String(args.groupId);
1628
+ if (args.copyBotOrderId != null) body.copyBotOrderId = String(args.copyBotOrderId);
1629
+ if (args.lang != null) body.lang = String(args.lang);
1630
+ return (await client.signedPost("/api/v1/bot/orders/futuresGrid/create", body)).data;
1631
+ }
1632
+ },
1633
+ {
1634
+ name: "pionex_bot_adjust_futures_grid_params",
1635
+ module: "bot",
1636
+ isWrite: true,
1637
+ description: "Adjust futures grid bot params (invest_in / adjust_params / invest_in_trigger).",
1638
+ inputSchema: {
1639
+ type: "object",
1640
+ additionalProperties: false,
1641
+ properties: {
1642
+ buOrderId: { type: "string" },
1643
+ type: { type: "string", enum: ["invest_in", "adjust_params", "invest_in_trigger"] },
1644
+ quoteInvestment: { type: "number" },
1645
+ extraMargin: { type: "boolean" },
1646
+ openPrice: { type: "number" },
1647
+ bottom: { type: "string" },
1648
+ top: { type: "string" },
1649
+ row: { type: "number" },
1650
+ extraMarginAmount: { type: "number" },
1651
+ isRecommend: { type: "boolean" },
1652
+ isReinvest: { type: "boolean" },
1653
+ investCoin: { type: "string" },
1654
+ investmentFrom: { type: "string", enum: ["USER", "LOCK_ACTIVITY"] },
1655
+ condition: { type: "string" },
1656
+ conditionDirection: { type: "string", enum: ["1", "-1"] },
1657
+ slippage: { type: "string" },
1658
+ adjustParamsSence: { type: "string" }
1659
+ },
1660
+ required: ["buOrderId", "type", "extraMargin", "openPrice"]
1661
+ },
1662
+ async handler(args, { client, config }) {
1663
+ if (config.readOnly) {
1664
+ throw new Error("Server is running in --read-only mode; bot adjust is disabled.");
1665
+ }
1666
+ const buOrderId = asNonEmptyString(args.buOrderId, "buOrderId");
1667
+ const type = asNonEmptyString(args.type, "type");
1668
+ assertEnum(type, "type", ["invest_in", "adjust_params", "invest_in_trigger"]);
1669
+ const extraMargin = asBoolean(args.extraMargin, "extraMargin");
1670
+ const openPrice = asFiniteNumber(args.openPrice, "openPrice");
1671
+ if (type === "invest_in" && args.quoteInvestment != null) {
1672
+ asPositiveNumber(args.quoteInvestment, "quoteInvestment");
1673
+ }
1674
+ if (type === "adjust_params") {
1675
+ const bottom = asPositiveDecimalString(args.bottom, "bottom");
1676
+ const top = asPositiveDecimalString(args.top, "top");
1677
+ if (Number(top) <= Number(bottom)) {
1678
+ throw new Error('Invalid "top": expected top > bottom.');
1679
+ }
1680
+ asPositiveInteger(args.row, "row");
1681
+ }
1682
+ if (type === "invest_in_trigger") {
1683
+ asPositiveDecimalString(args.condition, "condition");
1684
+ const conditionDirection = asNonEmptyString(args.conditionDirection, "conditionDirection");
1685
+ assertEnum(conditionDirection, "conditionDirection", ["1", "-1"]);
1686
+ }
1687
+ const body = {
1688
+ buOrderId,
1689
+ type,
1690
+ extraMargin,
1691
+ openPrice
1692
+ };
1693
+ if (args.quoteInvestment != null) body.quoteInvestment = asFiniteNumber(args.quoteInvestment, "quoteInvestment");
1694
+ if (args.bottom != null) body.bottom = asPositiveDecimalString(args.bottom, "bottom");
1695
+ if (args.top != null) body.top = asPositiveDecimalString(args.top, "top");
1696
+ if (args.row != null) body.row = asPositiveInteger(args.row, "row");
1697
+ if (args.extraMarginAmount != null) body.extraMarginAmount = asFiniteNumber(args.extraMarginAmount, "extraMarginAmount");
1698
+ if (args.isRecommend != null) body.isRecommend = asBoolean(args.isRecommend, "isRecommend");
1699
+ if (args.isReinvest != null) body.isReinvest = asBoolean(args.isReinvest, "isReinvest");
1700
+ if (args.investCoin != null) body.investCoin = String(args.investCoin);
1701
+ if (args.investmentFrom != null) {
1702
+ const investmentFrom = asNonEmptyString(args.investmentFrom, "investmentFrom");
1703
+ assertEnum(investmentFrom, "investmentFrom", ["USER", "LOCK_ACTIVITY"]);
1704
+ body.investmentFrom = investmentFrom;
1705
+ }
1706
+ if (args.condition != null) body.condition = asPositiveDecimalString(args.condition, "condition");
1707
+ if (args.conditionDirection != null) {
1708
+ const conditionDirection = asNonEmptyString(args.conditionDirection, "conditionDirection");
1709
+ assertEnum(conditionDirection, "conditionDirection", ["1", "-1"]);
1710
+ body.conditionDirection = conditionDirection;
1711
+ }
1712
+ if (args.slippage != null) body.slippage = String(args.slippage);
1713
+ if (args.adjustParamsSence != null) body.adjustParamsSence = String(args.adjustParamsSence);
1714
+ return (await client.signedPost("/api/v1/bot/orders/futuresGrid/adjustParams", body)).data;
1715
+ }
1716
+ },
1717
+ {
1718
+ name: "pionex_bot_reduce_futures_grid_position",
1719
+ module: "bot",
1720
+ isWrite: true,
1721
+ description: "Reduce futures grid bot position.",
1722
+ inputSchema: {
1723
+ type: "object",
1724
+ additionalProperties: false,
1725
+ properties: {
1726
+ buOrderId: { type: "string" },
1727
+ openPrice: { type: "string" },
1728
+ reduceNum: { type: "number" },
1729
+ slippage: { type: "string" },
1730
+ condition: { type: "string" },
1731
+ conditionDirection: { type: "string", enum: ["1", "-1"] }
1732
+ },
1733
+ required: ["buOrderId", "openPrice", "reduceNum"]
1734
+ },
1735
+ async handler(args, { client, config }) {
1736
+ if (config.readOnly) {
1737
+ throw new Error("Server is running in --read-only mode; bot reduce is disabled.");
1738
+ }
1739
+ const buOrderId = asNonEmptyString(args.buOrderId, "buOrderId");
1740
+ const openPrice = asPositiveDecimalString(args.openPrice, "openPrice");
1741
+ const reduceNum = asPositiveInteger(args.reduceNum, "reduceNum");
1742
+ const body = {
1743
+ buOrderId,
1744
+ openPrice,
1745
+ reduceNum
1746
+ };
1747
+ if (args.slippage != null) body.slippage = String(args.slippage);
1748
+ if (args.condition != null) body.condition = String(args.condition);
1749
+ if (args.conditionDirection != null) {
1750
+ const conditionDirection = asNonEmptyString(args.conditionDirection, "conditionDirection");
1751
+ assertEnum(conditionDirection, "conditionDirection", ["1", "-1"]);
1752
+ body.conditionDirection = conditionDirection;
1753
+ }
1754
+ return (await client.signedPost("/api/v1/bot/orders/futuresGrid/reduce", body)).data;
1755
+ }
1756
+ },
1757
+ {
1758
+ name: "pionex_bot_cancel_futures_grid_order",
1759
+ module: "bot",
1760
+ isWrite: true,
1761
+ description: "Cancel and close a futures grid bot order.",
1762
+ inputSchema: {
1763
+ type: "object",
1764
+ additionalProperties: false,
1765
+ properties: {
1766
+ buOrderId: { type: "string" },
1767
+ closeNote: { type: "string" },
1768
+ closeSellModel: { type: "string", enum: ["TO_QUOTE", "TO_USDT"] },
1769
+ immediate: { type: "boolean" },
1770
+ closeSlippage: { type: "string" }
1771
+ },
1772
+ required: ["buOrderId"]
1773
+ },
1774
+ async handler(args, { client, config }) {
1775
+ if (config.readOnly) {
1776
+ throw new Error("Server is running in --read-only mode; bot cancel is disabled.");
1777
+ }
1778
+ const buOrderId = asNonEmptyString(args.buOrderId, "buOrderId");
1779
+ const body = { buOrderId };
1780
+ if (args.closeNote != null) body.closeNote = String(args.closeNote);
1781
+ if (args.closeSellModel != null) {
1782
+ const closeSellModel = asNonEmptyString(args.closeSellModel, "closeSellModel");
1783
+ assertEnum(closeSellModel, "closeSellModel", ["TO_QUOTE", "TO_USDT"]);
1784
+ body.closeSellModel = closeSellModel;
1785
+ }
1786
+ if (args.immediate != null) body.immediate = asBoolean(args.immediate, "immediate");
1787
+ if (args.closeSlippage != null) body.closeSlippage = String(args.closeSlippage);
1788
+ return (await client.signedPost("/api/v1/bot/orders/futuresGrid/cancel", body)).data;
1789
+ }
1790
+ }
1791
+ ];
1792
+ }
1483
1793
  function allToolSpecs() {
1484
- return [...registerMarketTools(), ...registerAccountTools(), ...registerOrdersTools()];
1794
+ return [...registerMarketTools(), ...registerAccountTools(), ...registerOrdersTools(), ...registerBotTools()];
1485
1795
  }
1486
1796
  function createToolRunner(client, config) {
1487
1797
  const fullConfig = { ...config, modules: [...MODULES] };
@@ -1636,20 +1946,23 @@ function parseFlags(argv) {
1636
1946
  }
1637
1947
  function printPionexHelp() {
1638
1948
  process.stdout.write(`
1639
- Usage: pionex-trade-cli <group> <command> [args] [--flags]
1949
+ Usage: pionex <group> <command> [args] [--flags]
1640
1950
 
1641
1951
  Groups:
1642
1952
  market Market data (public)
1643
1953
  account Account data (requires auth)
1644
1954
  orders Spot orders (requires auth)
1955
+ bot Futures grid bot (requires auth)
1645
1956
 
1646
1957
  Examples:
1647
- pionex-trade-cli market depth BTC_USDT --limit 5
1648
- pionex-trade-cli market tickers --symbol BTC_USDT
1649
- pionex-trade-cli market symbols --symbols BTC_USDT
1650
- pionex-trade-cli account balance
1651
- pionex-trade-cli orders new --symbol BTC_USDT --side BUY --type MARKET --amount 10
1652
- pionex-trade-cli orders cancel --symbol BTC_USDT --order-id 123
1958
+ pionex market depth BTC_USDT --limit 5
1959
+ pionex market tickers --symbol BTC_USDT
1960
+ pionex market symbols --symbols BTC_USDT
1961
+ pionex account balance
1962
+ pionex orders new --symbol BTC_USDT --side BUY --type MARKET --amount 10
1963
+ pionex orders cancel --symbol BTC_USDT --order-id 123
1964
+ pionex bot get --bu-order-id <id>
1965
+ pionex bot create --key-id <keyId> --exchange pionex.v2 --base BTC --quote USDT --bu-order-data-json '{"top":"110000","bottom":"90000","row":100,"grid_type":"arithmetic","openPrice":"100000","trend":"long","leverage":5,"extraMargin":"0","quoteInvestment":"100"}'
1653
1966
 
1654
1967
  Global flags:
1655
1968
  --profile <name> Profile in ~/.pionex/config.toml
@@ -1659,6 +1972,21 @@ Global flags:
1659
1972
  --dry-run Print the tool call payload without executing (write ops only)
1660
1973
  `);
1661
1974
  }
1975
+ function parseJsonFlag(raw, flagName) {
1976
+ if (typeof raw !== "string") {
1977
+ throw new Error(`Missing required flag: --${flagName}`);
1978
+ }
1979
+ try {
1980
+ const parsed = JSON.parse(raw);
1981
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
1982
+ throw new Error("must be a JSON object");
1983
+ }
1984
+ return parsed;
1985
+ } catch (e) {
1986
+ const msg = e instanceof Error ? e.message : String(e);
1987
+ throw new Error(`Invalid --${flagName}: ${msg}`);
1988
+ }
1989
+ }
1662
1990
  async function runPionexCommand(argv) {
1663
1991
  const { positionals, flags } = parseFlags(argv);
1664
1992
  const group = positionals[0];
@@ -1679,7 +2007,7 @@ async function runPionexCommand(argv) {
1679
2007
  if (group === "market") {
1680
2008
  if (command === "depth") {
1681
2009
  const symbol = positionals[2];
1682
- if (!symbol) throw new Error("Missing symbol. Example: pionex-trade-cli market depth BTC_USDT");
2010
+ if (!symbol) throw new Error("Missing symbol. Example: pionex market depth BTC_USDT");
1683
2011
  const limit = flags.limit != null ? Number(flags.limit) : void 0;
1684
2012
  const out = await runTool("pionex_market_get_depth", { symbol, limit });
1685
2013
  process.stdout.write(JSON.stringify(out.data, null, 2) + "\n");
@@ -1687,7 +2015,7 @@ async function runPionexCommand(argv) {
1687
2015
  }
1688
2016
  if (command === "trades") {
1689
2017
  const symbol = positionals[2];
1690
- if (!symbol) throw new Error("Missing symbol. Example: pionex-trade-cli market trades BTC_USDT");
2018
+ if (!symbol) throw new Error("Missing symbol. Example: pionex market trades BTC_USDT");
1691
2019
  const limit = flags.limit != null ? Number(flags.limit) : void 0;
1692
2020
  const out = await runTool("pionex_market_get_trades", { symbol, limit });
1693
2021
  process.stdout.write(JSON.stringify(out.data, null, 2) + "\n");
@@ -1710,8 +2038,7 @@ async function runPionexCommand(argv) {
1710
2038
  if (command === "klines") {
1711
2039
  const symbol = typeof flags.symbol === "string" ? flags.symbol : positionals[2];
1712
2040
  const interval = typeof flags.interval === "string" ? flags.interval : positionals[3];
1713
- if (!symbol || !interval)
1714
- throw new Error("Missing symbol/interval. Example: pionex-trade-cli market klines BTC_USDT 60M");
2041
+ if (!symbol || !interval) throw new Error("Missing symbol/interval. Example: pionex market klines BTC_USDT 60M");
1715
2042
  const endTime = flags.endTime != null ? Number(flags.endTime) : void 0;
1716
2043
  const limit = flags.limit != null ? Number(flags.limit) : void 0;
1717
2044
  const out = await runTool("pionex_market_get_klines", { symbol, interval, endTime, limit });
@@ -1807,6 +2134,76 @@ async function runPionexCommand(argv) {
1807
2134
  }
1808
2135
  throw new Error(`Unknown orders command: ${command}`);
1809
2136
  }
2137
+ if (group === "bot") {
2138
+ if (command === "get") {
2139
+ const buOrderId = typeof flags["bu-order-id"] === "string" ? flags["bu-order-id"] : typeof flags.buOrderId === "string" ? flags.buOrderId : void 0;
2140
+ const lang = typeof flags.lang === "string" ? flags.lang : void 0;
2141
+ if (!buOrderId) throw new Error("Missing required flag: --bu-order-id");
2142
+ const out = await runTool("pionex_bot_get_futures_grid_order", { buOrderId, lang });
2143
+ process.stdout.write(JSON.stringify(out.data, null, 2) + "\n");
2144
+ return;
2145
+ }
2146
+ if (command === "create") {
2147
+ const keyId = typeof flags["key-id"] === "string" ? flags["key-id"] : typeof flags.keyId === "string" ? flags.keyId : void 0;
2148
+ const exchange = typeof flags.exchange === "string" ? flags.exchange : void 0;
2149
+ const base = typeof flags.base === "string" ? flags.base : void 0;
2150
+ const quote = typeof flags.quote === "string" ? flags.quote : void 0;
2151
+ const copyFrom = typeof flags["copy-from"] === "string" ? flags["copy-from"] : typeof flags.copyFrom === "string" ? flags.copyFrom : void 0;
2152
+ const copyType = typeof flags["copy-type"] === "string" ? flags["copy-type"] : typeof flags.copyType === "string" ? flags.copyType : void 0;
2153
+ const groupId = typeof flags["group-id"] === "string" ? flags["group-id"] : typeof flags.groupId === "string" ? flags.groupId : void 0;
2154
+ const copyBotOrderId = typeof flags["copy-bot-order-id"] === "string" ? flags["copy-bot-order-id"] : typeof flags.copyBotOrderId === "string" ? flags.copyBotOrderId : void 0;
2155
+ const lang = typeof flags.lang === "string" ? flags.lang : void 0;
2156
+ const buOrderData = parseJsonFlag(flags["bu-order-data-json"] ?? flags.buOrderDataJson, "bu-order-data-json");
2157
+ if (!keyId || !exchange || !base || !quote) {
2158
+ throw new Error("Missing required flags: --key-id --exchange --base --quote --bu-order-data-json");
2159
+ }
2160
+ const payload = { keyId, exchange, base, quote, copyFrom, copyType, groupId, copyBotOrderId, lang, buOrderData };
2161
+ if (dryRun) {
2162
+ process.stdout.write(JSON.stringify({ tool: "pionex_bot_create_futures_grid_order", args: payload }, null, 2) + "\n");
2163
+ return;
2164
+ }
2165
+ const out = await runTool("pionex_bot_create_futures_grid_order", payload);
2166
+ process.stdout.write(JSON.stringify(out.data, null, 2) + "\n");
2167
+ return;
2168
+ }
2169
+ if (command === "adjust") {
2170
+ const payload = parseJsonFlag(flags["body-json"] ?? flags.bodyJson, "body-json");
2171
+ if (dryRun) {
2172
+ process.stdout.write(JSON.stringify({ tool: "pionex_bot_adjust_futures_grid_params", args: payload }, null, 2) + "\n");
2173
+ return;
2174
+ }
2175
+ const out = await runTool("pionex_bot_adjust_futures_grid_params", payload);
2176
+ process.stdout.write(JSON.stringify(out.data, null, 2) + "\n");
2177
+ return;
2178
+ }
2179
+ if (command === "reduce") {
2180
+ const payload = parseJsonFlag(flags["body-json"] ?? flags.bodyJson, "body-json");
2181
+ if (dryRun) {
2182
+ process.stdout.write(JSON.stringify({ tool: "pionex_bot_reduce_futures_grid_position", args: payload }, null, 2) + "\n");
2183
+ return;
2184
+ }
2185
+ const out = await runTool("pionex_bot_reduce_futures_grid_position", payload);
2186
+ process.stdout.write(JSON.stringify(out.data, null, 2) + "\n");
2187
+ return;
2188
+ }
2189
+ if (command === "cancel") {
2190
+ const buOrderId = typeof flags["bu-order-id"] === "string" ? flags["bu-order-id"] : typeof flags.buOrderId === "string" ? flags.buOrderId : void 0;
2191
+ const closeNote = typeof flags["close-note"] === "string" ? flags["close-note"] : typeof flags.closeNote === "string" ? flags.closeNote : void 0;
2192
+ const closeSellModel = typeof flags["close-sell-model"] === "string" ? flags["close-sell-model"] : typeof flags.closeSellModel === "string" ? flags.closeSellModel : void 0;
2193
+ const immediate = typeof flags.immediate === "boolean" ? flags.immediate : void 0;
2194
+ const closeSlippage = typeof flags["close-slippage"] === "string" ? flags["close-slippage"] : typeof flags.closeSlippage === "string" ? flags.closeSlippage : void 0;
2195
+ if (!buOrderId) throw new Error("Missing required flag: --bu-order-id");
2196
+ const payload = { buOrderId, closeNote, closeSellModel, immediate, closeSlippage };
2197
+ if (dryRun) {
2198
+ process.stdout.write(JSON.stringify({ tool: "pionex_bot_cancel_futures_grid_order", args: payload }, null, 2) + "\n");
2199
+ return;
2200
+ }
2201
+ const out = await runTool("pionex_bot_cancel_futures_grid_order", payload);
2202
+ process.stdout.write(JSON.stringify(out.data, null, 2) + "\n");
2203
+ return;
2204
+ }
2205
+ throw new Error(`Unknown bot command: ${command}`);
2206
+ }
1810
2207
  throw new Error(`Unknown group: ${group}`);
1811
2208
  }
1812
2209
  function main() {