@pionex/pionex-trade-mcp 0.2.42 → 0.2.45

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
@@ -2242,6 +2242,214 @@ function registerBotTools() {
2242
2242
  const amount = asPositiveDecimalString2(args.amount, "amount");
2243
2243
  return (await client.signedPost("/api/v1/bot/orders/spotGrid/profit", { buOrderId, amount })).data;
2244
2244
  }
2245
+ },
2246
+ // ── Smart Copy ────────────────────────────────────────────────────────────
2247
+ {
2248
+ name: "pionex_bot_smart_copy_get_order",
2249
+ module: "bot",
2250
+ isWrite: false,
2251
+ description: "Get one smart copy bot order by buOrderId.",
2252
+ inputSchema: {
2253
+ type: "object",
2254
+ additionalProperties: false,
2255
+ properties: {
2256
+ buOrderId: { type: "string", description: "Smart copy bot order ID." }
2257
+ },
2258
+ required: ["buOrderId"]
2259
+ },
2260
+ async handler(args, { client }) {
2261
+ const buOrderId = asNonEmptyString3(args.buOrderId, "buOrderId");
2262
+ return (await client.signedGet("/api/v1/bot/orders/smartCopy/order", { buOrderId })).data;
2263
+ }
2264
+ },
2265
+ {
2266
+ name: "pionex_bot_smart_copy_check_params",
2267
+ module: "bot",
2268
+ isWrite: false,
2269
+ description: "Validate smart copy bot parameters before creating an order. Pass quote_investment='0' to get the allowed range only (no investment estimate). Returns max_investment, max_leverage, available_limit (and notional_limit when invest>0). Endpoint: POST /api/v1/bot/orders/smartCopy/checkParams",
2270
+ inputSchema: {
2271
+ type: "object",
2272
+ additionalProperties: false,
2273
+ required: ["base", "quote", "leverage", "quote_investment"],
2274
+ properties: {
2275
+ base: { type: "string", description: "Base currency (e.g. BTC)" },
2276
+ quote: { type: "string", description: "Quote currency (e.g. USDT)" },
2277
+ leverage: { type: "integer", description: "Leverage multiplier (e.g. 2)" },
2278
+ quote_investment: { type: "string", description: "Investment amount in quote currency; use '0' to get range only" },
2279
+ signal_type: { type: "string", description: "Optional; signal provider UUID to scope the check" },
2280
+ signal_param: { type: "string", description: "Optional; signal parameters as a JSON string" }
2281
+ }
2282
+ },
2283
+ async handler(args, { client }) {
2284
+ const base = asNonEmptyString3(args.base, "base");
2285
+ const quote = asNonEmptyString3(args.quote, "quote");
2286
+ const leverage = asPositiveInteger3(args.leverage, "leverage");
2287
+ const quote_investment = asNonEmptyString3(args.quote_investment, "quote_investment");
2288
+ const body = { base, quote, leverage, quote_investment };
2289
+ if (args.signal_type != null) body.signal_type = String(args.signal_type);
2290
+ if (args.signal_param != null) body.signal_param = String(args.signal_param);
2291
+ return (await client.signedPost("/api/v1/bot/orders/smartCopy/checkParams", body)).data;
2292
+ }
2293
+ },
2294
+ {
2295
+ name: "pionex_bot_smart_copy_create",
2296
+ module: "bot",
2297
+ isWrite: true,
2298
+ description: "Create a smart copy bot order. Required: base, quote, bu_order_data.quote_total_investment, bu_order_data.portfolio (each portfolio item needs base, signal_type, leverage). Returns buOrderId on success. Endpoint: POST /api/v1/bot/orders/smartCopy/create",
2299
+ inputSchema: {
2300
+ type: "object",
2301
+ additionalProperties: false,
2302
+ required: ["base", "quote", "bu_order_data"],
2303
+ properties: {
2304
+ base: { type: "string", description: "Base currency (e.g. BTC)" },
2305
+ quote: { type: "string", description: "Quote currency (e.g. USDT)" },
2306
+ bu_order_data: {
2307
+ type: "object",
2308
+ additionalProperties: false,
2309
+ required: ["quote_total_investment", "portfolio"],
2310
+ properties: {
2311
+ quote_total_investment: { type: "string", description: "Total investment in quote currency" },
2312
+ portfolio: {
2313
+ type: "array",
2314
+ items: {
2315
+ type: "object",
2316
+ additionalProperties: false,
2317
+ required: ["base", "signal_type", "leverage"],
2318
+ properties: {
2319
+ base: { type: "string", description: "Base currency for this signal" },
2320
+ signal_type: { type: "string", description: "Signal provider UUID" },
2321
+ leverage: { type: "integer", description: "Leverage multiplier" },
2322
+ percent: { type: "string", description: "Allocation fraction of total investment (e.g. '1' for 100%)" },
2323
+ signal_param: { type: "string", description: "Signal parameters as a JSON string" },
2324
+ profit_stop_ratio: { type: "string", description: "Take-profit ratio" },
2325
+ loss_stop_ratio: { type: "string", description: "Stop-loss ratio" }
2326
+ }
2327
+ },
2328
+ description: "Portfolio of signals to copy"
2329
+ },
2330
+ compound: { type: "boolean", description: "Enable compound reinvestment" },
2331
+ profit_stop_maker: { type: "boolean", description: "Enable profit stop maker" }
2332
+ }
2333
+ },
2334
+ key_id: { type: "string", description: "Optional key ID" },
2335
+ note: { type: "string", description: "Optional note" },
2336
+ copy_from: { type: "string", description: "Source bot order ID to copy settings from" },
2337
+ copy_type: { type: "string", description: "Copy type" },
2338
+ __dryRun: { type: "boolean", description: "If true, return resolved body without placing an order." }
2339
+ }
2340
+ },
2341
+ async handler(args, { client, config }) {
2342
+ if (config.readOnly) {
2343
+ throw new Error("Server is running in --read-only mode; bot smart_copy create is disabled.");
2344
+ }
2345
+ const base = asNonEmptyString3(args.base, "base");
2346
+ const quote = asNonEmptyString3(args.quote, "quote");
2347
+ const rawBuOrderData = asObject(args.bu_order_data, "bu_order_data");
2348
+ const quote_total_investment = asNonEmptyString3(rawBuOrderData.quote_total_investment, "bu_order_data.quote_total_investment");
2349
+ if (!Array.isArray(rawBuOrderData.portfolio) || rawBuOrderData.portfolio.length === 0) {
2350
+ throw new Error('Invalid "bu_order_data.portfolio": expected non-empty array.');
2351
+ }
2352
+ const portfolio = rawBuOrderData.portfolio.map((item, i) => {
2353
+ const p = {
2354
+ base: asNonEmptyString3(item.base, `portfolio[${i}].base`),
2355
+ signal_type: asNonEmptyString3(item.signal_type, `portfolio[${i}].signal_type`),
2356
+ leverage: asPositiveInteger3(item.leverage, `portfolio[${i}].leverage`)
2357
+ };
2358
+ if (item.percent != null) p.percent = asNonEmptyString3(item.percent, `portfolio[${i}].percent`);
2359
+ if (item.signal_param != null) p.signal_param = String(item.signal_param);
2360
+ if (item.profit_stop_ratio != null) p.profit_stop_ratio = String(item.profit_stop_ratio);
2361
+ if (item.loss_stop_ratio != null) p.loss_stop_ratio = String(item.loss_stop_ratio);
2362
+ return p;
2363
+ });
2364
+ const buOrderData = { quote_total_investment, portfolio };
2365
+ if (rawBuOrderData.compound != null) buOrderData.compound = asBoolean2(rawBuOrderData.compound, "bu_order_data.compound");
2366
+ if (rawBuOrderData.profit_stop_maker != null) buOrderData.profit_stop_maker = asBoolean2(rawBuOrderData.profit_stop_maker, "bu_order_data.profit_stop_maker");
2367
+ const body = { base, quote, bu_order_data: buOrderData };
2368
+ if (args.key_id != null) body.key_id = String(args.key_id);
2369
+ if (args.note != null) body.note = String(args.note);
2370
+ if (args.copy_from != null) body.copy_from = String(args.copy_from);
2371
+ if (args.copy_type != null) body.copy_type = String(args.copy_type);
2372
+ if (args.__dryRun === true) {
2373
+ return { dryRun: true, note: "No order was sent.", resolvedBody: body };
2374
+ }
2375
+ return (await client.signedPost("/api/v1/bot/orders/smartCopy/create", body)).data;
2376
+ }
2377
+ },
2378
+ {
2379
+ name: "pionex_bot_smart_copy_cancel",
2380
+ module: "bot",
2381
+ isWrite: true,
2382
+ description: "Cancel and close a smart copy bot order.",
2383
+ inputSchema: {
2384
+ type: "object",
2385
+ additionalProperties: false,
2386
+ required: ["bu_order_id"],
2387
+ properties: {
2388
+ bu_order_id: { type: "string", description: "Smart copy bot order ID." },
2389
+ close_note: { type: "string", description: "Optional close note." },
2390
+ convert_into_earn_coin: { type: "boolean", description: "Whether to convert remaining funds into earn coin." }
2391
+ }
2392
+ },
2393
+ async handler(args, { client, config }) {
2394
+ if (config.readOnly) {
2395
+ throw new Error("Server is running in --read-only mode; bot smart_copy cancel is disabled.");
2396
+ }
2397
+ const bu_order_id = asNonEmptyString3(args.bu_order_id, "bu_order_id");
2398
+ const body = { bu_order_id };
2399
+ if (args.close_note != null) body.close_note = String(args.close_note);
2400
+ if (args.convert_into_earn_coin != null) body.convert_into_earn_coin = asBoolean2(args.convert_into_earn_coin, "convert_into_earn_coin");
2401
+ return (await client.signedPost("/api/v1/bot/orders/smartCopy/cancel", body)).data;
2402
+ }
2403
+ },
2404
+ // ── Signal ────────────────────────────────────────────────────────────────
2405
+ {
2406
+ name: "pionex_bot_signal_add_listener",
2407
+ module: "bot",
2408
+ isWrite: true,
2409
+ description: "Push a trading signal to the Pionex signal platform (signal provider use). The platform forwards the signal to all smart copy bots subscribed to the given signalType. Use action='buy' to open a position and action='sell' to close it. Endpoint: POST /api/v1/bot/signal/listener",
2410
+ inputSchema: {
2411
+ type: "object",
2412
+ additionalProperties: false,
2413
+ required: ["signalType", "signalParam", "base", "quote", "time", "price", "data"],
2414
+ properties: {
2415
+ signalType: { type: "string", description: "Signal provider UUID." },
2416
+ signalParam: { type: "string", description: "Signal parameters as a JSON string (use '{}' for no extra params)." },
2417
+ base: { type: "string", description: "Base currency (e.g. BTC)." },
2418
+ quote: { type: "string", description: "Quote currency (e.g. USDT)." },
2419
+ time: { type: "string", description: "Signal timestamp in RFC 3339 format (e.g. '2024-01-01T12:00:00Z')." },
2420
+ price: { type: "string", description: "Current price at time of signal (e.g. '85000')." },
2421
+ data: {
2422
+ type: "object",
2423
+ additionalProperties: false,
2424
+ required: ["action", "position_size", "contracts"],
2425
+ properties: {
2426
+ action: { type: "string", enum: ["buy", "sell"], description: "'buy' to open a position, 'sell' to close." },
2427
+ position_size: { type: "string", description: "Target position size as a fraction (e.g. '1' = 100%)." },
2428
+ contracts: { type: "string", description: "Number of contracts." },
2429
+ direction: { type: "string", description: "Optional trade direction." }
2430
+ }
2431
+ }
2432
+ }
2433
+ },
2434
+ async handler(args, { client, config }) {
2435
+ if (config.readOnly) {
2436
+ throw new Error("Server is running in --read-only mode; bot signal add_listener is disabled.");
2437
+ }
2438
+ const signalType = asNonEmptyString3(args.signalType, "signalType");
2439
+ const signalParam = asNonEmptyString3(args.signalParam, "signalParam");
2440
+ const base = asNonEmptyString3(args.base, "base");
2441
+ const quote = asNonEmptyString3(args.quote, "quote");
2442
+ const time = asNonEmptyString3(args.time, "time");
2443
+ const price = asNonEmptyString3(args.price, "price");
2444
+ const rawData = asObject(args.data, "data");
2445
+ const action = asNonEmptyString3(rawData.action, "data.action");
2446
+ assertEnum3(action, "data.action", ["buy", "sell"]);
2447
+ const position_size = asNonEmptyString3(rawData.position_size, "data.position_size");
2448
+ const contracts = asNonEmptyString3(rawData.contracts, "data.contracts");
2449
+ const data = { action, position_size, contracts };
2450
+ if (rawData.direction != null) data.direction = String(rawData.direction);
2451
+ return (await client.signedPost("/api/v1/bot/signal/listener", { signalType, signalParam, base, quote, time, price, data })).data;
2452
+ }
2245
2453
  }
2246
2454
  ];
2247
2455
  }