@pionex/pionex-trade-mcp 0.2.41 → 0.2.44
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 +171 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1777,6 +1777,23 @@ function asPositiveDecimalString2(value, field) {
|
|
|
1777
1777
|
function normalizePerpBase(base) {
|
|
1778
1778
|
return base.endsWith(".PERP") ? base : `${base}.PERP`;
|
|
1779
1779
|
}
|
|
1780
|
+
function parseSmartCopyBuOrderData(raw) {
|
|
1781
|
+
const quoteInvestment = asPositiveDecimalString2(raw.quoteInvestment, "buOrderData.quoteInvestment");
|
|
1782
|
+
const leverageType = asNonEmptyString3(raw.leverageType, "buOrderData.leverageType");
|
|
1783
|
+
assertEnum3(leverageType, "buOrderData.leverageType", ["follow", "fixed"]);
|
|
1784
|
+
if (leverageType === "fixed" && raw.leverage == null) {
|
|
1785
|
+
throw new Error('Invalid "buOrderData.leverage": required when leverageType is "fixed".');
|
|
1786
|
+
}
|
|
1787
|
+
const out = { quoteInvestment, leverageType };
|
|
1788
|
+
if (raw.leverage != null) out.leverage = asPositiveNumber3(raw.leverage, "buOrderData.leverage");
|
|
1789
|
+
if (raw.maxInvestPerOrder != null) out.maxInvestPerOrder = asPositiveDecimalString2(raw.maxInvestPerOrder, "buOrderData.maxInvestPerOrder");
|
|
1790
|
+
if (raw.copyMode != null) {
|
|
1791
|
+
const copyMode = asNonEmptyString3(raw.copyMode, "buOrderData.copyMode");
|
|
1792
|
+
assertEnum3(copyMode, "buOrderData.copyMode", ["fixed_amount", "fixed_ratio"]);
|
|
1793
|
+
out.copyMode = copyMode;
|
|
1794
|
+
}
|
|
1795
|
+
return out;
|
|
1796
|
+
}
|
|
1780
1797
|
function registerBotTools() {
|
|
1781
1798
|
return [
|
|
1782
1799
|
{
|
|
@@ -2242,6 +2259,160 @@ function registerBotTools() {
|
|
|
2242
2259
|
const amount = asPositiveDecimalString2(args.amount, "amount");
|
|
2243
2260
|
return (await client.signedPost("/api/v1/bot/orders/spotGrid/profit", { buOrderId, amount })).data;
|
|
2244
2261
|
}
|
|
2262
|
+
},
|
|
2263
|
+
// ── Smart Copy ────────────────────────────────────────────────────────────
|
|
2264
|
+
{
|
|
2265
|
+
name: "pionex_bot_smart_copy_get_order",
|
|
2266
|
+
module: "bot",
|
|
2267
|
+
isWrite: false,
|
|
2268
|
+
description: "Get one smart copy bot order by buOrderId.",
|
|
2269
|
+
inputSchema: {
|
|
2270
|
+
type: "object",
|
|
2271
|
+
additionalProperties: false,
|
|
2272
|
+
properties: {
|
|
2273
|
+
buOrderId: { type: "string", description: "Smart copy bot order ID." }
|
|
2274
|
+
},
|
|
2275
|
+
required: ["buOrderId"]
|
|
2276
|
+
},
|
|
2277
|
+
async handler(args, { client }) {
|
|
2278
|
+
const buOrderId = asNonEmptyString3(args.buOrderId, "buOrderId");
|
|
2279
|
+
return (await client.signedGet("/api/v1/bot/orders/smartCopy/order", { buOrderId })).data;
|
|
2280
|
+
}
|
|
2281
|
+
},
|
|
2282
|
+
{
|
|
2283
|
+
name: "pionex_bot_smart_copy_check_params",
|
|
2284
|
+
module: "bot",
|
|
2285
|
+
isWrite: false,
|
|
2286
|
+
description: "Validate smart copy bot parameters before creating an order. Uses the same buOrderData structure as smart_copy_create. On FailedWithData error the response includes min_investment, max_investment. Endpoint: POST /api/v1/bot/orders/smartCopy/checkParams",
|
|
2287
|
+
inputSchema: {
|
|
2288
|
+
type: "object",
|
|
2289
|
+
additionalProperties: false,
|
|
2290
|
+
required: ["base", "quote", "buOrderData"],
|
|
2291
|
+
properties: {
|
|
2292
|
+
base: { type: "string", description: "Base currency (e.g. BTC)" },
|
|
2293
|
+
quote: { type: "string", description: "Quote currency (e.g. USDT)" },
|
|
2294
|
+
buOrderData: {
|
|
2295
|
+
type: "object",
|
|
2296
|
+
additionalProperties: false,
|
|
2297
|
+
required: ["quoteInvestment", "leverageType"],
|
|
2298
|
+
properties: {
|
|
2299
|
+
quoteInvestment: { type: "string", description: "Investment amount in quote currency." },
|
|
2300
|
+
leverageType: { type: "string", enum: ["follow", "fixed"], description: "Follow signal provider's leverage or use fixed value." },
|
|
2301
|
+
leverage: { type: "number", description: "Custom leverage (required when leverageType is 'fixed')." },
|
|
2302
|
+
maxInvestPerOrder: { type: "string", description: "Maximum investment per replicated order." },
|
|
2303
|
+
copyMode: { type: "string", enum: ["fixed_amount", "fixed_ratio"], description: "Copy mode." }
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
},
|
|
2308
|
+
async handler(args, { client }) {
|
|
2309
|
+
const base = asNonEmptyString3(args.base, "base");
|
|
2310
|
+
const quote = asNonEmptyString3(args.quote, "quote");
|
|
2311
|
+
const buOrderData = parseSmartCopyBuOrderData(asObject(args.buOrderData, "buOrderData"));
|
|
2312
|
+
return (await client.signedPost("/api/v1/bot/orders/smartCopy/checkParams", { base, quote, buOrderData })).data;
|
|
2313
|
+
}
|
|
2314
|
+
},
|
|
2315
|
+
{
|
|
2316
|
+
name: "pionex_bot_smart_copy_create",
|
|
2317
|
+
module: "bot",
|
|
2318
|
+
isWrite: true,
|
|
2319
|
+
description: "Create a smart copy bot order. Required: base, quote, buOrderData (quoteInvestment, leverageType). Optional top-level: copyFrom (signal source ID), copyBotOrderId. buOrderData optional: leverage (required if leverageType=fixed), maxInvestPerOrder, copyMode.",
|
|
2320
|
+
inputSchema: {
|
|
2321
|
+
type: "object",
|
|
2322
|
+
additionalProperties: false,
|
|
2323
|
+
required: ["base", "quote", "buOrderData"],
|
|
2324
|
+
properties: {
|
|
2325
|
+
base: { type: "string", description: "Base currency (e.g. BTC)" },
|
|
2326
|
+
quote: { type: "string", description: "Quote currency (e.g. USDT)" },
|
|
2327
|
+
buOrderData: {
|
|
2328
|
+
type: "object",
|
|
2329
|
+
additionalProperties: false,
|
|
2330
|
+
required: ["quoteInvestment", "leverageType"],
|
|
2331
|
+
properties: {
|
|
2332
|
+
quoteInvestment: { type: "string", description: "Investment amount in quote currency." },
|
|
2333
|
+
leverageType: { type: "string", enum: ["follow", "fixed"], description: "Follow signal provider's leverage or use fixed value." },
|
|
2334
|
+
leverage: { type: "number", description: "Custom leverage (required when leverageType is 'fixed')." },
|
|
2335
|
+
maxInvestPerOrder: { type: "string", description: "Maximum investment per replicated order." },
|
|
2336
|
+
copyMode: { type: "string", enum: ["fixed_amount", "fixed_ratio"], description: "Copy mode." }
|
|
2337
|
+
}
|
|
2338
|
+
},
|
|
2339
|
+
copyFrom: { type: "string", description: "Signal source / trader ID to copy from." },
|
|
2340
|
+
copyBotOrderId: { type: "string", description: "Reference bot order ID for copying settings." },
|
|
2341
|
+
__dryRun: { type: "boolean", description: "If true, validate and return resolved body without placing an order." }
|
|
2342
|
+
}
|
|
2343
|
+
},
|
|
2344
|
+
async handler(args, { client, config }) {
|
|
2345
|
+
if (config.readOnly) {
|
|
2346
|
+
throw new Error("Server is running in --read-only mode; bot smart_copy create is disabled.");
|
|
2347
|
+
}
|
|
2348
|
+
const base = asNonEmptyString3(args.base, "base");
|
|
2349
|
+
const quote = asNonEmptyString3(args.quote, "quote");
|
|
2350
|
+
const buOrderData = parseSmartCopyBuOrderData(asObject(args.buOrderData, "buOrderData"));
|
|
2351
|
+
const body = { base, quote, buOrderData };
|
|
2352
|
+
if (args.copyFrom != null) body.copyFrom = String(args.copyFrom);
|
|
2353
|
+
if (args.copyBotOrderId != null) body.copyBotOrderId = String(args.copyBotOrderId);
|
|
2354
|
+
if (args.__dryRun === true) {
|
|
2355
|
+
return {
|
|
2356
|
+
dryRun: true,
|
|
2357
|
+
note: "No order was sent. Body matches smartCopy/create request.",
|
|
2358
|
+
resolvedBody: body
|
|
2359
|
+
};
|
|
2360
|
+
}
|
|
2361
|
+
return (await client.signedPost("/api/v1/bot/orders/smartCopy/create", body)).data;
|
|
2362
|
+
}
|
|
2363
|
+
},
|
|
2364
|
+
{
|
|
2365
|
+
name: "pionex_bot_smart_copy_cancel",
|
|
2366
|
+
module: "bot",
|
|
2367
|
+
isWrite: true,
|
|
2368
|
+
description: "Cancel and close a smart copy bot order.",
|
|
2369
|
+
inputSchema: {
|
|
2370
|
+
type: "object",
|
|
2371
|
+
additionalProperties: false,
|
|
2372
|
+
required: ["buOrderId"],
|
|
2373
|
+
properties: {
|
|
2374
|
+
buOrderId: { type: "string", description: "Smart copy bot order ID." },
|
|
2375
|
+
closeSellModel: { type: "string", enum: ["NOT_SELL", "TO_QUOTE", "TO_USDT"], description: "How to handle the base asset on close." }
|
|
2376
|
+
}
|
|
2377
|
+
},
|
|
2378
|
+
async handler(args, { client, config }) {
|
|
2379
|
+
if (config.readOnly) {
|
|
2380
|
+
throw new Error("Server is running in --read-only mode; bot smart_copy cancel is disabled.");
|
|
2381
|
+
}
|
|
2382
|
+
const buOrderId = asNonEmptyString3(args.buOrderId, "buOrderId");
|
|
2383
|
+
const body = { buOrderId };
|
|
2384
|
+
if (args.closeSellModel != null) {
|
|
2385
|
+
const closeSellModel = asNonEmptyString3(args.closeSellModel, "closeSellModel");
|
|
2386
|
+
assertEnum3(closeSellModel, "closeSellModel", ["NOT_SELL", "TO_QUOTE", "TO_USDT"]);
|
|
2387
|
+
body.closeSellModel = closeSellModel;
|
|
2388
|
+
}
|
|
2389
|
+
return (await client.signedPost("/api/v1/bot/orders/smartCopy/cancel", body)).data;
|
|
2390
|
+
}
|
|
2391
|
+
},
|
|
2392
|
+
// ── Signal ────────────────────────────────────────────────────────────────
|
|
2393
|
+
{
|
|
2394
|
+
name: "pionex_bot_signal_add_listener",
|
|
2395
|
+
module: "bot",
|
|
2396
|
+
isWrite: true,
|
|
2397
|
+
description: "Subscribe to a signal provider / add a signal listener. Endpoint: POST /api/v1/bot/signal/listener",
|
|
2398
|
+
inputSchema: {
|
|
2399
|
+
type: "object",
|
|
2400
|
+
additionalProperties: false,
|
|
2401
|
+
required: ["signalSourceId"],
|
|
2402
|
+
properties: {
|
|
2403
|
+
signalSourceId: { type: "string", description: "Signal provider ID to subscribe to." },
|
|
2404
|
+
listenMode: { type: "string", description: "Subscription mode." }
|
|
2405
|
+
}
|
|
2406
|
+
},
|
|
2407
|
+
async handler(args, { client, config }) {
|
|
2408
|
+
if (config.readOnly) {
|
|
2409
|
+
throw new Error("Server is running in --read-only mode; bot signal add_listener is disabled.");
|
|
2410
|
+
}
|
|
2411
|
+
const signalSourceId = asNonEmptyString3(args.signalSourceId, "signalSourceId");
|
|
2412
|
+
const body = { signalSourceId };
|
|
2413
|
+
if (args.listenMode != null) body.listenMode = String(args.listenMode);
|
|
2414
|
+
return (await client.signedPost("/api/v1/bot/signal/listener", body)).data;
|
|
2415
|
+
}
|
|
2245
2416
|
}
|
|
2246
2417
|
];
|
|
2247
2418
|
}
|