@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 +4 -0
- package/dist/index.js +411 -14
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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
|
|
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
|
|
1648
|
-
pionex
|
|
1649
|
-
pionex
|
|
1650
|
-
pionex
|
|
1651
|
-
pionex
|
|
1652
|
-
pionex
|
|
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
|
|
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
|
|
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() {
|