@okx_ai/okx-trade-cli 1.3.1 → 1.3.2-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 +1035 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1453,13 +1453,14 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1453
1453
|
rateLimit
|
|
1454
1454
|
});
|
|
1455
1455
|
}
|
|
1456
|
-
async privatePost(path42, body, rateLimit) {
|
|
1456
|
+
async privatePost(path42, body, rateLimit, retryOnNetworkError) {
|
|
1457
1457
|
return this.request({
|
|
1458
1458
|
method: "POST",
|
|
1459
1459
|
path: path42,
|
|
1460
1460
|
auth: "private",
|
|
1461
1461
|
body,
|
|
1462
|
-
rateLimit
|
|
1462
|
+
rateLimit,
|
|
1463
|
+
retryOnNetworkError
|
|
1463
1464
|
});
|
|
1464
1465
|
}
|
|
1465
1466
|
setAuthHeaders(headers, method, requestPath, bodyJson, timestamp) {
|
|
@@ -1742,7 +1743,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1742
1743
|
vlog2(`Network failure, refreshing DoH: ${cause}`);
|
|
1743
1744
|
}
|
|
1744
1745
|
const shouldRetry = await this.doh.handleNetworkFailure();
|
|
1745
|
-
if (shouldRetry && reqConfig.method === "GET") {
|
|
1746
|
+
if (shouldRetry && (reqConfig.method === "GET" || reqConfig.retryOnNetworkError)) {
|
|
1746
1747
|
return this.request(reqConfig);
|
|
1747
1748
|
}
|
|
1748
1749
|
}
|
|
@@ -2218,6 +2219,7 @@ var MODULES = [
|
|
|
2218
2219
|
"account",
|
|
2219
2220
|
"event",
|
|
2220
2221
|
"news",
|
|
2222
|
+
"smartmoney",
|
|
2221
2223
|
...EARN_SUB_MODULE_IDS,
|
|
2222
2224
|
...BOT_SUB_MODULE_IDS,
|
|
2223
2225
|
"skills"
|
|
@@ -2240,6 +2242,7 @@ var MODULE_DESCRIPTIONS = {
|
|
|
2240
2242
|
"bot.grid": "Grid trading bot \u2014 create, monitor, and stop grid orders",
|
|
2241
2243
|
"bot.dca": "DCA (Martingale) bot \u2014 spot or contract recurring buys",
|
|
2242
2244
|
news: "Crypto news, sentiment analysis, and coin trend tracking",
|
|
2245
|
+
smartmoney: "Smart money signals \u2014 trader leaderboard, consensus signals, and position analysis",
|
|
2243
2246
|
skills: SKILLS_MARKETPLACE_DESC,
|
|
2244
2247
|
earn: "Earn products \u2014 Simple Earn, On-chain Earn, DCD, Flash Earn, and Auto-Earn",
|
|
2245
2248
|
bot: "Trading bot strategies (grid, dca)",
|
|
@@ -4246,10 +4249,133 @@ function registerGridTools() {
|
|
|
4246
4249
|
return normalizeWrite(response);
|
|
4247
4250
|
}
|
|
4248
4251
|
},
|
|
4252
|
+
{
|
|
4253
|
+
name: "grid_amend_order",
|
|
4254
|
+
module: "bot.grid",
|
|
4255
|
+
description: "Amend a running grid bot. [CAUTION] Modifies a running bot. Use grid_list_orders to confirm the bot is running and obtain the algoId before calling.\nSupports two modes, which can be combined in a single call:\n\u2022 Price-range mode (maxPx+minPx+gridNum): change upper/lower price boundary and grid count. Contract grid: if new range requires more margin, pass topUpAmt; omit to auto-use the minimum required. Spot grid: topUpAmt is not supported.\n\u2022 TP/SL mode (instId + any of tpTriggerPx/slTriggerPx/tpRatio/slRatio): update take-profit and/or stop-loss. Pass '-1' to explicitly clear an existing TP or SL. tpTriggerPx/slTriggerPx are absolute prices; tpRatio/slRatio are profit ratios (e.g. '0.1' = 10%).\nWhen both sets of params are provided, both APIs are called sequentially.\nDo NOT use to create a new grid bot \u2014 use grid_create_order instead. Do NOT use to stop a grid bot \u2014 use grid_stop_order instead.",
|
|
4256
|
+
isWrite: true,
|
|
4257
|
+
inputSchema: {
|
|
4258
|
+
type: "object",
|
|
4259
|
+
properties: {
|
|
4260
|
+
algoId: {
|
|
4261
|
+
type: "string",
|
|
4262
|
+
description: "Grid bot algo order ID (required)"
|
|
4263
|
+
},
|
|
4264
|
+
// ── Price-range mode ──────────────────────────────────────────────
|
|
4265
|
+
maxPx: {
|
|
4266
|
+
type: "string",
|
|
4267
|
+
description: "[Price-range mode] New upper price boundary. Triggers amend-algo-basic-param when provided."
|
|
4268
|
+
},
|
|
4269
|
+
minPx: {
|
|
4270
|
+
type: "string",
|
|
4271
|
+
description: "[Price-range mode] New lower price boundary. Required when maxPx is set."
|
|
4272
|
+
},
|
|
4273
|
+
gridNum: {
|
|
4274
|
+
type: "string",
|
|
4275
|
+
description: "[Price-range mode] New number of grid intervals (integer). Required when maxPx is set."
|
|
4276
|
+
},
|
|
4277
|
+
// ── TP/SL mode ────────────────────────────────────────────────────
|
|
4278
|
+
instId: {
|
|
4279
|
+
type: "string",
|
|
4280
|
+
description: "[TP/SL mode] Instrument ID, e.g. BTC-USDT. Required when setting TP/SL."
|
|
4281
|
+
},
|
|
4282
|
+
tpTriggerPx: {
|
|
4283
|
+
type: "string",
|
|
4284
|
+
description: "[TP/SL mode] Take-profit trigger price (absolute). Pass '-1' to clear."
|
|
4285
|
+
},
|
|
4286
|
+
slTriggerPx: {
|
|
4287
|
+
type: "string",
|
|
4288
|
+
description: "[TP/SL mode] Stop-loss trigger price (absolute). Pass '-1' to clear."
|
|
4289
|
+
},
|
|
4290
|
+
tpRatio: {
|
|
4291
|
+
type: "string",
|
|
4292
|
+
description: "[TP/SL mode] Take-profit ratio, e.g. '0.1' = 10% profit. Pass '-1' to clear."
|
|
4293
|
+
},
|
|
4294
|
+
slRatio: {
|
|
4295
|
+
type: "string",
|
|
4296
|
+
description: "[TP/SL mode] Stop-loss ratio, e.g. '0.1' = 10% drawdown. Pass '-1' to clear."
|
|
4297
|
+
},
|
|
4298
|
+
// ── Shared optional ───────────────────────────────────────────────
|
|
4299
|
+
topUpAmt: {
|
|
4300
|
+
type: "string",
|
|
4301
|
+
description: "Top-up amount. In price-range mode maps to topupAmount (contract grid only; omit to use minimum required). In TP/SL mode maps to topUpAmt."
|
|
4302
|
+
}
|
|
4303
|
+
},
|
|
4304
|
+
required: ["algoId"]
|
|
4305
|
+
},
|
|
4306
|
+
handler: async (rawArgs, context) => {
|
|
4307
|
+
const args = asRecord(rawArgs);
|
|
4308
|
+
const algoId = requireString(args, "algoId");
|
|
4309
|
+
const maxPx = readString(args, "maxPx");
|
|
4310
|
+
const instId = readString(args, "instId");
|
|
4311
|
+
const hasTpsl = readString(args, "tpTriggerPx") || readString(args, "slTriggerPx") || readString(args, "tpRatio") || readString(args, "slRatio");
|
|
4312
|
+
if (!maxPx && !hasTpsl) {
|
|
4313
|
+
throw new OkxApiError(
|
|
4314
|
+
"Nothing to amend. Provide maxPx+minPx+gridNum for price-range mode, or any of tpTriggerPx/slTriggerPx/tpRatio/slRatio (instId also required) for TP/SL mode (both can be combined).",
|
|
4315
|
+
{ code: "", endpoint: "grid_amend_order" }
|
|
4316
|
+
);
|
|
4317
|
+
}
|
|
4318
|
+
if (hasTpsl && !instId) {
|
|
4319
|
+
throw new OkxApiError(
|
|
4320
|
+
"TP/SL mode requires instId. Provide instId alongside the TP/SL parameters.",
|
|
4321
|
+
{ code: "", endpoint: "grid_amend_order" }
|
|
4322
|
+
);
|
|
4323
|
+
}
|
|
4324
|
+
const results = [];
|
|
4325
|
+
if (maxPx) {
|
|
4326
|
+
results.push(normalizeWrite(await context.client.privatePost(
|
|
4327
|
+
"/api/v5/tradingBot/grid/amend-algo-basic-param",
|
|
4328
|
+
compactObject({
|
|
4329
|
+
algoId,
|
|
4330
|
+
maxPx,
|
|
4331
|
+
minPx: requireString(args, "minPx"),
|
|
4332
|
+
gridNum: requireString(args, "gridNum"),
|
|
4333
|
+
// API field is "topupAmount" (lowercase u) — different from TP/SL mode's "topUpAmt"
|
|
4334
|
+
// Contract grid only; omitting lets the API use the minimum required
|
|
4335
|
+
topupAmount: readString(args, "topUpAmt")
|
|
4336
|
+
}),
|
|
4337
|
+
privateRateLimit("grid_amend_order", 20),
|
|
4338
|
+
true
|
|
4339
|
+
// retryOnNetworkError: amend sets fixed values, safe to retry
|
|
4340
|
+
)));
|
|
4341
|
+
}
|
|
4342
|
+
if (hasTpsl) {
|
|
4343
|
+
try {
|
|
4344
|
+
results.push(normalizeWrite(await context.client.privatePost(
|
|
4345
|
+
"/api/v5/tradingBot/grid/amend-order-algo",
|
|
4346
|
+
compactObject({
|
|
4347
|
+
algoId,
|
|
4348
|
+
instId,
|
|
4349
|
+
tpTriggerPx: readString(args, "tpTriggerPx"),
|
|
4350
|
+
slTriggerPx: readString(args, "slTriggerPx"),
|
|
4351
|
+
tpRatio: readString(args, "tpRatio"),
|
|
4352
|
+
slRatio: readString(args, "slRatio"),
|
|
4353
|
+
topUpAmt: readString(args, "topUpAmt")
|
|
4354
|
+
// API field is "topUpAmt" (uppercase U) — different from price-range mode's "topupAmount"
|
|
4355
|
+
}),
|
|
4356
|
+
privateRateLimit("grid_amend_order", 20),
|
|
4357
|
+
true
|
|
4358
|
+
// retryOnNetworkError: amend sets fixed values, safe to retry
|
|
4359
|
+
)));
|
|
4360
|
+
} catch (err) {
|
|
4361
|
+
if (results.length > 0) {
|
|
4362
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4363
|
+
throw new OkxApiError(
|
|
4364
|
+
`TP/SL amend failed (price-range amend already succeeded): ${msg}`,
|
|
4365
|
+
{ code: "", endpoint: "grid_amend_order" }
|
|
4366
|
+
);
|
|
4367
|
+
}
|
|
4368
|
+
throw err;
|
|
4369
|
+
}
|
|
4370
|
+
}
|
|
4371
|
+
const merged = results.flatMap((r) => Array.isArray(r.data) ? r.data : [r.data]);
|
|
4372
|
+
return { endpoint: results[0].endpoint, requestTime: results[0].requestTime, data: merged };
|
|
4373
|
+
}
|
|
4374
|
+
},
|
|
4249
4375
|
{
|
|
4250
4376
|
name: "grid_stop_order",
|
|
4251
4377
|
module: "bot.grid",
|
|
4252
|
-
description: "Stop a grid bot. [CAUTION]
|
|
4378
|
+
description: "Stop a running grid bot. [CAUTION] This stops the strategy and handles open orders/positions according to stopType. Default (stopType='1') closes all positions immediately \u2014 use this for a clean exit. stopType='2' stops the strategy without selling: spot grid keeps all base assets as-is (no sell-back to quote); contract grid cancels all grid orders but leaves the position open for manual close later.",
|
|
4253
4379
|
isWrite: true,
|
|
4254
4380
|
inputSchema: {
|
|
4255
4381
|
type: "object",
|
|
@@ -4258,13 +4384,13 @@ function registerGridTools() {
|
|
|
4258
4384
|
algoOrdType: {
|
|
4259
4385
|
type: "string",
|
|
4260
4386
|
enum: ["grid", "contract_grid"],
|
|
4261
|
-
description: "grid=Spot, contract_grid=Contract"
|
|
4387
|
+
description: "grid=Spot grid, contract_grid=Contract grid"
|
|
4262
4388
|
},
|
|
4263
|
-
instId: { type: "string", description: "e.g. BTC-USDT, BTC-
|
|
4389
|
+
instId: { type: "string", description: "Instrument ID, e.g. BTC-USDT, BTC-USDT-SWAP" },
|
|
4264
4390
|
stopType: {
|
|
4265
4391
|
type: "string",
|
|
4266
|
-
enum: ["1", "2"
|
|
4267
|
-
description: "1
|
|
4392
|
+
enum: ["1", "2"],
|
|
4393
|
+
description: "'1' (default): stop strategy and sell \u2014 spot grid sells all base assets back to quote; contract grid market-closes all positions. '2': stop strategy without selling \u2014 spot grid keeps base assets as-is; contract grid cancels all grid orders but leaves the position open. After stopType='2', the remaining position can be closed manually from the Positions page."
|
|
4268
4394
|
}
|
|
4269
4395
|
},
|
|
4270
4396
|
required: ["algoId", "algoOrdType", "instId"]
|
|
@@ -4279,7 +4405,9 @@ function registerGridTools() {
|
|
|
4279
4405
|
instId: requireString(args, "instId"),
|
|
4280
4406
|
stopType: readString(args, "stopType") ?? "1"
|
|
4281
4407
|
})],
|
|
4282
|
-
privateRateLimit("grid_stop_order", 20)
|
|
4408
|
+
privateRateLimit("grid_stop_order", 20),
|
|
4409
|
+
true
|
|
4410
|
+
// retryOnNetworkError: safe to retry — already-stopped returns an error but does not harm state
|
|
4283
4411
|
);
|
|
4284
4412
|
return normalizeWrite(response);
|
|
4285
4413
|
}
|
|
@@ -6426,6 +6554,401 @@ function registerEventContractTools() {
|
|
|
6426
6554
|
}
|
|
6427
6555
|
];
|
|
6428
6556
|
}
|
|
6557
|
+
var PATH_LEADERBOARD = "/api/v5/orbit/public/leaderboard";
|
|
6558
|
+
var PATH_POSITION_CURRENT = "/api/v5/orbit/public/position-current";
|
|
6559
|
+
var PATH_TRADE_RECORDS = "/api/v5/orbit/public/trade-records";
|
|
6560
|
+
var PATH_OVERVIEW = "/api/v5/journal/public/smartmoney/overview";
|
|
6561
|
+
var PATH_SIGNAL = "/api/v5/journal/public/smartmoney/signal";
|
|
6562
|
+
var PATH_SIGNAL_HISTORY = "/api/v5/journal/public/smartmoney/signal-history";
|
|
6563
|
+
var SIGNAL_POOL_FILTER_PROPS = {
|
|
6564
|
+
sortType: {
|
|
6565
|
+
type: "string",
|
|
6566
|
+
description: "pnl or pnlRatio"
|
|
6567
|
+
},
|
|
6568
|
+
period: {
|
|
6569
|
+
type: "string",
|
|
6570
|
+
description: "3|7|30|90 days"
|
|
6571
|
+
},
|
|
6572
|
+
pnl: {
|
|
6573
|
+
type: "string",
|
|
6574
|
+
description: "PNL_ANY|PNL_TOP50|PNL_TOP20|PNL_TOP5"
|
|
6575
|
+
},
|
|
6576
|
+
winRatio: {
|
|
6577
|
+
type: "string",
|
|
6578
|
+
description: "WR_ANY|WR_GE_50|WR_GE_80"
|
|
6579
|
+
},
|
|
6580
|
+
maxRetreat: {
|
|
6581
|
+
type: "string",
|
|
6582
|
+
description: "MR_ANY|MR_LE_20|MR_LE_50"
|
|
6583
|
+
},
|
|
6584
|
+
asset: {
|
|
6585
|
+
type: "string",
|
|
6586
|
+
description: "AUM_ANY|AUM_TOP50|AUM_TOP20|AUM_TOP5"
|
|
6587
|
+
}
|
|
6588
|
+
};
|
|
6589
|
+
var LEADERBOARD_POOL_FILTER_PROPS = {
|
|
6590
|
+
sortType: {
|
|
6591
|
+
type: "string",
|
|
6592
|
+
description: "pnl or pnl_ratio"
|
|
6593
|
+
},
|
|
6594
|
+
period: {
|
|
6595
|
+
type: "string",
|
|
6596
|
+
description: "3|7|30|90 days, empty=all"
|
|
6597
|
+
},
|
|
6598
|
+
pnl: {
|
|
6599
|
+
type: "string",
|
|
6600
|
+
description: "Min PnL USD"
|
|
6601
|
+
},
|
|
6602
|
+
winRatio: {
|
|
6603
|
+
type: "string",
|
|
6604
|
+
description: "Min ratio (0.8=80%)"
|
|
6605
|
+
},
|
|
6606
|
+
maxRetreat: {
|
|
6607
|
+
type: "string",
|
|
6608
|
+
description: "Max DD (0.1=10%)"
|
|
6609
|
+
},
|
|
6610
|
+
asset: {
|
|
6611
|
+
type: "string",
|
|
6612
|
+
description: "Min AUM USD"
|
|
6613
|
+
}
|
|
6614
|
+
};
|
|
6615
|
+
var POOL_FILTER_KEYS = ["sortType", "period", "pnl", "winRatio", "maxRetreat", "asset"];
|
|
6616
|
+
function readPoolFilters(args) {
|
|
6617
|
+
const result = {};
|
|
6618
|
+
for (const key of POOL_FILTER_KEYS) {
|
|
6619
|
+
const val = readString(args, key);
|
|
6620
|
+
if (val) result[key] = val;
|
|
6621
|
+
}
|
|
6622
|
+
return result;
|
|
6623
|
+
}
|
|
6624
|
+
function extractLeaderboardData(data) {
|
|
6625
|
+
if (Array.isArray(data)) return data;
|
|
6626
|
+
if (data && typeof data === "object") {
|
|
6627
|
+
const inner = data.data;
|
|
6628
|
+
if (Array.isArray(inner)) return inner;
|
|
6629
|
+
}
|
|
6630
|
+
return [];
|
|
6631
|
+
}
|
|
6632
|
+
var SMARTMONEY_DEMO_MESSAGE = "Smart Money features are not available in demo/simulated trading mode.";
|
|
6633
|
+
var SMARTMONEY_DEMO_SUGGESTION = "Switch to a live profile to use Smart Money features.";
|
|
6634
|
+
function withSmartmoneyDemoGuard(tool) {
|
|
6635
|
+
const originalHandler = tool.handler;
|
|
6636
|
+
return {
|
|
6637
|
+
...tool,
|
|
6638
|
+
handler: async (args, context) => {
|
|
6639
|
+
if (context.config.demo) {
|
|
6640
|
+
throw new ConfigError(
|
|
6641
|
+
SMARTMONEY_DEMO_MESSAGE,
|
|
6642
|
+
SMARTMONEY_DEMO_SUGGESTION
|
|
6643
|
+
);
|
|
6644
|
+
}
|
|
6645
|
+
return originalHandler(args, context);
|
|
6646
|
+
}
|
|
6647
|
+
};
|
|
6648
|
+
}
|
|
6649
|
+
function registerSmartmoneyTools() {
|
|
6650
|
+
const tools = [
|
|
6651
|
+
/* ---------- 1. Overview ---------- */
|
|
6652
|
+
{
|
|
6653
|
+
name: "smartmoney_get_overview",
|
|
6654
|
+
module: "smartmoney",
|
|
6655
|
+
description: "Multi-currency smart money overview ranked by most-watched currencies. Pass ts=Date.now() for latest data, or dataVersion (yyyyMMddHHmm) from a prior call. For single-currency signal with entry prices and trend, use smartmoney_get_signal.",
|
|
6656
|
+
isWrite: false,
|
|
6657
|
+
inputSchema: {
|
|
6658
|
+
type: "object",
|
|
6659
|
+
properties: {
|
|
6660
|
+
dataVersion: {
|
|
6661
|
+
type: "string",
|
|
6662
|
+
description: "yyyyMMddHHmm UTC (or use ts)"
|
|
6663
|
+
},
|
|
6664
|
+
ts: {
|
|
6665
|
+
type: "string",
|
|
6666
|
+
description: "Timestamp ms (or use dataVersion)"
|
|
6667
|
+
},
|
|
6668
|
+
instType: {
|
|
6669
|
+
type: "string",
|
|
6670
|
+
description: "SPOT|MARGIN|FUTURES|SWAP|OPTION"
|
|
6671
|
+
},
|
|
6672
|
+
...SIGNAL_POOL_FILTER_PROPS,
|
|
6673
|
+
lmtNum: {
|
|
6674
|
+
type: "string",
|
|
6675
|
+
description: "Trader pool size 1-500"
|
|
6676
|
+
},
|
|
6677
|
+
instCcyList: {
|
|
6678
|
+
type: "string",
|
|
6679
|
+
description: "Comma-separated e.g. BTC,ETH,SOL"
|
|
6680
|
+
},
|
|
6681
|
+
instCcy: {
|
|
6682
|
+
type: "string",
|
|
6683
|
+
description: "Single currency e.g. BTC"
|
|
6684
|
+
},
|
|
6685
|
+
topInstruments: {
|
|
6686
|
+
type: "string",
|
|
6687
|
+
description: "Top N instruments 1-100"
|
|
6688
|
+
}
|
|
6689
|
+
}
|
|
6690
|
+
},
|
|
6691
|
+
handler: async (rawArgs, context) => {
|
|
6692
|
+
const args = asRecord(rawArgs);
|
|
6693
|
+
const dv = readString(args, "dataVersion");
|
|
6694
|
+
const ts = readString(args, "ts");
|
|
6695
|
+
if (!dv && !ts) {
|
|
6696
|
+
throw new ValidationError('Either "dataVersion" or "ts" is required for smartmoney_get_overview.');
|
|
6697
|
+
}
|
|
6698
|
+
const response = await context.client.privateGet(
|
|
6699
|
+
PATH_OVERVIEW,
|
|
6700
|
+
compactObject({
|
|
6701
|
+
dataVersion: dv,
|
|
6702
|
+
ts,
|
|
6703
|
+
instType: readString(args, "instType"),
|
|
6704
|
+
...readPoolFilters(args),
|
|
6705
|
+
lmtNum: readString(args, "lmtNum"),
|
|
6706
|
+
instCcyList: readString(args, "instCcyList"),
|
|
6707
|
+
instCcy: readString(args, "instCcy"),
|
|
6708
|
+
topInstruments: readString(args, "topInstruments")
|
|
6709
|
+
}),
|
|
6710
|
+
publicRateLimit("smartmoney_get_overview", 5)
|
|
6711
|
+
);
|
|
6712
|
+
return normalizeResponse(response);
|
|
6713
|
+
}
|
|
6714
|
+
},
|
|
6715
|
+
/* ---------- 2. Signal ---------- */
|
|
6716
|
+
{
|
|
6717
|
+
name: "smartmoney_get_signal",
|
|
6718
|
+
module: "smartmoney",
|
|
6719
|
+
description: "Single-currency consensus signal: long/short ratio, entry prices, trend, capital flow. Requires instId or instCcy. Pass ts=Date.now() for latest data, or dataVersion from a prior call. For multi-currency overview, use smartmoney_get_overview. For timeline, use smartmoney_get_signal_history.",
|
|
6720
|
+
isWrite: false,
|
|
6721
|
+
inputSchema: {
|
|
6722
|
+
type: "object",
|
|
6723
|
+
properties: {
|
|
6724
|
+
instId: {
|
|
6725
|
+
type: "string",
|
|
6726
|
+
description: "e.g. BTC-USDT-SWAP (or use instCcy)"
|
|
6727
|
+
},
|
|
6728
|
+
instCcy: {
|
|
6729
|
+
type: "string",
|
|
6730
|
+
description: "e.g. BTC, SPOT/SWAP only (or use instId)"
|
|
6731
|
+
},
|
|
6732
|
+
dataVersion: {
|
|
6733
|
+
type: "string",
|
|
6734
|
+
description: "yyyyMMddHHmm UTC (or use ts)"
|
|
6735
|
+
},
|
|
6736
|
+
ts: {
|
|
6737
|
+
type: "string",
|
|
6738
|
+
description: "Timestamp ms (or use dataVersion)"
|
|
6739
|
+
},
|
|
6740
|
+
...SIGNAL_POOL_FILTER_PROPS,
|
|
6741
|
+
lmtNum: {
|
|
6742
|
+
type: "string",
|
|
6743
|
+
description: "Trader pool size 1-500"
|
|
6744
|
+
},
|
|
6745
|
+
authorIds: {
|
|
6746
|
+
type: "string",
|
|
6747
|
+
description: "Comma-separated user IDs e.g. 1001,1002"
|
|
6748
|
+
}
|
|
6749
|
+
}
|
|
6750
|
+
},
|
|
6751
|
+
handler: async (rawArgs, context) => {
|
|
6752
|
+
const args = asRecord(rawArgs);
|
|
6753
|
+
const instId = readString(args, "instId");
|
|
6754
|
+
const instCcy = readString(args, "instCcy");
|
|
6755
|
+
if (!instId && !instCcy) {
|
|
6756
|
+
throw new ValidationError('Either "instId" or "instCcy" is required for smartmoney_get_signal.');
|
|
6757
|
+
}
|
|
6758
|
+
const dv = readString(args, "dataVersion");
|
|
6759
|
+
const ts = readString(args, "ts");
|
|
6760
|
+
if (!dv && !ts) {
|
|
6761
|
+
throw new ValidationError('Either "dataVersion" or "ts" is required for smartmoney_get_signal.');
|
|
6762
|
+
}
|
|
6763
|
+
const response = await context.client.privateGet(
|
|
6764
|
+
PATH_SIGNAL,
|
|
6765
|
+
compactObject({
|
|
6766
|
+
instId,
|
|
6767
|
+
instCcy,
|
|
6768
|
+
dataVersion: dv,
|
|
6769
|
+
ts,
|
|
6770
|
+
...readPoolFilters(args),
|
|
6771
|
+
lmtNum: readString(args, "lmtNum"),
|
|
6772
|
+
authorIds: readString(args, "authorIds")
|
|
6773
|
+
}),
|
|
6774
|
+
publicRateLimit("smartmoney_get_signal", 5)
|
|
6775
|
+
);
|
|
6776
|
+
return normalizeResponse(response);
|
|
6777
|
+
}
|
|
6778
|
+
},
|
|
6779
|
+
/* ---------- 3. Signal History ---------- */
|
|
6780
|
+
{
|
|
6781
|
+
name: "smartmoney_get_signal_history",
|
|
6782
|
+
module: "smartmoney",
|
|
6783
|
+
description: "Signal history timeline sorted by ts DESC for trend analysis. Requires instId. Pass ts=Date.now() for latest data, or dataVersion from a prior call. For current snapshot, use smartmoney_get_signal.",
|
|
6784
|
+
isWrite: false,
|
|
6785
|
+
inputSchema: {
|
|
6786
|
+
type: "object",
|
|
6787
|
+
properties: {
|
|
6788
|
+
instId: {
|
|
6789
|
+
type: "string",
|
|
6790
|
+
description: "e.g. BTC-USDT-SWAP"
|
|
6791
|
+
},
|
|
6792
|
+
dataVersion: {
|
|
6793
|
+
type: "string",
|
|
6794
|
+
description: "yyyyMMddHHmm UTC (or use ts)"
|
|
6795
|
+
},
|
|
6796
|
+
ts: {
|
|
6797
|
+
type: "string",
|
|
6798
|
+
description: "Timestamp ms (or use dataVersion)"
|
|
6799
|
+
},
|
|
6800
|
+
granularity: {
|
|
6801
|
+
type: "string",
|
|
6802
|
+
description: "1h or 1d"
|
|
6803
|
+
},
|
|
6804
|
+
limit: {
|
|
6805
|
+
type: "string",
|
|
6806
|
+
description: "Data points 1-500"
|
|
6807
|
+
},
|
|
6808
|
+
...SIGNAL_POOL_FILTER_PROPS
|
|
6809
|
+
},
|
|
6810
|
+
required: ["instId"]
|
|
6811
|
+
},
|
|
6812
|
+
handler: async (rawArgs, context) => {
|
|
6813
|
+
const args = asRecord(rawArgs);
|
|
6814
|
+
const dv = readString(args, "dataVersion");
|
|
6815
|
+
const ts = readString(args, "ts");
|
|
6816
|
+
if (!dv && !ts) {
|
|
6817
|
+
throw new ValidationError('Either "dataVersion" or "ts" is required for smartmoney_get_signal_history.');
|
|
6818
|
+
}
|
|
6819
|
+
const response = await context.client.privateGet(
|
|
6820
|
+
PATH_SIGNAL_HISTORY,
|
|
6821
|
+
compactObject({
|
|
6822
|
+
instId: requireString(args, "instId"),
|
|
6823
|
+
dataVersion: dv,
|
|
6824
|
+
ts,
|
|
6825
|
+
granularity: readString(args, "granularity"),
|
|
6826
|
+
limit: readString(args, "limit"),
|
|
6827
|
+
...readPoolFilters(args)
|
|
6828
|
+
}),
|
|
6829
|
+
publicRateLimit("smartmoney_get_signal_history", 5)
|
|
6830
|
+
);
|
|
6831
|
+
return normalizeResponse(response);
|
|
6832
|
+
}
|
|
6833
|
+
},
|
|
6834
|
+
/* ---------- 4. Traders (list) ---------- */
|
|
6835
|
+
{
|
|
6836
|
+
name: "smartmoney_get_traders",
|
|
6837
|
+
module: "smartmoney",
|
|
6838
|
+
description: "List/filter leaderboard traders. For single trader detail: smartmoney_get_trader_detail.",
|
|
6839
|
+
isWrite: false,
|
|
6840
|
+
inputSchema: {
|
|
6841
|
+
type: "object",
|
|
6842
|
+
properties: {
|
|
6843
|
+
dataVersion: {
|
|
6844
|
+
type: "string",
|
|
6845
|
+
description: "yyyyMMddHHmm, omit=latest"
|
|
6846
|
+
},
|
|
6847
|
+
...LEADERBOARD_POOL_FILTER_PROPS,
|
|
6848
|
+
authorIds: {
|
|
6849
|
+
type: "string",
|
|
6850
|
+
description: "Comma-separated author IDs"
|
|
6851
|
+
},
|
|
6852
|
+
after: {
|
|
6853
|
+
type: "string",
|
|
6854
|
+
description: "Cursor after this authorId"
|
|
6855
|
+
},
|
|
6856
|
+
before: {
|
|
6857
|
+
type: "string",
|
|
6858
|
+
description: "Cursor before this authorId"
|
|
6859
|
+
},
|
|
6860
|
+
limit: {
|
|
6861
|
+
type: "string",
|
|
6862
|
+
description: "Max results 1-100"
|
|
6863
|
+
}
|
|
6864
|
+
}
|
|
6865
|
+
},
|
|
6866
|
+
handler: async (rawArgs, context) => {
|
|
6867
|
+
const args = asRecord(rawArgs);
|
|
6868
|
+
const response = await context.client.privateGet(
|
|
6869
|
+
PATH_LEADERBOARD,
|
|
6870
|
+
compactObject({
|
|
6871
|
+
dataVersion: readString(args, "dataVersion"),
|
|
6872
|
+
...readPoolFilters(args),
|
|
6873
|
+
authorIds: readString(args, "authorIds"),
|
|
6874
|
+
after: readString(args, "after"),
|
|
6875
|
+
before: readString(args, "before"),
|
|
6876
|
+
limit: readString(args, "limit")
|
|
6877
|
+
}),
|
|
6878
|
+
publicRateLimit("smartmoney_get_traders", 5)
|
|
6879
|
+
);
|
|
6880
|
+
const normalized = normalizeResponse(response);
|
|
6881
|
+
return { ...normalized, data: extractLeaderboardData(normalized.data) };
|
|
6882
|
+
}
|
|
6883
|
+
},
|
|
6884
|
+
/* ---------- 5. Trader Detail (composite) ---------- */
|
|
6885
|
+
{
|
|
6886
|
+
name: "smartmoney_get_trader_detail",
|
|
6887
|
+
module: "smartmoney",
|
|
6888
|
+
description: "Trader portrait: profile + positions + trades. Requires authorId from smartmoney_get_traders. Do NOT use for listing \u2014 use smartmoney_get_traders.",
|
|
6889
|
+
isWrite: false,
|
|
6890
|
+
inputSchema: {
|
|
6891
|
+
type: "object",
|
|
6892
|
+
properties: {
|
|
6893
|
+
authorId: {
|
|
6894
|
+
type: "string",
|
|
6895
|
+
description: "Trader author ID"
|
|
6896
|
+
},
|
|
6897
|
+
period: {
|
|
6898
|
+
type: "string",
|
|
6899
|
+
description: "3|7|30|90 days, omit=all"
|
|
6900
|
+
},
|
|
6901
|
+
instCcy: {
|
|
6902
|
+
type: "string",
|
|
6903
|
+
description: "Currency filter e.g. BTC"
|
|
6904
|
+
},
|
|
6905
|
+
tradeLimit: {
|
|
6906
|
+
type: "string",
|
|
6907
|
+
description: "Max trades 1-100"
|
|
6908
|
+
}
|
|
6909
|
+
},
|
|
6910
|
+
required: ["authorId"]
|
|
6911
|
+
},
|
|
6912
|
+
handler: async (rawArgs, context) => {
|
|
6913
|
+
const args = asRecord(rawArgs);
|
|
6914
|
+
const authorId = requireString(args, "authorId");
|
|
6915
|
+
const period = readString(args, "period");
|
|
6916
|
+
const instCcy = readString(args, "instCcy");
|
|
6917
|
+
const tradeLimit = readString(args, "tradeLimit");
|
|
6918
|
+
const [profileRes, positionsRes, tradesRes] = await Promise.all([
|
|
6919
|
+
context.client.privateGet(
|
|
6920
|
+
PATH_LEADERBOARD,
|
|
6921
|
+
compactObject({ authorIds: authorId, period }),
|
|
6922
|
+
publicRateLimit("smartmoney_get_traders", 5)
|
|
6923
|
+
),
|
|
6924
|
+
context.client.privateGet(
|
|
6925
|
+
PATH_POSITION_CURRENT,
|
|
6926
|
+
compactObject({ authorId, instCcy }),
|
|
6927
|
+
publicRateLimit("smartmoney_trader_positions", 5)
|
|
6928
|
+
),
|
|
6929
|
+
context.client.privateGet(
|
|
6930
|
+
PATH_TRADE_RECORDS,
|
|
6931
|
+
compactObject({ authorId, instCcy, limit: tradeLimit }),
|
|
6932
|
+
publicRateLimit("smartmoney_trade_records", 5)
|
|
6933
|
+
)
|
|
6934
|
+
]);
|
|
6935
|
+
const profileNorm = normalizeResponse(profileRes);
|
|
6936
|
+
const positionsNorm = normalizeResponse(positionsRes);
|
|
6937
|
+
const tradesNorm = normalizeResponse(tradesRes);
|
|
6938
|
+
return {
|
|
6939
|
+
endpoint: "smartmoney_get_trader_detail (composite)",
|
|
6940
|
+
requestTime: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6941
|
+
data: {
|
|
6942
|
+
profile: extractLeaderboardData(profileNorm.data),
|
|
6943
|
+
positions: positionsNorm.data,
|
|
6944
|
+
trades: tradesNorm.data
|
|
6945
|
+
}
|
|
6946
|
+
};
|
|
6947
|
+
}
|
|
6948
|
+
}
|
|
6949
|
+
];
|
|
6950
|
+
return tools.map(withSmartmoneyDemoGuard);
|
|
6951
|
+
}
|
|
6429
6952
|
function buildContractTradeTools(cfg) {
|
|
6430
6953
|
const { prefix, module, label, instTypes, instIdExample } = cfg;
|
|
6431
6954
|
const [defaultType, otherType] = instTypes;
|
|
@@ -6767,31 +7290,58 @@ function buildContractTradeTools(cfg) {
|
|
|
6767
7290
|
{
|
|
6768
7291
|
name: n("set_leverage"),
|
|
6769
7292
|
module,
|
|
6770
|
-
description: `Set leverage for a ${label} instrument or position. [CAUTION] Changes risk parameters
|
|
7293
|
+
description: `Set leverage for a ${label} instrument or position. [CAUTION] Changes risk parameters.
|
|
7294
|
+
Scenarios (SWAP/FUTURES only):
|
|
7295
|
+
\u2022 cross + any instId under the index \u2192 sets leverage at the index level
|
|
7296
|
+
\u2022 isolated + buy-sell (net) posMode \u2192 instId only
|
|
7297
|
+
\u2022 isolated + long-short (hedge) posMode \u2192 instId + posSide=long|short (BOTH directions must be set separately)
|
|
7298
|
+
Not supported: PORTFOLIO MARGIN accounts cannot adjust cross leverage for SWAP/FUTURES \u2014 the request will be rejected by OKX. Use account_get_config first if unsure of the account's margin mode.`,
|
|
6771
7299
|
isWrite: true,
|
|
6772
7300
|
inputSchema: {
|
|
6773
7301
|
type: "object",
|
|
6774
7302
|
properties: {
|
|
6775
7303
|
instId: { type: "string", description: instIdExample },
|
|
6776
|
-
lever: {
|
|
7304
|
+
lever: {
|
|
7305
|
+
type: "string",
|
|
7306
|
+
description: "Leverage multiplier as a positive number string, e.g. '10'. Max value depends on the instrument (query market_get_instruments \u2192 lever)."
|
|
7307
|
+
},
|
|
6777
7308
|
mgnMode: { type: "string", enum: ["cross", "isolated"] },
|
|
6778
7309
|
posSide: {
|
|
6779
7310
|
type: "string",
|
|
6780
|
-
enum: ["long", "short"
|
|
6781
|
-
description: "
|
|
7311
|
+
enum: ["long", "short"],
|
|
7312
|
+
description: "REQUIRED when mgnMode=isolated AND the account is in hedge (long/short) position mode. Use 'long' or 'short' \u2014 setting one side does NOT auto-apply to the other. Omit entirely for one-way (net) position mode or for cross margin."
|
|
6782
7313
|
}
|
|
6783
7314
|
},
|
|
6784
7315
|
required: ["instId", "lever", "mgnMode"]
|
|
6785
7316
|
},
|
|
6786
7317
|
handler: async (rawArgs, context) => {
|
|
6787
7318
|
const args = asRecord(rawArgs);
|
|
7319
|
+
const instId = requireString(args, "instId");
|
|
7320
|
+
const leverRaw = requireString(args, "lever");
|
|
7321
|
+
const leverNum = Number(leverRaw);
|
|
7322
|
+
if (!Number.isFinite(leverNum) || leverNum <= 0) {
|
|
7323
|
+
throw new ValidationError(
|
|
7324
|
+
`Parameter "lever" must be a positive number string, got "${leverRaw}".`
|
|
7325
|
+
);
|
|
7326
|
+
}
|
|
7327
|
+
const mgnMode = requireString(args, "mgnMode");
|
|
7328
|
+
assertEnum(mgnMode, "mgnMode", ["cross", "isolated"]);
|
|
7329
|
+
const posSide = readString(args, "posSide");
|
|
7330
|
+
if (posSide !== void 0) {
|
|
7331
|
+
assertEnum(posSide, "posSide", ["long", "short"]);
|
|
7332
|
+
if (mgnMode === "cross") {
|
|
7333
|
+
throw new ValidationError(
|
|
7334
|
+
`posSide="${posSide}" is only valid with mgnMode="isolated" in hedge mode. Omit posSide for cross margin.`
|
|
7335
|
+
);
|
|
7336
|
+
}
|
|
7337
|
+
}
|
|
6788
7338
|
const response = await context.client.privatePost(
|
|
6789
7339
|
"/api/v5/account/set-leverage",
|
|
6790
7340
|
compactObject({
|
|
6791
|
-
instId
|
|
6792
|
-
lever:
|
|
6793
|
-
mgnMode
|
|
6794
|
-
posSide
|
|
7341
|
+
instId,
|
|
7342
|
+
lever: leverRaw,
|
|
7343
|
+
mgnMode,
|
|
7344
|
+
posSide
|
|
6795
7345
|
}),
|
|
6796
7346
|
privateRateLimit(n("set_leverage"), 20)
|
|
6797
7347
|
);
|
|
@@ -7664,7 +8214,7 @@ function registerMarketFilterTools() {
|
|
|
7664
8214
|
sortBy: {
|
|
7665
8215
|
type: "string",
|
|
7666
8216
|
enum: ["last", "chg24hPct", "marketCapUsd", "volUsd24h", "fundingRate", "oiUsd", "listTime"],
|
|
7667
|
-
description: "Sort field. Default: volUsd24h. Note: marketCapUsd is only meaningful for SPOT (null for SWAP/FUTURES)."
|
|
8217
|
+
description: "Sort field. Default: volUsd24h. Note: marketCapUsd is only meaningful for SPOT (null for SWAP/FUTURES). To rank by OI *change* (oiDeltaPct / absOiDeltaPct), use market_filter_oi_change \u2014 market_filter only sorts by the current snapshot."
|
|
7668
8218
|
},
|
|
7669
8219
|
sortOrder: {
|
|
7670
8220
|
type: "string",
|
|
@@ -7777,7 +8327,7 @@ function registerMarketFilterTools() {
|
|
|
7777
8327
|
bar: {
|
|
7778
8328
|
type: "string",
|
|
7779
8329
|
enum: [...OI_BARS],
|
|
7780
|
-
description: "Bar window for OI change computation: 5m, 15m, 1H, 4H, 1D. Default: 1H"
|
|
8330
|
+
description: "Bar window for OI change computation: 5m, 15m, 1H, 4H, 1D (case-insensitive on server, but send canonical form here). Default: 1H"
|
|
7781
8331
|
},
|
|
7782
8332
|
// Filters
|
|
7783
8333
|
minOiUsd: {
|
|
@@ -7795,8 +8345,8 @@ function registerMarketFilterTools() {
|
|
|
7795
8345
|
// Sort / pagination
|
|
7796
8346
|
sortBy: {
|
|
7797
8347
|
type: "string",
|
|
7798
|
-
enum: ["oiUsd", "oiDeltaUsd", "oiDeltaPct", "volUsd24h", "last"],
|
|
7799
|
-
description: "Sort field. Default: oiDeltaPct (largest movers first)"
|
|
8348
|
+
enum: ["oiUsd", "oiDeltaUsd", "oiDeltaPct", "absOiDeltaPct", "volUsd24h", "fundingRate", "last"],
|
|
8349
|
+
description: "Sort field. Default: oiDeltaPct (largest movers first, signed \u2014 longs and shorts separate). Use absOiDeltaPct to sort by |oiDeltaPct| (largest-magnitude moves regardless of direction). fundingRate is also supported for SWAP. Do NOT use the market_filter tool's sort fields (chg24hPct, marketCapUsd, listTime) here \u2014 they are not in the OI-change Row."
|
|
7800
8350
|
},
|
|
7801
8351
|
sortOrder: {
|
|
7802
8352
|
type: "string",
|
|
@@ -7852,7 +8402,7 @@ var D_COINS_SENTIMENT = 'Comma-separated uppercase ticker symbols, max 20 (e.g.
|
|
|
7852
8402
|
var D_LANGUAGE = "Content language: zh-CN or en-US. Infer from user's message. No server default.";
|
|
7853
8403
|
var D_BEGIN = "Start time, Unix epoch milliseconds. API defaults to 72 hours ago when omitted. Pass explicitly for older topics (e.g. 'last 30 days'). Max range: 180 days. Parse relative time if given.";
|
|
7854
8404
|
var D_END = "End time, Unix epoch milliseconds. Parse relative time if given. Omit for no upper bound.";
|
|
7855
|
-
var D_IMPORTANCE = "Importance filter: high
|
|
8405
|
+
var D_IMPORTANCE = "Importance filter: 'low' returns all news (both low and high importance); 'high' narrows to major/breaking news only. Omitted \u2192 server default (high-only). Default to 'low' for broad browsing; pass 'high' only when the user explicitly asks for major news.";
|
|
7856
8406
|
var D_PLATFORM = "Filter by news source. Use values from news_get_domains (e.g. blockbeats, odaily_flash). Omit for all sources.";
|
|
7857
8407
|
var D_LIMIT = "Number of results (default 10, max 50).";
|
|
7858
8408
|
function registerNewsTools() {
|
|
@@ -7863,7 +8413,7 @@ function registerNewsTools() {
|
|
|
7863
8413
|
{
|
|
7864
8414
|
name: "news_get_latest",
|
|
7865
8415
|
module: "news",
|
|
7866
|
-
description: "Get crypto news sorted by time.
|
|
8416
|
+
description: "Get crypto news sorted by time. For broad browsing ('what happened recently', 'latest news', 'any big news today'), pass importance='low' to include both high and low importance. Server default (when importance omitted) returns only high-importance news. For coin-specific news, use news_get_by_coin instead.",
|
|
7867
8417
|
isWrite: false,
|
|
7868
8418
|
inputSchema: {
|
|
7869
8419
|
type: "object",
|
|
@@ -9524,6 +10074,82 @@ function registerSpotTradeTools() {
|
|
|
9524
10074
|
);
|
|
9525
10075
|
return normalizeResponse(response);
|
|
9526
10076
|
}
|
|
10077
|
+
},
|
|
10078
|
+
// ── set_leverage (SPOT margin: instId-level isolated OR ccy-level cross) ──
|
|
10079
|
+
// Covers OKX scenarios 1–5 (everything except SWAP/FUTURES, which are in
|
|
10080
|
+
// contract-trade.ts). Callers supply exactly one of {instId, ccy}:
|
|
10081
|
+
// • instId + isolated → scenario 1 (pair-level margin)
|
|
10082
|
+
// • instId + cross → scenario 3 (contract-mode pair-level cross margin)
|
|
10083
|
+
// • ccy + cross → scenarios 2 / 4 / 5 (spot/multi-ccy/PM currency-level cross)
|
|
10084
|
+
// Not applicable: posSide (spot has no long/short hedge).
|
|
10085
|
+
{
|
|
10086
|
+
name: "spot_set_leverage",
|
|
10087
|
+
module: "spot",
|
|
10088
|
+
description: "Set leverage for SPOT margin trading. Provide exactly ONE of instId (pair-level) or ccy (currency-level cross, requires borrow-enabled account / multi-ccy / portfolio margin). [CAUTION] Changes risk parameters.\nScenarios:\n \u2022 instId + mgnMode=isolated \u2192 pair-level isolated margin\n \u2022 instId + mgnMode=cross \u2192 pair-level cross margin (contract-mode account)\n \u2022 ccy + mgnMode=cross \u2192 currency-level cross margin (spot-with-borrow / multi-ccy / portfolio margin)\nWhen ccy is supplied, mgnMode MUST be cross. posSide is never applicable to spot margin.",
|
|
10089
|
+
isWrite: true,
|
|
10090
|
+
inputSchema: {
|
|
10091
|
+
type: "object",
|
|
10092
|
+
properties: {
|
|
10093
|
+
instId: {
|
|
10094
|
+
type: "string",
|
|
10095
|
+
description: "Spot pair, e.g. BTC-USDT. Provide instId OR ccy, not both."
|
|
10096
|
+
},
|
|
10097
|
+
ccy: {
|
|
10098
|
+
type: "string",
|
|
10099
|
+
description: "Margin currency, e.g. BTC. Required only for currency-level cross margin (borrow-enabled / multi-ccy / portfolio margin). Mutually exclusive with instId."
|
|
10100
|
+
},
|
|
10101
|
+
lever: {
|
|
10102
|
+
type: "string",
|
|
10103
|
+
description: "Leverage multiplier as a positive number string, e.g. '3'. Max depends on the pair (query market_get_instruments \u2192 lever) or the account policy for ccy-level."
|
|
10104
|
+
},
|
|
10105
|
+
mgnMode: {
|
|
10106
|
+
type: "string",
|
|
10107
|
+
enum: ["cross", "isolated"],
|
|
10108
|
+
description: "cross or isolated. Must be cross when ccy is supplied."
|
|
10109
|
+
}
|
|
10110
|
+
},
|
|
10111
|
+
required: ["lever", "mgnMode"]
|
|
10112
|
+
},
|
|
10113
|
+
handler: async (rawArgs, context) => {
|
|
10114
|
+
const args = asRecord(rawArgs);
|
|
10115
|
+
const instId = readString(args, "instId");
|
|
10116
|
+
const ccy = readString(args, "ccy");
|
|
10117
|
+
if (!instId && !ccy) {
|
|
10118
|
+
throw new ValidationError(
|
|
10119
|
+
`Missing required parameter: provide either "instId" (pair-level) or "ccy" (currency-level cross margin).`
|
|
10120
|
+
);
|
|
10121
|
+
}
|
|
10122
|
+
if (instId && ccy) {
|
|
10123
|
+
throw new ValidationError(
|
|
10124
|
+
`Parameters "instId" and "ccy" are mutually exclusive \u2014 provide only one. instId sets pair-level leverage; ccy sets currency-level cross margin leverage.`
|
|
10125
|
+
);
|
|
10126
|
+
}
|
|
10127
|
+
const leverRaw = requireString(args, "lever");
|
|
10128
|
+
const leverNum = Number(leverRaw);
|
|
10129
|
+
if (!Number.isFinite(leverNum) || leverNum <= 0) {
|
|
10130
|
+
throw new ValidationError(
|
|
10131
|
+
`Parameter "lever" must be a positive number string, got "${leverRaw}".`
|
|
10132
|
+
);
|
|
10133
|
+
}
|
|
10134
|
+
const mgnMode = requireString(args, "mgnMode");
|
|
10135
|
+
assertEnum(mgnMode, "mgnMode", ["cross", "isolated"]);
|
|
10136
|
+
if (ccy && mgnMode !== "cross") {
|
|
10137
|
+
throw new ValidationError(
|
|
10138
|
+
`When "ccy" is supplied, "mgnMode" must be "cross" (currency-level leverage only applies to cross margin).`
|
|
10139
|
+
);
|
|
10140
|
+
}
|
|
10141
|
+
const response = await context.client.privatePost(
|
|
10142
|
+
"/api/v5/account/set-leverage",
|
|
10143
|
+
compactObject({
|
|
10144
|
+
instId,
|
|
10145
|
+
ccy,
|
|
10146
|
+
lever: leverRaw,
|
|
10147
|
+
mgnMode
|
|
10148
|
+
}),
|
|
10149
|
+
privateRateLimit("spot_set_leverage", 20)
|
|
10150
|
+
);
|
|
10151
|
+
return normalizeResponse(response);
|
|
10152
|
+
}
|
|
9527
10153
|
}
|
|
9528
10154
|
];
|
|
9529
10155
|
}
|
|
@@ -9655,6 +10281,7 @@ function allToolSpecs() {
|
|
|
9655
10281
|
...registerNewsTools(),
|
|
9656
10282
|
...registerBotTools(),
|
|
9657
10283
|
...registerAllEarnTools(),
|
|
10284
|
+
...registerSmartmoneyTools(),
|
|
9658
10285
|
...registerAuditTools(),
|
|
9659
10286
|
...registerSkillsTools()
|
|
9660
10287
|
];
|
|
@@ -11015,7 +11642,7 @@ async function cmdDiagnoseMcp(options = {}) {
|
|
|
11015
11642
|
|
|
11016
11643
|
// src/commands/diagnose.ts
|
|
11017
11644
|
var CLI_VERSION = readCliVersion();
|
|
11018
|
-
var GIT_HASH = true ? "
|
|
11645
|
+
var GIT_HASH = true ? "d5c8ab1" : "dev";
|
|
11019
11646
|
function maskKey2(key) {
|
|
11020
11647
|
if (!key) return "(not set)";
|
|
11021
11648
|
if (key.length <= 8) return "****";
|
|
@@ -11554,17 +12181,17 @@ var CLI_REGISTRY = {
|
|
|
11554
12181
|
},
|
|
11555
12182
|
filter: {
|
|
11556
12183
|
toolName: "market_filter",
|
|
11557
|
-
usage: "okx market filter --instType <SPOT|SWAP|FUTURES> [--sortBy <
|
|
11558
|
-
description: "Screen / rank instruments by multi-dimensional criteria (price, volume, OI, funding rate, market cap, etc.)"
|
|
12184
|
+
usage: "okx market filter --instType <SPOT|SWAP|FUTURES> [--sortBy <last|chg24hPct|marketCapUsd|volUsd24h|fundingRate|oiUsd|listTime>] [--sortOrder <asc|desc>] [--limit <1-100>] [--baseCcy <ccy>] [--quoteCcy <ccy>] [--settleCcy <ccy>] [--instFamily <fam>] [--ctType <linear|inverse>] [--minLast <n>] [--maxLast <n>] [--minChg24hPct <n>] [--maxChg24hPct <n>] [--minMarketCapUsd <n>] [--maxMarketCapUsd <n>] [--minVolUsd24h <n>] [--maxVolUsd24h <n>] [--minFundingRate <n>] [--maxFundingRate <n>] [--minOiUsd <n>] [--maxOiUsd <n>]",
|
|
12185
|
+
description: "Screen / rank instruments by multi-dimensional criteria (price, volume, OI, funding rate, market cap, etc.). For OI *change* ranking use `market oi-change`."
|
|
11559
12186
|
},
|
|
11560
12187
|
"oi-history": {
|
|
11561
12188
|
toolName: "market_get_oi_history",
|
|
11562
|
-
usage: "okx market oi-history <instId> [--bar <5m|15m|1H|4H|1D>] [--limit <
|
|
12189
|
+
usage: "okx market oi-history <instId> [--bar <5m|15m|1H|4H|1D>] [--limit <1-500>] [--ts <ms>]",
|
|
11563
12190
|
description: "Open interest history time series with bar-over-bar delta for a single instrument"
|
|
11564
12191
|
},
|
|
11565
12192
|
"oi-change": {
|
|
11566
12193
|
toolName: "market_filter_oi_change",
|
|
11567
|
-
usage: "okx market oi-change --instType <SWAP|FUTURES> [--bar <5m|15m|1H|4H|1D>] [--sortBy <
|
|
12194
|
+
usage: "okx market oi-change --instType <SWAP|FUTURES> [--bar <5m|15m|1H|4H|1D>] [--sortBy <oiUsd|oiDeltaUsd|oiDeltaPct|absOiDeltaPct|volUsd24h|fundingRate|last>] [--sortOrder <asc|desc>] [--limit <1-100>] [--minOiUsd <n>] [--minVolUsd24h <n>] [--minAbsOiDeltaPct <n>]",
|
|
11568
12195
|
description: "Find instruments with largest OI changes over a bar window (accumulation/distribution scanner)"
|
|
11569
12196
|
}
|
|
11570
12197
|
},
|
|
@@ -11577,10 +12204,10 @@ var CLI_REGISTRY = {
|
|
|
11577
12204
|
usage: "okx market indicator list",
|
|
11578
12205
|
description: "List all supported technical indicators"
|
|
11579
12206
|
},
|
|
11580
|
-
"<
|
|
12207
|
+
"<indicator> <instId>": {
|
|
11581
12208
|
toolName: "market_get_indicator",
|
|
11582
|
-
usage: "okx market indicator <
|
|
11583
|
-
description: "Get indicator values for an instrument (e.g. okx market indicator BTC-USDT-SWAP
|
|
12209
|
+
usage: "okx market indicator <indicator> <instId> [--bar <3m|5m|15m|1H|4H|12Hutc|1Dutc|3Dutc|1Wutc>] [--limit <1-100>] [--backtest-time <ts>] [--params <json>]",
|
|
12210
|
+
description: "Get indicator values for an instrument (e.g. okx market indicator rsi BTC-USDT-SWAP). NOTE: 1m is not supported for indicators."
|
|
11584
12211
|
}
|
|
11585
12212
|
}
|
|
11586
12213
|
}
|
|
@@ -11700,6 +12327,11 @@ var CLI_REGISTRY = {
|
|
|
11700
12327
|
alternateTools: ["spot_batch_amend", "spot_batch_cancel"],
|
|
11701
12328
|
usage: "okx spot batch --action <place|amend|cancel> --orders '<json>'",
|
|
11702
12329
|
description: "Batch place, amend, or cancel spot orders"
|
|
12330
|
+
},
|
|
12331
|
+
leverage: {
|
|
12332
|
+
toolName: "spot_set_leverage",
|
|
12333
|
+
usage: "okx spot leverage ( --instId <pair> | --ccy <ccy> ) --lever <positive-number> --mgnMode <cross|isolated>",
|
|
12334
|
+
description: "Set leverage for SPOT margin. Provide instId (pair-level) OR ccy (currency-level cross, for borrow-enabled/multi-ccy/portfolio margin). When ccy is used, mgnMode must be cross."
|
|
11703
12335
|
}
|
|
11704
12336
|
},
|
|
11705
12337
|
subgroups: {
|
|
@@ -11782,8 +12414,8 @@ var CLI_REGISTRY = {
|
|
|
11782
12414
|
},
|
|
11783
12415
|
leverage: {
|
|
11784
12416
|
toolName: "swap_set_leverage",
|
|
11785
|
-
usage: "okx swap leverage --instId <id> --lever <
|
|
11786
|
-
description: "Set leverage for a swap instrument"
|
|
12417
|
+
usage: "okx swap leverage --instId <id> --lever <positive-number> --mgnMode <cross|isolated> [--posSide <long|short>]",
|
|
12418
|
+
description: "Set leverage for a swap instrument. posSide is REQUIRED when mgnMode=isolated and account is in hedge mode \u2014 must be set for BOTH long and short separately. Not supported for portfolio margin + cross."
|
|
11787
12419
|
},
|
|
11788
12420
|
"get-leverage": {
|
|
11789
12421
|
toolName: "swap_get_leverage",
|
|
@@ -11881,8 +12513,8 @@ var CLI_REGISTRY = {
|
|
|
11881
12513
|
},
|
|
11882
12514
|
leverage: {
|
|
11883
12515
|
toolName: "futures_set_leverage",
|
|
11884
|
-
usage: "okx futures leverage --instId <id> --lever <
|
|
11885
|
-
description: "Set leverage for a futures instrument"
|
|
12516
|
+
usage: "okx futures leverage --instId <id> --lever <positive-number> --mgnMode <cross|isolated> [--posSide <long|short>]",
|
|
12517
|
+
description: "Set leverage for a futures instrument. posSide is REQUIRED when mgnMode=isolated and account is in hedge mode \u2014 must be set for BOTH long and short separately. Not supported for portfolio margin + cross."
|
|
11886
12518
|
},
|
|
11887
12519
|
batch: {
|
|
11888
12520
|
toolName: "futures_batch_orders",
|
|
@@ -12192,9 +12824,14 @@ var CLI_REGISTRY = {
|
|
|
12192
12824
|
usage: "okx bot grid create --instId <id> --algoOrdType <grid|contract_grid> --maxPx <px> --minPx <px> --gridNum <n>\n [--runType <1|2>] [--quoteSz <n>] [--baseSz <n>]\n [--direction <long|short|neutral>] [--lever <n>] [--sz <n>] [--basePos] [--no-basePos]\n [--tpTriggerPx <px>] [--slTriggerPx <px>] [--tpRatio <n>] [--slRatio <n>] [--algoClOrdId <id>]",
|
|
12193
12825
|
description: "Create a new grid bot order (contract grid opens base position by default)"
|
|
12194
12826
|
},
|
|
12827
|
+
amend: {
|
|
12828
|
+
toolName: "grid_amend_order",
|
|
12829
|
+
usage: "okx bot grid amend --algoId <id> --maxPx <px> --minPx <px> --gridNum <n> [--topUpAmt <n>]\n okx bot grid amend --algoId <id> --instId <id> [--tpTriggerPx <px>] [--slTriggerPx <px>] [--tpRatio <n>] [--slRatio <n>] [--topUpAmt <n>]",
|
|
12830
|
+
description: "Amend a running grid bot. Price-range mode: provide --maxPx/--minPx/--gridNum. TP/SL mode: provide --instId and TP/SL flags."
|
|
12831
|
+
},
|
|
12195
12832
|
stop: {
|
|
12196
12833
|
toolName: "grid_stop_order",
|
|
12197
|
-
usage: "okx bot grid stop --algoId <id> --algoOrdType <type> --instId <id> [--stopType <1|2
|
|
12834
|
+
usage: "okx bot grid stop --algoId <id> --algoOrdType <type> --instId <id> [--stopType <1|2>]",
|
|
12198
12835
|
description: "Stop a running grid bot order"
|
|
12199
12836
|
}
|
|
12200
12837
|
}
|
|
@@ -12282,6 +12919,37 @@ var CLI_REGISTRY = {
|
|
|
12282
12919
|
}
|
|
12283
12920
|
}
|
|
12284
12921
|
},
|
|
12922
|
+
// ── smartmoney ─────────────────────────────────────────────────────────────
|
|
12923
|
+
smartmoney: {
|
|
12924
|
+
description: "Smart money signals \u2014 trader leaderboard, consensus signals, and position analysis",
|
|
12925
|
+
commands: {
|
|
12926
|
+
overview: {
|
|
12927
|
+
toolName: "smartmoney_get_overview",
|
|
12928
|
+
usage: "okx smartmoney overview [--dataVersion <ver>] [--ts <ms>] [--instType <SWAP|SPOT>] [--sortType <pnl|pnlRatio>] [--period <3|7|30|90>] [--pnl <tier>] [--winRatio <tier>] [--maxRetreat <tier>] [--asset <tier>] [--lmtNum <n>] [--instCcyList <ccys>] [--instCcy <ccy>] [--topInstruments <n>] [--json]",
|
|
12929
|
+
description: "Multi-currency smart money overview with aggregated signals"
|
|
12930
|
+
},
|
|
12931
|
+
signal: {
|
|
12932
|
+
toolName: "smartmoney_get_signal",
|
|
12933
|
+
usage: "okx smartmoney signal [--instId <id>] [--instCcy <ccy>] [--dataVersion <ver>] [--ts <ms>] [--sortType <pnl|pnlRatio>] [--period <3|7|30|90>] [--pnl <tier>] [--winRatio <tier>] [--maxRetreat <tier>] [--asset <tier>] [--lmtNum <n>] [--authorIds <ids>] [--json]",
|
|
12934
|
+
description: "Single-currency aggregated consensus signal"
|
|
12935
|
+
},
|
|
12936
|
+
"signal-history": {
|
|
12937
|
+
toolName: "smartmoney_get_signal_history",
|
|
12938
|
+
usage: "okx smartmoney signal-history --instId <id> [--dataVersion <ver>] [--ts <ms>] [--granularity <1h|1d>] [--limit <n>] [--sortType <pnl|pnlRatio>] [--period <3|7|30|90>] [--pnl <tier>] [--winRatio <tier>] [--maxRetreat <tier>] [--asset <tier>] [--json]",
|
|
12939
|
+
description: "Signal history timeline for trend analysis"
|
|
12940
|
+
},
|
|
12941
|
+
traders: {
|
|
12942
|
+
toolName: "smartmoney_get_traders",
|
|
12943
|
+
usage: 'okx smartmoney traders [--dataVersion <ts>] [--sortType <pnl|pnl_ratio>] [--period <""|3|7|30|90>] [--pnl <n>] [--winRatio <r>] [--maxRetreat <r>] [--asset <n>] [--authorIds <ids>] [--limit <n>] [--after <id>] [--before <id>] [--json]',
|
|
12944
|
+
description: "List/filter traders from the smart money leaderboard"
|
|
12945
|
+
},
|
|
12946
|
+
trader: {
|
|
12947
|
+
toolName: "smartmoney_get_trader_detail",
|
|
12948
|
+
usage: "okx smartmoney trader --authorId <id> [--period <3|7|30|90>] [--instCcy <ccy>] [--tradeLimit <n>] [--json]",
|
|
12949
|
+
description: "Trader full portrait (profile + positions + trades)"
|
|
12950
|
+
}
|
|
12951
|
+
}
|
|
12952
|
+
},
|
|
12285
12953
|
// ── config ─────────────────────────────────────────────────────────────────
|
|
12286
12954
|
config: {
|
|
12287
12955
|
description: "Manage CLI configuration profiles",
|
|
@@ -12581,7 +13249,7 @@ function formatTime(ts) {
|
|
|
12581
13249
|
async function cmdNewsLatest(run, opts) {
|
|
12582
13250
|
const result = await run("news_get_latest", {
|
|
12583
13251
|
coins: opts.coins,
|
|
12584
|
-
importance: opts.importance,
|
|
13252
|
+
importance: opts.importance ?? "low",
|
|
12585
13253
|
platform: opts.platform,
|
|
12586
13254
|
begin: opts.begin,
|
|
12587
13255
|
end: opts.end,
|
|
@@ -12633,7 +13301,7 @@ async function cmdNewsImportant(run, opts) {
|
|
|
12633
13301
|
async function cmdNewsByCoin(run, coins, opts) {
|
|
12634
13302
|
const result = await run("news_get_by_coin", {
|
|
12635
13303
|
coins,
|
|
12636
|
-
importance: opts.importance,
|
|
13304
|
+
importance: opts.importance ?? "low",
|
|
12637
13305
|
platform: opts.platform,
|
|
12638
13306
|
begin: opts.begin,
|
|
12639
13307
|
end: opts.end,
|
|
@@ -12659,7 +13327,7 @@ async function cmdNewsSearch(run, keyword, opts) {
|
|
|
12659
13327
|
const result = await run("news_search", {
|
|
12660
13328
|
keyword: keyword || void 0,
|
|
12661
13329
|
coins: opts.coins,
|
|
12662
|
-
importance: opts.importance,
|
|
13330
|
+
importance: opts.importance ?? "low",
|
|
12663
13331
|
platform: opts.platform,
|
|
12664
13332
|
sentiment: opts.sentiment,
|
|
12665
13333
|
sortBy: opts.sortBy,
|
|
@@ -13008,6 +13676,7 @@ var CLI_OPTIONS = {
|
|
|
13008
13676
|
slRatio: { type: "string" },
|
|
13009
13677
|
algoClOrdId: { type: "string" },
|
|
13010
13678
|
stopType: { type: "string" },
|
|
13679
|
+
topUpAmt: { type: "string" },
|
|
13011
13680
|
live: { type: "boolean", default: false },
|
|
13012
13681
|
// market extras
|
|
13013
13682
|
instType: { type: "string" },
|
|
@@ -13064,6 +13733,22 @@ var CLI_OPTIONS = {
|
|
|
13064
13733
|
// audit
|
|
13065
13734
|
since: { type: "string" },
|
|
13066
13735
|
tool: { type: "string" },
|
|
13736
|
+
// smartmoney
|
|
13737
|
+
authorId: { type: "string" },
|
|
13738
|
+
authorIds: { type: "string" },
|
|
13739
|
+
dataVersion: { type: "string" },
|
|
13740
|
+
sortType: { type: "string" },
|
|
13741
|
+
granularity: { type: "string" },
|
|
13742
|
+
lmtNum: { type: "string" },
|
|
13743
|
+
instCcy: { type: "string" },
|
|
13744
|
+
instCcyList: { type: "string" },
|
|
13745
|
+
topInstruments: { type: "string" },
|
|
13746
|
+
tradeLimit: { type: "string" },
|
|
13747
|
+
// smartmoney pool filters
|
|
13748
|
+
pnl: { type: "string" },
|
|
13749
|
+
winRatio: { type: "string" },
|
|
13750
|
+
maxRetreat: { type: "string" },
|
|
13751
|
+
asset: { type: "string" },
|
|
13067
13752
|
// upgrade
|
|
13068
13753
|
beta: { type: "boolean", default: false },
|
|
13069
13754
|
check: { type: "boolean", default: false },
|
|
@@ -14065,6 +14750,19 @@ async function cmdSpotBatch(run, opts) {
|
|
|
14065
14750
|
if (opts.json) return printJson(data);
|
|
14066
14751
|
emitBatchResults(data ?? []);
|
|
14067
14752
|
}
|
|
14753
|
+
async function cmdSpotSetLeverage(run, opts) {
|
|
14754
|
+
const result = await run("spot_set_leverage", {
|
|
14755
|
+
instId: opts.instId,
|
|
14756
|
+
ccy: opts.ccy,
|
|
14757
|
+
lever: opts.lever,
|
|
14758
|
+
mgnMode: opts.mgnMode
|
|
14759
|
+
});
|
|
14760
|
+
const data = getData4(result);
|
|
14761
|
+
if (opts.json) return printJson(data);
|
|
14762
|
+
const r = data?.[0];
|
|
14763
|
+
const target = r?.["instId"] ?? r?.["ccy"] ?? "";
|
|
14764
|
+
outputLine(`Leverage set: ${r?.["lever"]}x ${target} (${r?.["mgnMode"]})`);
|
|
14765
|
+
}
|
|
14068
14766
|
|
|
14069
14767
|
// src/commands/swap.ts
|
|
14070
14768
|
function getData5(result) {
|
|
@@ -15432,6 +16130,178 @@ function extractFixedOffers(result) {
|
|
|
15432
16130
|
return [];
|
|
15433
16131
|
}
|
|
15434
16132
|
|
|
16133
|
+
// src/commands/smartmoney.ts
|
|
16134
|
+
function printDataList2(data, json, emptyMsg, mapper) {
|
|
16135
|
+
if (json) {
|
|
16136
|
+
printJson(data);
|
|
16137
|
+
return;
|
|
16138
|
+
}
|
|
16139
|
+
if (!data.length) {
|
|
16140
|
+
outputLine(emptyMsg);
|
|
16141
|
+
return;
|
|
16142
|
+
}
|
|
16143
|
+
printTable(data.map(mapper));
|
|
16144
|
+
}
|
|
16145
|
+
function poolFilterArgs(o) {
|
|
16146
|
+
const result = {};
|
|
16147
|
+
if (o.sortType) result.sortType = o.sortType;
|
|
16148
|
+
if (o.period) result.period = o.period;
|
|
16149
|
+
if (o.pnl) result.pnl = o.pnl;
|
|
16150
|
+
if (o.winRatio) result.winRatio = o.winRatio;
|
|
16151
|
+
if (o.maxRetreat) result.maxRetreat = o.maxRetreat;
|
|
16152
|
+
if (o.asset) result.asset = o.asset;
|
|
16153
|
+
return result;
|
|
16154
|
+
}
|
|
16155
|
+
async function cmdSmartmoneyOverview(run, opts) {
|
|
16156
|
+
const result = await run("smartmoney_get_overview", {
|
|
16157
|
+
dataVersion: opts.dataVersion,
|
|
16158
|
+
ts: opts.ts,
|
|
16159
|
+
instType: opts.instType,
|
|
16160
|
+
...poolFilterArgs(opts),
|
|
16161
|
+
lmtNum: opts.lmtNum,
|
|
16162
|
+
instCcyList: opts.instCcyList,
|
|
16163
|
+
instCcy: opts.instCcy,
|
|
16164
|
+
topInstruments: opts.topInstruments
|
|
16165
|
+
});
|
|
16166
|
+
const data = extractData(result);
|
|
16167
|
+
printDataList2(data, opts.json, "No overview data", (r) => ({
|
|
16168
|
+
instId: r["instId"],
|
|
16169
|
+
tradersWithPosition: r["tradersWithPosition"],
|
|
16170
|
+
longRatio: r["longRatio"],
|
|
16171
|
+
weightedLongRatio: r["weightedLongRatio"],
|
|
16172
|
+
netNotionalUsdt: r["netNotionalUsdt"],
|
|
16173
|
+
vs24h: r["vs24h"]
|
|
16174
|
+
}));
|
|
16175
|
+
}
|
|
16176
|
+
async function cmdSmartmoneySignal(run, opts) {
|
|
16177
|
+
const result = await run("smartmoney_get_signal", {
|
|
16178
|
+
instId: opts.instId,
|
|
16179
|
+
instCcy: opts.instCcy,
|
|
16180
|
+
dataVersion: opts.dataVersion,
|
|
16181
|
+
ts: opts.ts,
|
|
16182
|
+
...poolFilterArgs(opts),
|
|
16183
|
+
lmtNum: opts.lmtNum,
|
|
16184
|
+
authorIds: opts.authorIds
|
|
16185
|
+
});
|
|
16186
|
+
const data = extractData(result);
|
|
16187
|
+
const signal = data[0];
|
|
16188
|
+
if (opts.json) {
|
|
16189
|
+
printJson(signal ?? {});
|
|
16190
|
+
return;
|
|
16191
|
+
}
|
|
16192
|
+
if (!signal) {
|
|
16193
|
+
outputLine("No signal data");
|
|
16194
|
+
return;
|
|
16195
|
+
}
|
|
16196
|
+
printKv({
|
|
16197
|
+
instId: signal["instId"],
|
|
16198
|
+
instType: signal["instType"],
|
|
16199
|
+
tradersWithPosition: signal["tradersWithPosition"],
|
|
16200
|
+
tradersTotal: signal["tradersTotal"],
|
|
16201
|
+
longRatio: signal["longRatio"],
|
|
16202
|
+
weightedLongRatio: signal["weightedLongRatio"],
|
|
16203
|
+
avgLongWinRatio: signal["avgLongWinRatio"],
|
|
16204
|
+
avgShortWinRatio: signal["avgShortWinRatio"],
|
|
16205
|
+
longNotionalUsdt: signal["longNotionalUsdt"],
|
|
16206
|
+
shortNotionalUsdt: signal["shortNotionalUsdt"],
|
|
16207
|
+
netNotionalUsdt: signal["netNotionalUsdt"],
|
|
16208
|
+
longTraders: signal["longTraders"],
|
|
16209
|
+
shortTraders: signal["shortTraders"],
|
|
16210
|
+
vs1h: signal["vs1h"],
|
|
16211
|
+
vs24h: signal["vs24h"],
|
|
16212
|
+
vs7d: signal["vs7d"],
|
|
16213
|
+
smartMoneyLongAvgEntry: signal["smartMoneyLongAvgEntry"],
|
|
16214
|
+
smartMoneyShortAvgEntry: signal["smartMoneyShortAvgEntry"],
|
|
16215
|
+
totalNotionalVs24h: signal["totalNotionalVs24h"],
|
|
16216
|
+
currentPrice: signal["currentPrice"],
|
|
16217
|
+
priceChange24h: signal["priceChange24h"],
|
|
16218
|
+
fundingRate: signal["fundingRate"],
|
|
16219
|
+
openInterest: signal["openInterest"],
|
|
16220
|
+
longShortAccountRatio: signal["longShortAccountRatio"]
|
|
16221
|
+
});
|
|
16222
|
+
}
|
|
16223
|
+
async function cmdSmartmoneySignalHistory(run, opts) {
|
|
16224
|
+
const result = await run("smartmoney_get_signal_history", {
|
|
16225
|
+
instId: opts.instId,
|
|
16226
|
+
dataVersion: opts.dataVersion,
|
|
16227
|
+
ts: opts.ts,
|
|
16228
|
+
granularity: opts.granularity,
|
|
16229
|
+
limit: opts.limit,
|
|
16230
|
+
...poolFilterArgs(opts)
|
|
16231
|
+
});
|
|
16232
|
+
const data = extractData(result);
|
|
16233
|
+
printDataList2(data, opts.json, "No signal history data", (r) => ({
|
|
16234
|
+
ts: r["ts"],
|
|
16235
|
+
longRatio: r["longRatio"],
|
|
16236
|
+
weightedLongRatio: r["weightedLongRatio"],
|
|
16237
|
+
tradersWithPosition: r["tradersWithPosition"],
|
|
16238
|
+
netNotionalUsdt: r["netNotionalUsdt"],
|
|
16239
|
+
totalNotionalUsdt: r["totalNotionalUsdt"],
|
|
16240
|
+
tradersQualified: r["tradersQualified"]
|
|
16241
|
+
}));
|
|
16242
|
+
}
|
|
16243
|
+
async function cmdSmartmoneyTraders(run, opts) {
|
|
16244
|
+
const data = extractData(await run("smartmoney_get_traders", {
|
|
16245
|
+
dataVersion: opts.dataVersion,
|
|
16246
|
+
...poolFilterArgs(opts),
|
|
16247
|
+
authorIds: opts.authorIds,
|
|
16248
|
+
after: opts.after,
|
|
16249
|
+
before: opts.before,
|
|
16250
|
+
limit: opts.limit
|
|
16251
|
+
}));
|
|
16252
|
+
printDataList2(data, opts.json, "No traders found", (r) => ({
|
|
16253
|
+
authorId: r["authorId"],
|
|
16254
|
+
nickName: r["nickName"],
|
|
16255
|
+
pnl: r["pnl"],
|
|
16256
|
+
pnlRatio: r["pnlRatio"],
|
|
16257
|
+
winRatio: r["winRatio"],
|
|
16258
|
+
asset: r["asset"]
|
|
16259
|
+
}));
|
|
16260
|
+
}
|
|
16261
|
+
async function cmdSmartmoneyTraderDetail(run, opts) {
|
|
16262
|
+
const result = await run("smartmoney_get_trader_detail", {
|
|
16263
|
+
authorId: opts.authorId,
|
|
16264
|
+
period: opts.period,
|
|
16265
|
+
instCcy: opts.instCcy,
|
|
16266
|
+
tradeLimit: opts.tradeLimit
|
|
16267
|
+
});
|
|
16268
|
+
const data = result;
|
|
16269
|
+
const inner = data["data"];
|
|
16270
|
+
if (opts.json) {
|
|
16271
|
+
printJson(inner ?? {});
|
|
16272
|
+
return;
|
|
16273
|
+
}
|
|
16274
|
+
if (!inner) {
|
|
16275
|
+
outputLine("No data");
|
|
16276
|
+
return;
|
|
16277
|
+
}
|
|
16278
|
+
const profileArr = inner["profile"];
|
|
16279
|
+
if (Array.isArray(profileArr) && profileArr.length > 0) {
|
|
16280
|
+
const p = profileArr[0];
|
|
16281
|
+
outputLine("=== Profile ===");
|
|
16282
|
+
printKv({
|
|
16283
|
+
authorId: p["authorId"],
|
|
16284
|
+
nickName: p["nickName"],
|
|
16285
|
+
pnl: p["pnl"],
|
|
16286
|
+
pnlRatio: p["pnlRatio"],
|
|
16287
|
+
winRatio: p["winRatio"],
|
|
16288
|
+
maxRetreat: p["maxRetreat"],
|
|
16289
|
+
asset: p["asset"],
|
|
16290
|
+
onboardDuration: p["onboardDuration"]
|
|
16291
|
+
});
|
|
16292
|
+
}
|
|
16293
|
+
const posArr = inner["positions"];
|
|
16294
|
+
if (Array.isArray(posArr) && posArr.length > 0) {
|
|
16295
|
+
outputLine("\n=== Current Positions ===");
|
|
16296
|
+
printJson(posArr);
|
|
16297
|
+
}
|
|
16298
|
+
const tradeArr = inner["trades"];
|
|
16299
|
+
if (Array.isArray(tradeArr) && tradeArr.length > 0) {
|
|
16300
|
+
outputLine("\n=== Recent Trades ===");
|
|
16301
|
+
printJson(tradeArr);
|
|
16302
|
+
}
|
|
16303
|
+
}
|
|
16304
|
+
|
|
15435
16305
|
// src/commands/auto-earn.ts
|
|
15436
16306
|
var USDG_EARN_CURRENCIES = /* @__PURE__ */ new Set(["USDG", "BUIDL"]);
|
|
15437
16307
|
function isSupported(status) {
|
|
@@ -15685,6 +16555,28 @@ async function cmdGridCreate(run, opts) {
|
|
|
15685
16555
|
if (opts.json) return printJson(data);
|
|
15686
16556
|
emitWriteResult5(data?.[0], "Grid bot created", "algoId");
|
|
15687
16557
|
}
|
|
16558
|
+
async function cmdGridAmend(run, opts) {
|
|
16559
|
+
const result = await run("grid_amend_order", {
|
|
16560
|
+
algoId: opts.algoId,
|
|
16561
|
+
instId: opts.instId,
|
|
16562
|
+
maxPx: opts.maxPx,
|
|
16563
|
+
minPx: opts.minPx,
|
|
16564
|
+
gridNum: opts.gridNum,
|
|
16565
|
+
tpTriggerPx: opts.tpTriggerPx,
|
|
16566
|
+
slTriggerPx: opts.slTriggerPx,
|
|
16567
|
+
tpRatio: opts.tpRatio,
|
|
16568
|
+
slRatio: opts.slRatio,
|
|
16569
|
+
topUpAmt: opts.topUpAmt
|
|
16570
|
+
});
|
|
16571
|
+
const data = getData8(result);
|
|
16572
|
+
if (opts.json) return printJson(data);
|
|
16573
|
+
const item = data?.[0];
|
|
16574
|
+
if (item?.["algoId"]) {
|
|
16575
|
+
outputLine(`Grid bot amended: ${item["algoId"]} (OK)`);
|
|
16576
|
+
} else {
|
|
16577
|
+
emitWriteResult5(item, "Grid bot amended", "algoId");
|
|
16578
|
+
}
|
|
16579
|
+
}
|
|
15688
16580
|
async function cmdGridStop(run, opts) {
|
|
15689
16581
|
const result = await run("grid_stop_order", {
|
|
15690
16582
|
algoId: opts.algoId,
|
|
@@ -16912,7 +17804,7 @@ async function cmdEventCancel(run, opts) {
|
|
|
16912
17804
|
// src/index.ts
|
|
16913
17805
|
var _require3 = createRequire3(import.meta.url);
|
|
16914
17806
|
var CLI_VERSION2 = _require3("../package.json").version;
|
|
16915
|
-
var GIT_HASH2 = true ? "
|
|
17807
|
+
var GIT_HASH2 = true ? "d5c8ab1" : "dev";
|
|
16916
17808
|
function handleDohCommand(action, json, force, binaryPath) {
|
|
16917
17809
|
if (action === "status") return cmdDohStatus(json, binaryPath);
|
|
16918
17810
|
if (action === "install") return cmdDohInstall(json, binaryPath);
|
|
@@ -17017,6 +17909,9 @@ function handleMarketFilterCommand(run, action, rest, v, json) {
|
|
|
17017
17909
|
limit,
|
|
17018
17910
|
json
|
|
17019
17911
|
});
|
|
17912
|
+
errorLine(`Unknown market command: ${action}`);
|
|
17913
|
+
errorLine("Valid: ticker, tickers, orderbook, candles, trades, instruments, mark-price, funding-rate, open-interest, index-ticker, price-limit, stock-tokens, instruments-by-category, indicator, filter, oi-history, oi-change");
|
|
17914
|
+
process.exitCode = 1;
|
|
17020
17915
|
}
|
|
17021
17916
|
function handleIndicatorAction(run, rest, v, json) {
|
|
17022
17917
|
if (rest[0] === "list") return cmdMarketIndicatorList(json);
|
|
@@ -17187,6 +18082,14 @@ function handleSpotCommand(run, action, rest, v, json) {
|
|
|
17187
18082
|
return handleSpotAlgoCommand(run, rest[0], v, json);
|
|
17188
18083
|
if (action === "batch")
|
|
17189
18084
|
return cmdSpotBatch(run, { action: v.action, orders: v.orders, json });
|
|
18085
|
+
if (action === "leverage")
|
|
18086
|
+
return cmdSpotSetLeverage(run, {
|
|
18087
|
+
instId: v.instId,
|
|
18088
|
+
ccy: v.ccy,
|
|
18089
|
+
lever: v.lever,
|
|
18090
|
+
mgnMode: v.mgnMode,
|
|
18091
|
+
json
|
|
18092
|
+
});
|
|
17190
18093
|
}
|
|
17191
18094
|
function handleSwapAlgoCommand(run, subAction, v, json) {
|
|
17192
18095
|
if (subAction === "trail")
|
|
@@ -17580,6 +18483,20 @@ function handleBotGridCommand(run, v, rest, json) {
|
|
|
17580
18483
|
algoClOrdId: v.algoClOrdId,
|
|
17581
18484
|
json
|
|
17582
18485
|
});
|
|
18486
|
+
if (subAction === "amend")
|
|
18487
|
+
return cmdGridAmend(run, {
|
|
18488
|
+
algoId: v.algoId,
|
|
18489
|
+
instId: v.instId,
|
|
18490
|
+
maxPx: v.maxPx,
|
|
18491
|
+
minPx: v.minPx,
|
|
18492
|
+
gridNum: v.gridNum,
|
|
18493
|
+
tpTriggerPx: v.tpTriggerPx,
|
|
18494
|
+
slTriggerPx: v.slTriggerPx,
|
|
18495
|
+
tpRatio: v.tpRatio,
|
|
18496
|
+
slRatio: v.slRatio,
|
|
18497
|
+
topUpAmt: v.topUpAmt,
|
|
18498
|
+
json
|
|
18499
|
+
});
|
|
17583
18500
|
if (subAction === "stop")
|
|
17584
18501
|
return cmdGridStop(run, {
|
|
17585
18502
|
algoId: v.algoId,
|
|
@@ -17672,6 +18589,82 @@ function handleEarnFlashEarnCommand(run, action, v, json) {
|
|
|
17672
18589
|
errorLine("Valid: projects");
|
|
17673
18590
|
process.exitCode = 1;
|
|
17674
18591
|
}
|
|
18592
|
+
function handleSmartmoneyCommand(run, action, rest, v, json) {
|
|
18593
|
+
const poolFilters = {
|
|
18594
|
+
sortType: v.sortType,
|
|
18595
|
+
period: v.period,
|
|
18596
|
+
pnl: v.pnl,
|
|
18597
|
+
winRatio: v.winRatio,
|
|
18598
|
+
maxRetreat: v.maxRetreat,
|
|
18599
|
+
asset: v.asset
|
|
18600
|
+
};
|
|
18601
|
+
if (action === "overview")
|
|
18602
|
+
return cmdSmartmoneyOverview(run, {
|
|
18603
|
+
dataVersion: v.dataVersion,
|
|
18604
|
+
ts: v.ts,
|
|
18605
|
+
instType: v.instType,
|
|
18606
|
+
...poolFilters,
|
|
18607
|
+
lmtNum: v.lmtNum,
|
|
18608
|
+
instCcyList: v.instCcyList,
|
|
18609
|
+
instCcy: v.instCcy,
|
|
18610
|
+
topInstruments: v.topInstruments,
|
|
18611
|
+
json
|
|
18612
|
+
});
|
|
18613
|
+
if (action === "signal")
|
|
18614
|
+
return cmdSmartmoneySignal(run, {
|
|
18615
|
+
instId: v.instId,
|
|
18616
|
+
dataVersion: v.dataVersion,
|
|
18617
|
+
ts: v.ts,
|
|
18618
|
+
...poolFilters,
|
|
18619
|
+
instCcy: v.instCcy,
|
|
18620
|
+
lmtNum: v.lmtNum,
|
|
18621
|
+
authorIds: v.authorIds,
|
|
18622
|
+
json
|
|
18623
|
+
});
|
|
18624
|
+
if (action === "signal-history") {
|
|
18625
|
+
if (!v.instId) {
|
|
18626
|
+
errorLine("Missing required --instId: okx smartmoney signal-history --instId <id>");
|
|
18627
|
+
process.exitCode = 1;
|
|
18628
|
+
return;
|
|
18629
|
+
}
|
|
18630
|
+
return cmdSmartmoneySignalHistory(run, {
|
|
18631
|
+
instId: v.instId,
|
|
18632
|
+
dataVersion: v.dataVersion,
|
|
18633
|
+
ts: v.ts,
|
|
18634
|
+
granularity: v.granularity,
|
|
18635
|
+
limit: v.limit,
|
|
18636
|
+
...poolFilters,
|
|
18637
|
+
json
|
|
18638
|
+
});
|
|
18639
|
+
}
|
|
18640
|
+
if (action === "traders")
|
|
18641
|
+
return cmdSmartmoneyTraders(run, {
|
|
18642
|
+
dataVersion: v.dataVersion,
|
|
18643
|
+
...poolFilters,
|
|
18644
|
+
authorIds: v.authorIds,
|
|
18645
|
+
after: v.after,
|
|
18646
|
+
before: v.before,
|
|
18647
|
+
limit: v.limit,
|
|
18648
|
+
json
|
|
18649
|
+
});
|
|
18650
|
+
if (action === "trader") {
|
|
18651
|
+
if (!v.authorId) {
|
|
18652
|
+
errorLine("Missing required --authorId: okx smartmoney trader --authorId <id>");
|
|
18653
|
+
process.exitCode = 1;
|
|
18654
|
+
return;
|
|
18655
|
+
}
|
|
18656
|
+
return cmdSmartmoneyTraderDetail(run, {
|
|
18657
|
+
authorId: v.authorId,
|
|
18658
|
+
period: v.period,
|
|
18659
|
+
instCcy: v.instCcy,
|
|
18660
|
+
tradeLimit: v.tradeLimit,
|
|
18661
|
+
json
|
|
18662
|
+
});
|
|
18663
|
+
}
|
|
18664
|
+
errorLine(`Unknown smartmoney command: ${action}`);
|
|
18665
|
+
errorLine("Valid: overview, signal, signal-history, traders, trader");
|
|
18666
|
+
process.exitCode = 1;
|
|
18667
|
+
}
|
|
17675
18668
|
function handleEarnSavingsCommand(run, action, rest, v, json) {
|
|
17676
18669
|
const limit = v.limit !== void 0 ? Number(v.limit) : void 0;
|
|
17677
18670
|
if (action === "balance") return cmdEarnSavingsBalance(run, rest[0] ?? v.ccy, json);
|
|
@@ -17961,6 +18954,7 @@ async function main() {
|
|
|
17961
18954
|
news: () => handleNewsCommand(run, action, rest, v, json),
|
|
17962
18955
|
bot: () => handleBotCommand(run, action, rest, v, json),
|
|
17963
18956
|
earn: () => handleEarnCommand(run, action, rest, v, json),
|
|
18957
|
+
smartmoney: () => handleSmartmoneyCommand(run, action, rest, v, json),
|
|
17964
18958
|
skill: () => handleSkillCommand(run, action, rest, v, json, config)
|
|
17965
18959
|
};
|
|
17966
18960
|
const handler = moduleHandlers[module];
|
|
@@ -17995,6 +18989,7 @@ export {
|
|
|
17995
18989
|
handleOptionCommand,
|
|
17996
18990
|
handleSetupCommand,
|
|
17997
18991
|
handleSkillCommand,
|
|
18992
|
+
handleSmartmoneyCommand,
|
|
17998
18993
|
handleSpotAlgoCommand,
|
|
17999
18994
|
handleSpotCommand,
|
|
18000
18995
|
handleSwapAlgoCommand,
|