@okx_ai/okx-trade-cli 1.2.5-beta.5 → 1.2.6-beta.1
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 +751 -559
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1019,9 +1019,9 @@ var OKX_CODE_BEHAVIORS = {
|
|
|
1019
1019
|
"50100": { retry: false, suggestion: "API key lacks required permissions. Update API key permissions." },
|
|
1020
1020
|
"50110": { retry: false, suggestion: "API key expired. Generate a new API key." },
|
|
1021
1021
|
// Insufficient funds / margin → do not retry
|
|
1022
|
-
"51008": { retry: false, suggestion: "Insufficient balance.
|
|
1023
|
-
"51119": { retry: false, suggestion: "Insufficient margin. Add margin
|
|
1024
|
-
"51127": { retry: false, suggestion: "Insufficient available margin. Reduce position or
|
|
1022
|
+
"51008": { retry: false, suggestion: "Insufficient balance in trading account. Check funding account via account_get_asset_balance \u2014 funds may be there. Use account_transfer (from=18, to=6) to move funds to trading account, then retry." },
|
|
1023
|
+
"51119": { retry: false, suggestion: "Insufficient margin. Add margin or check funding account (account_get_asset_balance). Transfer via account_transfer (from=18, to=6) if needed." },
|
|
1024
|
+
"51127": { retry: false, suggestion: "Insufficient available margin. Reduce position, add margin, or transfer from funding account (account_transfer from=18 to=6)." },
|
|
1025
1025
|
// Instrument unavailable → do not retry
|
|
1026
1026
|
"51021": { retry: false, suggestion: "Instrument does not exist. Check instId." },
|
|
1027
1027
|
"51022": { retry: false, suggestion: "Instrument not available for trading." },
|
|
@@ -1104,6 +1104,15 @@ var OkxRestClient = class {
|
|
|
1104
1104
|
rateLimit
|
|
1105
1105
|
});
|
|
1106
1106
|
}
|
|
1107
|
+
async publicPost(path42, body, rateLimit) {
|
|
1108
|
+
return this.request({
|
|
1109
|
+
method: "POST",
|
|
1110
|
+
path: path42,
|
|
1111
|
+
auth: "public",
|
|
1112
|
+
body,
|
|
1113
|
+
rateLimit
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1107
1116
|
async privatePost(path42, body, rateLimit) {
|
|
1108
1117
|
return this.request({
|
|
1109
1118
|
method: "POST",
|
|
@@ -1258,46 +1267,6 @@ var OkxRestClient = class {
|
|
|
1258
1267
|
return this.processResponse(rawText, response, elapsed, traceId, reqConfig, requestPath);
|
|
1259
1268
|
}
|
|
1260
1269
|
};
|
|
1261
|
-
var DEFAULT_SOURCE_TAG = "MCP";
|
|
1262
|
-
var OKX_SITES = {
|
|
1263
|
-
global: {
|
|
1264
|
-
label: "Global",
|
|
1265
|
-
apiBaseUrl: "https://www.okx.com",
|
|
1266
|
-
webUrl: "https://www.okx.com"
|
|
1267
|
-
},
|
|
1268
|
-
eea: {
|
|
1269
|
-
label: "EEA",
|
|
1270
|
-
apiBaseUrl: "https://eea.okx.com",
|
|
1271
|
-
webUrl: "https://my.okx.com"
|
|
1272
|
-
},
|
|
1273
|
-
us: {
|
|
1274
|
-
label: "US",
|
|
1275
|
-
apiBaseUrl: "https://app.okx.com",
|
|
1276
|
-
webUrl: "https://app.okx.com"
|
|
1277
|
-
}
|
|
1278
|
-
};
|
|
1279
|
-
var SITE_IDS = Object.keys(OKX_SITES);
|
|
1280
|
-
var BOT_SUB_MODULE_IDS = [
|
|
1281
|
-
"bot.grid",
|
|
1282
|
-
"bot.dca"
|
|
1283
|
-
];
|
|
1284
|
-
var BOT_DEFAULT_SUB_MODULES = ["bot.grid"];
|
|
1285
|
-
var EARN_SUB_MODULE_IDS = [
|
|
1286
|
-
"earn.savings",
|
|
1287
|
-
"earn.onchain",
|
|
1288
|
-
"earn.dcd"
|
|
1289
|
-
];
|
|
1290
|
-
var MODULES = [
|
|
1291
|
-
"market",
|
|
1292
|
-
"spot",
|
|
1293
|
-
"swap",
|
|
1294
|
-
"futures",
|
|
1295
|
-
"option",
|
|
1296
|
-
"account",
|
|
1297
|
-
...EARN_SUB_MODULE_IDS,
|
|
1298
|
-
...BOT_SUB_MODULE_IDS
|
|
1299
|
-
];
|
|
1300
|
-
var DEFAULT_MODULES = ["spot", "swap", "option", "account", ...BOT_DEFAULT_SUB_MODULES];
|
|
1301
1270
|
function asRecord(value) {
|
|
1302
1271
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1303
1272
|
return {};
|
|
@@ -1422,6 +1391,152 @@ function assertNotDemo(config, endpoint) {
|
|
|
1422
1391
|
);
|
|
1423
1392
|
}
|
|
1424
1393
|
}
|
|
1394
|
+
var INDICATOR_BARS = [
|
|
1395
|
+
"3m",
|
|
1396
|
+
"5m",
|
|
1397
|
+
"15m",
|
|
1398
|
+
"1H",
|
|
1399
|
+
"4H",
|
|
1400
|
+
"12Hutc",
|
|
1401
|
+
"1Dutc",
|
|
1402
|
+
"3Dutc",
|
|
1403
|
+
"1Wutc"
|
|
1404
|
+
];
|
|
1405
|
+
var INDICATOR_CODE_OVERRIDES = {
|
|
1406
|
+
"rainbow": "BTCRAINBOW",
|
|
1407
|
+
"range-filter": "RANGEFILTER",
|
|
1408
|
+
"stoch-rsi": "STOCHRSI",
|
|
1409
|
+
"pi-cycle-top": "PI_CYCLE_TOP",
|
|
1410
|
+
"pi-cycle-bottom": "PI_CYCLE_BOTTOM",
|
|
1411
|
+
// boll is an alias for bb; server supports BB not BOLL
|
|
1412
|
+
"boll": "BB"
|
|
1413
|
+
};
|
|
1414
|
+
function resolveIndicatorCode(name) {
|
|
1415
|
+
const lower = name.toLowerCase();
|
|
1416
|
+
return INDICATOR_CODE_OVERRIDES[lower] ?? name.toUpperCase().replace(/-/g, "_");
|
|
1417
|
+
}
|
|
1418
|
+
function readNumberArray(args, key) {
|
|
1419
|
+
const value = args[key];
|
|
1420
|
+
if (value === void 0 || value === null) return void 0;
|
|
1421
|
+
if (!Array.isArray(value)) return void 0;
|
|
1422
|
+
return value.map((item) => Number(item));
|
|
1423
|
+
}
|
|
1424
|
+
function registerIndicatorTools() {
|
|
1425
|
+
return [
|
|
1426
|
+
{
|
|
1427
|
+
name: "market_get_indicator",
|
|
1428
|
+
module: "market",
|
|
1429
|
+
description: "Get technical indicator values for an instrument (MA, EMA, RSI, MACD, BB, KDJ, SUPERTREND, AHR999, BTCRAINBOW, and more). No credentials required.",
|
|
1430
|
+
isWrite: false,
|
|
1431
|
+
inputSchema: {
|
|
1432
|
+
type: "object",
|
|
1433
|
+
properties: {
|
|
1434
|
+
instId: {
|
|
1435
|
+
type: "string",
|
|
1436
|
+
description: "Instrument ID, e.g. BTC-USDT"
|
|
1437
|
+
},
|
|
1438
|
+
indicator: {
|
|
1439
|
+
type: "string",
|
|
1440
|
+
description: "Indicator name (case-insensitive). Examples: ma, ema, rsi, macd, bb, kdj, supertrend, ahr999, rainbow, pi-cycle-top, pi-cycle-bottom, mayer, envelope, halftrend, alphatrend, pmax, waddah, tdi, qqe, range-filter"
|
|
1441
|
+
},
|
|
1442
|
+
bar: {
|
|
1443
|
+
type: "string",
|
|
1444
|
+
enum: [...INDICATOR_BARS],
|
|
1445
|
+
description: "Timeframe. Default: 1H"
|
|
1446
|
+
},
|
|
1447
|
+
params: {
|
|
1448
|
+
type: "array",
|
|
1449
|
+
items: { type: "number" },
|
|
1450
|
+
description: "Indicator parameters, e.g. [5, 20] for MA with periods 5 and 20"
|
|
1451
|
+
},
|
|
1452
|
+
returnList: {
|
|
1453
|
+
type: "boolean",
|
|
1454
|
+
description: "Return a historical list instead of the latest value only. Default: false"
|
|
1455
|
+
},
|
|
1456
|
+
limit: {
|
|
1457
|
+
type: "integer",
|
|
1458
|
+
minimum: 1,
|
|
1459
|
+
maximum: 100,
|
|
1460
|
+
description: "Number of historical records to return (only used when returnList=true). Default: 10"
|
|
1461
|
+
},
|
|
1462
|
+
backtestTime: {
|
|
1463
|
+
type: "integer",
|
|
1464
|
+
description: "Backtest timestamp in milliseconds. Omit for live (real-time) mode"
|
|
1465
|
+
}
|
|
1466
|
+
},
|
|
1467
|
+
required: ["instId", "indicator"]
|
|
1468
|
+
},
|
|
1469
|
+
handler: async (rawArgs, context) => {
|
|
1470
|
+
const args = asRecord(rawArgs);
|
|
1471
|
+
const instId = requireString(args, "instId");
|
|
1472
|
+
const indicator = requireString(args, "indicator");
|
|
1473
|
+
const bar = readString(args, "bar") ?? "1H";
|
|
1474
|
+
const params = readNumberArray(args, "params");
|
|
1475
|
+
const returnList = readBoolean(args, "returnList") ?? false;
|
|
1476
|
+
const limit = readNumber(args, "limit") ?? 10;
|
|
1477
|
+
const backtestTime = readNumber(args, "backtestTime");
|
|
1478
|
+
const apiCode = resolveIndicatorCode(indicator);
|
|
1479
|
+
const indicatorConfig = compactObject({
|
|
1480
|
+
paramList: params && params.length > 0 ? params : void 0,
|
|
1481
|
+
returnList,
|
|
1482
|
+
limit: returnList ? limit : void 0
|
|
1483
|
+
});
|
|
1484
|
+
const body = compactObject({
|
|
1485
|
+
instId,
|
|
1486
|
+
timeframes: [bar],
|
|
1487
|
+
indicators: { [apiCode]: indicatorConfig },
|
|
1488
|
+
backtestTime
|
|
1489
|
+
});
|
|
1490
|
+
const response = await context.client.publicPost(
|
|
1491
|
+
"/api/v5/aigc/mcp/indicators",
|
|
1492
|
+
body,
|
|
1493
|
+
publicRateLimit("market_get_indicator", 5)
|
|
1494
|
+
);
|
|
1495
|
+
return normalizeResponse(response);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
];
|
|
1499
|
+
}
|
|
1500
|
+
var DEFAULT_SOURCE_TAG = "MCP";
|
|
1501
|
+
var OKX_SITES = {
|
|
1502
|
+
global: {
|
|
1503
|
+
label: "Global",
|
|
1504
|
+
apiBaseUrl: "https://www.okx.com",
|
|
1505
|
+
webUrl: "https://www.okx.com"
|
|
1506
|
+
},
|
|
1507
|
+
eea: {
|
|
1508
|
+
label: "EEA",
|
|
1509
|
+
apiBaseUrl: "https://eea.okx.com",
|
|
1510
|
+
webUrl: "https://my.okx.com"
|
|
1511
|
+
},
|
|
1512
|
+
us: {
|
|
1513
|
+
label: "US",
|
|
1514
|
+
apiBaseUrl: "https://app.okx.com",
|
|
1515
|
+
webUrl: "https://app.okx.com"
|
|
1516
|
+
}
|
|
1517
|
+
};
|
|
1518
|
+
var SITE_IDS = Object.keys(OKX_SITES);
|
|
1519
|
+
var BOT_SUB_MODULE_IDS = [
|
|
1520
|
+
"bot.grid",
|
|
1521
|
+
"bot.dca"
|
|
1522
|
+
];
|
|
1523
|
+
var BOT_DEFAULT_SUB_MODULES = ["bot.grid"];
|
|
1524
|
+
var EARN_SUB_MODULE_IDS = [
|
|
1525
|
+
"earn.savings",
|
|
1526
|
+
"earn.onchain",
|
|
1527
|
+
"earn.dcd"
|
|
1528
|
+
];
|
|
1529
|
+
var MODULES = [
|
|
1530
|
+
"market",
|
|
1531
|
+
"spot",
|
|
1532
|
+
"swap",
|
|
1533
|
+
"futures",
|
|
1534
|
+
"option",
|
|
1535
|
+
"account",
|
|
1536
|
+
...EARN_SUB_MODULE_IDS,
|
|
1537
|
+
...BOT_SUB_MODULE_IDS
|
|
1538
|
+
];
|
|
1539
|
+
var DEFAULT_MODULES = ["spot", "swap", "option", "account", ...BOT_DEFAULT_SUB_MODULES];
|
|
1425
1540
|
function registerAccountTools() {
|
|
1426
1541
|
return [
|
|
1427
1542
|
{
|
|
@@ -3196,7 +3311,7 @@ function registerEarnTools() {
|
|
|
3196
3311
|
{
|
|
3197
3312
|
name: "earn_get_savings_balance",
|
|
3198
3313
|
module: "earn.savings",
|
|
3199
|
-
description: "Get Simple Earn (savings/flexible earn) balance. Returns current holdings for all currencies or a specific one. To show market rates alongside balance (\u5E02\u573A\u5747\u5229\u7387), call earn_get_lending_rate_history \u2014 do NOT use earn_get_lending_rate_summary for this purpose.
|
|
3314
|
+
description: "Get Simple Earn (savings/flexible earn) balance. Returns current holdings for all currencies or a specific one. To show market rates alongside balance (\u5E02\u573A\u5747\u5229\u7387), call earn_get_lending_rate_history \u2014 do NOT use earn_get_lending_rate_summary for this purpose.",
|
|
3200
3315
|
isWrite: false,
|
|
3201
3316
|
inputSchema: {
|
|
3202
3317
|
type: "object",
|
|
@@ -3220,7 +3335,7 @@ function registerEarnTools() {
|
|
|
3220
3335
|
{
|
|
3221
3336
|
name: "earn_savings_purchase",
|
|
3222
3337
|
module: "earn.savings",
|
|
3223
|
-
description: "Purchase Simple Earn (savings/flexible earn). [CAUTION] Moves real funds into earn product.
|
|
3338
|
+
description: "Purchase Simple Earn (savings/flexible earn). [CAUTION] Moves real funds into earn product.",
|
|
3224
3339
|
isWrite: true,
|
|
3225
3340
|
inputSchema: {
|
|
3226
3341
|
type: "object",
|
|
@@ -3259,7 +3374,7 @@ function registerEarnTools() {
|
|
|
3259
3374
|
{
|
|
3260
3375
|
name: "earn_savings_redeem",
|
|
3261
3376
|
module: "earn.savings",
|
|
3262
|
-
description: "Redeem Simple Earn (savings/flexible earn). [CAUTION] Withdraws funds from earn product.
|
|
3377
|
+
description: "Redeem Simple Earn (savings/flexible earn). [CAUTION] Withdraws funds from earn product.",
|
|
3263
3378
|
isWrite: true,
|
|
3264
3379
|
inputSchema: {
|
|
3265
3380
|
type: "object",
|
|
@@ -3293,7 +3408,7 @@ function registerEarnTools() {
|
|
|
3293
3408
|
{
|
|
3294
3409
|
name: "earn_set_lending_rate",
|
|
3295
3410
|
module: "earn.savings",
|
|
3296
|
-
description: "Set lending rate for Simple Earn. [CAUTION] Changes your lending rate preference.
|
|
3411
|
+
description: "Set lending rate for Simple Earn. [CAUTION] Changes your lending rate preference.",
|
|
3297
3412
|
isWrite: true,
|
|
3298
3413
|
inputSchema: {
|
|
3299
3414
|
type: "object",
|
|
@@ -3326,7 +3441,7 @@ function registerEarnTools() {
|
|
|
3326
3441
|
{
|
|
3327
3442
|
name: "earn_get_lending_history",
|
|
3328
3443
|
module: "earn.savings",
|
|
3329
|
-
description: "Get market lending rate history for Simple Earn. Use this tool to query market lending rates. Returns market lending records with amount, rate, and earnings data.
|
|
3444
|
+
description: "Get market lending rate history for Simple Earn. Use this tool to query market lending rates. Returns market lending records with amount, rate, and earnings data.",
|
|
3330
3445
|
isWrite: false,
|
|
3331
3446
|
inputSchema: {
|
|
3332
3447
|
type: "object",
|
|
@@ -3367,7 +3482,7 @@ function registerEarnTools() {
|
|
|
3367
3482
|
{
|
|
3368
3483
|
name: "earn_get_lending_rate_summary",
|
|
3369
3484
|
module: "earn.savings",
|
|
3370
|
-
description: "Get coin lending market rate summary. NOT related to Simple Earn.
|
|
3485
|
+
description: "Get coin lending market rate summary. NOT related to Simple Earn. Use this to query the lending/borrowing market rates (\u501F\u5E01\u5E02\u573A\u5229\u7387). Returns aggregate overview: average rate (avgRate), estimated next-cycle rate (estRate), previous-cycle rate (preRate), and available lending amounts.",
|
|
3371
3486
|
isWrite: false,
|
|
3372
3487
|
inputSchema: {
|
|
3373
3488
|
type: "object",
|
|
@@ -3391,7 +3506,7 @@ function registerEarnTools() {
|
|
|
3391
3506
|
{
|
|
3392
3507
|
name: "earn_get_lending_rate_history",
|
|
3393
3508
|
module: "earn.savings",
|
|
3394
|
-
description: "Query Simple Earn lending rates.
|
|
3509
|
+
description: "Query Simple Earn lending rates. Use this tool when the user asks about current or historical lending rates for Simple Earn, or when displaying savings balance with market rate context (\u5E02\u573A\u5747\u5229\u7387). Returns actual settled lending rate records (lendingRate field) with timestamps, ordered newest-first.",
|
|
3395
3510
|
isWrite: false,
|
|
3396
3511
|
inputSchema: {
|
|
3397
3512
|
type: "object",
|
|
@@ -3439,22 +3554,22 @@ function registerOnchainEarnTools() {
|
|
|
3439
3554
|
{
|
|
3440
3555
|
name: "onchain_earn_get_offers",
|
|
3441
3556
|
module: "earn.onchain",
|
|
3442
|
-
description: "
|
|
3557
|
+
description: "List staking/DeFi products with APY, terms, and limits. Always show protocol name (protocol field) and earnings currency (earningData[].ccy) when presenting results.",
|
|
3443
3558
|
isWrite: false,
|
|
3444
3559
|
inputSchema: {
|
|
3445
3560
|
type: "object",
|
|
3446
3561
|
properties: {
|
|
3447
3562
|
productId: {
|
|
3448
3563
|
type: "string",
|
|
3449
|
-
description: "
|
|
3564
|
+
description: "Product ID filter."
|
|
3450
3565
|
},
|
|
3451
3566
|
protocolType: {
|
|
3452
3567
|
type: "string",
|
|
3453
|
-
description: "
|
|
3568
|
+
description: "staking|defi"
|
|
3454
3569
|
},
|
|
3455
3570
|
ccy: {
|
|
3456
3571
|
type: "string",
|
|
3457
|
-
description: "
|
|
3572
|
+
description: "e.g. ETH"
|
|
3458
3573
|
}
|
|
3459
3574
|
}
|
|
3460
3575
|
},
|
|
@@ -3478,34 +3593,34 @@ function registerOnchainEarnTools() {
|
|
|
3478
3593
|
{
|
|
3479
3594
|
name: "onchain_earn_purchase",
|
|
3480
3595
|
module: "earn.onchain",
|
|
3481
|
-
description: "
|
|
3596
|
+
description: "Invest in a staking/DeFi product. [CAUTION] Moves real funds. Not available in demo mode.",
|
|
3482
3597
|
isWrite: true,
|
|
3483
3598
|
inputSchema: {
|
|
3484
3599
|
type: "object",
|
|
3485
3600
|
properties: {
|
|
3486
3601
|
productId: {
|
|
3487
3602
|
type: "string",
|
|
3488
|
-
description: "Product ID
|
|
3603
|
+
description: "Product ID"
|
|
3489
3604
|
},
|
|
3490
3605
|
investData: {
|
|
3491
3606
|
type: "array",
|
|
3492
|
-
description: "
|
|
3607
|
+
description: "Array of {ccy, amt} to invest.",
|
|
3493
3608
|
items: {
|
|
3494
3609
|
type: "object",
|
|
3495
3610
|
properties: {
|
|
3496
|
-
ccy: { type: "string", description: "
|
|
3497
|
-
amt: { type: "string"
|
|
3611
|
+
ccy: { type: "string", description: "e.g. ETH" },
|
|
3612
|
+
amt: { type: "string" }
|
|
3498
3613
|
},
|
|
3499
3614
|
required: ["ccy", "amt"]
|
|
3500
3615
|
}
|
|
3501
3616
|
},
|
|
3502
3617
|
term: {
|
|
3503
3618
|
type: "string",
|
|
3504
|
-
description: "Investment term in days
|
|
3619
|
+
description: "Investment term in days, required for fixed-term products."
|
|
3505
3620
|
},
|
|
3506
3621
|
tag: {
|
|
3507
3622
|
type: "string",
|
|
3508
|
-
description: "Order tag
|
|
3623
|
+
description: "Order tag."
|
|
3509
3624
|
}
|
|
3510
3625
|
},
|
|
3511
3626
|
required: ["productId", "investData"]
|
|
@@ -3532,22 +3647,22 @@ function registerOnchainEarnTools() {
|
|
|
3532
3647
|
{
|
|
3533
3648
|
name: "onchain_earn_redeem",
|
|
3534
3649
|
module: "earn.onchain",
|
|
3535
|
-
description: "Redeem
|
|
3650
|
+
description: "Redeem a staking/DeFi investment. [CAUTION] Some products have lock periods, early redemption may incur penalties. Not available in demo mode.",
|
|
3536
3651
|
isWrite: true,
|
|
3537
3652
|
inputSchema: {
|
|
3538
3653
|
type: "object",
|
|
3539
3654
|
properties: {
|
|
3540
3655
|
ordId: {
|
|
3541
3656
|
type: "string",
|
|
3542
|
-
description: "Order ID
|
|
3657
|
+
description: "Order ID"
|
|
3543
3658
|
},
|
|
3544
3659
|
protocolType: {
|
|
3545
3660
|
type: "string",
|
|
3546
|
-
description: "
|
|
3661
|
+
description: "staking|defi"
|
|
3547
3662
|
},
|
|
3548
3663
|
allowEarlyRedeem: {
|
|
3549
3664
|
type: "boolean",
|
|
3550
|
-
description: "Allow early
|
|
3665
|
+
description: "Allow early exit for fixed-term products, may incur penalties. Default: false."
|
|
3551
3666
|
}
|
|
3552
3667
|
},
|
|
3553
3668
|
required: ["ordId", "protocolType"]
|
|
@@ -3573,18 +3688,18 @@ function registerOnchainEarnTools() {
|
|
|
3573
3688
|
{
|
|
3574
3689
|
name: "onchain_earn_cancel",
|
|
3575
3690
|
module: "earn.onchain",
|
|
3576
|
-
description: "Cancel pending
|
|
3691
|
+
description: "Cancel a pending staking/DeFi purchase order. [CAUTION] Not available in demo mode.",
|
|
3577
3692
|
isWrite: true,
|
|
3578
3693
|
inputSchema: {
|
|
3579
3694
|
type: "object",
|
|
3580
3695
|
properties: {
|
|
3581
3696
|
ordId: {
|
|
3582
3697
|
type: "string",
|
|
3583
|
-
description: "Order ID
|
|
3698
|
+
description: "Order ID"
|
|
3584
3699
|
},
|
|
3585
3700
|
protocolType: {
|
|
3586
3701
|
type: "string",
|
|
3587
|
-
description: "
|
|
3702
|
+
description: "staking|defi"
|
|
3588
3703
|
}
|
|
3589
3704
|
},
|
|
3590
3705
|
required: ["ordId", "protocolType"]
|
|
@@ -3609,26 +3724,26 @@ function registerOnchainEarnTools() {
|
|
|
3609
3724
|
{
|
|
3610
3725
|
name: "onchain_earn_get_active_orders",
|
|
3611
3726
|
module: "earn.onchain",
|
|
3612
|
-
description: "
|
|
3727
|
+
description: "List current active staking/DeFi investments.",
|
|
3613
3728
|
isWrite: false,
|
|
3614
3729
|
inputSchema: {
|
|
3615
3730
|
type: "object",
|
|
3616
3731
|
properties: {
|
|
3617
3732
|
productId: {
|
|
3618
3733
|
type: "string",
|
|
3619
|
-
description: "
|
|
3734
|
+
description: "Product ID filter."
|
|
3620
3735
|
},
|
|
3621
3736
|
protocolType: {
|
|
3622
3737
|
type: "string",
|
|
3623
|
-
description: "
|
|
3738
|
+
description: "staking|defi"
|
|
3624
3739
|
},
|
|
3625
3740
|
ccy: {
|
|
3626
3741
|
type: "string",
|
|
3627
|
-
description: "
|
|
3742
|
+
description: "e.g. ETH"
|
|
3628
3743
|
},
|
|
3629
3744
|
state: {
|
|
3630
3745
|
type: "string",
|
|
3631
|
-
description: "
|
|
3746
|
+
description: "8=pending, 13=cancelling, 9=onchain, 1=earning, 2=redeeming"
|
|
3632
3747
|
}
|
|
3633
3748
|
}
|
|
3634
3749
|
},
|
|
@@ -3653,34 +3768,34 @@ function registerOnchainEarnTools() {
|
|
|
3653
3768
|
{
|
|
3654
3769
|
name: "onchain_earn_get_order_history",
|
|
3655
3770
|
module: "earn.onchain",
|
|
3656
|
-
description: "
|
|
3771
|
+
description: "List past staking/DeFi orders including redeemed ones.",
|
|
3657
3772
|
isWrite: false,
|
|
3658
3773
|
inputSchema: {
|
|
3659
3774
|
type: "object",
|
|
3660
3775
|
properties: {
|
|
3661
3776
|
productId: {
|
|
3662
3777
|
type: "string",
|
|
3663
|
-
description: "
|
|
3778
|
+
description: "Product ID filter."
|
|
3664
3779
|
},
|
|
3665
3780
|
protocolType: {
|
|
3666
3781
|
type: "string",
|
|
3667
|
-
description: "
|
|
3782
|
+
description: "staking|defi"
|
|
3668
3783
|
},
|
|
3669
3784
|
ccy: {
|
|
3670
3785
|
type: "string",
|
|
3671
|
-
description: "
|
|
3786
|
+
description: "e.g. ETH"
|
|
3672
3787
|
},
|
|
3673
3788
|
after: {
|
|
3674
3789
|
type: "string",
|
|
3675
|
-
description: "
|
|
3790
|
+
description: "Cursor: results older than this order ID."
|
|
3676
3791
|
},
|
|
3677
3792
|
before: {
|
|
3678
3793
|
type: "string",
|
|
3679
|
-
description: "
|
|
3794
|
+
description: "Cursor: results newer than this order ID."
|
|
3680
3795
|
},
|
|
3681
3796
|
limit: {
|
|
3682
3797
|
type: "string",
|
|
3683
|
-
description: "Max results
|
|
3798
|
+
description: "Max results (default 100, max 100)."
|
|
3684
3799
|
}
|
|
3685
3800
|
}
|
|
3686
3801
|
},
|
|
@@ -4059,7 +4174,12 @@ function buildContractTradeTools(cfg) {
|
|
|
4059
4174
|
},
|
|
4060
4175
|
sz: {
|
|
4061
4176
|
type: "string",
|
|
4062
|
-
description: "Contracts count
|
|
4177
|
+
description: "Contracts count by default. Set tgtCcy=quote_ccy to use USDT amount instead."
|
|
4178
|
+
},
|
|
4179
|
+
tgtCcy: {
|
|
4180
|
+
type: "string",
|
|
4181
|
+
enum: ["base_ccy", "quote_ccy"],
|
|
4182
|
+
description: "Size unit. base_ccy(default): sz in contracts, quote_ccy: sz in USDT"
|
|
4063
4183
|
},
|
|
4064
4184
|
px: { type: "string", description: "Required for limit/post_only/fok/ioc" },
|
|
4065
4185
|
reduceOnly: {
|
|
@@ -4087,6 +4207,7 @@ function buildContractTradeTools(cfg) {
|
|
|
4087
4207
|
posSide: readString(args, "posSide"),
|
|
4088
4208
|
ordType: requireString(args, "ordType"),
|
|
4089
4209
|
sz: requireString(args, "sz"),
|
|
4210
|
+
tgtCcy: readString(args, "tgtCcy"),
|
|
4090
4211
|
px: readString(args, "px"),
|
|
4091
4212
|
reduceOnly: typeof reduceOnly === "boolean" ? String(reduceOnly) : void 0,
|
|
4092
4213
|
clOrdId: readString(args, "clOrdId"),
|
|
@@ -5715,7 +5836,7 @@ function registerSpotTradeTools() {
|
|
|
5715
5836
|
{
|
|
5716
5837
|
name: "spot_place_order",
|
|
5717
5838
|
module: "spot",
|
|
5718
|
-
description: "Place a spot order.
|
|
5839
|
+
description: "Place a spot order. Attach TP/SL via tpTriggerPx/slTriggerPx. [CAUTION] Executes real trades.",
|
|
5719
5840
|
isWrite: true,
|
|
5720
5841
|
inputSchema: {
|
|
5721
5842
|
type: "object",
|
|
@@ -5727,7 +5848,7 @@ function registerSpotTradeTools() {
|
|
|
5727
5848
|
tdMode: {
|
|
5728
5849
|
type: "string",
|
|
5729
5850
|
enum: ["cash", "cross", "isolated"],
|
|
5730
|
-
description: "cash=regular spot
|
|
5851
|
+
description: "cash=regular spot, cross/isolated=margin"
|
|
5731
5852
|
},
|
|
5732
5853
|
side: {
|
|
5733
5854
|
type: "string",
|
|
@@ -5740,7 +5861,12 @@ function registerSpotTradeTools() {
|
|
|
5740
5861
|
},
|
|
5741
5862
|
sz: {
|
|
5742
5863
|
type: "string",
|
|
5743
|
-
description: "Buy market: quote amount
|
|
5864
|
+
description: "Buy market: quote amount, all others: base amount"
|
|
5865
|
+
},
|
|
5866
|
+
tgtCcy: {
|
|
5867
|
+
type: "string",
|
|
5868
|
+
enum: ["base_ccy", "quote_ccy"],
|
|
5869
|
+
description: "Size unit. base_ccy(default): sz in base (e.g. BTC), quote_ccy: sz in quote (e.g. USDT)"
|
|
5744
5870
|
},
|
|
5745
5871
|
px: {
|
|
5746
5872
|
type: "string",
|
|
@@ -5752,19 +5878,19 @@ function registerSpotTradeTools() {
|
|
|
5752
5878
|
},
|
|
5753
5879
|
tpTriggerPx: {
|
|
5754
5880
|
type: "string",
|
|
5755
|
-
description: "TP trigger price
|
|
5881
|
+
description: "TP trigger price"
|
|
5756
5882
|
},
|
|
5757
5883
|
tpOrdPx: {
|
|
5758
5884
|
type: "string",
|
|
5759
|
-
description: "TP order price
|
|
5885
|
+
description: "TP order price, -1=market"
|
|
5760
5886
|
},
|
|
5761
5887
|
slTriggerPx: {
|
|
5762
5888
|
type: "string",
|
|
5763
|
-
description: "SL trigger price
|
|
5889
|
+
description: "SL trigger price"
|
|
5764
5890
|
},
|
|
5765
5891
|
slOrdPx: {
|
|
5766
5892
|
type: "string",
|
|
5767
|
-
description: "SL order price
|
|
5893
|
+
description: "SL order price, -1=market"
|
|
5768
5894
|
}
|
|
5769
5895
|
},
|
|
5770
5896
|
required: ["instId", "tdMode", "side", "ordType", "sz"]
|
|
@@ -5780,6 +5906,7 @@ function registerSpotTradeTools() {
|
|
|
5780
5906
|
side: requireString(args, "side"),
|
|
5781
5907
|
ordType: requireString(args, "ordType"),
|
|
5782
5908
|
sz: requireString(args, "sz"),
|
|
5909
|
+
tgtCcy: readString(args, "tgtCcy"),
|
|
5783
5910
|
px: readString(args, "px"),
|
|
5784
5911
|
clOrdId: readString(args, "clOrdId"),
|
|
5785
5912
|
tag: context.config.sourceTag,
|
|
@@ -5793,7 +5920,7 @@ function registerSpotTradeTools() {
|
|
|
5793
5920
|
{
|
|
5794
5921
|
name: "spot_cancel_order",
|
|
5795
5922
|
module: "spot",
|
|
5796
|
-
description: "Cancel an unfilled spot order
|
|
5923
|
+
description: "Cancel an unfilled spot order.",
|
|
5797
5924
|
isWrite: true,
|
|
5798
5925
|
inputSchema: {
|
|
5799
5926
|
type: "object",
|
|
@@ -5806,8 +5933,7 @@ function registerSpotTradeTools() {
|
|
|
5806
5933
|
type: "string"
|
|
5807
5934
|
},
|
|
5808
5935
|
clOrdId: {
|
|
5809
|
-
type: "string"
|
|
5810
|
-
description: "Client order ID"
|
|
5936
|
+
type: "string"
|
|
5811
5937
|
}
|
|
5812
5938
|
},
|
|
5813
5939
|
required: ["instId"]
|
|
@@ -5839,24 +5965,22 @@ function registerSpotTradeTools() {
|
|
|
5839
5965
|
description: "e.g. BTC-USDT"
|
|
5840
5966
|
},
|
|
5841
5967
|
ordId: {
|
|
5842
|
-
type: "string"
|
|
5843
|
-
description: "Order ID"
|
|
5968
|
+
type: "string"
|
|
5844
5969
|
},
|
|
5845
5970
|
clOrdId: {
|
|
5846
|
-
type: "string"
|
|
5847
|
-
description: "Client order ID"
|
|
5971
|
+
type: "string"
|
|
5848
5972
|
},
|
|
5849
5973
|
newSz: {
|
|
5850
5974
|
type: "string",
|
|
5851
|
-
description: "New
|
|
5975
|
+
description: "New size in base currency"
|
|
5852
5976
|
},
|
|
5853
5977
|
newPx: {
|
|
5854
5978
|
type: "string",
|
|
5855
|
-
description: "New
|
|
5979
|
+
description: "New price"
|
|
5856
5980
|
},
|
|
5857
5981
|
newClOrdId: {
|
|
5858
5982
|
type: "string",
|
|
5859
|
-
description: "
|
|
5983
|
+
description: "Replacement client order ID"
|
|
5860
5984
|
}
|
|
5861
5985
|
},
|
|
5862
5986
|
required: ["instId"]
|
|
@@ -5881,15 +6005,14 @@ function registerSpotTradeTools() {
|
|
|
5881
6005
|
{
|
|
5882
6006
|
name: "spot_get_orders",
|
|
5883
6007
|
module: "spot",
|
|
5884
|
-
description: "Query spot
|
|
6008
|
+
description: "Query spot orders. status: open(active)|history(7d)|archive(3mo).",
|
|
5885
6009
|
isWrite: false,
|
|
5886
6010
|
inputSchema: {
|
|
5887
6011
|
type: "object",
|
|
5888
6012
|
properties: {
|
|
5889
6013
|
status: {
|
|
5890
6014
|
type: "string",
|
|
5891
|
-
enum: ["open", "history", "archive"]
|
|
5892
|
-
description: "open=active, history=7d, archive=3mo"
|
|
6015
|
+
enum: ["open", "history", "archive"]
|
|
5893
6016
|
},
|
|
5894
6017
|
instId: {
|
|
5895
6018
|
type: "string",
|
|
@@ -5905,11 +6028,11 @@ function registerSpotTradeTools() {
|
|
|
5905
6028
|
},
|
|
5906
6029
|
after: {
|
|
5907
6030
|
type: "string",
|
|
5908
|
-
description: "
|
|
6031
|
+
description: "Cursor: older than this order ID"
|
|
5909
6032
|
},
|
|
5910
6033
|
before: {
|
|
5911
6034
|
type: "string",
|
|
5912
|
-
description: "
|
|
6035
|
+
description: "Cursor: newer than this order ID"
|
|
5913
6036
|
},
|
|
5914
6037
|
begin: {
|
|
5915
6038
|
type: "string",
|
|
@@ -5950,7 +6073,7 @@ function registerSpotTradeTools() {
|
|
|
5950
6073
|
{
|
|
5951
6074
|
name: "spot_place_algo_order",
|
|
5952
6075
|
module: "spot",
|
|
5953
|
-
description: "Place a spot algo order: TP/SL (conditional/oco) or trailing stop (move_order_stop).
|
|
6076
|
+
description: "Place a spot algo order: TP/SL (conditional/oco) or trailing stop (move_order_stop). [CAUTION] Executes real trades.",
|
|
5954
6077
|
isWrite: true,
|
|
5955
6078
|
inputSchema: {
|
|
5956
6079
|
type: "object",
|
|
@@ -5962,7 +6085,7 @@ function registerSpotTradeTools() {
|
|
|
5962
6085
|
tdMode: {
|
|
5963
6086
|
type: "string",
|
|
5964
6087
|
enum: ["cash", "cross", "isolated"],
|
|
5965
|
-
description: "cash
|
|
6088
|
+
description: "cash(default)=spot, cross/isolated=margin"
|
|
5966
6089
|
},
|
|
5967
6090
|
side: {
|
|
5968
6091
|
type: "string",
|
|
@@ -5971,7 +6094,7 @@ function registerSpotTradeTools() {
|
|
|
5971
6094
|
ordType: {
|
|
5972
6095
|
type: "string",
|
|
5973
6096
|
enum: ["conditional", "oco", "move_order_stop"],
|
|
5974
|
-
description: "conditional=single TP/SL
|
|
6097
|
+
description: "conditional=single TP/SL, oco=TP+SL pair, move_order_stop=trailing stop"
|
|
5975
6098
|
},
|
|
5976
6099
|
sz: {
|
|
5977
6100
|
type: "string",
|
|
@@ -5983,7 +6106,7 @@ function registerSpotTradeTools() {
|
|
|
5983
6106
|
},
|
|
5984
6107
|
tpOrdPx: {
|
|
5985
6108
|
type: "string",
|
|
5986
|
-
description: "TP order price
|
|
6109
|
+
description: "TP order price, -1=market (conditional/oco only)"
|
|
5987
6110
|
},
|
|
5988
6111
|
slTriggerPx: {
|
|
5989
6112
|
type: "string",
|
|
@@ -5991,19 +6114,19 @@ function registerSpotTradeTools() {
|
|
|
5991
6114
|
},
|
|
5992
6115
|
slOrdPx: {
|
|
5993
6116
|
type: "string",
|
|
5994
|
-
description: "SL order price
|
|
6117
|
+
description: "SL order price, -1=market (conditional/oco only)"
|
|
5995
6118
|
},
|
|
5996
6119
|
callbackRatio: {
|
|
5997
6120
|
type: "string",
|
|
5998
|
-
description: "Callback ratio
|
|
6121
|
+
description: "Callback ratio e.g. 0.01=1%, use ratio or spread (move_order_stop only)"
|
|
5999
6122
|
},
|
|
6000
6123
|
callbackSpread: {
|
|
6001
6124
|
type: "string",
|
|
6002
|
-
description: "Callback spread in price units
|
|
6125
|
+
description: "Callback spread in price units, use ratio or spread (move_order_stop only)"
|
|
6003
6126
|
},
|
|
6004
6127
|
activePx: {
|
|
6005
6128
|
type: "string",
|
|
6006
|
-
description: "Activation price
|
|
6129
|
+
description: "Activation price, trailing starts when market hits this (move_order_stop only)"
|
|
6007
6130
|
}
|
|
6008
6131
|
},
|
|
6009
6132
|
required: ["instId", "side", "ordType", "sz"]
|
|
@@ -6041,12 +6164,12 @@ function registerSpotTradeTools() {
|
|
|
6041
6164
|
type: "object",
|
|
6042
6165
|
properties: {
|
|
6043
6166
|
instId: { type: "string", description: "e.g. BTC-USDT" },
|
|
6044
|
-
algoId: { type: "string"
|
|
6045
|
-
newSz: { type: "string", description: "New
|
|
6167
|
+
algoId: { type: "string" },
|
|
6168
|
+
newSz: { type: "string", description: "New size in base currency" },
|
|
6046
6169
|
newTpTriggerPx: { type: "string", description: "New TP trigger price" },
|
|
6047
|
-
newTpOrdPx: { type: "string", description: "New TP order price
|
|
6170
|
+
newTpOrdPx: { type: "string", description: "New TP order price, -1=market" },
|
|
6048
6171
|
newSlTriggerPx: { type: "string", description: "New SL trigger price" },
|
|
6049
|
-
newSlOrdPx: { type: "string", description: "New SL order price
|
|
6172
|
+
newSlOrdPx: { type: "string", description: "New SL order price, -1=market" }
|
|
6050
6173
|
},
|
|
6051
6174
|
required: ["instId", "algoId"]
|
|
6052
6175
|
},
|
|
@@ -6081,8 +6204,7 @@ function registerSpotTradeTools() {
|
|
|
6081
6204
|
description: "e.g. BTC-USDT"
|
|
6082
6205
|
},
|
|
6083
6206
|
algoId: {
|
|
6084
|
-
type: "string"
|
|
6085
|
-
description: "Algo order ID"
|
|
6207
|
+
type: "string"
|
|
6086
6208
|
}
|
|
6087
6209
|
},
|
|
6088
6210
|
required: ["instId", "algoId"]
|
|
@@ -6113,7 +6235,7 @@ function registerSpotTradeTools() {
|
|
|
6113
6235
|
status: {
|
|
6114
6236
|
type: "string",
|
|
6115
6237
|
enum: ["pending", "history"],
|
|
6116
|
-
description: "pending=active (default)
|
|
6238
|
+
description: "pending=active (default), history=completed"
|
|
6117
6239
|
},
|
|
6118
6240
|
instId: {
|
|
6119
6241
|
type: "string",
|
|
@@ -6122,15 +6244,15 @@ function registerSpotTradeTools() {
|
|
|
6122
6244
|
ordType: {
|
|
6123
6245
|
type: "string",
|
|
6124
6246
|
enum: ["conditional", "oco", "move_order_stop"],
|
|
6125
|
-
description: "Filter by type
|
|
6247
|
+
description: "Filter by type"
|
|
6126
6248
|
},
|
|
6127
6249
|
after: {
|
|
6128
6250
|
type: "string",
|
|
6129
|
-
description: "
|
|
6251
|
+
description: "Cursor: older than this algo ID"
|
|
6130
6252
|
},
|
|
6131
6253
|
before: {
|
|
6132
6254
|
type: "string",
|
|
6133
|
-
description: "
|
|
6255
|
+
description: "Cursor: newer than this algo ID"
|
|
6134
6256
|
},
|
|
6135
6257
|
limit: {
|
|
6136
6258
|
type: "number",
|
|
@@ -6139,7 +6261,7 @@ function registerSpotTradeTools() {
|
|
|
6139
6261
|
state: {
|
|
6140
6262
|
type: "string",
|
|
6141
6263
|
enum: ["effective", "canceled", "order_failed"],
|
|
6142
|
-
description: "Required
|
|
6264
|
+
description: "Required for history. effective=triggered, canceled, order_failed. Default: effective."
|
|
6143
6265
|
}
|
|
6144
6266
|
}
|
|
6145
6267
|
},
|
|
@@ -6182,14 +6304,14 @@ function registerSpotTradeTools() {
|
|
|
6182
6304
|
{
|
|
6183
6305
|
name: "spot_get_fills",
|
|
6184
6306
|
module: "spot",
|
|
6185
|
-
description: "Get spot transaction
|
|
6307
|
+
description: "Get spot transaction fills. archive=false(3d, default)|true(up to 3mo).",
|
|
6186
6308
|
isWrite: false,
|
|
6187
6309
|
inputSchema: {
|
|
6188
6310
|
type: "object",
|
|
6189
6311
|
properties: {
|
|
6190
6312
|
archive: {
|
|
6191
6313
|
type: "boolean",
|
|
6192
|
-
description: "true=up to
|
|
6314
|
+
description: "true=up to 3mo, false=3d (default)"
|
|
6193
6315
|
},
|
|
6194
6316
|
instId: {
|
|
6195
6317
|
type: "string",
|
|
@@ -6201,11 +6323,11 @@ function registerSpotTradeTools() {
|
|
|
6201
6323
|
},
|
|
6202
6324
|
after: {
|
|
6203
6325
|
type: "string",
|
|
6204
|
-
description: "
|
|
6326
|
+
description: "Cursor: older than this bill ID"
|
|
6205
6327
|
},
|
|
6206
6328
|
before: {
|
|
6207
6329
|
type: "string",
|
|
6208
|
-
description: "
|
|
6330
|
+
description: "Cursor: newer than this bill ID"
|
|
6209
6331
|
},
|
|
6210
6332
|
begin: {
|
|
6211
6333
|
type: "string",
|
|
@@ -6245,19 +6367,18 @@ function registerSpotTradeTools() {
|
|
|
6245
6367
|
{
|
|
6246
6368
|
name: "spot_batch_orders",
|
|
6247
6369
|
module: "spot",
|
|
6248
|
-
description: "[CAUTION] Batch place/cancel/amend up to 20 spot orders
|
|
6370
|
+
description: "[CAUTION] Batch place/cancel/amend up to 20 spot orders. action: place|cancel|amend.",
|
|
6249
6371
|
isWrite: true,
|
|
6250
6372
|
inputSchema: {
|
|
6251
6373
|
type: "object",
|
|
6252
6374
|
properties: {
|
|
6253
6375
|
action: {
|
|
6254
6376
|
type: "string",
|
|
6255
|
-
enum: ["place", "cancel", "amend"]
|
|
6256
|
-
description: "place|cancel|amend"
|
|
6377
|
+
enum: ["place", "cancel", "amend"]
|
|
6257
6378
|
},
|
|
6258
6379
|
orders: {
|
|
6259
6380
|
type: "array",
|
|
6260
|
-
description: "Array (max 20). place: {instId,side,ordType,sz,tdMode
|
|
6381
|
+
description: "Array (max 20). place: {instId,side,ordType,sz,tdMode(default cash; use cross for unified/margin accounts),px?,clOrdId?,tpTriggerPx?,tpOrdPx?,slTriggerPx?,slOrdPx?}. cancel: {instId,ordId|clOrdId}. amend: {instId,ordId|clOrdId,newSz?,newPx?}.",
|
|
6261
6382
|
items: {
|
|
6262
6383
|
type: "object"
|
|
6263
6384
|
}
|
|
@@ -6304,7 +6425,7 @@ function registerSpotTradeTools() {
|
|
|
6304
6425
|
{
|
|
6305
6426
|
name: "spot_get_order",
|
|
6306
6427
|
module: "spot",
|
|
6307
|
-
description: "Get details of a single spot order
|
|
6428
|
+
description: "Get details of a single spot order.",
|
|
6308
6429
|
isWrite: false,
|
|
6309
6430
|
inputSchema: {
|
|
6310
6431
|
type: "object",
|
|
@@ -6341,7 +6462,7 @@ function registerSpotTradeTools() {
|
|
|
6341
6462
|
{
|
|
6342
6463
|
name: "spot_batch_amend",
|
|
6343
6464
|
module: "spot",
|
|
6344
|
-
description: "[CAUTION] Batch amend up to 20 unfilled spot orders
|
|
6465
|
+
description: "[CAUTION] Batch amend up to 20 unfilled spot orders.",
|
|
6345
6466
|
isWrite: true,
|
|
6346
6467
|
inputSchema: {
|
|
6347
6468
|
type: "object",
|
|
@@ -6371,7 +6492,7 @@ function registerSpotTradeTools() {
|
|
|
6371
6492
|
{
|
|
6372
6493
|
name: "spot_batch_cancel",
|
|
6373
6494
|
module: "spot",
|
|
6374
|
-
description: "[CAUTION] Batch cancel up to 20 spot orders
|
|
6495
|
+
description: "[CAUTION] Batch cancel up to 20 spot orders.",
|
|
6375
6496
|
isWrite: true,
|
|
6376
6497
|
inputSchema: {
|
|
6377
6498
|
type: "object",
|
|
@@ -6514,6 +6635,7 @@ function registerSwapTradeTools() {
|
|
|
6514
6635
|
function allToolSpecs() {
|
|
6515
6636
|
return [
|
|
6516
6637
|
...registerMarketTools(),
|
|
6638
|
+
...registerIndicatorTools(),
|
|
6517
6639
|
...registerSpotTradeTools(),
|
|
6518
6640
|
...registerSwapTradeTools(),
|
|
6519
6641
|
...registerFuturesTools(),
|
|
@@ -6545,20 +6667,38 @@ function readFullConfig() {
|
|
|
6545
6667
|
const path42 = configFilePath();
|
|
6546
6668
|
if (!existsSync(path42)) return { profiles: {} };
|
|
6547
6669
|
const raw = readFileSync(path42, "utf-8");
|
|
6548
|
-
|
|
6670
|
+
try {
|
|
6671
|
+
return parse(raw);
|
|
6672
|
+
} catch (err) {
|
|
6673
|
+
throw new ConfigError(
|
|
6674
|
+
`Failed to parse ${path42}: ${err instanceof Error ? err.message : String(err)}`,
|
|
6675
|
+
`If your passphrase or keys contain special characters:
|
|
6676
|
+
- Contains # \\ " \u2192 use single quotes: passphrase = 'your#pass'
|
|
6677
|
+
- Contains ' \u2192 use double quotes: passphrase = "your'pass"
|
|
6678
|
+
- Contains both \u2192 use triple quotes: passphrase = '''your'#pass'''
|
|
6679
|
+
Or re-run: okx config init`
|
|
6680
|
+
);
|
|
6681
|
+
}
|
|
6549
6682
|
}
|
|
6550
6683
|
function readTomlProfile(profileName) {
|
|
6551
6684
|
const config = readFullConfig();
|
|
6552
6685
|
const name = profileName ?? config.default_profile ?? "default";
|
|
6553
6686
|
return config.profiles?.[name] ?? {};
|
|
6554
6687
|
}
|
|
6688
|
+
var CONFIG_HEADER = `# OKX Trade Kit Configuration
|
|
6689
|
+
# If editing manually, wrap values containing special chars in quotes:
|
|
6690
|
+
# passphrase = 'value' (if value contains # \\ ")
|
|
6691
|
+
# passphrase = "value" (if value contains ')
|
|
6692
|
+
# passphrase = '''value''' (if value contains both)
|
|
6693
|
+
|
|
6694
|
+
`;
|
|
6555
6695
|
function writeFullConfig(config) {
|
|
6556
6696
|
const path42 = configFilePath();
|
|
6557
6697
|
const dir = dirname(path42);
|
|
6558
6698
|
if (!existsSync(dir)) {
|
|
6559
6699
|
mkdirSync(dir, { recursive: true });
|
|
6560
6700
|
}
|
|
6561
|
-
writeFileSync(path42, stringify(config), "utf-8");
|
|
6701
|
+
writeFileSync(path42, CONFIG_HEADER + stringify(config), "utf-8");
|
|
6562
6702
|
}
|
|
6563
6703
|
function expandShorthand(moduleId) {
|
|
6564
6704
|
if (moduleId === "all") return [...MODULES];
|
|
@@ -6883,6 +7023,73 @@ import tls from "tls";
|
|
|
6883
7023
|
// src/commands/diagnose-utils.ts
|
|
6884
7024
|
import fs2 from "fs";
|
|
6885
7025
|
import { createRequire } from "module";
|
|
7026
|
+
|
|
7027
|
+
// src/formatter.ts
|
|
7028
|
+
import { EOL } from "os";
|
|
7029
|
+
var stdioOutput = {
|
|
7030
|
+
out: (message) => process.stdout.write(message),
|
|
7031
|
+
err: (message) => process.stderr.write(message)
|
|
7032
|
+
};
|
|
7033
|
+
var activeOutput = stdioOutput;
|
|
7034
|
+
function setOutput(impl) {
|
|
7035
|
+
activeOutput = impl;
|
|
7036
|
+
}
|
|
7037
|
+
function output(message) {
|
|
7038
|
+
activeOutput.out(message);
|
|
7039
|
+
}
|
|
7040
|
+
function errorOutput(message) {
|
|
7041
|
+
activeOutput.err(message);
|
|
7042
|
+
}
|
|
7043
|
+
function outputLine(message) {
|
|
7044
|
+
activeOutput.out(message + EOL);
|
|
7045
|
+
}
|
|
7046
|
+
function errorLine(message) {
|
|
7047
|
+
activeOutput.err(message + EOL);
|
|
7048
|
+
}
|
|
7049
|
+
function printJson(data) {
|
|
7050
|
+
activeOutput.out(JSON.stringify(data, null, 2) + EOL);
|
|
7051
|
+
}
|
|
7052
|
+
function printTable(rows) {
|
|
7053
|
+
if (rows.length === 0) {
|
|
7054
|
+
activeOutput.out("(no data)" + EOL);
|
|
7055
|
+
return;
|
|
7056
|
+
}
|
|
7057
|
+
const keys = Object.keys(rows[0]);
|
|
7058
|
+
const widths = keys.map(
|
|
7059
|
+
(k) => Math.max(k.length, ...rows.map((r) => String(r[k] ?? "").length))
|
|
7060
|
+
);
|
|
7061
|
+
const header = keys.map((k, i) => k.padEnd(widths[i])).join(" ");
|
|
7062
|
+
const divider = widths.map((w) => "-".repeat(w)).join(" ");
|
|
7063
|
+
activeOutput.out(header + EOL + divider + EOL);
|
|
7064
|
+
for (const row of rows) {
|
|
7065
|
+
activeOutput.out(keys.map((k, i) => String(row[k] ?? "").padEnd(widths[i])).join(" ") + EOL);
|
|
7066
|
+
}
|
|
7067
|
+
}
|
|
7068
|
+
function printKv(obj, indent = 0) {
|
|
7069
|
+
const pad = " ".repeat(indent);
|
|
7070
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
7071
|
+
if (v !== null && typeof v === "object" && !Array.isArray(v)) {
|
|
7072
|
+
activeOutput.out(`${pad}${k}:${EOL}`);
|
|
7073
|
+
printKv(v, indent + 2);
|
|
7074
|
+
} else {
|
|
7075
|
+
activeOutput.out(`${pad}${k.padEnd(20 - indent)} ${v}${EOL}`);
|
|
7076
|
+
}
|
|
7077
|
+
}
|
|
7078
|
+
}
|
|
7079
|
+
function markFailedIfSCodeError(data) {
|
|
7080
|
+
if (!Array.isArray(data)) return;
|
|
7081
|
+
for (const item of data) {
|
|
7082
|
+
if (item !== null && typeof item === "object") {
|
|
7083
|
+
const sCode = item["sCode"];
|
|
7084
|
+
if (sCode !== void 0 && sCode !== "0" && sCode !== 0) {
|
|
7085
|
+
process.exitCode = 1;
|
|
7086
|
+
return;
|
|
7087
|
+
}
|
|
7088
|
+
}
|
|
7089
|
+
}
|
|
7090
|
+
}
|
|
7091
|
+
|
|
7092
|
+
// src/commands/diagnose-utils.ts
|
|
6886
7093
|
var _require = createRequire(import.meta.url);
|
|
6887
7094
|
function readCliVersion() {
|
|
6888
7095
|
for (const rel of ["../package.json", "../../package.json"]) {
|
|
@@ -6899,18 +7106,14 @@ var Report = class {
|
|
|
6899
7106
|
this.lines.push({ key, value });
|
|
6900
7107
|
}
|
|
6901
7108
|
print() {
|
|
6902
|
-
const w = process.stdout.write.bind(process.stdout);
|
|
6903
7109
|
const sep = "\u2500".repeat(52);
|
|
6904
|
-
|
|
6905
|
-
\u2500\u2500 Diagnostic Report (copy & share) ${sep.slice(35)}
|
|
6906
|
-
`);
|
|
7110
|
+
outputLine("");
|
|
7111
|
+
outputLine(` \u2500\u2500 Diagnostic Report (copy & share) ${sep.slice(35)}`);
|
|
6907
7112
|
for (const { key, value } of this.lines) {
|
|
6908
|
-
|
|
6909
|
-
`);
|
|
7113
|
+
outputLine(` ${key.padEnd(14)} ${value}`);
|
|
6910
7114
|
}
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
`);
|
|
7115
|
+
outputLine(` ${sep}`);
|
|
7116
|
+
outputLine("");
|
|
6914
7117
|
}
|
|
6915
7118
|
/** Write report to a file path, returns true on success. */
|
|
6916
7119
|
writeToFile(filePath) {
|
|
@@ -6931,31 +7134,25 @@ var Report = class {
|
|
|
6931
7134
|
}
|
|
6932
7135
|
};
|
|
6933
7136
|
function ok(label, detail) {
|
|
6934
|
-
|
|
6935
|
-
`);
|
|
7137
|
+
outputLine(` \u2713 ${label.padEnd(14)} ${detail}`);
|
|
6936
7138
|
}
|
|
6937
7139
|
function fail(label, detail, hints) {
|
|
6938
|
-
|
|
6939
|
-
`);
|
|
7140
|
+
outputLine(` \u2717 ${label.padEnd(14)} ${detail}`);
|
|
6940
7141
|
for (const hint of hints) {
|
|
6941
|
-
|
|
6942
|
-
`);
|
|
7142
|
+
outputLine(` \u2192 ${hint}`);
|
|
6943
7143
|
}
|
|
6944
7144
|
}
|
|
6945
7145
|
function section(title) {
|
|
6946
|
-
|
|
6947
|
-
${title}
|
|
6948
|
-
`);
|
|
7146
|
+
outputLine("");
|
|
7147
|
+
outputLine(` ${title}`);
|
|
6949
7148
|
}
|
|
6950
7149
|
function writeReportIfRequested(report, outputPath) {
|
|
6951
7150
|
if (!outputPath) return;
|
|
6952
7151
|
const written = report.writeToFile(outputPath);
|
|
6953
7152
|
if (written) {
|
|
6954
|
-
|
|
6955
|
-
`);
|
|
7153
|
+
outputLine(` Report saved to: ${outputPath}`);
|
|
6956
7154
|
} else {
|
|
6957
|
-
|
|
6958
|
-
`);
|
|
7155
|
+
errorLine(` Warning: failed to write report to: ${outputPath}`);
|
|
6959
7156
|
}
|
|
6960
7157
|
}
|
|
6961
7158
|
function sanitize(value) {
|
|
@@ -7155,8 +7352,7 @@ function checkMcpLogs(report) {
|
|
|
7155
7352
|
report.add("mcp_log", logPath);
|
|
7156
7353
|
if (lines.length > 0) {
|
|
7157
7354
|
ok("last lines", `(${lines.length} shown)`);
|
|
7158
|
-
for (const line of lines)
|
|
7159
|
-
`);
|
|
7355
|
+
for (const line of lines) outputLine(` ${sanitize(line)}`);
|
|
7160
7356
|
} else {
|
|
7161
7357
|
ok("last lines", "(empty log)");
|
|
7162
7358
|
}
|
|
@@ -7291,8 +7487,9 @@ function checkModuleLoading(entryPath, report) {
|
|
|
7291
7487
|
}
|
|
7292
7488
|
}
|
|
7293
7489
|
async function cmdDiagnoseMcp(options = {}) {
|
|
7294
|
-
|
|
7295
|
-
|
|
7490
|
+
outputLine("");
|
|
7491
|
+
outputLine(" OKX MCP Server Diagnostics");
|
|
7492
|
+
outputLine(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
7296
7493
|
const report = new Report();
|
|
7297
7494
|
report.add("ts", (/* @__PURE__ */ new Date()).toISOString());
|
|
7298
7495
|
report.add("mode", "mcp");
|
|
@@ -7313,11 +7510,11 @@ async function cmdDiagnoseMcp(options = {}) {
|
|
|
7313
7510
|
handshakePassed = true;
|
|
7314
7511
|
}
|
|
7315
7512
|
const allPassed = nodePassed && entryPassed && cfgPassed && moduleLoadPassed && handshakePassed;
|
|
7316
|
-
|
|
7513
|
+
outputLine("");
|
|
7317
7514
|
if (allPassed) {
|
|
7318
|
-
|
|
7515
|
+
outputLine(" Result: All checks passed \u2713");
|
|
7319
7516
|
} else {
|
|
7320
|
-
|
|
7517
|
+
outputLine(" Result: Some checks failed \u2717");
|
|
7321
7518
|
process.exitCode = 1;
|
|
7322
7519
|
}
|
|
7323
7520
|
report.add("result", allPassed ? "PASS" : "FAIL");
|
|
@@ -7327,7 +7524,7 @@ async function cmdDiagnoseMcp(options = {}) {
|
|
|
7327
7524
|
|
|
7328
7525
|
// src/commands/diagnose.ts
|
|
7329
7526
|
var CLI_VERSION = readCliVersion();
|
|
7330
|
-
var GIT_HASH = true ? "
|
|
7527
|
+
var GIT_HASH = true ? "c27439d" : "dev";
|
|
7331
7528
|
function maskKey2(key) {
|
|
7332
7529
|
if (!key) return "(not set)";
|
|
7333
7530
|
if (key.length <= 8) return "****";
|
|
@@ -7569,22 +7766,52 @@ async function cmdDiagnose(config, profile, options = {}) {
|
|
|
7569
7766
|
}
|
|
7570
7767
|
return runCliChecks(config, profile, options.output);
|
|
7571
7768
|
}
|
|
7769
|
+
function checkConfigFile(report) {
|
|
7770
|
+
section("Config File");
|
|
7771
|
+
const path5 = configFilePath();
|
|
7772
|
+
try {
|
|
7773
|
+
readFullConfig();
|
|
7774
|
+
ok("Config parse", `${path5} OK`);
|
|
7775
|
+
report.add("config_parse", "OK");
|
|
7776
|
+
return true;
|
|
7777
|
+
} catch (e) {
|
|
7778
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
7779
|
+
fail("Config parse", msg, [
|
|
7780
|
+
`If passphrase contains special characters (# \\ " '), wrap in quotes:`,
|
|
7781
|
+
` Contains # \\ " \u2192 passphrase = 'value'`,
|
|
7782
|
+
` Contains ' \u2192 passphrase = "value"`,
|
|
7783
|
+
" Contains both \u2192 passphrase = '''value'''",
|
|
7784
|
+
"Or re-run: okx config init"
|
|
7785
|
+
]);
|
|
7786
|
+
report.add("config_parse", `FAIL ${msg}`);
|
|
7787
|
+
return false;
|
|
7788
|
+
}
|
|
7789
|
+
}
|
|
7572
7790
|
async function runCliChecks(config, profile, outputPath) {
|
|
7573
7791
|
process.stdout.write("\n OKX Trade CLI Diagnostics\n");
|
|
7574
7792
|
process.stdout.write(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
|
|
7575
7793
|
const report = new Report();
|
|
7576
7794
|
report.add("ts", (/* @__PURE__ */ new Date()).toISOString());
|
|
7795
|
+
const configFilePassed = checkConfigFile(report);
|
|
7577
7796
|
const envPassed = checkEnvironment(report);
|
|
7797
|
+
if (!config) {
|
|
7798
|
+
fail("Config", "Could not load config (see Config File check above)", []);
|
|
7799
|
+
report.add("result", "FAIL");
|
|
7800
|
+
report.print();
|
|
7801
|
+
writeReportIfRequested(report, outputPath);
|
|
7802
|
+
process.exitCode = 1;
|
|
7803
|
+
return;
|
|
7804
|
+
}
|
|
7578
7805
|
const cfgPassed = checkConfig(config, profile, report);
|
|
7579
7806
|
const client = new OkxRestClient(config);
|
|
7580
7807
|
const netPassed = await checkNetwork(config, client, report);
|
|
7581
7808
|
const authPassed = await checkAuth(client, config, report);
|
|
7582
|
-
const allPassed = envPassed && cfgPassed && netPassed && authPassed;
|
|
7583
|
-
|
|
7809
|
+
const allPassed = configFilePassed && envPassed && cfgPassed && netPassed && authPassed;
|
|
7810
|
+
outputLine("");
|
|
7584
7811
|
if (allPassed) {
|
|
7585
|
-
|
|
7812
|
+
outputLine(" Result: All checks passed \u2713");
|
|
7586
7813
|
} else {
|
|
7587
|
-
|
|
7814
|
+
outputLine(" Result: Some checks failed \u2717");
|
|
7588
7815
|
process.exitCode = 1;
|
|
7589
7816
|
}
|
|
7590
7817
|
report.add("result", allPassed ? "PASS" : "FAIL");
|
|
@@ -7606,6 +7833,9 @@ function loadProfileConfig(opts) {
|
|
|
7606
7833
|
});
|
|
7607
7834
|
}
|
|
7608
7835
|
|
|
7836
|
+
// src/help.ts
|
|
7837
|
+
import { EOL as EOL2 } from "os";
|
|
7838
|
+
|
|
7609
7839
|
// src/commands/client-setup.ts
|
|
7610
7840
|
import * as fs5 from "fs";
|
|
7611
7841
|
var DETECTABLE_CLIENTS = ["claude-desktop", "cursor", "windsurf"];
|
|
@@ -7621,14 +7851,11 @@ function cmdSetupClients() {
|
|
|
7621
7851
|
}
|
|
7622
7852
|
}
|
|
7623
7853
|
if (detected.length > 0) {
|
|
7624
|
-
|
|
7625
|
-
`);
|
|
7854
|
+
outputLine("Detected clients:");
|
|
7626
7855
|
for (const { id, path: path5 } of detected) {
|
|
7627
|
-
|
|
7628
|
-
`);
|
|
7856
|
+
outputLine(` ${id.padEnd(16)} ${path5}`);
|
|
7629
7857
|
}
|
|
7630
|
-
|
|
7631
|
-
`);
|
|
7858
|
+
outputLine("");
|
|
7632
7859
|
}
|
|
7633
7860
|
printSetupUsage();
|
|
7634
7861
|
}
|
|
@@ -8203,13 +8430,12 @@ function printGlobalHelp() {
|
|
|
8203
8430
|
lines.push(` ${name.padEnd(colWidth)}${group.description}`);
|
|
8204
8431
|
}
|
|
8205
8432
|
lines.push("", 'Run "okx <module> --help" for module details.', "");
|
|
8206
|
-
|
|
8433
|
+
output(lines.join(EOL2));
|
|
8207
8434
|
}
|
|
8208
8435
|
function printModuleHelp(moduleName) {
|
|
8209
8436
|
const group = HELP_TREE[moduleName];
|
|
8210
8437
|
if (!group) {
|
|
8211
|
-
|
|
8212
|
-
`);
|
|
8438
|
+
errorLine(`Unknown module: ${moduleName}`);
|
|
8213
8439
|
process.exitCode = 1;
|
|
8214
8440
|
return;
|
|
8215
8441
|
}
|
|
@@ -8253,20 +8479,18 @@ function printModuleHelp(moduleName) {
|
|
|
8253
8479
|
}
|
|
8254
8480
|
}
|
|
8255
8481
|
lines.push("");
|
|
8256
|
-
|
|
8482
|
+
output(lines.join(EOL2));
|
|
8257
8483
|
}
|
|
8258
8484
|
function printSubgroupHelp(moduleName, subgroupName) {
|
|
8259
8485
|
const group = HELP_TREE[moduleName];
|
|
8260
8486
|
if (!group) {
|
|
8261
|
-
|
|
8262
|
-
`);
|
|
8487
|
+
errorLine(`Unknown module: ${moduleName}`);
|
|
8263
8488
|
process.exitCode = 1;
|
|
8264
8489
|
return;
|
|
8265
8490
|
}
|
|
8266
8491
|
const subgroup = group.subgroups?.[subgroupName];
|
|
8267
8492
|
if (!subgroup) {
|
|
8268
|
-
|
|
8269
|
-
`);
|
|
8493
|
+
errorLine(`Unknown subgroup: ${moduleName} ${subgroupName}`);
|
|
8270
8494
|
process.exitCode = 1;
|
|
8271
8495
|
return;
|
|
8272
8496
|
}
|
|
@@ -8282,7 +8506,7 @@ function printSubgroupHelp(moduleName, subgroupName) {
|
|
|
8282
8506
|
printCommandList(lines, subgroup.commands);
|
|
8283
8507
|
}
|
|
8284
8508
|
lines.push("");
|
|
8285
|
-
|
|
8509
|
+
output(lines.join(EOL2));
|
|
8286
8510
|
}
|
|
8287
8511
|
function printCommandList(lines, commands) {
|
|
8288
8512
|
const names = Object.keys(commands);
|
|
@@ -8333,6 +8557,7 @@ var CLI_OPTIONS = {
|
|
|
8333
8557
|
px: { type: "string" },
|
|
8334
8558
|
posSide: { type: "string" },
|
|
8335
8559
|
tdMode: { type: "string" },
|
|
8560
|
+
tgtCcy: { type: "string" },
|
|
8336
8561
|
// leverage
|
|
8337
8562
|
lever: { type: "string" },
|
|
8338
8563
|
mgnMode: { type: "string" },
|
|
@@ -8433,6 +8658,10 @@ var CLI_OPTIONS = {
|
|
|
8433
8658
|
maxTermDays: { type: "string" },
|
|
8434
8659
|
expDate: { type: "string" },
|
|
8435
8660
|
minAnnualizedYield: { type: "string" },
|
|
8661
|
+
// indicator
|
|
8662
|
+
params: { type: "string" },
|
|
8663
|
+
list: { type: "boolean", default: false },
|
|
8664
|
+
"backtest-time": { type: "string" },
|
|
8436
8665
|
// diagnostics — cli/mcp/all/output are diagnose-specific; verbose is shared
|
|
8437
8666
|
verbose: { type: "boolean", default: false },
|
|
8438
8667
|
mcp: { type: "boolean", default: false },
|
|
@@ -8467,42 +8696,6 @@ function parseCli(argv) {
|
|
|
8467
8696
|
return { values, positionals };
|
|
8468
8697
|
}
|
|
8469
8698
|
|
|
8470
|
-
// src/formatter.ts
|
|
8471
|
-
function printJson(data) {
|
|
8472
|
-
process.stdout.write(JSON.stringify(data, null, 2) + "\n");
|
|
8473
|
-
}
|
|
8474
|
-
function printTable(rows) {
|
|
8475
|
-
if (rows.length === 0) {
|
|
8476
|
-
process.stdout.write("(no data)\n");
|
|
8477
|
-
return;
|
|
8478
|
-
}
|
|
8479
|
-
const keys = Object.keys(rows[0]);
|
|
8480
|
-
const widths = keys.map(
|
|
8481
|
-
(k) => Math.max(k.length, ...rows.map((r) => String(r[k] ?? "").length))
|
|
8482
|
-
);
|
|
8483
|
-
const header = keys.map((k, i) => k.padEnd(widths[i])).join(" ");
|
|
8484
|
-
const divider = widths.map((w) => "-".repeat(w)).join(" ");
|
|
8485
|
-
process.stdout.write(header + "\n" + divider + "\n");
|
|
8486
|
-
for (const row of rows) {
|
|
8487
|
-
process.stdout.write(
|
|
8488
|
-
keys.map((k, i) => String(row[k] ?? "").padEnd(widths[i])).join(" ") + "\n"
|
|
8489
|
-
);
|
|
8490
|
-
}
|
|
8491
|
-
}
|
|
8492
|
-
function printKv(obj, indent = 0) {
|
|
8493
|
-
const pad = " ".repeat(indent);
|
|
8494
|
-
for (const [k, v] of Object.entries(obj)) {
|
|
8495
|
-
if (v !== null && typeof v === "object" && !Array.isArray(v)) {
|
|
8496
|
-
process.stdout.write(`${pad}${k}:
|
|
8497
|
-
`);
|
|
8498
|
-
printKv(v, indent + 2);
|
|
8499
|
-
} else {
|
|
8500
|
-
process.stdout.write(`${pad}${k.padEnd(20 - indent)} ${v}
|
|
8501
|
-
`);
|
|
8502
|
-
}
|
|
8503
|
-
}
|
|
8504
|
-
}
|
|
8505
|
-
|
|
8506
8699
|
// src/commands/market.ts
|
|
8507
8700
|
function getData(result) {
|
|
8508
8701
|
return result.data;
|
|
@@ -8538,7 +8731,7 @@ async function cmdMarketFundingRate(run, instId, opts) {
|
|
|
8538
8731
|
} else {
|
|
8539
8732
|
const r = items?.[0];
|
|
8540
8733
|
if (!r) {
|
|
8541
|
-
|
|
8734
|
+
outputLine("No data");
|
|
8542
8735
|
return;
|
|
8543
8736
|
}
|
|
8544
8737
|
printKv({
|
|
@@ -8611,7 +8804,7 @@ async function cmdMarketPriceLimit(run, instId, json) {
|
|
|
8611
8804
|
if (json) return printJson(items);
|
|
8612
8805
|
const r = items?.[0];
|
|
8613
8806
|
if (!r) {
|
|
8614
|
-
|
|
8807
|
+
outputLine("No data");
|
|
8615
8808
|
return;
|
|
8616
8809
|
}
|
|
8617
8810
|
printKv({
|
|
@@ -8639,7 +8832,7 @@ async function cmdMarketTicker(run, instId, json) {
|
|
|
8639
8832
|
const items = getData(result);
|
|
8640
8833
|
if (json) return printJson(items);
|
|
8641
8834
|
if (!items?.length) {
|
|
8642
|
-
|
|
8835
|
+
outputLine("No data");
|
|
8643
8836
|
return;
|
|
8644
8837
|
}
|
|
8645
8838
|
const t = items[0];
|
|
@@ -8673,17 +8866,16 @@ async function cmdMarketOrderbook(run, instId, sz, json) {
|
|
|
8673
8866
|
if (json) return printJson(data);
|
|
8674
8867
|
const book = data[0];
|
|
8675
8868
|
if (!book) {
|
|
8676
|
-
|
|
8869
|
+
outputLine("No data");
|
|
8677
8870
|
return;
|
|
8678
8871
|
}
|
|
8679
8872
|
const asks = book["asks"].slice(0, 5);
|
|
8680
8873
|
const bids = book["bids"].slice(0, 5);
|
|
8681
|
-
|
|
8682
|
-
|
|
8683
|
-
`);
|
|
8684
|
-
|
|
8685
|
-
for (const [p, s] of bids)
|
|
8686
|
-
`);
|
|
8874
|
+
outputLine("Asks (price / size):");
|
|
8875
|
+
asks.reverse();
|
|
8876
|
+
for (const [p, s] of asks) outputLine(` ${p.padStart(16)} ${s}`);
|
|
8877
|
+
outputLine("Bids (price / size):");
|
|
8878
|
+
for (const [p, s] of bids) outputLine(` ${p.padStart(16)} ${s}`);
|
|
8687
8879
|
}
|
|
8688
8880
|
async function cmdMarketCandles(run, instId, opts) {
|
|
8689
8881
|
const result = await run("market_get_candles", { instId, bar: opts.bar, limit: opts.limit });
|
|
@@ -8700,6 +8892,54 @@ async function cmdMarketCandles(run, instId, opts) {
|
|
|
8700
8892
|
}))
|
|
8701
8893
|
);
|
|
8702
8894
|
}
|
|
8895
|
+
async function cmdMarketIndicator(run, indicator, instId, opts) {
|
|
8896
|
+
const params = opts.params ? opts.params.split(",").map((p) => Number(p.trim())).filter((n) => !Number.isNaN(n)) : void 0;
|
|
8897
|
+
const result = await run("market_get_indicator", {
|
|
8898
|
+
instId,
|
|
8899
|
+
indicator,
|
|
8900
|
+
bar: opts.bar,
|
|
8901
|
+
params: params && params.length > 0 ? params : void 0,
|
|
8902
|
+
returnList: opts.list ?? false,
|
|
8903
|
+
limit: opts.limit,
|
|
8904
|
+
backtestTime: opts.backtestTime
|
|
8905
|
+
});
|
|
8906
|
+
const outerArray = getData(result);
|
|
8907
|
+
if (opts.json) return printJson(outerArray);
|
|
8908
|
+
if (!outerArray?.length) {
|
|
8909
|
+
process.stdout.write("No data\n");
|
|
8910
|
+
return;
|
|
8911
|
+
}
|
|
8912
|
+
const apiCode = resolveIndicatorCode(indicator);
|
|
8913
|
+
const response = outerArray[0];
|
|
8914
|
+
const innerArray = response["data"];
|
|
8915
|
+
const instData = innerArray?.[0];
|
|
8916
|
+
const timeframes = instData?.["timeframes"];
|
|
8917
|
+
if (!timeframes) {
|
|
8918
|
+
process.stdout.write(JSON.stringify(outerArray, null, 2) + "\n");
|
|
8919
|
+
return;
|
|
8920
|
+
}
|
|
8921
|
+
for (const [tf, tfData] of Object.entries(timeframes)) {
|
|
8922
|
+
const indicators = tfData?.["indicators"];
|
|
8923
|
+
const values = indicators?.[apiCode];
|
|
8924
|
+
if (!values?.length) continue;
|
|
8925
|
+
process.stdout.write(`${instId} \xB7 ${apiCode} \xB7 ${tf}
|
|
8926
|
+
`);
|
|
8927
|
+
process.stdout.write("\u2500".repeat(40) + "\n");
|
|
8928
|
+
if (opts.list) {
|
|
8929
|
+
const tableRows = values.map((entry) => ({
|
|
8930
|
+
ts: new Date(Number(entry["ts"])).toLocaleString(),
|
|
8931
|
+
...entry["values"]
|
|
8932
|
+
}));
|
|
8933
|
+
printTable(tableRows);
|
|
8934
|
+
} else {
|
|
8935
|
+
const latest = values[0];
|
|
8936
|
+
printKv({
|
|
8937
|
+
ts: new Date(Number(latest["ts"])).toLocaleString(),
|
|
8938
|
+
...latest["values"]
|
|
8939
|
+
});
|
|
8940
|
+
}
|
|
8941
|
+
}
|
|
8942
|
+
}
|
|
8703
8943
|
async function cmdMarketStockTokens(run, opts) {
|
|
8704
8944
|
const result = await run("market_get_stock_tokens", { instType: opts.instType, instId: opts.instId });
|
|
8705
8945
|
const items = getData(result);
|
|
@@ -8757,7 +8997,7 @@ async function cmdAccountPositions(run, opts) {
|
|
|
8757
8997
|
if (opts.json) return printJson(positions);
|
|
8758
8998
|
const open = (positions ?? []).filter((p) => Number(p["pos"]) !== 0);
|
|
8759
8999
|
if (!open.length) {
|
|
8760
|
-
|
|
9000
|
+
outputLine("No open positions");
|
|
8761
9001
|
return;
|
|
8762
9002
|
}
|
|
8763
9003
|
printTable(
|
|
@@ -8795,7 +9035,7 @@ async function cmdAccountFees(run, opts) {
|
|
|
8795
9035
|
if (opts.json) return printJson(data);
|
|
8796
9036
|
const fee = data?.[0];
|
|
8797
9037
|
if (!fee) {
|
|
8798
|
-
|
|
9038
|
+
outputLine("No data");
|
|
8799
9039
|
return;
|
|
8800
9040
|
}
|
|
8801
9041
|
printKv({
|
|
@@ -8813,7 +9053,7 @@ async function cmdAccountConfig(run, json) {
|
|
|
8813
9053
|
if (json) return printJson(data);
|
|
8814
9054
|
const cfg = data?.[0];
|
|
8815
9055
|
if (!cfg) {
|
|
8816
|
-
|
|
9056
|
+
outputLine("No data");
|
|
8817
9057
|
return;
|
|
8818
9058
|
}
|
|
8819
9059
|
printKv({
|
|
@@ -8831,8 +9071,7 @@ async function cmdAccountSetPositionMode(run, posMode, json) {
|
|
|
8831
9071
|
const data = getData2(result);
|
|
8832
9072
|
if (json) return printJson(data);
|
|
8833
9073
|
const r = data?.[0];
|
|
8834
|
-
|
|
8835
|
-
`);
|
|
9074
|
+
outputLine(`Position mode set: ${r?.["posMode"]}`);
|
|
8836
9075
|
}
|
|
8837
9076
|
async function cmdAccountMaxSize(run, opts) {
|
|
8838
9077
|
const result = await run("account_get_max_size", { instId: opts.instId, tdMode: opts.tdMode, px: opts.px });
|
|
@@ -8840,7 +9079,7 @@ async function cmdAccountMaxSize(run, opts) {
|
|
|
8840
9079
|
if (opts.json) return printJson(data);
|
|
8841
9080
|
const r = data?.[0];
|
|
8842
9081
|
if (!r) {
|
|
8843
|
-
|
|
9082
|
+
outputLine("No data");
|
|
8844
9083
|
return;
|
|
8845
9084
|
}
|
|
8846
9085
|
printKv({ instId: r["instId"], maxBuy: r["maxBuy"], maxSell: r["maxSell"] });
|
|
@@ -8851,7 +9090,7 @@ async function cmdAccountMaxAvailSize(run, opts) {
|
|
|
8851
9090
|
if (opts.json) return printJson(data);
|
|
8852
9091
|
const r = data?.[0];
|
|
8853
9092
|
if (!r) {
|
|
8854
|
-
|
|
9093
|
+
outputLine("No data");
|
|
8855
9094
|
return;
|
|
8856
9095
|
}
|
|
8857
9096
|
printKv({ instId: r["instId"], availBuy: r["availBuy"], availSell: r["availSell"] });
|
|
@@ -8895,8 +9134,7 @@ async function cmdAccountTransfer(run, opts) {
|
|
|
8895
9134
|
const data = getData2(result);
|
|
8896
9135
|
if (opts.json) return printJson(data);
|
|
8897
9136
|
const r = data?.[0];
|
|
8898
|
-
|
|
8899
|
-
`);
|
|
9137
|
+
outputLine(`Transfer: ${r?.["transId"]} (${r?.["ccy"]} ${r?.["amt"]})`);
|
|
8900
9138
|
}
|
|
8901
9139
|
function readAuditLogs(logDir, days = 7) {
|
|
8902
9140
|
const entries = [];
|
|
@@ -8938,7 +9176,7 @@ function cmdAccountAudit(opts) {
|
|
|
8938
9176
|
entries = entries.slice(0, limit);
|
|
8939
9177
|
if (opts.json) return printJson(entries);
|
|
8940
9178
|
if (!entries.length) {
|
|
8941
|
-
|
|
9179
|
+
outputLine("No audit log entries");
|
|
8942
9180
|
return;
|
|
8943
9181
|
}
|
|
8944
9182
|
printTable(
|
|
@@ -8956,6 +9194,25 @@ function cmdAccountAudit(opts) {
|
|
|
8956
9194
|
function getData3(result) {
|
|
8957
9195
|
return result.data;
|
|
8958
9196
|
}
|
|
9197
|
+
function emitWriteResult(item, label, idKey) {
|
|
9198
|
+
const isError = item?.["sCode"] !== "0" && item?.["sCode"] !== 0;
|
|
9199
|
+
if (isError) {
|
|
9200
|
+
errorLine(`Error: ${item?.["sMsg"]} (sCode ${item?.["sCode"]})`);
|
|
9201
|
+
} else {
|
|
9202
|
+
outputLine(`${label}: ${item?.[idKey]} (OK)`);
|
|
9203
|
+
}
|
|
9204
|
+
}
|
|
9205
|
+
function emitBatchResults(items) {
|
|
9206
|
+
for (const r of items) {
|
|
9207
|
+
const isError = r["sCode"] !== "0" && r["sCode"] !== 0;
|
|
9208
|
+
const id = r["ordId"] ?? r["clOrdId"] ?? "?";
|
|
9209
|
+
if (isError) {
|
|
9210
|
+
errorLine(`${id}: ${r["sMsg"]} (sCode ${r["sCode"]})`);
|
|
9211
|
+
} else {
|
|
9212
|
+
outputLine(`${id}: OK`);
|
|
9213
|
+
}
|
|
9214
|
+
}
|
|
9215
|
+
}
|
|
8959
9216
|
async function cmdSpotOrders(run, opts) {
|
|
8960
9217
|
const result = await run("spot_get_orders", { instId: opts.instId, status: opts.status });
|
|
8961
9218
|
const orders = getData3(result);
|
|
@@ -8980,6 +9237,7 @@ async function cmdSpotPlace(run, opts) {
|
|
|
8980
9237
|
side: opts.side,
|
|
8981
9238
|
ordType: opts.ordType,
|
|
8982
9239
|
sz: opts.sz,
|
|
9240
|
+
tgtCcy: opts.tgtCcy,
|
|
8983
9241
|
px: opts.px,
|
|
8984
9242
|
tpTriggerPx: opts.tpTriggerPx,
|
|
8985
9243
|
tpOrdPx: opts.tpOrdPx,
|
|
@@ -8988,9 +9246,7 @@ async function cmdSpotPlace(run, opts) {
|
|
|
8988
9246
|
});
|
|
8989
9247
|
const data = getData3(result);
|
|
8990
9248
|
if (opts.json) return printJson(data);
|
|
8991
|
-
|
|
8992
|
-
process.stdout.write(`Order placed: ${order?.["ordId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
8993
|
-
`);
|
|
9249
|
+
emitWriteResult(data?.[0], "Order placed", "ordId");
|
|
8994
9250
|
}
|
|
8995
9251
|
async function cmdSpotCancel(run, opts) {
|
|
8996
9252
|
const { instId, ordId, clOrdId, json } = opts;
|
|
@@ -8998,9 +9254,7 @@ async function cmdSpotCancel(run, opts) {
|
|
|
8998
9254
|
const result = await run("spot_cancel_order", { instId, ...ordId ? { ordId } : { clOrdId } });
|
|
8999
9255
|
const data = getData3(result);
|
|
9000
9256
|
if (json) return printJson(data);
|
|
9001
|
-
|
|
9002
|
-
process.stdout.write(`Cancelled: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9003
|
-
`);
|
|
9257
|
+
emitWriteResult(data?.[0], "Cancelled", "ordId");
|
|
9004
9258
|
}
|
|
9005
9259
|
async function cmdSpotAlgoPlace(run, opts) {
|
|
9006
9260
|
const result = await run("spot_place_algo_order", {
|
|
@@ -9019,11 +9273,7 @@ async function cmdSpotAlgoPlace(run, opts) {
|
|
|
9019
9273
|
});
|
|
9020
9274
|
const data = getData3(result);
|
|
9021
9275
|
if (opts.json) return printJson(data);
|
|
9022
|
-
|
|
9023
|
-
process.stdout.write(
|
|
9024
|
-
`Algo order placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9025
|
-
`
|
|
9026
|
-
);
|
|
9276
|
+
emitWriteResult(data?.[0], "Algo order placed", "algoId");
|
|
9027
9277
|
}
|
|
9028
9278
|
async function cmdSpotAlgoAmend(run, opts) {
|
|
9029
9279
|
const result = await run("spot_amend_algo_order", {
|
|
@@ -9037,21 +9287,13 @@ async function cmdSpotAlgoAmend(run, opts) {
|
|
|
9037
9287
|
});
|
|
9038
9288
|
const data = getData3(result);
|
|
9039
9289
|
if (opts.json) return printJson(data);
|
|
9040
|
-
|
|
9041
|
-
process.stdout.write(
|
|
9042
|
-
`Algo order amended: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9043
|
-
`
|
|
9044
|
-
);
|
|
9290
|
+
emitWriteResult(data?.[0], "Algo order amended", "algoId");
|
|
9045
9291
|
}
|
|
9046
9292
|
async function cmdSpotAlgoCancel(run, instId, algoId, json) {
|
|
9047
9293
|
const result = await run("spot_cancel_algo_order", { instId, algoId });
|
|
9048
9294
|
const data = getData3(result);
|
|
9049
9295
|
if (json) return printJson(data);
|
|
9050
|
-
|
|
9051
|
-
process.stdout.write(
|
|
9052
|
-
`Algo order cancelled: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9053
|
-
`
|
|
9054
|
-
);
|
|
9296
|
+
emitWriteResult(data?.[0], "Algo order cancelled", "algoId");
|
|
9055
9297
|
}
|
|
9056
9298
|
async function cmdSpotGet(run, opts) {
|
|
9057
9299
|
const result = await run("spot_get_order", { instId: opts.instId, ordId: opts.ordId, clOrdId: opts.clOrdId });
|
|
@@ -9059,7 +9301,7 @@ async function cmdSpotGet(run, opts) {
|
|
|
9059
9301
|
if (opts.json) return printJson(data);
|
|
9060
9302
|
const o = data?.[0];
|
|
9061
9303
|
if (!o) {
|
|
9062
|
-
|
|
9304
|
+
outputLine("No data");
|
|
9063
9305
|
return;
|
|
9064
9306
|
}
|
|
9065
9307
|
printKv({
|
|
@@ -9085,9 +9327,7 @@ async function cmdSpotAmend(run, opts) {
|
|
|
9085
9327
|
});
|
|
9086
9328
|
const data = getData3(result);
|
|
9087
9329
|
if (opts.json) return printJson(data);
|
|
9088
|
-
|
|
9089
|
-
process.stdout.write(`Order amended: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9090
|
-
`);
|
|
9330
|
+
emitWriteResult(data?.[0], "Order amended", "ordId");
|
|
9091
9331
|
}
|
|
9092
9332
|
async function cmdSpotAlgoOrders(run, opts) {
|
|
9093
9333
|
const result = await run("spot_get_algo_orders", {
|
|
@@ -9098,7 +9338,7 @@ async function cmdSpotAlgoOrders(run, opts) {
|
|
|
9098
9338
|
const orders = getData3(result);
|
|
9099
9339
|
if (opts.json) return printJson(orders);
|
|
9100
9340
|
if (!(orders ?? []).length) {
|
|
9101
|
-
|
|
9341
|
+
outputLine("No algo orders");
|
|
9102
9342
|
return;
|
|
9103
9343
|
}
|
|
9104
9344
|
printTable(
|
|
@@ -9142,23 +9382,19 @@ async function cmdSpotAlgoTrailPlace(run, opts) {
|
|
|
9142
9382
|
});
|
|
9143
9383
|
const data = getData3(result);
|
|
9144
9384
|
if (opts.json) return printJson(data);
|
|
9145
|
-
|
|
9146
|
-
process.stdout.write(
|
|
9147
|
-
`Trailing stop placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9148
|
-
`
|
|
9149
|
-
);
|
|
9385
|
+
emitWriteResult(data?.[0], "Trailing stop placed", "algoId");
|
|
9150
9386
|
}
|
|
9151
9387
|
async function cmdSpotBatch(run, opts) {
|
|
9152
9388
|
let parsed;
|
|
9153
9389
|
try {
|
|
9154
9390
|
parsed = JSON.parse(opts.orders);
|
|
9155
9391
|
} catch {
|
|
9156
|
-
|
|
9392
|
+
errorLine("Error: --orders must be a valid JSON array");
|
|
9157
9393
|
process.exitCode = 1;
|
|
9158
9394
|
return;
|
|
9159
9395
|
}
|
|
9160
9396
|
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
9161
|
-
|
|
9397
|
+
errorLine("Error: --orders must be a non-empty JSON array");
|
|
9162
9398
|
process.exitCode = 1;
|
|
9163
9399
|
return;
|
|
9164
9400
|
}
|
|
@@ -9169,31 +9405,46 @@ async function cmdSpotBatch(run, opts) {
|
|
|
9169
9405
|
};
|
|
9170
9406
|
const tool = toolMap[opts.action];
|
|
9171
9407
|
if (!tool) {
|
|
9172
|
-
|
|
9173
|
-
`);
|
|
9408
|
+
errorLine("Error: --action must be one of: place, amend, cancel");
|
|
9174
9409
|
process.exitCode = 1;
|
|
9175
9410
|
return;
|
|
9176
9411
|
}
|
|
9177
9412
|
const result = await run(tool, tool === "spot_batch_orders" ? { action: opts.action, orders: parsed } : { orders: parsed });
|
|
9178
9413
|
const data = getData3(result);
|
|
9179
9414
|
if (opts.json) return printJson(data);
|
|
9180
|
-
|
|
9181
|
-
process.stdout.write(`${r["ordId"] ?? r["clOrdId"] ?? "?"}: ${r["sCode"] === "0" ? "OK" : r["sMsg"]}
|
|
9182
|
-
`);
|
|
9183
|
-
}
|
|
9415
|
+
emitBatchResults(data ?? []);
|
|
9184
9416
|
}
|
|
9185
9417
|
|
|
9186
9418
|
// src/commands/swap.ts
|
|
9187
9419
|
function getData4(result) {
|
|
9188
9420
|
return result.data;
|
|
9189
9421
|
}
|
|
9422
|
+
function emitWriteResult2(item, label, idKey) {
|
|
9423
|
+
const isError = item?.["sCode"] !== "0" && item?.["sCode"] !== 0;
|
|
9424
|
+
if (isError) {
|
|
9425
|
+
errorLine(`Error: ${item?.["sMsg"]} (sCode ${item?.["sCode"]})`);
|
|
9426
|
+
} else {
|
|
9427
|
+
outputLine(`${label}: ${item?.[idKey]} (OK)`);
|
|
9428
|
+
}
|
|
9429
|
+
}
|
|
9430
|
+
function emitBatchResults2(items) {
|
|
9431
|
+
for (const r of items) {
|
|
9432
|
+
const isError = r["sCode"] !== "0" && r["sCode"] !== 0;
|
|
9433
|
+
const id = r["ordId"] ?? r["clOrdId"] ?? "?";
|
|
9434
|
+
if (isError) {
|
|
9435
|
+
errorLine(`${id}: ${r["sMsg"]} (sCode ${r["sCode"]})`);
|
|
9436
|
+
} else {
|
|
9437
|
+
outputLine(`${id}: OK`);
|
|
9438
|
+
}
|
|
9439
|
+
}
|
|
9440
|
+
}
|
|
9190
9441
|
async function cmdSwapPositions(run, instId, json) {
|
|
9191
9442
|
const result = await run("swap_get_positions", { instId });
|
|
9192
9443
|
const positions = getData4(result);
|
|
9193
9444
|
if (json) return printJson(positions);
|
|
9194
9445
|
const open = (positions ?? []).filter((p) => Number(p["pos"]) !== 0);
|
|
9195
9446
|
if (!open.length) {
|
|
9196
|
-
|
|
9447
|
+
outputLine("No open positions");
|
|
9197
9448
|
return;
|
|
9198
9449
|
}
|
|
9199
9450
|
printTable(
|
|
@@ -9232,6 +9483,7 @@ async function cmdSwapPlace(run, opts) {
|
|
|
9232
9483
|
side: opts.side,
|
|
9233
9484
|
ordType: opts.ordType,
|
|
9234
9485
|
sz: opts.sz,
|
|
9486
|
+
tgtCcy: opts.tgtCcy,
|
|
9235
9487
|
posSide: opts.posSide,
|
|
9236
9488
|
px: opts.px,
|
|
9237
9489
|
tpTriggerPx: opts.tpTriggerPx,
|
|
@@ -9241,9 +9493,7 @@ async function cmdSwapPlace(run, opts) {
|
|
|
9241
9493
|
});
|
|
9242
9494
|
const data = getData4(result);
|
|
9243
9495
|
if (opts.json) return printJson(data);
|
|
9244
|
-
|
|
9245
|
-
process.stdout.write(`Order placed: ${order?.["ordId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9246
|
-
`);
|
|
9496
|
+
emitWriteResult2(data?.[0], "Order placed", "ordId");
|
|
9247
9497
|
}
|
|
9248
9498
|
async function cmdSwapCancel(run, opts) {
|
|
9249
9499
|
const { instId, ordId, clOrdId, json } = opts;
|
|
@@ -9251,9 +9501,7 @@ async function cmdSwapCancel(run, opts) {
|
|
|
9251
9501
|
const result = await run("swap_cancel_order", { instId, ...ordId ? { ordId } : { clOrdId } });
|
|
9252
9502
|
const data = getData4(result);
|
|
9253
9503
|
if (json) return printJson(data);
|
|
9254
|
-
|
|
9255
|
-
process.stdout.write(`Cancelled: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9256
|
-
`);
|
|
9504
|
+
emitWriteResult2(data?.[0], "Cancelled", "ordId");
|
|
9257
9505
|
}
|
|
9258
9506
|
async function cmdSwapAlgoPlace(run, opts) {
|
|
9259
9507
|
const result = await run("swap_place_algo_order", {
|
|
@@ -9274,11 +9522,7 @@ async function cmdSwapAlgoPlace(run, opts) {
|
|
|
9274
9522
|
});
|
|
9275
9523
|
const data = getData4(result);
|
|
9276
9524
|
if (opts.json) return printJson(data);
|
|
9277
|
-
|
|
9278
|
-
process.stdout.write(
|
|
9279
|
-
`Algo order placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9280
|
-
`
|
|
9281
|
-
);
|
|
9525
|
+
emitWriteResult2(data?.[0], "Algo order placed", "algoId");
|
|
9282
9526
|
}
|
|
9283
9527
|
async function cmdSwapAlgoAmend(run, opts) {
|
|
9284
9528
|
const result = await run("swap_amend_algo_order", {
|
|
@@ -9292,11 +9536,7 @@ async function cmdSwapAlgoAmend(run, opts) {
|
|
|
9292
9536
|
});
|
|
9293
9537
|
const data = getData4(result);
|
|
9294
9538
|
if (opts.json) return printJson(data);
|
|
9295
|
-
|
|
9296
|
-
process.stdout.write(
|
|
9297
|
-
`Algo order amended: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9298
|
-
`
|
|
9299
|
-
);
|
|
9539
|
+
emitWriteResult2(data?.[0], "Algo order amended", "algoId");
|
|
9300
9540
|
}
|
|
9301
9541
|
async function cmdSwapAlgoTrailPlace(run, opts) {
|
|
9302
9542
|
const result = await run("swap_place_move_stop_order", {
|
|
@@ -9312,21 +9552,13 @@ async function cmdSwapAlgoTrailPlace(run, opts) {
|
|
|
9312
9552
|
});
|
|
9313
9553
|
const data = getData4(result);
|
|
9314
9554
|
if (opts.json) return printJson(data);
|
|
9315
|
-
|
|
9316
|
-
process.stdout.write(
|
|
9317
|
-
`Trailing stop placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9318
|
-
`
|
|
9319
|
-
);
|
|
9555
|
+
emitWriteResult2(data?.[0], "Trailing stop placed", "algoId");
|
|
9320
9556
|
}
|
|
9321
9557
|
async function cmdSwapAlgoCancel(run, instId, algoId, json) {
|
|
9322
9558
|
const result = await run("swap_cancel_algo_orders", { orders: [{ instId, algoId }] });
|
|
9323
9559
|
const data = getData4(result);
|
|
9324
9560
|
if (json) return printJson(data);
|
|
9325
|
-
|
|
9326
|
-
process.stdout.write(
|
|
9327
|
-
`Algo order cancelled: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9328
|
-
`
|
|
9329
|
-
);
|
|
9561
|
+
emitWriteResult2(data?.[0], "Algo order cancelled", "algoId");
|
|
9330
9562
|
}
|
|
9331
9563
|
async function cmdSwapAlgoOrders(run, opts) {
|
|
9332
9564
|
const result = await run("swap_get_algo_orders", {
|
|
@@ -9337,7 +9569,7 @@ async function cmdSwapAlgoOrders(run, opts) {
|
|
|
9337
9569
|
const orders = getData4(result);
|
|
9338
9570
|
if (opts.json) return printJson(orders);
|
|
9339
9571
|
if (!(orders ?? []).length) {
|
|
9340
|
-
|
|
9572
|
+
outputLine("No algo orders");
|
|
9341
9573
|
return;
|
|
9342
9574
|
}
|
|
9343
9575
|
printTable(
|
|
@@ -9374,7 +9606,7 @@ async function cmdSwapGet(run, opts) {
|
|
|
9374
9606
|
if (opts.json) return printJson(data);
|
|
9375
9607
|
const o = data?.[0];
|
|
9376
9608
|
if (!o) {
|
|
9377
|
-
|
|
9609
|
+
outputLine("No data");
|
|
9378
9610
|
return;
|
|
9379
9611
|
}
|
|
9380
9612
|
printKv({
|
|
@@ -9401,8 +9633,7 @@ async function cmdSwapClose(run, opts) {
|
|
|
9401
9633
|
const data = getData4(result);
|
|
9402
9634
|
if (opts.json) return printJson(data);
|
|
9403
9635
|
const r = data?.[0];
|
|
9404
|
-
|
|
9405
|
-
`);
|
|
9636
|
+
outputLine(`Position closed: ${r?.["instId"]} ${r?.["posSide"] ?? ""}`);
|
|
9406
9637
|
}
|
|
9407
9638
|
async function cmdSwapGetLeverage(run, opts) {
|
|
9408
9639
|
const result = await run("swap_get_leverage", { instId: opts.instId, mgnMode: opts.mgnMode });
|
|
@@ -9427,9 +9658,7 @@ async function cmdSwapAmend(run, opts) {
|
|
|
9427
9658
|
});
|
|
9428
9659
|
const data = getData4(result);
|
|
9429
9660
|
if (opts.json) return printJson(data);
|
|
9430
|
-
|
|
9431
|
-
process.stdout.write(`Order amended: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9432
|
-
`);
|
|
9661
|
+
emitWriteResult2(data?.[0], "Order amended", "ordId");
|
|
9433
9662
|
}
|
|
9434
9663
|
async function cmdSwapSetLeverage(run, opts) {
|
|
9435
9664
|
const result = await run("swap_set_leverage", {
|
|
@@ -9441,20 +9670,19 @@ async function cmdSwapSetLeverage(run, opts) {
|
|
|
9441
9670
|
const data = getData4(result);
|
|
9442
9671
|
if (opts.json) return printJson(data);
|
|
9443
9672
|
const r = data?.[0];
|
|
9444
|
-
|
|
9445
|
-
`);
|
|
9673
|
+
outputLine(`Leverage set: ${r?.["lever"]}x ${r?.["instId"]}`);
|
|
9446
9674
|
}
|
|
9447
9675
|
async function cmdSwapBatch(run, opts) {
|
|
9448
9676
|
let parsed;
|
|
9449
9677
|
try {
|
|
9450
9678
|
parsed = JSON.parse(opts.orders);
|
|
9451
9679
|
} catch {
|
|
9452
|
-
|
|
9680
|
+
errorLine("Error: --orders must be a valid JSON array");
|
|
9453
9681
|
process.exitCode = 1;
|
|
9454
9682
|
return;
|
|
9455
9683
|
}
|
|
9456
9684
|
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
9457
|
-
|
|
9685
|
+
errorLine("Error: --orders must be a non-empty JSON array");
|
|
9458
9686
|
process.exitCode = 1;
|
|
9459
9687
|
return;
|
|
9460
9688
|
}
|
|
@@ -9465,24 +9693,39 @@ async function cmdSwapBatch(run, opts) {
|
|
|
9465
9693
|
};
|
|
9466
9694
|
const tool = toolMap[opts.action];
|
|
9467
9695
|
if (!tool) {
|
|
9468
|
-
|
|
9469
|
-
`);
|
|
9696
|
+
errorLine("Error: --action must be one of: place, amend, cancel");
|
|
9470
9697
|
process.exitCode = 1;
|
|
9471
9698
|
return;
|
|
9472
9699
|
}
|
|
9473
9700
|
const result = await run(tool, tool === "swap_batch_orders" ? { action: opts.action, orders: parsed } : { orders: parsed });
|
|
9474
9701
|
const data = getData4(result);
|
|
9475
9702
|
if (opts.json) return printJson(data);
|
|
9476
|
-
|
|
9477
|
-
process.stdout.write(`${r["ordId"] ?? r["clOrdId"] ?? "?"}: ${r["sCode"] === "0" ? "OK" : r["sMsg"]}
|
|
9478
|
-
`);
|
|
9479
|
-
}
|
|
9703
|
+
emitBatchResults2(data ?? []);
|
|
9480
9704
|
}
|
|
9481
9705
|
|
|
9482
9706
|
// src/commands/futures.ts
|
|
9483
9707
|
function getData5(result) {
|
|
9484
9708
|
return result.data;
|
|
9485
9709
|
}
|
|
9710
|
+
function emitWriteResult3(item, label, idKey) {
|
|
9711
|
+
const isError = item?.["sCode"] !== "0" && item?.["sCode"] !== 0;
|
|
9712
|
+
if (isError) {
|
|
9713
|
+
errorLine(`Error: ${item?.["sMsg"]} (sCode ${item?.["sCode"]})`);
|
|
9714
|
+
} else {
|
|
9715
|
+
outputLine(`${label}: ${item?.[idKey]} (OK)`);
|
|
9716
|
+
}
|
|
9717
|
+
}
|
|
9718
|
+
function emitBatchResults3(items) {
|
|
9719
|
+
for (const r of items) {
|
|
9720
|
+
const isError = r["sCode"] !== "0" && r["sCode"] !== 0;
|
|
9721
|
+
const id = r["ordId"] ?? r["clOrdId"] ?? "?";
|
|
9722
|
+
if (isError) {
|
|
9723
|
+
errorLine(`${id}: ${r["sMsg"]} (sCode ${r["sCode"]})`);
|
|
9724
|
+
} else {
|
|
9725
|
+
outputLine(`${id}: OK`);
|
|
9726
|
+
}
|
|
9727
|
+
}
|
|
9728
|
+
}
|
|
9486
9729
|
async function cmdFuturesOrders(run, opts) {
|
|
9487
9730
|
const result = await run("futures_get_orders", { instId: opts.instId, status: opts.status });
|
|
9488
9731
|
const orders = getData5(result);
|
|
@@ -9506,7 +9749,7 @@ async function cmdFuturesPositions(run, instId, json) {
|
|
|
9506
9749
|
if (json) return printJson(positions);
|
|
9507
9750
|
const open = (positions ?? []).filter((p) => Number(p["pos"]) !== 0);
|
|
9508
9751
|
if (!open.length) {
|
|
9509
|
-
|
|
9752
|
+
outputLine("No open positions");
|
|
9510
9753
|
return;
|
|
9511
9754
|
}
|
|
9512
9755
|
printTable(
|
|
@@ -9542,6 +9785,7 @@ async function cmdFuturesPlace(run, opts) {
|
|
|
9542
9785
|
side: opts.side,
|
|
9543
9786
|
ordType: opts.ordType,
|
|
9544
9787
|
sz: opts.sz,
|
|
9788
|
+
tgtCcy: opts.tgtCcy,
|
|
9545
9789
|
posSide: opts.posSide,
|
|
9546
9790
|
px: opts.px,
|
|
9547
9791
|
reduceOnly: opts.reduceOnly,
|
|
@@ -9552,9 +9796,7 @@ async function cmdFuturesPlace(run, opts) {
|
|
|
9552
9796
|
});
|
|
9553
9797
|
const data = getData5(result);
|
|
9554
9798
|
if (opts.json) return printJson(data);
|
|
9555
|
-
|
|
9556
|
-
process.stdout.write(`Order placed: ${order?.["ordId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9557
|
-
`);
|
|
9799
|
+
emitWriteResult3(data?.[0], "Order placed", "ordId");
|
|
9558
9800
|
}
|
|
9559
9801
|
async function cmdFuturesCancel(run, opts) {
|
|
9560
9802
|
const { instId, ordId, clOrdId, json } = opts;
|
|
@@ -9562,9 +9804,7 @@ async function cmdFuturesCancel(run, opts) {
|
|
|
9562
9804
|
const result = await run("futures_cancel_order", { instId, ...ordId ? { ordId } : { clOrdId } });
|
|
9563
9805
|
const data = getData5(result);
|
|
9564
9806
|
if (json) return printJson(data);
|
|
9565
|
-
|
|
9566
|
-
process.stdout.write(`Cancelled: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9567
|
-
`);
|
|
9807
|
+
emitWriteResult3(data?.[0], "Cancelled", "ordId");
|
|
9568
9808
|
}
|
|
9569
9809
|
async function cmdFuturesGet(run, opts) {
|
|
9570
9810
|
const result = await run("futures_get_order", { instId: opts.instId, ordId: opts.ordId });
|
|
@@ -9572,7 +9812,7 @@ async function cmdFuturesGet(run, opts) {
|
|
|
9572
9812
|
if (opts.json) return printJson(data);
|
|
9573
9813
|
const o = data?.[0];
|
|
9574
9814
|
if (!o) {
|
|
9575
|
-
|
|
9815
|
+
outputLine("No data");
|
|
9576
9816
|
return;
|
|
9577
9817
|
}
|
|
9578
9818
|
printKv({
|
|
@@ -9599,9 +9839,7 @@ async function cmdFuturesAmend(run, opts) {
|
|
|
9599
9839
|
});
|
|
9600
9840
|
const data = getData5(result);
|
|
9601
9841
|
if (opts.json) return printJson(data);
|
|
9602
|
-
|
|
9603
|
-
process.stdout.write(`Order amended: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9604
|
-
`);
|
|
9842
|
+
emitWriteResult3(data?.[0], "Order amended", "ordId");
|
|
9605
9843
|
}
|
|
9606
9844
|
async function cmdFuturesClose(run, opts) {
|
|
9607
9845
|
const result = await run("futures_close_position", {
|
|
@@ -9613,8 +9851,7 @@ async function cmdFuturesClose(run, opts) {
|
|
|
9613
9851
|
const data = getData5(result);
|
|
9614
9852
|
if (opts.json) return printJson(data);
|
|
9615
9853
|
const r = data?.[0];
|
|
9616
|
-
|
|
9617
|
-
`);
|
|
9854
|
+
outputLine(`Position closed: ${r?.["instId"]} ${r?.["posSide"] ?? ""}`);
|
|
9618
9855
|
}
|
|
9619
9856
|
async function cmdFuturesSetLeverage(run, opts) {
|
|
9620
9857
|
const result = await run("futures_set_leverage", {
|
|
@@ -9626,8 +9863,7 @@ async function cmdFuturesSetLeverage(run, opts) {
|
|
|
9626
9863
|
const data = getData5(result);
|
|
9627
9864
|
if (opts.json) return printJson(data);
|
|
9628
9865
|
const r = data?.[0];
|
|
9629
|
-
|
|
9630
|
-
`);
|
|
9866
|
+
outputLine(`Leverage set: ${r?.["lever"]}x ${r?.["instId"]}`);
|
|
9631
9867
|
}
|
|
9632
9868
|
async function cmdFuturesGetLeverage(run, opts) {
|
|
9633
9869
|
const result = await run("futures_get_leverage", { instId: opts.instId, mgnMode: opts.mgnMode });
|
|
@@ -9647,12 +9883,12 @@ async function cmdFuturesBatch(run, opts) {
|
|
|
9647
9883
|
try {
|
|
9648
9884
|
parsed = JSON.parse(opts.orders);
|
|
9649
9885
|
} catch {
|
|
9650
|
-
|
|
9886
|
+
errorLine("Error: --orders must be a valid JSON array");
|
|
9651
9887
|
process.exitCode = 1;
|
|
9652
9888
|
return;
|
|
9653
9889
|
}
|
|
9654
9890
|
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
9655
|
-
|
|
9891
|
+
errorLine("Error: --orders must be a non-empty JSON array");
|
|
9656
9892
|
process.exitCode = 1;
|
|
9657
9893
|
return;
|
|
9658
9894
|
}
|
|
@@ -9663,18 +9899,14 @@ async function cmdFuturesBatch(run, opts) {
|
|
|
9663
9899
|
};
|
|
9664
9900
|
const tool = toolMap[opts.action];
|
|
9665
9901
|
if (!tool) {
|
|
9666
|
-
|
|
9667
|
-
`);
|
|
9902
|
+
errorLine("Error: --action must be one of: place, amend, cancel");
|
|
9668
9903
|
process.exitCode = 1;
|
|
9669
9904
|
return;
|
|
9670
9905
|
}
|
|
9671
9906
|
const result = await run(tool, tool === "futures_batch_orders" ? { orders: parsed } : { orders: parsed });
|
|
9672
9907
|
const data = getData5(result);
|
|
9673
9908
|
if (opts.json) return printJson(data);
|
|
9674
|
-
|
|
9675
|
-
process.stdout.write(`${r["ordId"] ?? r["clOrdId"] ?? "?"}: ${r["sCode"] === "0" ? "OK" : r["sMsg"]}
|
|
9676
|
-
`);
|
|
9677
|
-
}
|
|
9909
|
+
emitBatchResults3(data ?? []);
|
|
9678
9910
|
}
|
|
9679
9911
|
async function cmdFuturesAlgoPlace(run, opts) {
|
|
9680
9912
|
const result = await run("futures_place_algo_order", {
|
|
@@ -9695,11 +9927,7 @@ async function cmdFuturesAlgoPlace(run, opts) {
|
|
|
9695
9927
|
});
|
|
9696
9928
|
const data = getData5(result);
|
|
9697
9929
|
if (opts.json) return printJson(data);
|
|
9698
|
-
|
|
9699
|
-
process.stdout.write(
|
|
9700
|
-
`Algo order placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9701
|
-
`
|
|
9702
|
-
);
|
|
9930
|
+
emitWriteResult3(data?.[0], "Algo order placed", "algoId");
|
|
9703
9931
|
}
|
|
9704
9932
|
async function cmdFuturesAlgoTrailPlace(run, opts) {
|
|
9705
9933
|
const result = await run("futures_place_move_stop_order", {
|
|
@@ -9715,11 +9943,7 @@ async function cmdFuturesAlgoTrailPlace(run, opts) {
|
|
|
9715
9943
|
});
|
|
9716
9944
|
const data = getData5(result);
|
|
9717
9945
|
if (opts.json) return printJson(data);
|
|
9718
|
-
|
|
9719
|
-
process.stdout.write(
|
|
9720
|
-
`Trailing stop placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9721
|
-
`
|
|
9722
|
-
);
|
|
9946
|
+
emitWriteResult3(data?.[0], "Trailing stop placed", "algoId");
|
|
9723
9947
|
}
|
|
9724
9948
|
async function cmdFuturesAlgoAmend(run, opts) {
|
|
9725
9949
|
const result = await run("futures_amend_algo_order", {
|
|
@@ -9733,21 +9957,13 @@ async function cmdFuturesAlgoAmend(run, opts) {
|
|
|
9733
9957
|
});
|
|
9734
9958
|
const data = getData5(result);
|
|
9735
9959
|
if (opts.json) return printJson(data);
|
|
9736
|
-
|
|
9737
|
-
process.stdout.write(
|
|
9738
|
-
`Algo order amended: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9739
|
-
`
|
|
9740
|
-
);
|
|
9960
|
+
emitWriteResult3(data?.[0], "Algo order amended", "algoId");
|
|
9741
9961
|
}
|
|
9742
9962
|
async function cmdFuturesAlgoCancel(run, instId, algoId, json) {
|
|
9743
9963
|
const result = await run("futures_cancel_algo_orders", { orders: [{ instId, algoId }] });
|
|
9744
9964
|
const data = getData5(result);
|
|
9745
9965
|
if (json) return printJson(data);
|
|
9746
|
-
|
|
9747
|
-
process.stdout.write(
|
|
9748
|
-
`Algo order cancelled: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9749
|
-
`
|
|
9750
|
-
);
|
|
9966
|
+
emitWriteResult3(data?.[0], "Algo order cancelled", "algoId");
|
|
9751
9967
|
}
|
|
9752
9968
|
async function cmdFuturesAlgoOrders(run, opts) {
|
|
9753
9969
|
const result = await run("futures_get_algo_orders", {
|
|
@@ -9758,7 +9974,7 @@ async function cmdFuturesAlgoOrders(run, opts) {
|
|
|
9758
9974
|
const orders = getData5(result);
|
|
9759
9975
|
if (opts.json) return printJson(orders);
|
|
9760
9976
|
if (!(orders ?? []).length) {
|
|
9761
|
-
|
|
9977
|
+
outputLine("No algo orders");
|
|
9762
9978
|
return;
|
|
9763
9979
|
}
|
|
9764
9980
|
printTable(
|
|
@@ -9779,6 +9995,25 @@ async function cmdFuturesAlgoOrders(run, opts) {
|
|
|
9779
9995
|
function getData6(result) {
|
|
9780
9996
|
return result.data;
|
|
9781
9997
|
}
|
|
9998
|
+
function emitWriteResult4(item, label, idKey) {
|
|
9999
|
+
const isError = item?.["sCode"] !== "0" && item?.["sCode"] !== 0;
|
|
10000
|
+
if (isError) {
|
|
10001
|
+
errorLine(`Error: ${item?.["sMsg"]} (sCode ${item?.["sCode"]})`);
|
|
10002
|
+
} else {
|
|
10003
|
+
outputLine(`${label}: ${item?.[idKey]} (OK)`);
|
|
10004
|
+
}
|
|
10005
|
+
}
|
|
10006
|
+
function emitBatchResults4(items) {
|
|
10007
|
+
for (const r of items) {
|
|
10008
|
+
const isError = r["sCode"] !== "0" && r["sCode"] !== 0;
|
|
10009
|
+
const id = r["ordId"] ?? r["clOrdId"] ?? "?";
|
|
10010
|
+
if (isError) {
|
|
10011
|
+
errorLine(`${id}: ${r["sMsg"]} (sCode ${r["sCode"]})`);
|
|
10012
|
+
} else {
|
|
10013
|
+
outputLine(`${id}: OK`);
|
|
10014
|
+
}
|
|
10015
|
+
}
|
|
10016
|
+
}
|
|
9782
10017
|
async function cmdOptionOrders(run, opts) {
|
|
9783
10018
|
const result = await run("option_get_orders", {
|
|
9784
10019
|
instId: opts.instId,
|
|
@@ -9809,7 +10044,7 @@ async function cmdOptionGet(run, opts) {
|
|
|
9809
10044
|
if (opts.json) return printJson(data);
|
|
9810
10045
|
const o = data?.[0];
|
|
9811
10046
|
if (!o) {
|
|
9812
|
-
|
|
10047
|
+
outputLine("No data");
|
|
9813
10048
|
return;
|
|
9814
10049
|
}
|
|
9815
10050
|
printKv({
|
|
@@ -9834,7 +10069,7 @@ async function cmdOptionPositions(run, opts) {
|
|
|
9834
10069
|
if (opts.json) return printJson(positions);
|
|
9835
10070
|
const open = (positions ?? []).filter((p) => Number(p["pos"]) !== 0);
|
|
9836
10071
|
if (!open.length) {
|
|
9837
|
-
|
|
10072
|
+
outputLine("No open positions");
|
|
9838
10073
|
return;
|
|
9839
10074
|
}
|
|
9840
10075
|
printTable(
|
|
@@ -9924,9 +10159,7 @@ async function cmdOptionPlace(run, opts) {
|
|
|
9924
10159
|
});
|
|
9925
10160
|
const data = getData6(result);
|
|
9926
10161
|
if (opts.json) return printJson(data);
|
|
9927
|
-
|
|
9928
|
-
process.stdout.write(`Order placed: ${order?.["ordId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9929
|
-
`);
|
|
10162
|
+
emitWriteResult4(data?.[0], "Order placed", "ordId");
|
|
9930
10163
|
}
|
|
9931
10164
|
async function cmdOptionCancel(run, opts) {
|
|
9932
10165
|
const result = await run("option_cancel_order", {
|
|
@@ -9936,9 +10169,7 @@ async function cmdOptionCancel(run, opts) {
|
|
|
9936
10169
|
});
|
|
9937
10170
|
const data = getData6(result);
|
|
9938
10171
|
if (opts.json) return printJson(data);
|
|
9939
|
-
|
|
9940
|
-
process.stdout.write(`Cancelled: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9941
|
-
`);
|
|
10172
|
+
emitWriteResult4(data?.[0], "Cancelled", "ordId");
|
|
9942
10173
|
}
|
|
9943
10174
|
async function cmdOptionAmend(run, opts) {
|
|
9944
10175
|
const result = await run("option_amend_order", {
|
|
@@ -9950,31 +10181,26 @@ async function cmdOptionAmend(run, opts) {
|
|
|
9950
10181
|
});
|
|
9951
10182
|
const data = getData6(result);
|
|
9952
10183
|
if (opts.json) return printJson(data);
|
|
9953
|
-
|
|
9954
|
-
process.stdout.write(`Amended: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9955
|
-
`);
|
|
10184
|
+
emitWriteResult4(data?.[0], "Amended", "ordId");
|
|
9956
10185
|
}
|
|
9957
10186
|
async function cmdOptionBatchCancel(run, opts) {
|
|
9958
10187
|
let parsed;
|
|
9959
10188
|
try {
|
|
9960
10189
|
parsed = JSON.parse(opts.orders);
|
|
9961
10190
|
} catch {
|
|
9962
|
-
|
|
10191
|
+
errorLine("Error: --orders must be a valid JSON array");
|
|
9963
10192
|
process.exitCode = 1;
|
|
9964
10193
|
return;
|
|
9965
10194
|
}
|
|
9966
10195
|
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
9967
|
-
|
|
10196
|
+
errorLine("Error: --orders must be a non-empty JSON array");
|
|
9968
10197
|
process.exitCode = 1;
|
|
9969
10198
|
return;
|
|
9970
10199
|
}
|
|
9971
10200
|
const result = await run("option_batch_cancel", { orders: parsed });
|
|
9972
10201
|
const data = getData6(result);
|
|
9973
10202
|
if (opts.json) return printJson(data);
|
|
9974
|
-
|
|
9975
|
-
process.stdout.write(`${r["ordId"]}: ${r["sCode"] === "0" ? "OK" : r["sMsg"]}
|
|
9976
|
-
`);
|
|
9977
|
-
}
|
|
10203
|
+
emitBatchResults4(data ?? []);
|
|
9978
10204
|
}
|
|
9979
10205
|
async function cmdOptionAlgoPlace(run, opts) {
|
|
9980
10206
|
const result = await run("option_place_algo_order", {
|
|
@@ -9992,11 +10218,7 @@ async function cmdOptionAlgoPlace(run, opts) {
|
|
|
9992
10218
|
});
|
|
9993
10219
|
const data = getData6(result);
|
|
9994
10220
|
if (opts.json) return printJson(data);
|
|
9995
|
-
|
|
9996
|
-
process.stdout.write(
|
|
9997
|
-
`Algo order placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9998
|
-
`
|
|
9999
|
-
);
|
|
10221
|
+
emitWriteResult4(data?.[0], "Algo order placed", "algoId");
|
|
10000
10222
|
}
|
|
10001
10223
|
async function cmdOptionAlgoAmend(run, opts) {
|
|
10002
10224
|
const result = await run("option_amend_algo_order", {
|
|
@@ -10010,21 +10232,13 @@ async function cmdOptionAlgoAmend(run, opts) {
|
|
|
10010
10232
|
});
|
|
10011
10233
|
const data = getData6(result);
|
|
10012
10234
|
if (opts.json) return printJson(data);
|
|
10013
|
-
|
|
10014
|
-
process.stdout.write(
|
|
10015
|
-
`Algo order amended: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
10016
|
-
`
|
|
10017
|
-
);
|
|
10235
|
+
emitWriteResult4(data?.[0], "Algo order amended", "algoId");
|
|
10018
10236
|
}
|
|
10019
10237
|
async function cmdOptionAlgoCancel(run, opts) {
|
|
10020
10238
|
const result = await run("option_cancel_algo_orders", { orders: [{ instId: opts.instId, algoId: opts.algoId }] });
|
|
10021
10239
|
const data = getData6(result);
|
|
10022
10240
|
if (opts.json) return printJson(data);
|
|
10023
|
-
|
|
10024
|
-
process.stdout.write(
|
|
10025
|
-
`Algo order cancelled: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
10026
|
-
`
|
|
10027
|
-
);
|
|
10241
|
+
emitWriteResult4(data?.[0], "Algo order cancelled", "algoId");
|
|
10028
10242
|
}
|
|
10029
10243
|
async function cmdOptionAlgoOrders(run, opts) {
|
|
10030
10244
|
const result = await run("option_get_algo_orders", {
|
|
@@ -10035,7 +10249,7 @@ async function cmdOptionAlgoOrders(run, opts) {
|
|
|
10035
10249
|
const orders = getData6(result);
|
|
10036
10250
|
if (opts.json) return printJson(orders);
|
|
10037
10251
|
if (!(orders ?? []).length) {
|
|
10038
|
-
|
|
10252
|
+
outputLine("No algo orders");
|
|
10039
10253
|
return;
|
|
10040
10254
|
}
|
|
10041
10255
|
printTable(
|
|
@@ -10136,21 +10350,18 @@ function prompt(rl, question) {
|
|
|
10136
10350
|
function cmdConfigShow(json) {
|
|
10137
10351
|
const config = readFullConfig();
|
|
10138
10352
|
if (json) return printJson(config);
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
`);
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
`);
|
|
10353
|
+
outputLine(`Config: ${configFilePath()}`);
|
|
10354
|
+
outputLine("");
|
|
10355
|
+
outputLine(`default_profile: ${config.default_profile ?? "(not set)"}`);
|
|
10356
|
+
outputLine("");
|
|
10145
10357
|
for (const [name, profile] of Object.entries(config.profiles)) {
|
|
10146
|
-
|
|
10147
|
-
`);
|
|
10358
|
+
outputLine(`[${name}]`);
|
|
10148
10359
|
printKv({
|
|
10149
10360
|
api_key: profile.api_key ? maskSecret(profile.api_key) : "(not set)",
|
|
10150
10361
|
demo: profile.demo ?? false,
|
|
10151
10362
|
base_url: profile.base_url ?? "(default)"
|
|
10152
10363
|
}, 2);
|
|
10153
|
-
|
|
10364
|
+
outputLine("");
|
|
10154
10365
|
}
|
|
10155
10366
|
}
|
|
10156
10367
|
function cmdConfigSet(key, value) {
|
|
@@ -10158,11 +10369,9 @@ function cmdConfigSet(key, value) {
|
|
|
10158
10369
|
if (key === "default_profile") {
|
|
10159
10370
|
config.default_profile = value;
|
|
10160
10371
|
writeCliConfig(config);
|
|
10161
|
-
|
|
10162
|
-
`);
|
|
10372
|
+
outputLine(`default_profile set to "${value}"`);
|
|
10163
10373
|
} else {
|
|
10164
|
-
|
|
10165
|
-
`);
|
|
10374
|
+
errorLine(`Unknown config key: ${key}`);
|
|
10166
10375
|
process.exitCode = 1;
|
|
10167
10376
|
}
|
|
10168
10377
|
}
|
|
@@ -10198,24 +10407,22 @@ function buildProfileEntry(siteKey, apiKey, secretKey, passphrase, demo) {
|
|
|
10198
10407
|
}
|
|
10199
10408
|
async function cmdConfigInit(lang = "en") {
|
|
10200
10409
|
const t = messages[lang];
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
`);
|
|
10410
|
+
outputLine(t.title);
|
|
10411
|
+
outputLine("");
|
|
10204
10412
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
10205
10413
|
try {
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
|
|
10210
|
-
process.stdout.write(" 3) US (app.okx.com)\n");
|
|
10414
|
+
outputLine(t.selectSite);
|
|
10415
|
+
outputLine(" 1) Global (www.okx.com) [default]");
|
|
10416
|
+
outputLine(" 2) EEA (my.okx.com)");
|
|
10417
|
+
outputLine(" 3) US (app.okx.com)");
|
|
10211
10418
|
const siteRaw = (await prompt(rl, t.sitePrompt)).trim();
|
|
10212
10419
|
const siteKey = parseSiteKey(siteRaw);
|
|
10213
10420
|
const demoRaw = (await prompt(rl, t.demoPrompt)).trim().toLowerCase();
|
|
10214
10421
|
const demo = demoRaw !== "n";
|
|
10215
10422
|
const apiUrl = buildApiUrl(siteKey, demo);
|
|
10216
10423
|
const hintText = demo ? t.hintDemo : t.hintLive;
|
|
10217
|
-
|
|
10218
|
-
|
|
10424
|
+
output(t.createApiKey(apiUrl));
|
|
10425
|
+
output(t.hint(hintText));
|
|
10219
10426
|
try {
|
|
10220
10427
|
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
10221
10428
|
spawnSync2(opener, [apiUrl], { stdio: "ignore", shell: process.platform === "win32" });
|
|
@@ -10228,35 +10435,30 @@ async function cmdConfigInit(lang = "en") {
|
|
|
10228
10435
|
if (config.profiles[profileName]) {
|
|
10229
10436
|
const overwrite = (await prompt(rl, t.profileExists(profileName))).trim().toLowerCase();
|
|
10230
10437
|
if (overwrite !== "y") {
|
|
10231
|
-
|
|
10232
|
-
`);
|
|
10438
|
+
outputLine(t.cancelled);
|
|
10233
10439
|
return;
|
|
10234
10440
|
}
|
|
10235
10441
|
}
|
|
10236
10442
|
const apiKey = (await prompt(rl, "API Key: ")).trim();
|
|
10237
10443
|
if (!apiKey) {
|
|
10238
|
-
|
|
10239
|
-
`);
|
|
10444
|
+
errorLine(t.emptyApiKey);
|
|
10240
10445
|
process.exitCode = 1;
|
|
10241
10446
|
return;
|
|
10242
10447
|
}
|
|
10243
10448
|
const secretKey = (await prompt(rl, "Secret Key: ")).trim();
|
|
10244
10449
|
if (!secretKey) {
|
|
10245
|
-
|
|
10246
|
-
`);
|
|
10450
|
+
errorLine(t.emptySecretKey);
|
|
10247
10451
|
process.exitCode = 1;
|
|
10248
10452
|
return;
|
|
10249
10453
|
}
|
|
10250
10454
|
const passphrase = (await prompt(rl, "Passphrase: ")).trim();
|
|
10251
10455
|
if (!passphrase) {
|
|
10252
|
-
|
|
10253
|
-
`);
|
|
10456
|
+
errorLine(t.emptyPassphrase);
|
|
10254
10457
|
process.exitCode = 1;
|
|
10255
10458
|
return;
|
|
10256
10459
|
}
|
|
10257
10460
|
if (demo) {
|
|
10258
|
-
|
|
10259
|
-
`);
|
|
10461
|
+
outputLine(t.demoSelected);
|
|
10260
10462
|
}
|
|
10261
10463
|
const profileEntry = buildProfileEntry(siteKey, apiKey, secretKey, passphrase, demo);
|
|
10262
10464
|
config.profiles[profileName] = profileEntry;
|
|
@@ -10266,18 +10468,18 @@ async function cmdConfigInit(lang = "en") {
|
|
|
10266
10468
|
const configPath = configFilePath();
|
|
10267
10469
|
try {
|
|
10268
10470
|
writeCliConfig(config);
|
|
10269
|
-
|
|
10270
|
-
|
|
10271
|
-
|
|
10471
|
+
output(t.saved(configPath));
|
|
10472
|
+
output(t.defaultProfile(profileName));
|
|
10473
|
+
output(t.usage);
|
|
10272
10474
|
} catch (err) {
|
|
10273
10475
|
const message = err instanceof Error ? err.message : String(err);
|
|
10274
10476
|
const isPermission = err instanceof Error && "code" in err && (err.code === "EACCES" || err.code === "EPERM");
|
|
10275
|
-
|
|
10477
|
+
errorOutput(t.writeFailed(message));
|
|
10276
10478
|
if (isPermission) {
|
|
10277
|
-
|
|
10479
|
+
errorOutput(t.permissionDenied(configPath));
|
|
10278
10480
|
}
|
|
10279
|
-
|
|
10280
|
-
|
|
10481
|
+
errorOutput(t.manualWrite(configPath));
|
|
10482
|
+
outputLine(stringify(config));
|
|
10281
10483
|
process.exitCode = 1;
|
|
10282
10484
|
}
|
|
10283
10485
|
} finally {
|
|
@@ -10301,9 +10503,8 @@ function cmdConfigAddProfile(kvPairs, force) {
|
|
|
10301
10503
|
if (!sk) missing.push("SK");
|
|
10302
10504
|
if (!pp) missing.push("PP");
|
|
10303
10505
|
if (missing.length > 0) {
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
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");
|
|
10506
|
+
errorLine(`Error: missing required parameter(s): ${missing.join(", ")}`);
|
|
10507
|
+
errorLine("Usage: okx config add-profile AK=<key> SK=<secret> PP=<passphrase> [site=global|eea|us] [demo=true|false] [name=<name>] [--force]");
|
|
10307
10508
|
process.exitCode = 1;
|
|
10308
10509
|
return;
|
|
10309
10510
|
}
|
|
@@ -10313,8 +10514,7 @@ function cmdConfigAddProfile(kvPairs, force) {
|
|
|
10313
10514
|
const profileName = params["NAME"] ?? defaultName;
|
|
10314
10515
|
const config = readFullConfig();
|
|
10315
10516
|
if (config.profiles[profileName] && !force) {
|
|
10316
|
-
|
|
10317
|
-
`);
|
|
10517
|
+
errorLine(`Error: profile "${profileName}" already exists. Use --force to overwrite.`);
|
|
10318
10518
|
process.exitCode = 1;
|
|
10319
10519
|
return;
|
|
10320
10520
|
}
|
|
@@ -10323,65 +10523,54 @@ function cmdConfigAddProfile(kvPairs, force) {
|
|
|
10323
10523
|
config.profiles[profileName] = entry;
|
|
10324
10524
|
config.default_profile = profileName;
|
|
10325
10525
|
writeCliConfig(config);
|
|
10326
|
-
|
|
10327
|
-
`);
|
|
10328
|
-
process.stdout.write(`Default profile set to: ${profileName}
|
|
10329
|
-
`);
|
|
10526
|
+
outputLine(`Profile "${profileName}" saved to ${configFilePath()}`);
|
|
10527
|
+
outputLine(`Default profile set to: ${profileName}`);
|
|
10330
10528
|
}
|
|
10331
10529
|
function cmdConfigListProfile() {
|
|
10332
10530
|
const config = readFullConfig();
|
|
10333
10531
|
const entries = Object.entries(config.profiles);
|
|
10334
10532
|
if (entries.length === 0) {
|
|
10335
|
-
|
|
10533
|
+
outputLine("No profiles found. Run: okx config add-profile AK=<key> SK=<secret> PP=<passphrase>");
|
|
10336
10534
|
return;
|
|
10337
10535
|
}
|
|
10338
|
-
|
|
10339
|
-
|
|
10340
|
-
`);
|
|
10536
|
+
outputLine(`Config: ${configFilePath()}`);
|
|
10537
|
+
outputLine("");
|
|
10341
10538
|
for (const [name, profile] of entries) {
|
|
10342
10539
|
const isDefault = name === config.default_profile;
|
|
10343
10540
|
const marker = isDefault ? " *" : "";
|
|
10344
10541
|
const site = profile.site ?? inferSiteFromBaseUrl(profile.base_url);
|
|
10345
10542
|
const mode = profile.demo !== false ? "demo (\u6A21\u62DF\u76D8)" : "live (\u5B9E\u76D8)";
|
|
10346
|
-
|
|
10347
|
-
`);
|
|
10348
|
-
|
|
10349
|
-
`);
|
|
10350
|
-
|
|
10351
|
-
`);
|
|
10352
|
-
|
|
10353
|
-
`);
|
|
10354
|
-
process.stdout.write(` site: ${site}
|
|
10355
|
-
`);
|
|
10356
|
-
process.stdout.write(` mode: ${mode}
|
|
10357
|
-
`);
|
|
10358
|
-
process.stdout.write("\n");
|
|
10543
|
+
outputLine(`[${name}]${marker}`);
|
|
10544
|
+
outputLine(` api_key: ${maskSecret(profile.api_key)}`);
|
|
10545
|
+
outputLine(` secret_key: ${maskSecret(profile.secret_key)}`);
|
|
10546
|
+
outputLine(` passphrase: ${maskSecret(profile.passphrase)}`);
|
|
10547
|
+
outputLine(` site: ${site}`);
|
|
10548
|
+
outputLine(` mode: ${mode}`);
|
|
10549
|
+
outputLine("");
|
|
10359
10550
|
}
|
|
10360
10551
|
}
|
|
10361
10552
|
function cmdConfigUse(profileName) {
|
|
10362
10553
|
if (!profileName) {
|
|
10363
|
-
|
|
10554
|
+
errorLine("Error: profile name is required.");
|
|
10555
|
+
errorLine("Usage: okx config use <profile-name>");
|
|
10364
10556
|
process.exitCode = 1;
|
|
10365
10557
|
return;
|
|
10366
10558
|
}
|
|
10367
10559
|
const config = readFullConfig();
|
|
10368
10560
|
const available = Object.keys(config.profiles);
|
|
10369
10561
|
if (!config.profiles[profileName]) {
|
|
10370
|
-
|
|
10371
|
-
`);
|
|
10562
|
+
errorLine(`Error: profile "${profileName}" does not exist.`);
|
|
10372
10563
|
if (available.length > 0) {
|
|
10373
|
-
|
|
10374
|
-
`);
|
|
10564
|
+
errorLine(`Available profiles: ${available.join(", ")}`);
|
|
10375
10565
|
} else {
|
|
10376
|
-
|
|
10566
|
+
errorLine("No profiles configured. Run: okx config add-profile AK=<key> SK=<secret> PP=<passphrase>");
|
|
10377
10567
|
}
|
|
10378
10568
|
process.exitCode = 1;
|
|
10379
10569
|
return;
|
|
10380
10570
|
}
|
|
10381
10571
|
config.default_profile = profileName;
|
|
10382
10572
|
writeCliConfig(config);
|
|
10383
|
-
|
|
10384
|
-
`);
|
|
10573
|
+
outputLine(`Default profile set to: "${profileName}"`);
|
|
10385
10574
|
}
|
|
10386
10575
|
|
|
10387
10576
|
// src/commands/earn.ts
|
|
@@ -10398,7 +10587,7 @@ function printDataList(data, json, emptyMsg, mapper) {
|
|
|
10398
10587
|
return;
|
|
10399
10588
|
}
|
|
10400
10589
|
if (!data.length) {
|
|
10401
|
-
|
|
10590
|
+
outputLine(emptyMsg);
|
|
10402
10591
|
return;
|
|
10403
10592
|
}
|
|
10404
10593
|
printTable(data.map(mapper));
|
|
@@ -10422,7 +10611,7 @@ async function cmdEarnSavingsPurchase(run, opts) {
|
|
|
10422
10611
|
}
|
|
10423
10612
|
const r = data[0];
|
|
10424
10613
|
if (!r) {
|
|
10425
|
-
|
|
10614
|
+
outputLine("No response data");
|
|
10426
10615
|
return;
|
|
10427
10616
|
}
|
|
10428
10617
|
printKv({ ccy: r["ccy"], amt: r["amt"], side: r["side"], rate: r["rate"] });
|
|
@@ -10435,7 +10624,7 @@ async function cmdEarnSavingsRedeem(run, opts) {
|
|
|
10435
10624
|
}
|
|
10436
10625
|
const r = data[0];
|
|
10437
10626
|
if (!r) {
|
|
10438
|
-
|
|
10627
|
+
outputLine("No response data");
|
|
10439
10628
|
return;
|
|
10440
10629
|
}
|
|
10441
10630
|
printKv({ ccy: r["ccy"], amt: r["amt"], side: r["side"] });
|
|
@@ -10447,8 +10636,7 @@ async function cmdEarnSetLendingRate(run, opts) {
|
|
|
10447
10636
|
return;
|
|
10448
10637
|
}
|
|
10449
10638
|
const r = data[0];
|
|
10450
|
-
|
|
10451
|
-
`);
|
|
10639
|
+
outputLine(`Lending rate set: ${r?.["ccy"]} \u2192 ${r?.["rate"]}`);
|
|
10452
10640
|
}
|
|
10453
10641
|
async function cmdEarnLendingHistory(run, opts) {
|
|
10454
10642
|
const data = extractData(await run("earn_get_lending_history", { ccy: opts.ccy, limit: opts.limit }));
|
|
@@ -10480,6 +10668,14 @@ async function cmdEarnLendingRateHistory(run, opts) {
|
|
|
10480
10668
|
}
|
|
10481
10669
|
|
|
10482
10670
|
// src/commands/bot.ts
|
|
10671
|
+
function emitWriteResult5(item, label, idKey) {
|
|
10672
|
+
const isError = item?.["sCode"] !== "0" && item?.["sCode"] !== 0;
|
|
10673
|
+
if (isError) {
|
|
10674
|
+
errorLine(`Error: ${item?.["sMsg"]} (sCode ${item?.["sCode"]})`);
|
|
10675
|
+
} else {
|
|
10676
|
+
outputLine(`${label}: ${item?.[idKey]} (OK)`);
|
|
10677
|
+
}
|
|
10678
|
+
}
|
|
10483
10679
|
function getData7(result) {
|
|
10484
10680
|
return result.data;
|
|
10485
10681
|
}
|
|
@@ -10493,7 +10689,7 @@ async function cmdGridOrders(run, opts) {
|
|
|
10493
10689
|
const orders = getData7(result) ?? [];
|
|
10494
10690
|
if (opts.json) return printJson(orders);
|
|
10495
10691
|
if (!orders.length) {
|
|
10496
|
-
|
|
10692
|
+
outputLine("No grid bots");
|
|
10497
10693
|
return;
|
|
10498
10694
|
}
|
|
10499
10695
|
printTable(
|
|
@@ -10517,7 +10713,7 @@ async function cmdGridDetails(run, opts) {
|
|
|
10517
10713
|
});
|
|
10518
10714
|
const detail = (getData7(result) ?? [])[0];
|
|
10519
10715
|
if (!detail) {
|
|
10520
|
-
|
|
10716
|
+
outputLine("Bot not found");
|
|
10521
10717
|
return;
|
|
10522
10718
|
}
|
|
10523
10719
|
if (opts.json) return printJson(detail);
|
|
@@ -10546,7 +10742,7 @@ async function cmdGridSubOrders(run, opts) {
|
|
|
10546
10742
|
const orders = getData7(result) ?? [];
|
|
10547
10743
|
if (opts.json) return printJson(orders);
|
|
10548
10744
|
if (!orders.length) {
|
|
10549
|
-
|
|
10745
|
+
outputLine("No sub-orders");
|
|
10550
10746
|
return;
|
|
10551
10747
|
}
|
|
10552
10748
|
printTable(
|
|
@@ -10580,10 +10776,7 @@ async function cmdGridCreate(run, opts) {
|
|
|
10580
10776
|
const data = getData7(result);
|
|
10581
10777
|
if (opts.json) return printJson(data);
|
|
10582
10778
|
const r = data?.[0];
|
|
10583
|
-
|
|
10584
|
-
`Grid bot created: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
10585
|
-
`
|
|
10586
|
-
);
|
|
10779
|
+
emitWriteResult5(data?.[0], "Grid bot created", "algoId");
|
|
10587
10780
|
}
|
|
10588
10781
|
async function cmdGridStop(run, opts) {
|
|
10589
10782
|
const result = await run("grid_stop_order", {
|
|
@@ -10595,10 +10788,7 @@ async function cmdGridStop(run, opts) {
|
|
|
10595
10788
|
const data = getData7(result);
|
|
10596
10789
|
if (opts.json) return printJson(data);
|
|
10597
10790
|
const r = data?.[0];
|
|
10598
|
-
|
|
10599
|
-
`Grid bot stopped: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
10600
|
-
`
|
|
10601
|
-
);
|
|
10791
|
+
emitWriteResult5(data?.[0], "Grid bot stopped", "algoId");
|
|
10602
10792
|
}
|
|
10603
10793
|
async function cmdDcaCreate(run, opts) {
|
|
10604
10794
|
const result = await run("dca_create_order", {
|
|
@@ -10621,10 +10811,7 @@ async function cmdDcaCreate(run, opts) {
|
|
|
10621
10811
|
const data = getData7(result);
|
|
10622
10812
|
if (opts.json) return printJson(data);
|
|
10623
10813
|
const r = data?.[0];
|
|
10624
|
-
|
|
10625
|
-
`DCA bot created: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
10626
|
-
`
|
|
10627
|
-
);
|
|
10814
|
+
emitWriteResult5(data?.[0], "DCA bot created", "algoId");
|
|
10628
10815
|
}
|
|
10629
10816
|
async function cmdDcaStop(run, opts) {
|
|
10630
10817
|
const result = await run("dca_stop_order", {
|
|
@@ -10633,10 +10820,7 @@ async function cmdDcaStop(run, opts) {
|
|
|
10633
10820
|
const data = getData7(result);
|
|
10634
10821
|
if (opts.json) return printJson(data);
|
|
10635
10822
|
const r = data?.[0];
|
|
10636
|
-
|
|
10637
|
-
`DCA bot stopped: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
10638
|
-
`
|
|
10639
|
-
);
|
|
10823
|
+
emitWriteResult5(data?.[0], "DCA bot stopped", "algoId");
|
|
10640
10824
|
}
|
|
10641
10825
|
async function cmdDcaOrders(run, opts) {
|
|
10642
10826
|
const result = await run("dca_get_orders", {
|
|
@@ -10647,7 +10831,7 @@ async function cmdDcaOrders(run, opts) {
|
|
|
10647
10831
|
const orders = getData7(result) ?? [];
|
|
10648
10832
|
if (opts.json) return printJson(orders);
|
|
10649
10833
|
if (!orders.length) {
|
|
10650
|
-
|
|
10834
|
+
outputLine("No DCA bots");
|
|
10651
10835
|
return;
|
|
10652
10836
|
}
|
|
10653
10837
|
printTable(
|
|
@@ -10667,7 +10851,7 @@ async function cmdDcaDetails(run, opts) {
|
|
|
10667
10851
|
});
|
|
10668
10852
|
const detail = (getData7(result) ?? [])[0];
|
|
10669
10853
|
if (!detail) {
|
|
10670
|
-
|
|
10854
|
+
outputLine("DCA bot not found");
|
|
10671
10855
|
return;
|
|
10672
10856
|
}
|
|
10673
10857
|
if (opts.json) return printJson(detail);
|
|
@@ -10695,7 +10879,7 @@ async function cmdDcaSubOrders(run, opts) {
|
|
|
10695
10879
|
const orders = getData7(result) ?? [];
|
|
10696
10880
|
if (opts.json) return printJson(orders);
|
|
10697
10881
|
if (!orders.length) {
|
|
10698
|
-
|
|
10882
|
+
outputLine("No sub-orders");
|
|
10699
10883
|
return;
|
|
10700
10884
|
}
|
|
10701
10885
|
printTable(
|
|
@@ -10784,7 +10968,7 @@ async function cmdDcdPairs(run, json) {
|
|
|
10784
10968
|
return;
|
|
10785
10969
|
}
|
|
10786
10970
|
if (!data.length) {
|
|
10787
|
-
|
|
10971
|
+
outputLine("No currency pairs available");
|
|
10788
10972
|
return;
|
|
10789
10973
|
}
|
|
10790
10974
|
printTable(data.map((r) => ({
|
|
@@ -10849,7 +11033,7 @@ async function cmdDcdProducts(run, opts) {
|
|
|
10849
11033
|
return;
|
|
10850
11034
|
}
|
|
10851
11035
|
if (!data.length) {
|
|
10852
|
-
|
|
11036
|
+
outputLine("No products matched");
|
|
10853
11037
|
return;
|
|
10854
11038
|
}
|
|
10855
11039
|
printTable(data.map((r) => ({
|
|
@@ -10869,7 +11053,7 @@ async function cmdDcdRedeemExecute(run, opts) {
|
|
|
10869
11053
|
const quoteData = extractArray(quoteResult);
|
|
10870
11054
|
const q = quoteData[0];
|
|
10871
11055
|
if (!q) {
|
|
10872
|
-
|
|
11056
|
+
outputLine("Failed to get redeem quote");
|
|
10873
11057
|
return;
|
|
10874
11058
|
}
|
|
10875
11059
|
const redeemResult = await run("dcd_redeem", {
|
|
@@ -10879,7 +11063,7 @@ async function cmdDcdRedeemExecute(run, opts) {
|
|
|
10879
11063
|
const redeemData = extractArray(redeemResult);
|
|
10880
11064
|
const r = redeemData[0];
|
|
10881
11065
|
if (!r) {
|
|
10882
|
-
|
|
11066
|
+
outputLine("No response data");
|
|
10883
11067
|
return;
|
|
10884
11068
|
}
|
|
10885
11069
|
if (opts.json) {
|
|
@@ -10902,7 +11086,7 @@ async function cmdDcdOrderState(run, opts) {
|
|
|
10902
11086
|
}
|
|
10903
11087
|
const r = data[0];
|
|
10904
11088
|
if (!r) {
|
|
10905
|
-
|
|
11089
|
+
outputLine("Order not found");
|
|
10906
11090
|
return;
|
|
10907
11091
|
}
|
|
10908
11092
|
printKv({
|
|
@@ -10932,7 +11116,7 @@ async function cmdDcdOrders(run, opts) {
|
|
|
10932
11116
|
return;
|
|
10933
11117
|
}
|
|
10934
11118
|
if (!data.length) {
|
|
10935
|
-
|
|
11119
|
+
outputLine("No orders found");
|
|
10936
11120
|
return;
|
|
10937
11121
|
}
|
|
10938
11122
|
printTable(data.map((r) => ({
|
|
@@ -10963,7 +11147,7 @@ async function cmdDcdQuoteAndBuy(run, opts) {
|
|
|
10963
11147
|
const r = tradeData[0];
|
|
10964
11148
|
const q = result["quote"];
|
|
10965
11149
|
if (!r) {
|
|
10966
|
-
|
|
11150
|
+
outputLine("No quote returned");
|
|
10967
11151
|
return;
|
|
10968
11152
|
}
|
|
10969
11153
|
const ordId = r["ordId"];
|
|
@@ -10980,7 +11164,7 @@ async function cmdDcdQuoteAndBuy(run, opts) {
|
|
|
10980
11164
|
return;
|
|
10981
11165
|
}
|
|
10982
11166
|
if (q) {
|
|
10983
|
-
|
|
11167
|
+
outputLine("Quote:");
|
|
10984
11168
|
printKv({
|
|
10985
11169
|
quoteId: q["quoteId"],
|
|
10986
11170
|
annualizedYield: q["annualizedYield"] ? `${q["annualizedYield"]}%` : "\u2014",
|
|
@@ -10988,12 +11172,13 @@ async function cmdDcdQuoteAndBuy(run, opts) {
|
|
|
10988
11172
|
notionalSz: q["notionalSz"],
|
|
10989
11173
|
notionalCcy: q["notionalCcy"]
|
|
10990
11174
|
});
|
|
10991
|
-
|
|
11175
|
+
outputLine("");
|
|
10992
11176
|
}
|
|
10993
|
-
|
|
11177
|
+
outputLine("Order placed:");
|
|
10994
11178
|
printKv({ ordId: r["ordId"], quoteId: r["quoteId"], state: r["state"] ?? r["status"] });
|
|
10995
11179
|
if (stateRow) {
|
|
10996
|
-
|
|
11180
|
+
outputLine("");
|
|
11181
|
+
outputLine("Order state:");
|
|
10997
11182
|
printKv({
|
|
10998
11183
|
ordId: stateRow["ordId"],
|
|
10999
11184
|
state: stateRow["state"],
|
|
@@ -11008,7 +11193,7 @@ async function cmdDcdQuoteAndBuy(run, opts) {
|
|
|
11008
11193
|
// src/index.ts
|
|
11009
11194
|
var _require3 = createRequire3(import.meta.url);
|
|
11010
11195
|
var CLI_VERSION2 = _require3("../package.json").version;
|
|
11011
|
-
var GIT_HASH2 = true ? "
|
|
11196
|
+
var GIT_HASH2 = true ? "c27439d" : "dev";
|
|
11012
11197
|
function handleConfigCommand(action, rest, json, lang, force) {
|
|
11013
11198
|
if (action === "init") return cmdConfigInit(lang === "zh" ? "zh" : "en");
|
|
11014
11199
|
if (action === "show") return cmdConfigShow(json);
|
|
@@ -11017,8 +11202,7 @@ function handleConfigCommand(action, rest, json, lang, force) {
|
|
|
11017
11202
|
if (action === "add-profile") return cmdConfigAddProfile(rest, force ?? false);
|
|
11018
11203
|
if (action === "list-profile") return cmdConfigListProfile();
|
|
11019
11204
|
if (action === "use") return cmdConfigUse(rest[0]);
|
|
11020
|
-
|
|
11021
|
-
`);
|
|
11205
|
+
errorLine(`Unknown config command: ${action}`);
|
|
11022
11206
|
process.exitCode = 1;
|
|
11023
11207
|
}
|
|
11024
11208
|
function handleSetupCommand(v) {
|
|
@@ -11027,11 +11211,8 @@ function handleSetupCommand(v) {
|
|
|
11027
11211
|
return;
|
|
11028
11212
|
}
|
|
11029
11213
|
if (!SUPPORTED_CLIENTS.includes(v.client)) {
|
|
11030
|
-
|
|
11031
|
-
|
|
11032
|
-
Supported: ${SUPPORTED_CLIENTS.join(", ")}
|
|
11033
|
-
`
|
|
11034
|
-
);
|
|
11214
|
+
errorLine(`Unknown client: "${v.client}"`);
|
|
11215
|
+
errorLine(`Supported: ${SUPPORTED_CLIENTS.join(", ")}`);
|
|
11035
11216
|
process.exitCode = 1;
|
|
11036
11217
|
return;
|
|
11037
11218
|
}
|
|
@@ -11055,6 +11236,18 @@ function handleMarketPublicCommand(run, action, rest, v, json) {
|
|
|
11055
11236
|
return cmdMarketOpenInterest(run, { instType: v.instType, instId: v.instId, json });
|
|
11056
11237
|
if (action === "stock-tokens")
|
|
11057
11238
|
return cmdMarketStockTokens(run, { instType: v.instType, instId: v.instId, json });
|
|
11239
|
+
if (action === "indicator") {
|
|
11240
|
+
const limit = v.limit !== void 0 ? Number(v.limit) : void 0;
|
|
11241
|
+
const backtestTime = v["backtest-time"] !== void 0 ? Number(v["backtest-time"]) : void 0;
|
|
11242
|
+
return cmdMarketIndicator(run, rest[0], rest[1], {
|
|
11243
|
+
bar: v.bar,
|
|
11244
|
+
params: v.params,
|
|
11245
|
+
list: v.list,
|
|
11246
|
+
limit,
|
|
11247
|
+
backtestTime,
|
|
11248
|
+
json
|
|
11249
|
+
});
|
|
11250
|
+
}
|
|
11058
11251
|
}
|
|
11059
11252
|
function handleMarketDataCommand(run, action, rest, v, json) {
|
|
11060
11253
|
const limit = v.limit !== void 0 ? Number(v.limit) : void 0;
|
|
@@ -11195,6 +11388,7 @@ function handleSpotCommand(run, action, rest, v, json) {
|
|
|
11195
11388
|
side: v.side,
|
|
11196
11389
|
ordType: v.ordType,
|
|
11197
11390
|
sz: v.sz,
|
|
11391
|
+
tgtCcy: v.tgtCcy,
|
|
11198
11392
|
px: v.px,
|
|
11199
11393
|
tpTriggerPx: v.tpTriggerPx,
|
|
11200
11394
|
tpOrdPx: v.tpOrdPx,
|
|
@@ -11304,6 +11498,7 @@ function handleSwapCommand(run, action, rest, v, json) {
|
|
|
11304
11498
|
posSide: v.posSide,
|
|
11305
11499
|
px: v.px,
|
|
11306
11500
|
tdMode: v.tdMode ?? "cross",
|
|
11501
|
+
tgtCcy: v.tgtCcy,
|
|
11307
11502
|
tpTriggerPx: v.tpTriggerPx,
|
|
11308
11503
|
tpOrdPx: v.tpOrdPx,
|
|
11309
11504
|
slTriggerPx: v.slTriggerPx,
|
|
@@ -11505,6 +11700,7 @@ function handleFuturesCommand(run, action, rest, v, json) {
|
|
|
11505
11700
|
ordType: v.ordType,
|
|
11506
11701
|
sz: v.sz,
|
|
11507
11702
|
tdMode: v.tdMode ?? "cross",
|
|
11703
|
+
tgtCcy: v.tgtCcy,
|
|
11508
11704
|
posSide: v.posSide,
|
|
11509
11705
|
px: v.px,
|
|
11510
11706
|
reduceOnly: v.reduceOnly,
|
|
@@ -11633,9 +11829,8 @@ function handleEarnCommand(run, submodule, rest, v, json) {
|
|
|
11633
11829
|
if (submodule === "savings") return handleEarnSavingsCommand(run, action, innerRest, v, json);
|
|
11634
11830
|
if (submodule === "onchain") return handleEarnOnchainCommand(run, action, v, json);
|
|
11635
11831
|
if (submodule === "dcd") return handleEarnDcdCommand(run, action, v, json);
|
|
11636
|
-
|
|
11637
|
-
Valid: savings, onchain, dcd
|
|
11638
|
-
`);
|
|
11832
|
+
errorLine(`Unknown earn sub-module: ${submodule}`);
|
|
11833
|
+
errorLine("Valid: savings, onchain, dcd");
|
|
11639
11834
|
process.exitCode = 1;
|
|
11640
11835
|
}
|
|
11641
11836
|
function handleEarnSavingsCommand(run, action, rest, v, json) {
|
|
@@ -11647,8 +11842,7 @@ function handleEarnSavingsCommand(run, action, rest, v, json) {
|
|
|
11647
11842
|
if (action === "lending-history") return cmdEarnLendingHistory(run, { ccy: v.ccy, limit, json });
|
|
11648
11843
|
if (action === "rate-summary") return cmdEarnLendingRateSummary(run, rest[0] ?? v.ccy, json);
|
|
11649
11844
|
if (action === "rate-history") return cmdEarnLendingRateHistory(run, { ccy: v.ccy, limit, json });
|
|
11650
|
-
|
|
11651
|
-
`);
|
|
11845
|
+
errorLine(`Unknown earn savings command: ${action}`);
|
|
11652
11846
|
process.exitCode = 1;
|
|
11653
11847
|
}
|
|
11654
11848
|
function handleEarnOnchainCommand(run, action, v, json) {
|
|
@@ -11658,8 +11852,7 @@ function handleEarnOnchainCommand(run, action, v, json) {
|
|
|
11658
11852
|
if (action === "cancel") return cmdOnchainEarnCancel(run, v).then((r) => outputResult(r, json));
|
|
11659
11853
|
if (action === "orders") return cmdOnchainEarnActiveOrders(run, v).then((r) => outputResult(r, json));
|
|
11660
11854
|
if (action === "history") return cmdOnchainEarnOrderHistory(run, v).then((r) => outputResult(r, json));
|
|
11661
|
-
|
|
11662
|
-
`);
|
|
11855
|
+
errorLine(`Unknown earn onchain command: ${action}`);
|
|
11663
11856
|
process.exitCode = 1;
|
|
11664
11857
|
}
|
|
11665
11858
|
function parseDcdOpts(v) {
|
|
@@ -11714,16 +11907,15 @@ function handleEarnDcdCommand(run, action, v, json) {
|
|
|
11714
11907
|
limit,
|
|
11715
11908
|
json
|
|
11716
11909
|
});
|
|
11717
|
-
|
|
11718
|
-
Valid: pairs, products, quote-and-buy, redeem-execute, order, orders
|
|
11719
|
-
`);
|
|
11910
|
+
errorLine(`Unknown earn dcd command: ${action}`);
|
|
11911
|
+
errorLine("Valid: pairs, products, quote-and-buy, redeem-execute, order, orders");
|
|
11720
11912
|
process.exitCode = 1;
|
|
11721
11913
|
}
|
|
11722
11914
|
function outputResult(result, json) {
|
|
11723
11915
|
if (json) {
|
|
11724
|
-
|
|
11916
|
+
outputLine(JSON.stringify(result, null, 2));
|
|
11725
11917
|
} else {
|
|
11726
|
-
|
|
11918
|
+
outputLine(JSON.stringify(result.data, null, 2));
|
|
11727
11919
|
}
|
|
11728
11920
|
}
|
|
11729
11921
|
function printHelpForLevel(positionals) {
|
|
@@ -11732,24 +11924,15 @@ function printHelpForLevel(positionals) {
|
|
|
11732
11924
|
else if (!subgroup) printHelp(module);
|
|
11733
11925
|
else printHelp(module, subgroup);
|
|
11734
11926
|
}
|
|
11735
|
-
function printVerboseConfigSummary(config, profile) {
|
|
11736
|
-
let authLabel = "\u2717";
|
|
11737
|
-
if (config.hasAuth && config.apiKey) {
|
|
11738
|
-
authLabel = `\u2713(${config.apiKey.slice(0, 3)}***${config.apiKey.slice(-3)})`;
|
|
11739
|
-
} else if (config.hasAuth) {
|
|
11740
|
-
authLabel = "\u2713";
|
|
11741
|
-
}
|
|
11742
|
-
process.stderr.write(
|
|
11743
|
-
`[verbose] config: profile=${profile ?? "default"} site=${config.site} base=${config.baseUrl} auth=${authLabel} demo=${config.demo ? "on" : "off"} modules=${config.modules.join(",")}
|
|
11744
|
-
`
|
|
11745
|
-
);
|
|
11746
|
-
}
|
|
11747
11927
|
async function main() {
|
|
11928
|
+
setOutput({
|
|
11929
|
+
out: (m) => process.stdout.write(m),
|
|
11930
|
+
err: (m) => process.stderr.write(m)
|
|
11931
|
+
});
|
|
11748
11932
|
checkForUpdates("@okx_ai/okx-trade-cli", CLI_VERSION2);
|
|
11749
11933
|
const { values, positionals } = parseCli(process.argv.slice(2));
|
|
11750
11934
|
if (values.version) {
|
|
11751
|
-
|
|
11752
|
-
`);
|
|
11935
|
+
outputLine(`${CLI_VERSION2} (${GIT_HASH2})`);
|
|
11753
11936
|
return;
|
|
11754
11937
|
}
|
|
11755
11938
|
if (values.help || positionals.length === 0) {
|
|
@@ -11761,11 +11944,25 @@ async function main() {
|
|
|
11761
11944
|
const json = v.json ?? false;
|
|
11762
11945
|
if (module === "config") return handleConfigCommand(action, rest, json, v.lang, v.force);
|
|
11763
11946
|
if (module === "setup") return handleSetupCommand(v);
|
|
11947
|
+
if (module === "diagnose") {
|
|
11948
|
+
let config2;
|
|
11949
|
+
try {
|
|
11950
|
+
config2 = loadProfileConfig({ profile: v.profile, demo: v.demo, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
|
|
11951
|
+
} catch {
|
|
11952
|
+
}
|
|
11953
|
+
return cmdDiagnose(config2, v.profile ?? "default", { mcp: v.mcp, cli: v.cli, all: v.all, output: v.output });
|
|
11954
|
+
}
|
|
11764
11955
|
const config = loadProfileConfig({ profile: v.profile, demo: v.demo, verbose: v.verbose, userAgent: `okx-trade-cli/${CLI_VERSION2}`, sourceTag: "CLI" });
|
|
11765
|
-
if (config.verbose) printVerboseConfigSummary(config, v.profile);
|
|
11766
|
-
if (module === "diagnose") return cmdDiagnose(config, v.profile ?? "default", { mcp: v.mcp, cli: v.cli, all: v.all, output: v.output });
|
|
11767
11956
|
const client = new OkxRestClient(config);
|
|
11768
|
-
const
|
|
11957
|
+
const baseRunner = createToolRunner(client, config);
|
|
11958
|
+
const writeToolNames = new Set(allToolSpecs().filter((t) => t.isWrite).map((t) => t.name));
|
|
11959
|
+
const run = async (toolName, args) => {
|
|
11960
|
+
const result = await baseRunner(toolName, args);
|
|
11961
|
+
if (writeToolNames.has(toolName)) {
|
|
11962
|
+
markFailedIfSCodeError(result.data);
|
|
11963
|
+
}
|
|
11964
|
+
return result;
|
|
11965
|
+
};
|
|
11769
11966
|
const moduleHandlers = {
|
|
11770
11967
|
market: () => handleMarketCommand(run, action, rest, v, json),
|
|
11771
11968
|
account: () => handleAccountCommand(run, action, rest, v, json),
|
|
@@ -11778,20 +11975,15 @@ async function main() {
|
|
|
11778
11975
|
};
|
|
11779
11976
|
const handler = moduleHandlers[module];
|
|
11780
11977
|
if (handler) return handler();
|
|
11781
|
-
|
|
11782
|
-
`);
|
|
11978
|
+
errorLine(`Unknown command: ${module} ${action ?? ""}`);
|
|
11783
11979
|
process.exitCode = 1;
|
|
11784
11980
|
}
|
|
11785
11981
|
main().catch((error) => {
|
|
11786
11982
|
const payload = toToolErrorPayload(error);
|
|
11787
|
-
|
|
11788
|
-
`);
|
|
11789
|
-
if (payload.
|
|
11790
|
-
`);
|
|
11791
|
-
if (payload.suggestion) process.stderr.write(`Hint: ${payload.suggestion}
|
|
11792
|
-
`);
|
|
11793
|
-
process.stderr.write(`Version: @okx_ai/okx-trade-cli@${CLI_VERSION2}
|
|
11794
|
-
`);
|
|
11983
|
+
errorLine(`Error: ${payload.message}`);
|
|
11984
|
+
if (payload.traceId) errorLine(`TraceId: ${payload.traceId}`);
|
|
11985
|
+
if (payload.suggestion) errorLine(`Hint: ${payload.suggestion}`);
|
|
11986
|
+
errorLine(`Version: @okx_ai/okx-trade-cli@${CLI_VERSION2}`);
|
|
11795
11987
|
process.exitCode = 1;
|
|
11796
11988
|
});
|
|
11797
11989
|
export {
|