@okx_ai/okx-trade-cli 1.3.4-beta.2 → 1.3.5-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 +301 -236
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1157,8 +1157,8 @@ var PilotManager = class {
|
|
|
1157
1157
|
* Apply a Pilot node: set up the custom Agent + base URL.
|
|
1158
1158
|
*
|
|
1159
1159
|
* node.ip may be a real IP or a domain (CNAME like *.aliyunddos1021.com).
|
|
1160
|
-
* - Real IP
|
|
1161
|
-
* - Domain
|
|
1160
|
+
* - Real IP -> use directly in lookup callback
|
|
1161
|
+
* - Domain -> dns.lookup on every connection to get a fresh IP
|
|
1162
1162
|
*/
|
|
1163
1163
|
applyNode(node, protocol) {
|
|
1164
1164
|
this.pilotNode = node;
|
|
@@ -1508,29 +1508,29 @@ var RateLimiter = class {
|
|
|
1508
1508
|
}
|
|
1509
1509
|
};
|
|
1510
1510
|
var OKX_CODE_BEHAVIORS = {
|
|
1511
|
-
// Rate limit
|
|
1511
|
+
// Rate limit -> throw RateLimitError
|
|
1512
1512
|
"50011": { retry: true, suggestion: "Rate limited. Back off and retry after a delay." },
|
|
1513
1513
|
"50061": { retry: true, suggestion: "Too many connections. Reduce request frequency and retry." },
|
|
1514
|
-
// Server temporarily unavailable
|
|
1514
|
+
// Server temporarily unavailable -> retryable
|
|
1515
1515
|
"50001": { retry: true, suggestion: "Service temporarily unavailable. Retry in a few minutes." },
|
|
1516
1516
|
"50004": { retry: true, suggestion: "Endpoint request timeout. Retry later." },
|
|
1517
1517
|
"50013": { retry: true, suggestion: "System busy. Retry after 1-2 seconds." },
|
|
1518
1518
|
"50026": { retry: true, suggestion: "System error. Retry in a few minutes." },
|
|
1519
|
-
// Region / compliance restriction
|
|
1519
|
+
// Region / compliance restriction -> do not retry
|
|
1520
1520
|
"51155": { retry: false, suggestion: "Feature unavailable in your region (site: {site}). Verify your site setting matches your account registration region. Available sites: global, eea, us. Do not retry." },
|
|
1521
1521
|
"51734": { retry: false, suggestion: "Feature not supported for your KYC country (site: {site}). Verify your site setting matches your account registration region. Available sites: global, eea, us. Do not retry." },
|
|
1522
|
-
// Account issues
|
|
1522
|
+
// Account issues -> do not retry
|
|
1523
1523
|
"50007": { retry: false, suggestion: "Account suspended. Contact OKX support. Do not retry." },
|
|
1524
1524
|
"50009": { retry: false, suggestion: "Account blocked by risk control. Contact OKX support. Do not retry." },
|
|
1525
1525
|
"51009": { retry: false, suggestion: "Account mode not supported for this operation. Check account settings." },
|
|
1526
|
-
// API key permission / expiry
|
|
1526
|
+
// API key permission / expiry -> do not retry
|
|
1527
1527
|
"50100": { retry: false, suggestion: "API key lacks required permissions. Update API key permissions." },
|
|
1528
1528
|
"50110": { retry: false, suggestion: "API key expired. Generate a new API key." },
|
|
1529
|
-
// Insufficient funds / margin
|
|
1530
|
-
"51008": { retry: false, suggestion: "Insufficient balance in trading account. Check funding account via account_get_asset_balance
|
|
1529
|
+
// Insufficient funds / margin -> do not retry
|
|
1530
|
+
"51008": { retry: false, suggestion: "Insufficient balance in trading account. Check funding account via account_get_asset_balance - funds may be there. Use account_transfer (from=18, to=6) to move funds to trading account, then retry." },
|
|
1531
1531
|
"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." },
|
|
1532
1532
|
"51127": { retry: false, suggestion: "Insufficient available margin. Reduce position, add margin, or transfer from funding account (account_transfer from=18 to=6)." },
|
|
1533
|
-
// Instrument unavailable
|
|
1533
|
+
// Instrument unavailable -> do not retry
|
|
1534
1534
|
"51021": { retry: false, suggestion: "Instrument does not exist. Check instId." },
|
|
1535
1535
|
"51022": { retry: false, suggestion: "Instrument not available for trading." },
|
|
1536
1536
|
"51027": { retry: false, suggestion: "Contract has expired." }
|
|
@@ -1614,11 +1614,11 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1614
1614
|
}
|
|
1615
1615
|
}
|
|
1616
1616
|
/**
|
|
1617
|
-
* Dynamic auth
|
|
1617
|
+
* Dynamic auth - determines auth method per request.
|
|
1618
1618
|
*
|
|
1619
|
-
* 1. API key in config
|
|
1620
|
-
* 2. OAuth token via okx-auth binary
|
|
1621
|
-
* 3. Neither
|
|
1619
|
+
* 1. API key in config -> HMAC signing (no OAuth fallback)
|
|
1620
|
+
* 2. OAuth token via okx-auth binary -> Bearer token
|
|
1621
|
+
* 3. Neither -> throw ConfigError
|
|
1622
1622
|
*/
|
|
1623
1623
|
async applyAuth(headers, method, requestPath, bodyJson, timestamp) {
|
|
1624
1624
|
if (this.config.apiKey && this.config.secretKey && this.config.passphrase) {
|
|
@@ -1772,7 +1772,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1772
1772
|
};
|
|
1773
1773
|
}
|
|
1774
1774
|
// ---------------------------------------------------------------------------
|
|
1775
|
-
// Binary (non-JSON) download
|
|
1775
|
+
// Binary (non-JSON) download - reuses auth, proxy, rate-limit, verbose
|
|
1776
1776
|
// ---------------------------------------------------------------------------
|
|
1777
1777
|
static DEFAULT_MAX_BYTES = 50 * 1024 * 1024;
|
|
1778
1778
|
// 50 MB
|
|
@@ -2384,7 +2384,7 @@ var INDICATOR_CODE_OVERRIDES = {
|
|
|
2384
2384
|
// default: NVI_PVI
|
|
2385
2385
|
"top-long-short": "TOPLONGSHORT"
|
|
2386
2386
|
// default: TOP_LONG_SHORT
|
|
2387
|
-
// Note: range-filter
|
|
2387
|
+
// Note: range-filter -> RANGE_FILTER is correct via the default rule; no override needed.
|
|
2388
2388
|
};
|
|
2389
2389
|
var KNOWN_INDICATORS = [
|
|
2390
2390
|
// Moving Averages
|
|
@@ -2633,7 +2633,7 @@ var MODULES = [
|
|
|
2633
2633
|
"skills"
|
|
2634
2634
|
];
|
|
2635
2635
|
var DEFAULT_MODULES = ["spot", "swap", "option", "account", ...BOT_DEFAULT_SUB_MODULES, "skills"];
|
|
2636
|
-
var SKILLS_MARKETPLACE_DESC = "OKX Skills Marketplace
|
|
2636
|
+
var SKILLS_MARKETPLACE_DESC = "OKX Skills Marketplace - search, install, and manage agent skills";
|
|
2637
2637
|
var MODULE_DESCRIPTIONS = {
|
|
2638
2638
|
market: "Market data (ticker, orderbook, candles, trades)",
|
|
2639
2639
|
spot: "Spot trading (orders, algo orders)",
|
|
@@ -2641,18 +2641,18 @@ var MODULE_DESCRIPTIONS = {
|
|
|
2641
2641
|
futures: "Futures trading (orders, positions, algo orders, leverage)",
|
|
2642
2642
|
option: "Options trading (orders, positions, greeks)",
|
|
2643
2643
|
account: "Account balance, positions, bills, and configuration",
|
|
2644
|
-
"earn.savings": "Simple Earn
|
|
2645
|
-
"earn.onchain": "On-chain Earn
|
|
2646
|
-
"earn.dcd": "DCD (Dual Currency Deposit)
|
|
2647
|
-
"earn.autoearn": "Auto-earn
|
|
2648
|
-
"earn.flash": "Flash Earn
|
|
2649
|
-
event: "Event contracts
|
|
2650
|
-
"bot.grid": "Grid trading bot
|
|
2651
|
-
"bot.dca": "DCA (Martingale) bot
|
|
2644
|
+
"earn.savings": "Simple Earn - flexible savings, fixed-term, and lending",
|
|
2645
|
+
"earn.onchain": "On-chain Earn - staking and DeFi products",
|
|
2646
|
+
"earn.dcd": "DCD (Dual Currency Deposit) - structured products with fixed yield",
|
|
2647
|
+
"earn.autoearn": "Auto-earn - automatically lend, stake, or earn on idle assets",
|
|
2648
|
+
"earn.flash": "Flash Earn - short-window high-yield earn projects",
|
|
2649
|
+
event: "Event contracts - binary prediction markets (YES/NO, UP/DOWN)",
|
|
2650
|
+
"bot.grid": "Grid trading bot - create, monitor, and stop grid orders",
|
|
2651
|
+
"bot.dca": "DCA (Martingale) bot - spot or contract recurring buys",
|
|
2652
2652
|
news: "Crypto news, sentiment analysis, and coin trend tracking",
|
|
2653
|
-
smartmoney: "Smart money signals
|
|
2653
|
+
smartmoney: "Smart money signals - trader leaderboard, consensus signals, and position analysis",
|
|
2654
2654
|
skills: SKILLS_MARKETPLACE_DESC,
|
|
2655
|
-
earn: "Earn products
|
|
2655
|
+
earn: "Earn products - Simple Earn, On-chain Earn, DCD, Flash Earn, and Auto-Earn",
|
|
2656
2656
|
bot: "Trading bot strategies (grid, dca)",
|
|
2657
2657
|
config: "Manage CLI configuration profiles",
|
|
2658
2658
|
setup: "Set up client integrations (Cursor, Windsurf, Claude, etc.)",
|
|
@@ -2713,7 +2713,7 @@ function registerAccountTools() {
|
|
|
2713
2713
|
},
|
|
2714
2714
|
type: {
|
|
2715
2715
|
type: "string",
|
|
2716
|
-
description: "0=main account (default), 1=main
|
|
2716
|
+
description: "0=main account (default), 1=main->sub, 2=sub->main, 3=sub->sub"
|
|
2717
2717
|
},
|
|
2718
2718
|
subAcct: {
|
|
2719
2719
|
type: "string",
|
|
@@ -3297,7 +3297,7 @@ function computeContracts(p) {
|
|
|
3297
3297
|
);
|
|
3298
3298
|
}
|
|
3299
3299
|
const contractsStr = contractsRounded.toFixed(lotSzDecimals);
|
|
3300
|
-
const conversionNote = isMarginMode ? `Converting ${sz} USDT margin (${leverStr}x leverage)
|
|
3300
|
+
const conversionNote = isMarginMode ? `Converting ${sz} USDT margin (${leverStr}x leverage) -> ${contractsStr} contracts (notional value \u2248 ${(contractsRounded * contractValue).toFixed(2)} USDT, ctVal=${ctValStr}, lastPx=${lastStr}, lever=${leverStr}, minSz=${minSzStr}, lotSz=${lotSzStr})` : `Converting ${sz} USDT -> ${contractsStr} contracts (ctVal=${ctValStr}, lastPx=${lastStr}, minSz=${minSzStr}, lotSz=${lotSzStr})`;
|
|
3301
3301
|
return { contractsStr, conversionNote };
|
|
3302
3302
|
}
|
|
3303
3303
|
async function resolveQuoteCcySz(instId, sz, tgtCcy, instType, client, tdMode) {
|
|
@@ -3345,7 +3345,7 @@ function registerAlgoTradeTools() {
|
|
|
3345
3345
|
{
|
|
3346
3346
|
name: "swap_place_algo_order",
|
|
3347
3347
|
module: "swap",
|
|
3348
|
-
description: "Place a SWAP/FUTURES algo order. [CAUTION] Executes real trades. conditional: single TP, single SL, or both on one order. oco: TP+SL simultaneously
|
|
3348
|
+
description: "Place a SWAP/FUTURES algo order. [CAUTION] Executes real trades. conditional: single TP, single SL, or both on one order. oco: TP+SL simultaneously - first trigger cancels the other. move_order_stop: trailing stop (callbackRatio or callbackSpread). trigger: pending order activated when triggerPx is hit (provide triggerPx + orderPx). chase: smart-follow best bid/ask. iceberg: split large order into child orders at intervals. twap: time-weighted average price order splitting.",
|
|
3349
3349
|
isWrite: true,
|
|
3350
3350
|
inputSchema: {
|
|
3351
3351
|
type: "object",
|
|
@@ -3705,7 +3705,7 @@ function registerFuturesAlgoTools() {
|
|
|
3705
3705
|
{
|
|
3706
3706
|
name: "futures_place_algo_order",
|
|
3707
3707
|
module: "futures",
|
|
3708
|
-
description: "Place a FUTURES delivery algo order. [CAUTION] Executes real trades. conditional: single TP, single SL, or both on one order. oco: TP+SL simultaneously
|
|
3708
|
+
description: "Place a FUTURES delivery algo order. [CAUTION] Executes real trades. conditional: single TP, single SL, or both on one order. oco: TP+SL simultaneously - first trigger cancels the other. move_order_stop: trailing stop (callbackRatio or callbackSpread). trigger: pending order activated when triggerPx is hit (provide triggerPx + orderPx). chase: smart-follow best bid/ask. iceberg: split large order into child orders at intervals. twap: time-weighted average price order splitting.",
|
|
3709
3709
|
isWrite: true,
|
|
3710
3710
|
inputSchema: {
|
|
3711
3711
|
type: "object",
|
|
@@ -3930,7 +3930,7 @@ function registerFuturesAlgoTools() {
|
|
|
3930
3930
|
{
|
|
3931
3931
|
name: "futures_amend_algo_order",
|
|
3932
3932
|
module: "futures",
|
|
3933
|
-
description: "Amend a pending FUTURES delivery algo order (modify TP/SL prices or size). Also covers TP/SL orders attached when placing the main order
|
|
3933
|
+
description: "Amend a pending FUTURES delivery algo order (modify TP/SL prices or size). Also covers TP/SL orders attached when placing the main order - look up algoId via futures_get_algo_orders first.",
|
|
3934
3934
|
isWrite: true,
|
|
3935
3935
|
inputSchema: {
|
|
3936
3936
|
type: "object",
|
|
@@ -4383,7 +4383,7 @@ function registerSkillsTools() {
|
|
|
4383
4383
|
{
|
|
4384
4384
|
name: "skills_get_categories",
|
|
4385
4385
|
module: "skills",
|
|
4386
|
-
description: "List all available skill categories in OKX Skills Marketplace. Use the returned categoryId as input to skills_search for category filtering. Do NOT use for searching or downloading skills
|
|
4386
|
+
description: "List all available skill categories in OKX Skills Marketplace. Use the returned categoryId as input to skills_search for category filtering. Do NOT use for searching or downloading skills - use skills_search or skills_download.",
|
|
4387
4387
|
inputSchema: {
|
|
4388
4388
|
type: "object",
|
|
4389
4389
|
properties: {},
|
|
@@ -4395,7 +4395,7 @@ function registerSkillsTools() {
|
|
|
4395
4395
|
{
|
|
4396
4396
|
name: "skills_search",
|
|
4397
4397
|
module: "skills",
|
|
4398
|
-
description: "Search for skills in OKX Skills Marketplace by keyword or category. To get valid category IDs, call skills_get_categories first. Returns skill names for use with skills_download. Do NOT use for downloading
|
|
4398
|
+
description: "Search for skills in OKX Skills Marketplace by keyword or category. To get valid category IDs, call skills_get_categories first. Returns skill names for use with skills_download. Do NOT use for downloading - use skills_download.",
|
|
4399
4399
|
inputSchema: {
|
|
4400
4400
|
type: "object",
|
|
4401
4401
|
properties: {
|
|
@@ -4424,7 +4424,7 @@ function registerSkillsTools() {
|
|
|
4424
4424
|
{
|
|
4425
4425
|
name: "skills_download",
|
|
4426
4426
|
module: "skills",
|
|
4427
|
-
description: "Download a skill package from OKX Skills Marketplace to a local directory. Always call skills_search first to confirm the skill name exists. Downloads the latest approved version. NOTE: Downloads third-party developer content
|
|
4427
|
+
description: "Download a skill package from OKX Skills Marketplace to a local directory. Always call skills_search first to confirm the skill name exists. Downloads the latest approved version. NOTE: Downloads third-party developer content - does NOT install to agents. For full installation use CLI: okx skill add <name>. Use when the user wants to inspect or manually install a skill package.",
|
|
4428
4428
|
inputSchema: {
|
|
4429
4429
|
type: "object",
|
|
4430
4430
|
properties: {
|
|
@@ -4705,7 +4705,7 @@ function registerGridTools() {
|
|
|
4705
4705
|
{
|
|
4706
4706
|
name: "grid_amend_order",
|
|
4707
4707
|
module: "bot.grid",
|
|
4708
|
-
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
|
|
4708
|
+
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 - use grid_create_order instead. Do NOT use to stop a grid bot - use grid_stop_order instead.",
|
|
4709
4709
|
isWrite: true,
|
|
4710
4710
|
inputSchema: {
|
|
4711
4711
|
type: "object",
|
|
@@ -4783,7 +4783,7 @@ function registerGridTools() {
|
|
|
4783
4783
|
maxPx,
|
|
4784
4784
|
minPx: requireString(args, "minPx"),
|
|
4785
4785
|
gridNum: requireString(args, "gridNum"),
|
|
4786
|
-
// API field is "topupAmount" (lowercase u)
|
|
4786
|
+
// API field is "topupAmount" (lowercase u) - different from TP/SL mode's "topUpAmt"
|
|
4787
4787
|
// Contract grid only; omitting lets the API use the minimum required
|
|
4788
4788
|
topupAmount: readString(args, "topUpAmt")
|
|
4789
4789
|
}),
|
|
@@ -4804,7 +4804,7 @@ function registerGridTools() {
|
|
|
4804
4804
|
tpRatio: readString(args, "tpRatio"),
|
|
4805
4805
|
slRatio: readString(args, "slRatio"),
|
|
4806
4806
|
topUpAmt: readString(args, "topUpAmt")
|
|
4807
|
-
// API field is "topUpAmt" (uppercase U)
|
|
4807
|
+
// API field is "topUpAmt" (uppercase U) - different from price-range mode's "topupAmount"
|
|
4808
4808
|
}),
|
|
4809
4809
|
privateRateLimit("grid_amend_order", 20),
|
|
4810
4810
|
true
|
|
@@ -4828,7 +4828,7 @@ function registerGridTools() {
|
|
|
4828
4828
|
{
|
|
4829
4829
|
name: "grid_stop_order",
|
|
4830
4830
|
module: "bot.grid",
|
|
4831
|
-
description: "Stop a
|
|
4831
|
+
description: "[CAUTION] Stop a grid bot or close its remaining open position \u2014 real trades, irreversible. Workflow: (1) If the user has not specified which bot to stop, call grid_get_orders first and ask the user to confirm which bot before proceeding. (2) Call grid_get_order_details to check the current 'state' field. (3) If state='running' \u2192 call this tool: stopType='1' (default, clean exit) \u2014 spot grid sells all base assets back to quote; contract grid market-closes all positions. stopType='2' (keep assets) \u2014 spot grid keeps base assets as-is; contract grid cancels grid orders but leaves the position open. (4) If state='no_close_position' \u2192 call this tool with stopType='1' to close the remaining open position.",
|
|
4832
4832
|
isWrite: true,
|
|
4833
4833
|
inputSchema: {
|
|
4834
4834
|
type: "object",
|
|
@@ -4843,7 +4843,7 @@ function registerGridTools() {
|
|
|
4843
4843
|
stopType: {
|
|
4844
4844
|
type: "string",
|
|
4845
4845
|
enum: ["1", "2"],
|
|
4846
|
-
description: "'1' (default): stop strategy and sell
|
|
4846
|
+
description: "'1' (default): stop strategy and sell - spot grid sells all base assets back to quote; contract grid market-closes all positions. '2': stop strategy without selling - 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."
|
|
4847
4847
|
}
|
|
4848
4848
|
},
|
|
4849
4849
|
required: ["algoId", "algoOrdType", "instId"]
|
|
@@ -4860,7 +4860,7 @@ function registerGridTools() {
|
|
|
4860
4860
|
})],
|
|
4861
4861
|
privateRateLimit("grid_stop_order", 20),
|
|
4862
4862
|
true
|
|
4863
|
-
// retryOnNetworkError: safe to retry
|
|
4863
|
+
// retryOnNetworkError: safe to retry - already-stopped returns an error but does not harm state
|
|
4864
4864
|
);
|
|
4865
4865
|
return normalizeWrite(response);
|
|
4866
4866
|
}
|
|
@@ -5006,7 +5006,7 @@ function registerDcaTools() {
|
|
|
5006
5006
|
{
|
|
5007
5007
|
name: "dca_stop_order",
|
|
5008
5008
|
module: "bot.dca",
|
|
5009
|
-
description: "Stop a
|
|
5009
|
+
description: "[CAUTION] Stop a DCA bot or close its remaining open position \u2014 real trades, irreversible. Workflow: (1) If the user has not specified which bot to stop, call dca_get_orders first and ask the user to confirm which bot before proceeding. (2) Call dca_get_order_details to check the current 'state' field. (3) If state='running' \u2192 call this tool. (4) If state='no_close_position' \u2192 call this tool with stopType='1' to close the remaining open position. spot_dca requires stopType: 1=sell all tokens, 2=keep tokens.",
|
|
5010
5010
|
isWrite: true,
|
|
5011
5011
|
inputSchema: {
|
|
5012
5012
|
type: "object",
|
|
@@ -5161,7 +5161,7 @@ function registerEarnTools() {
|
|
|
5161
5161
|
{
|
|
5162
5162
|
name: "earn_get_savings_balance",
|
|
5163
5163
|
module: "earn.savings",
|
|
5164
|
-
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. earn_get_lending_rate_history also returns fixed-term (\u5B9A\u671F) product offers, so one call gives a complete view of both flexible and fixed options. Do NOT use for fixed-term (\u5B9A\u671F) order queries
|
|
5164
|
+
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. earn_get_lending_rate_history also returns fixed-term (\u5B9A\u671F) product offers, so one call gives a complete view of both flexible and fixed options. Do NOT use for fixed-term (\u5B9A\u671F) order queries - use earn_get_fixed_order_list instead.",
|
|
5165
5165
|
isWrite: false,
|
|
5166
5166
|
inputSchema: {
|
|
5167
5167
|
type: "object",
|
|
@@ -5185,7 +5185,7 @@ function registerEarnTools() {
|
|
|
5185
5185
|
{
|
|
5186
5186
|
name: "earn_get_fixed_order_list",
|
|
5187
5187
|
module: "earn.savings",
|
|
5188
|
-
description: "Get Simple Earn Fixed (\u5B9A\u671F\u8D5A\u5E01) lending order list. Returns orders sorted by creation time descending. Use this to check status of fixed-term lending orders (pending/earning/expired/settled/cancelled). Do NOT use for flexible earn balance
|
|
5188
|
+
description: "Get Simple Earn Fixed (\u5B9A\u671F\u8D5A\u5E01) lending order list. Returns orders sorted by creation time descending. Use this to check status of fixed-term lending orders (pending/earning/expired/settled/cancelled). Do NOT use for flexible earn balance - use earn_get_savings_balance instead. If the result is empty, do NOT display any fixed-term section in the output.",
|
|
5189
5189
|
isWrite: false,
|
|
5190
5190
|
inputSchema: {
|
|
5191
5191
|
type: "object",
|
|
@@ -5237,7 +5237,7 @@ function registerEarnTools() {
|
|
|
5237
5237
|
},
|
|
5238
5238
|
rate: {
|
|
5239
5239
|
type: "string",
|
|
5240
|
-
description: "Minimum lending rate threshold (annual, decimal). e.g. 0.01 = 1%. Only matched when market rate \u2265 this value. Defaults to 0.01. Keep at 0.01 to maximize matching probability
|
|
5240
|
+
description: "Minimum lending rate threshold (annual, decimal). e.g. 0.01 = 1%. Only matched when market rate \u2265 this value. Defaults to 0.01. Keep at 0.01 to maximize matching probability - do NOT raise this to increase yield, as actual yield (lendingRate) is determined by market supply/demand, not this setting."
|
|
5241
5241
|
}
|
|
5242
5242
|
},
|
|
5243
5243
|
required: ["ccy", "amt"]
|
|
@@ -5304,7 +5304,7 @@ function registerEarnTools() {
|
|
|
5304
5304
|
},
|
|
5305
5305
|
rate: {
|
|
5306
5306
|
type: "string",
|
|
5307
|
-
description: "Minimum lending rate threshold (annual, decimal). e.g. 0.01 = 1%. Only matched when market rate \u2265 this value. Keep at 0.01 to maximize matching probability
|
|
5307
|
+
description: "Minimum lending rate threshold (annual, decimal). e.g. 0.01 = 1%. Only matched when market rate \u2265 this value. Keep at 0.01 to maximize matching probability - do NOT raise this to increase yield, as actual yield (lendingRate) is determined by market supply/demand, not this setting."
|
|
5308
5308
|
}
|
|
5309
5309
|
},
|
|
5310
5310
|
required: ["ccy", "rate"]
|
|
@@ -5366,7 +5366,7 @@ function registerEarnTools() {
|
|
|
5366
5366
|
{
|
|
5367
5367
|
name: "earn_fixed_purchase",
|
|
5368
5368
|
module: "earn.savings",
|
|
5369
|
-
description: "Purchase Simple Earn Fixed (\u5B9A\u671F) product, two-step flow. First call (confirm omitted or false): returns purchase preview with product details and risk warning. Preview offer fields: lendQuota = remaining quota (\u5269\u4F59\u989D\u5EA6), soldOut = whether product is sold out (lendQuota is 0). YOU MUST display the 'warning' field from the preview response to the user VERBATIM before asking for confirmation
|
|
5369
|
+
description: "Purchase Simple Earn Fixed (\u5B9A\u671F) product, two-step flow. First call (confirm omitted or false): returns purchase preview with product details and risk warning. Preview offer fields: lendQuota = remaining quota (\u5269\u4F59\u989D\u5EA6), soldOut = whether product is sold out (lendQuota is 0). YOU MUST display the 'warning' field from the preview response to the user VERBATIM before asking for confirmation - do NOT omit or summarize it. Second call (confirm=true): executes the purchase. Only proceed after the user explicitly confirms. IMPORTANT: Orders in 'pending' (\u5339\u914D\u4E2D) state can still be cancelled via earn_fixed_redeem; once the status changes to 'earning' (\u8D5A\u5E01\u4E2D), funds are LOCKED until maturity - no early redemption allowed.",
|
|
5370
5370
|
isWrite: true,
|
|
5371
5371
|
inputSchema: {
|
|
5372
5372
|
type: "object",
|
|
@@ -5425,7 +5425,7 @@ function registerEarnTools() {
|
|
|
5425
5425
|
term,
|
|
5426
5426
|
offer: offerWithSoldOut,
|
|
5427
5427
|
currentFlexibleRate: rateArr[0]?.["lendingRate"] ?? null,
|
|
5428
|
-
warning: "\u26A0\uFE0F Orders still in 'pending' state can be cancelled before matching completes. Once the status changes to 'earning', funds are LOCKED until maturity
|
|
5428
|
+
warning: "\u26A0\uFE0F Orders still in 'pending' state can be cancelled before matching completes. Once the status changes to 'earning', funds are LOCKED until maturity - early redemption is NOT allowed. Please call again with confirm=true to proceed."
|
|
5429
5429
|
};
|
|
5430
5430
|
}
|
|
5431
5431
|
assertNotDemo(context.config, "earn_fixed_purchase");
|
|
@@ -5440,7 +5440,7 @@ function registerEarnTools() {
|
|
|
5440
5440
|
{
|
|
5441
5441
|
name: "earn_fixed_redeem",
|
|
5442
5442
|
module: "earn.savings",
|
|
5443
|
-
description: "Redeem Simple Earn Fixed (\u5B9A\u671F\u8D5A\u5E01) order. [CAUTION] Redeems a fixed-term lending order. Always redeems the full order amount. Only orders in 'pending' (\u5339\u914D\u4E2D) state can be redeemed
|
|
5443
|
+
description: "Redeem Simple Earn Fixed (\u5B9A\u671F\u8D5A\u5E01) order. [CAUTION] Redeems a fixed-term lending order. Always redeems the full order amount. Only orders in 'pending' (\u5339\u914D\u4E2D) state can be redeemed - orders in 'earning' state are locked until maturity and cannot be redeemed early. Do NOT use for flexible earn redemption - use earn_savings_redeem instead.",
|
|
5444
5444
|
isWrite: true,
|
|
5445
5445
|
inputSchema: {
|
|
5446
5446
|
type: "object",
|
|
@@ -5468,7 +5468,7 @@ function registerEarnTools() {
|
|
|
5468
5468
|
{
|
|
5469
5469
|
name: "earn_get_lending_rate_history",
|
|
5470
5470
|
module: "earn.savings",
|
|
5471
|
-
description: "Query Simple Earn lending rates and fixed-term offers. Use this tool when the user asks about Simple Earn products, current or historical lending rates, or when displaying savings balance with market rate context (\u5E02\u573A\u5747\u5229\u7387). Returns lending rate history (lendingRate field, newest-first) AND available fixed-term (\u5B9A\u671F) offers with APR, term, min amount, and quota
|
|
5471
|
+
description: "Query Simple Earn lending rates and fixed-term offers. Use this tool when the user asks about Simple Earn products, current or historical lending rates, or when displaying savings balance with market rate context (\u5E02\u573A\u5747\u5229\u7387). Returns lending rate history (lendingRate field, newest-first) AND available fixed-term (\u5B9A\u671F) offers with APR, term, min amount, and quota - one call gives a complete view of both flexible and fixed options. In fixedOffers: lendQuota = remaining quota (\u5269\u4F59\u989D\u5EA6), soldOut = whether product is sold out (lendQuota is 0). To get current flexible APY: use limit=1 and read lendingRate.",
|
|
5472
5472
|
isWrite: false,
|
|
5473
5473
|
inputSchema: {
|
|
5474
5474
|
type: "object",
|
|
@@ -5801,7 +5801,7 @@ function registerOnchainEarnTools() {
|
|
|
5801
5801
|
}
|
|
5802
5802
|
var DCD_CODE_BEHAVIORS = {
|
|
5803
5803
|
"50001": { retry: true, suggestion: "Service temporarily unavailable. Retry in a few minutes." },
|
|
5804
|
-
"50002": { retry: false, suggestion: "Invalid JSON in request body. This is likely a bug
|
|
5804
|
+
"50002": { retry: false, suggestion: "Invalid JSON in request body. This is likely a bug - check request parameters." },
|
|
5805
5805
|
"50014": { retry: false, suggestion: "Missing required parameter. Check that all required fields are provided." },
|
|
5806
5806
|
"50016": { retry: false, suggestion: "notionalCcy does not match productId option type. Use baseCcy for CALL, quoteCcy for PUT." },
|
|
5807
5807
|
"50026": { retry: true, suggestion: "DCD system error. Retry in a few minutes." },
|
|
@@ -6176,7 +6176,7 @@ function registerFlashEarnTools() {
|
|
|
6176
6176
|
{
|
|
6177
6177
|
name: "earn_get_flash_earn_projects",
|
|
6178
6178
|
module: "earn.flash",
|
|
6179
|
-
description: "Get Flash Earn projects. Use this to browse upcoming or in-progress Flash Earn opportunities. Do NOT use for purchase or redeem actions
|
|
6179
|
+
description: "Get Flash Earn projects. Use this to browse upcoming or in-progress Flash Earn opportunities. Do NOT use for purchase or redeem actions - Flash Earn is query-only in this module.",
|
|
6180
6180
|
isWrite: false,
|
|
6181
6181
|
inputSchema: {
|
|
6182
6182
|
type: "object",
|
|
@@ -6572,7 +6572,7 @@ function handlePlaceOrderError(base, rawArgs, endpoint) {
|
|
|
6572
6572
|
const seriesId = extractSeriesId(instId);
|
|
6573
6573
|
const expiryMs = inferExpiryMsFromInstId(instId);
|
|
6574
6574
|
const isExpired = expiryMs !== null && expiryMs < Date.now();
|
|
6575
|
-
const reason = isExpired ? `The contract (${instId}) has expired.` : `The contract (${instId}) was not found
|
|
6575
|
+
const reason = isExpired ? `The contract (${instId}) has expired.` : `The contract (${instId}) was not found - it may not exist or has not started yet.`;
|
|
6576
6576
|
throw new OkxApiError(
|
|
6577
6577
|
`${reason} Ask the user if they'd like to place the same order on the next session. If yes, call event_get_markets with seriesId=${seriesId} and state=live to find available contracts.`,
|
|
6578
6578
|
{ code: sCode, endpoint }
|
|
@@ -6588,17 +6588,17 @@ var OUTCOME_SCHEMA = {
|
|
|
6588
6588
|
UP/DOWN direction contracts: UP (price rises during the period) or DOWN (price falls).
|
|
6589
6589
|
YES/NO price-target or touch contracts: YES (condition met) or NO (condition not met).
|
|
6590
6590
|
Check the series type from event_get_series to determine which applies.
|
|
6591
|
-
NOTE: px is the event contract price (0.01
|
|
6591
|
+
NOTE: px is the event contract price (0.01-0.99), NOT the underlying asset price. It reflects market-implied probability when actively trading.`
|
|
6592
6592
|
};
|
|
6593
6593
|
function registerEventContractTools() {
|
|
6594
6594
|
return [
|
|
6595
6595
|
// -----------------------------------------------------------------------
|
|
6596
|
-
// Read-only
|
|
6596
|
+
// Read-only - browse (user-facing) + series / events / markets (internal)
|
|
6597
6597
|
// -----------------------------------------------------------------------
|
|
6598
6598
|
{
|
|
6599
6599
|
name: "event_browse",
|
|
6600
6600
|
module: "event",
|
|
6601
|
-
description: "Browse currently active (in-progress) event contracts. Call when user asks what event contracts are available to trade. Returns only in-progress contracts (floorStrike set). If a live quote field px is present, it is the event contract price (0.01
|
|
6601
|
+
description: "Browse currently active (in-progress) event contracts. Call when user asks what event contracts are available to trade. Returns only in-progress contracts (floorStrike set). If a live quote field px is present, it is the event contract price (0.01-0.99), not the underlying asset price; it reflects the market-implied probability when actively trading. Grouped by settlement type and underlying. Do NOT use for querying contracts within a specific series - use event_get_markets with seriesId instead.",
|
|
6602
6602
|
isWrite: false,
|
|
6603
6603
|
inputSchema: {
|
|
6604
6604
|
type: "object",
|
|
@@ -6717,7 +6717,7 @@ function registerEventContractTools() {
|
|
|
6717
6717
|
{
|
|
6718
6718
|
name: "event_get_markets",
|
|
6719
6719
|
module: "event",
|
|
6720
|
-
description: "List tradeable contracts within a series. state=live for active contracts, state=expired for settlement results. floorStrike=strike price; px (when present) is the event contract price (0.01
|
|
6720
|
+
description: "List tradeable contracts within a series. state=live for active contracts, state=expired for settlement results. floorStrike=strike price; px (when present) is the event contract price (0.01-0.99), not the underlying asset price - reflects the market-implied probability when actively trading; outcome pre-translated (pending/YES/NO/UP/DOWN); timestamps UTC+8. Do NOT use for discovering what series are available across all underlyings - use event_browse instead.",
|
|
6721
6721
|
isWrite: false,
|
|
6722
6722
|
inputSchema: {
|
|
6723
6723
|
type: "object",
|
|
@@ -6798,7 +6798,7 @@ function registerEventContractTools() {
|
|
|
6798
6798
|
{
|
|
6799
6799
|
name: "event_get_orders",
|
|
6800
6800
|
module: "event",
|
|
6801
|
-
description: "Query event contract orders (open, 7d history, or 3-month archive). outcome pre-translated (YES/NO/UP/DOWN). Do NOT use for trade executions
|
|
6801
|
+
description: "Query event contract orders (open, 7d history, or 3-month archive). outcome pre-translated (YES/NO/UP/DOWN). Do NOT use for trade executions - use event_get_fills for fill records and settlement outcomes.",
|
|
6802
6802
|
isWrite: false,
|
|
6803
6803
|
inputSchema: {
|
|
6804
6804
|
type: "object",
|
|
@@ -6856,7 +6856,7 @@ function registerEventContractTools() {
|
|
|
6856
6856
|
{
|
|
6857
6857
|
name: "event_get_fills",
|
|
6858
6858
|
module: "event",
|
|
6859
|
-
description: "Get event contract fill history (trade executions and settlement payouts). archive=true for up to 3mo, false (default) for last 3d. outcome pre-translated (YES/NO/UP/DOWN). Each record includes a 'type' field: 'fill' (opening trade) or 'settlement' (expiry payout with settlementResult win/loss and pnl). Do NOT use for order status
|
|
6859
|
+
description: "Get event contract fill history (trade executions and settlement payouts). archive=true for up to 3mo, false (default) for last 3d. outcome pre-translated (YES/NO/UP/DOWN). Each record includes a 'type' field: 'fill' (opening trade) or 'settlement' (expiry payout with settlementResult win/loss and pnl). Do NOT use for order status - use event_get_orders instead.",
|
|
6860
6860
|
isWrite: false,
|
|
6861
6861
|
inputSchema: {
|
|
6862
6862
|
type: "object",
|
|
@@ -6898,15 +6898,15 @@ function registerEventContractTools() {
|
|
|
6898
6898
|
}
|
|
6899
6899
|
},
|
|
6900
6900
|
// -----------------------------------------------------------------------
|
|
6901
|
-
// Private
|
|
6901
|
+
// Private - write
|
|
6902
6902
|
// -----------------------------------------------------------------------
|
|
6903
6903
|
{
|
|
6904
6904
|
name: "event_place_order",
|
|
6905
6905
|
module: "event",
|
|
6906
6906
|
description: `Place an event contract order. [CAUTION] Places a real order. Before placing, call event_get_markets(seriesId, state=live) to obtain the instId of the target contract.
|
|
6907
6907
|
- outcome: UP/YES (bet price goes up/condition met) or DOWN/NO (bet price goes down/condition not met)
|
|
6908
|
-
- For limit orders: px is the event contract price (0.01
|
|
6909
|
-
- tdMode is always isolated; speedBump is auto-set per exchange requirement
|
|
6908
|
+
- For limit orders: px is the event contract price (0.01-0.99), NOT the underlying asset price. It reflects market-implied probability when actively trading
|
|
6909
|
+
- tdMode is always isolated; speedBump is auto-set per exchange requirement - do not pass either`,
|
|
6910
6910
|
isWrite: true,
|
|
6911
6911
|
inputSchema: {
|
|
6912
6912
|
type: "object",
|
|
@@ -6932,7 +6932,7 @@ function registerEventContractTools() {
|
|
|
6932
6932
|
},
|
|
6933
6933
|
px: {
|
|
6934
6934
|
type: "string",
|
|
6935
|
-
description: "Event contract price (0.01
|
|
6935
|
+
description: "Event contract price (0.01-0.99). Required when ordType=limit. Do NOT use for market orders."
|
|
6936
6936
|
}
|
|
6937
6937
|
},
|
|
6938
6938
|
required: ["instId", "side", "outcome", "sz"]
|
|
@@ -6985,7 +6985,7 @@ function registerEventContractTools() {
|
|
|
6985
6985
|
properties: {
|
|
6986
6986
|
instId: { type: "string", description: "Event contract instrument ID" },
|
|
6987
6987
|
ordId: { type: "string", description: "Order ID to amend" },
|
|
6988
|
-
newPx: { type: "string", description: "New event contract price (0.01
|
|
6988
|
+
newPx: { type: "string", description: "New event contract price (0.01-0.99). Omit to keep current." },
|
|
6989
6989
|
newSz: { type: "string", description: "New size in contracts (omit to keep current)" }
|
|
6990
6990
|
},
|
|
6991
6991
|
required: ["instId", "ordId"]
|
|
@@ -7039,7 +7039,7 @@ function registerEventContractTools() {
|
|
|
7039
7039
|
if (sCode === "51001") {
|
|
7040
7040
|
const expiryMs = inferExpiryMsFromInstId(instId);
|
|
7041
7041
|
const isExpired = expiryMs !== null && expiryMs < Date.now();
|
|
7042
|
-
const reason = isExpired ? `The contract (${instId}) has already expired
|
|
7042
|
+
const reason = isExpired ? `The contract (${instId}) has already expired - the order was auto-cancelled at settlement. Check event_get_fills to confirm the outcome.` : `Instrument (${instId}) not found. Verify the instId with event_get_markets before retrying.`;
|
|
7043
7043
|
throw new OkxApiError(reason, { code: sCode, endpoint: response.endpoint });
|
|
7044
7044
|
}
|
|
7045
7045
|
}
|
|
@@ -7074,25 +7074,25 @@ var SIGNAL_POOL_FILTER_PROPS = {
|
|
|
7074
7074
|
type: "string",
|
|
7075
7075
|
enum: ["PNL_ANY", "PNL_TOP50", "PNL_TOP20", "PNL_TOP5"],
|
|
7076
7076
|
default: "PNL_ANY",
|
|
7077
|
-
description: "PnL percentile gate
|
|
7077
|
+
description: "PnL percentile gate. Naming: `TOP{N}` = top N% percentile (NOT an absolute PnL value). PNL_ANY = no filter; PNL_TOP50 = PnL \u2265 P50 (median); PNL_TOP20 = \u2265 P80; PNL_TOP5 = \u2265 P95. PnL distribution is long-tailed - use percentile, not absolute thresholds."
|
|
7078
7078
|
},
|
|
7079
7079
|
winRateTier: {
|
|
7080
7080
|
type: "string",
|
|
7081
7081
|
enum: ["WR_ANY", "WR_GE_50", "WR_GE_80"],
|
|
7082
7082
|
default: "WR_ANY",
|
|
7083
|
-
description: "Minimum win-rate gate (absolute thresholds, NOT percentile). Naming: `GE_{N}` = career win-rate \u2265 N%
|
|
7083
|
+
description: "Minimum win-rate gate (absolute thresholds, NOT percentile). Naming: `GE_{N}` = career win-rate \u2265 N% - distinct from `pnlTier`/`aumTier` `TOP{N}` which are percentiles. WR_ANY = no filter; WR_GE_50 = \u2265 50%; WR_GE_80 = \u2265 80%."
|
|
7084
7084
|
},
|
|
7085
7085
|
maxDrawdownTier: {
|
|
7086
7086
|
type: "string",
|
|
7087
7087
|
enum: ["MR_ANY", "MR_LE_20", "MR_LE_50"],
|
|
7088
7088
|
default: "MR_ANY",
|
|
7089
|
-
description: "Maximum-drawdown gate (absolute thresholds, NOT percentile; smaller drawdown = lower risk). Naming: `LE_{N}` = drawdown \u2264 N%
|
|
7089
|
+
description: "Maximum-drawdown gate (absolute thresholds, NOT percentile; smaller drawdown = lower risk). Naming: `LE_{N}` = drawdown \u2264 N% - distinct from `pnlTier`/`aumTier` `TOP{N}` which are percentiles. MR_ANY = no filter; MR_LE_20 = drawdown \u2264 20%; MR_LE_50 = \u2264 50%."
|
|
7090
7090
|
},
|
|
7091
7091
|
aumTier: {
|
|
7092
7092
|
type: "string",
|
|
7093
7093
|
enum: ["AUM_ANY", "AUM_TOP50", "AUM_TOP20", "AUM_TOP5"],
|
|
7094
7094
|
default: "AUM_ANY",
|
|
7095
|
-
description: "AUM (Assets Under Management) percentile gate. Naming: `TOP{N}` = top N% percentile (NOT an absolute USD amount). AUM_ANY = no filter; AUM_TOP50 = AUM \u2265 P50; AUM_TOP20 = \u2265 P80; AUM_TOP5 = \u2265 P95. AUM is long-tailed
|
|
7095
|
+
description: "AUM (Assets Under Management) percentile gate. Naming: `TOP{N}` = top N% percentile (NOT an absolute USD amount). AUM_ANY = no filter; AUM_TOP50 = AUM \u2265 P50; AUM_TOP20 = \u2265 P80; AUM_TOP5 = \u2265 P95. AUM is long-tailed - use percentile, not absolute USD."
|
|
7096
7096
|
}
|
|
7097
7097
|
};
|
|
7098
7098
|
var LEADERBOARD_POOL_FILTER_PROPS = {
|
|
@@ -7110,19 +7110,19 @@ var LEADERBOARD_POOL_FILTER_PROPS = {
|
|
|
7110
7110
|
},
|
|
7111
7111
|
minPnl: {
|
|
7112
7112
|
type: "string",
|
|
7113
|
-
description: 'Minimum absolute PnL in USD as a string, e.g. `"10000"`
|
|
7113
|
+
description: 'Minimum absolute PnL in USD as a string, e.g. `"10000"` -> traders with PnL \u2265 $10,000. Numeric threshold - distinct from the signal-side `pnlTier` percentile enum.'
|
|
7114
7114
|
},
|
|
7115
7115
|
minWinRate: {
|
|
7116
7116
|
type: "string",
|
|
7117
|
-
description: 'Minimum win-rate as a decimal in 0~1 range, passed as a string, e.g. `"0.8"`
|
|
7117
|
+
description: 'Minimum win-rate as a decimal in 0~1 range, passed as a string, e.g. `"0.8"` -> traders with win-rate \u2265 80%. Numeric threshold - distinct from the signal-side `winRateTier` enum.'
|
|
7118
7118
|
},
|
|
7119
7119
|
maxDrawdown: {
|
|
7120
7120
|
type: "string",
|
|
7121
|
-
description: 'Maximum drawdown as a decimal, passed as a string, e.g. `"0.1"`
|
|
7121
|
+
description: 'Maximum drawdown as a decimal, passed as a string, e.g. `"0.1"` -> traders with drawdown \u2264 10%. Lower = lower risk. Numeric threshold - distinct from the signal-side `maxDrawdownTier` enum.'
|
|
7122
7122
|
},
|
|
7123
7123
|
minAum: {
|
|
7124
7124
|
type: "string",
|
|
7125
|
-
description: 'Minimum AUM (Assets Under Management) in USD as a string, e.g. `"1000"`
|
|
7125
|
+
description: 'Minimum AUM (Assets Under Management) in USD as a string, e.g. `"1000"` -> traders with AUM \u2265 $1,000. Numeric threshold - distinct from the signal-side `aumTier` percentile enum.'
|
|
7126
7126
|
}
|
|
7127
7127
|
};
|
|
7128
7128
|
var LEADERBOARD_FILTER_UPSTREAM_NAMES = {
|
|
@@ -7256,11 +7256,11 @@ var PAGINATION_PROP = {
|
|
|
7256
7256
|
}
|
|
7257
7257
|
};
|
|
7258
7258
|
var TRADER_ITEM_PROPS = {
|
|
7259
|
-
authorId: { type: "string", description: "Trader's unique ID
|
|
7259
|
+
authorId: { type: "string", description: "Trader's unique ID - pass to other smartmoney_get_trader_* tools." },
|
|
7260
7260
|
nickName: { type: "string", description: "Display nickname." },
|
|
7261
7261
|
pnl: { type: "string", description: "Absolute PnL in USD over the requested `period` (numeric string)." },
|
|
7262
7262
|
pnlRatio: { type: "string", description: 'PnL as a decimal ratio over the requested `period` (e.g. "0.35" = +35%).' },
|
|
7263
|
-
asset: { type: "string", description: "AUM (Assets Under Management) in USD
|
|
7263
|
+
asset: { type: "string", description: "AUM (Assets Under Management) in USD - same field that the input `minAum` filter applies to." },
|
|
7264
7264
|
winRate: { type: "string", description: "Lifetime win-rate as a decimal (0~1)." },
|
|
7265
7265
|
maxDrawdown: { type: "string", description: 'Max drawdown as a decimal (e.g. "0.2" = 20%). Lower = lower risk.' },
|
|
7266
7266
|
onboardDuration: { type: "string", description: "Days the trader has been onboarded on the leaderboard (numeric string)." },
|
|
@@ -7289,7 +7289,7 @@ var SIGNAL_ITEM_PROPS = {
|
|
|
7289
7289
|
},
|
|
7290
7290
|
tradersQualified: {
|
|
7291
7291
|
type: "integer",
|
|
7292
|
-
description: "
|
|
7292
|
+
description: "Final aggregation pool size after tier filters + top-N truncation by `sortBy`. Bounded by the request's pool size limit (`lmtNum` for `_by_filter` variants, `authorIds.length` for `_by_trader` variants). Smaller than the bound only when the upstream candidate pool (traders passing all tier filters) contains fewer entries than the bound \u2014 typical for low-volume instruments or very strict tier combos."
|
|
7293
7293
|
},
|
|
7294
7294
|
longTraders: { type: "integer", description: "Number of pool traders currently long this asset (incl. double-sided)." },
|
|
7295
7295
|
shortTraders: { type: "integer", description: "Number of pool traders currently short this asset (incl. double-sided)." },
|
|
@@ -7299,19 +7299,19 @@ var SIGNAL_ITEM_PROPS = {
|
|
|
7299
7299
|
properties: {
|
|
7300
7300
|
longNotionalUsdt: {
|
|
7301
7301
|
type: "string",
|
|
7302
|
-
description: "Sum of long-side notional in USDT, weighted by each trader's ENTRY PRICE (price_avg), not mark price. Moves only when positions are opened / closed / scaled
|
|
7302
|
+
description: "Sum of long-side notional in USDT, weighted by each trader's ENTRY PRICE (price_avg), not mark price. Moves only when positions are opened / closed / scaled - stays constant when positions are unchanged."
|
|
7303
7303
|
},
|
|
7304
7304
|
shortNotionalUsdt: {
|
|
7305
7305
|
type: "string",
|
|
7306
|
-
description: "Sum of short-side notional in USDT, weighted by each trader's ENTRY PRICE (price_avg), not mark price. Moves only when positions are opened / closed / scaled
|
|
7306
|
+
description: "Sum of short-side notional in USDT, weighted by each trader's ENTRY PRICE (price_avg), not mark price. Moves only when positions are opened / closed / scaled - stays constant when positions are unchanged."
|
|
7307
7307
|
},
|
|
7308
7308
|
netNotionalUsdt: {
|
|
7309
7309
|
type: "string",
|
|
7310
|
-
description: "Net directional notional in USDT = long \u2212 short. Weighted by each trader's ENTRY PRICE (price_avg), not mark price
|
|
7310
|
+
description: "Net directional notional in USDT = long \u2212 short. Weighted by each trader's ENTRY PRICE (price_avg), not mark price - reflects position scaling, not underlying price movement."
|
|
7311
7311
|
},
|
|
7312
7312
|
totalNotionalUsdt: {
|
|
7313
7313
|
type: "string",
|
|
7314
|
-
description: "Gross notional in USDT = long + short. Weighted by each trader's ENTRY PRICE (price_avg), not mark price
|
|
7314
|
+
description: "Gross notional in USDT = long + short. Weighted by each trader's ENTRY PRICE (price_avg), not mark price - reflects position scaling (open / close / add), not underlying price movement. Stays constant across buckets when traders hold positions unchanged."
|
|
7315
7315
|
},
|
|
7316
7316
|
totalNotionalVs24h: {
|
|
7317
7317
|
type: "string",
|
|
@@ -7341,7 +7341,7 @@ var SIGNAL_ITEM_PROPS = {
|
|
|
7341
7341
|
},
|
|
7342
7342
|
weightedLongRatio: {
|
|
7343
7343
|
type: "string",
|
|
7344
|
-
description: "Notional-weighted long ratio = \u03A3(long_notional) / \u03A3(notional). Notional uses each trader's ENTRY PRICE (price_avg), not mark price
|
|
7344
|
+
description: "Notional-weighted long ratio = \u03A3(long_notional) / \u03A3(notional). Notional uses each trader's ENTRY PRICE (price_avg), not mark price - ratio shifts only when positions are scaled. NULL when no notional."
|
|
7345
7345
|
},
|
|
7346
7346
|
weightedShortRatio: {
|
|
7347
7347
|
type: "string",
|
|
@@ -7376,7 +7376,7 @@ var SIGNAL_HISTORY_ITEM_PROPS = {
|
|
|
7376
7376
|
},
|
|
7377
7377
|
weightedLongRatio: {
|
|
7378
7378
|
type: "string",
|
|
7379
|
-
description: "Notional-weighted long ratio at this bucket = \u03A3(long_notional) / \u03A3(notional). Decimal 0~1. Notional uses each trader's ENTRY PRICE (price_avg), not mark price
|
|
7379
|
+
description: "Notional-weighted long ratio at this bucket = \u03A3(long_notional) / \u03A3(notional). Decimal 0~1. Notional uses each trader's ENTRY PRICE (price_avg), not mark price - ratio shifts only when positions are scaled."
|
|
7380
7380
|
},
|
|
7381
7381
|
weightedShortRatio: {
|
|
7382
7382
|
type: "string",
|
|
@@ -7396,13 +7396,16 @@ var SIGNAL_HISTORY_ITEM_PROPS = {
|
|
|
7396
7396
|
},
|
|
7397
7397
|
netNotionalUsdt: {
|
|
7398
7398
|
type: "string",
|
|
7399
|
-
description: "Net directional notional in USDT at this bucket = long notional \u2212 short notional. Weighted by each trader's ENTRY PRICE (price_avg), not mark price
|
|
7399
|
+
description: "Net directional notional in USDT at this bucket = long notional \u2212 short notional. Weighted by each trader's ENTRY PRICE (price_avg), not mark price - reflects position scaling, not underlying price movement."
|
|
7400
7400
|
},
|
|
7401
7401
|
totalNotionalUsdt: {
|
|
7402
7402
|
type: "string",
|
|
7403
|
-
description: "Gross notional in USDT at this bucket = long notional + short notional. Weighted by each trader's ENTRY PRICE (price_avg), not mark price
|
|
7403
|
+
description: "Gross notional in USDT at this bucket = long notional + short notional. Weighted by each trader's ENTRY PRICE (price_avg), not mark price - tracks capital deployed (rising = adding, falling = retreating). Stays constant across buckets when traders hold positions unchanged."
|
|
7404
|
+
},
|
|
7405
|
+
tradersQualified: {
|
|
7406
|
+
type: "integer",
|
|
7407
|
+
description: "Final aggregation pool size in this bucket after tier filters + top-N truncation by `sortBy`. Bounded by the request's pool size limit (`lmtNum` for `_by_filter` variants, `authorIds.length` for `_by_trader` variants). The funnel + top-N selection runs once per query (not per bucket); each bucket reuses the same selected pool for position aggregation. Smaller than the bound only when the upstream candidate pool underflows."
|
|
7404
7408
|
},
|
|
7405
|
-
tradersQualified: { type: "integer", description: "Pool size after applying tier filters (includes traders without a position)." },
|
|
7406
7409
|
dataVersion: { type: "string", description: "Snapshot version key in `yyyyMMddHH` UTC (10-digit, e.g. `2026042820`)." }
|
|
7407
7410
|
};
|
|
7408
7411
|
function registerSmartmoneyTools() {
|
|
@@ -7414,7 +7417,7 @@ function registerSmartmoneyTools() {
|
|
|
7414
7417
|
{
|
|
7415
7418
|
name: "smartmoney_get_traders_by_filter",
|
|
7416
7419
|
module: "smartmoney",
|
|
7417
|
-
description: "Leaderboard ranking of OKX smart-money traders, filtered by pool conditions and ranked by `sortBy`. Use when: discovering top performers by criteria (PnL / win-rate / drawdown / AUM). See also: `smartmoney_get_performance_by_trader` (lookup by ID), `smartmoney_search_trader` (lookup by nickname). Note: `updateTime` is 12-digit `yyyyMMddHHmm` UTC+8, different from signal tools' 10-digit UTC `asOfTime`/`dataVersion`
|
|
7420
|
+
description: "Leaderboard ranking of OKX smart-money traders, filtered by pool conditions and ranked by `sortBy`. Use when: discovering top performers by criteria (PnL / win-rate / drawdown / AUM). See also: `smartmoney_get_performance_by_trader` (lookup by ID), `smartmoney_search_trader` (lookup by nickname). Note: `updateTime` is 12-digit `yyyyMMddHHmm` UTC+8, different from signal tools' 10-digit UTC `asOfTime`/`dataVersion` - do not cross-pass.",
|
|
7418
7421
|
isWrite: false,
|
|
7419
7422
|
outputSchema: envelope(
|
|
7420
7423
|
{ type: "array", items: { type: "object", properties: TRADER_ITEM_PROPS } },
|
|
@@ -7431,16 +7434,16 @@ function registerSmartmoneyTools() {
|
|
|
7431
7434
|
properties: {
|
|
7432
7435
|
updateTime: {
|
|
7433
7436
|
type: "string",
|
|
7434
|
-
description: 'Snapshot version key
|
|
7437
|
+
description: 'Snapshot version key - 12-digit `yyyyMMddHHmm` (UTC+8) as a string, e.g. `"202604301815"`. Omit to query the latest snapshot (refreshed every ~5 min).'
|
|
7435
7438
|
},
|
|
7436
7439
|
...LEADERBOARD_POOL_FILTER_PROPS,
|
|
7437
7440
|
after: {
|
|
7438
7441
|
type: "string",
|
|
7439
|
-
description: 'Pagination cursor (older page)
|
|
7442
|
+
description: 'Pagination cursor (older page) - pass the `authorId` of the last item from the previous page as a string, e.g. `"872913470357110787"`. Cursor anchors on `authorId` while preserving the current `sortBy` order.'
|
|
7440
7443
|
},
|
|
7441
7444
|
before: {
|
|
7442
7445
|
type: "string",
|
|
7443
|
-
description: 'Pagination cursor (newer page)
|
|
7446
|
+
description: 'Pagination cursor (newer page) - pass the `authorId` of the first item from the previous page as a string, e.g. `"872913470357110787"`. Cursor anchors on `authorId` while preserving the current `sortBy` order.'
|
|
7444
7447
|
},
|
|
7445
7448
|
limit: {
|
|
7446
7449
|
type: "integer",
|
|
@@ -7480,7 +7483,7 @@ function registerSmartmoneyTools() {
|
|
|
7480
7483
|
{
|
|
7481
7484
|
name: "smartmoney_get_performance_by_trader",
|
|
7482
7485
|
module: "smartmoney",
|
|
7483
|
-
description: "PnL / win-rate / drawdown profile for one or more traders looked up by `authorIds`. Use when: caller already has trader IDs and needs their performance metrics. See also: `smartmoney_search_trader` (resolve nickname
|
|
7486
|
+
description: "PnL / win-rate / drawdown profile for one or more traders looked up by `authorIds`. Use when: caller already has trader IDs and needs their performance metrics. See also: `smartmoney_search_trader` (resolve nickname -> authorId), `smartmoney_get_traders_by_filter` (criteria-based discovery). Note: response `updateTime` is 12-digit `yyyyMMddHHmm` UTC+8 - do not pass to signal-side tools' `asOfTime` (10-digit UTC).",
|
|
7484
7487
|
isWrite: false,
|
|
7485
7488
|
outputSchema: envelope(
|
|
7486
7489
|
{ type: "array", items: { type: "object", properties: TRADER_ITEM_PROPS } },
|
|
@@ -7550,7 +7553,7 @@ function registerSmartmoneyTools() {
|
|
|
7550
7553
|
{
|
|
7551
7554
|
name: "smartmoney_get_trader_positions",
|
|
7552
7555
|
module: "smartmoney",
|
|
7553
|
-
description: "Currently-open positions held by a single trader (direction, size, leverage, entry, conviction). Use when: inspecting what a top trader is holding RIGHT NOW. See also: `smartmoney_get_trader_positions_history` (closed positions), `smartmoney_search_trader` (nickname
|
|
7556
|
+
description: "Currently-open positions held by a single trader (direction, size, leverage, entry, conviction). Use when: inspecting what a top trader is holding RIGHT NOW. See also: `smartmoney_get_trader_positions_history` (closed positions), `smartmoney_search_trader` (nickname -> authorId), `smartmoney_get_traders_by_filter` (discover trader).",
|
|
7554
7557
|
isWrite: false,
|
|
7555
7558
|
outputSchema: envelope({
|
|
7556
7559
|
type: "array",
|
|
@@ -7570,9 +7573,9 @@ function registerSmartmoneyTools() {
|
|
|
7570
7573
|
direction: {
|
|
7571
7574
|
type: "string",
|
|
7572
7575
|
enum: ["long", "short"],
|
|
7573
|
-
description: 'Derived clean direction (`long` | `short`)
|
|
7576
|
+
description: 'Derived clean direction (`long` | `short`) - handler computes this from `posSide` + sign of `pos` so agents do not have to branch on the `posSide="net"` net-mode case.'
|
|
7574
7577
|
},
|
|
7575
|
-
posCcy: { type: "string", description: 'Position currency
|
|
7578
|
+
posCcy: { type: "string", description: 'Position currency - the asset being held, e.g. "BTC".' },
|
|
7576
7579
|
quoteCcy: { type: "string", description: 'Quote currency the position is priced/settled in, e.g. "USDT".' },
|
|
7577
7580
|
pos: {
|
|
7578
7581
|
type: "string",
|
|
@@ -7601,7 +7604,7 @@ function registerSmartmoneyTools() {
|
|
|
7601
7604
|
},
|
|
7602
7605
|
instId: {
|
|
7603
7606
|
type: "string",
|
|
7604
|
-
description: 'Optional instrument filter. Accepts either full instId (e.g. "BTC-USDT-SWAP") or bare base currency (e.g. "BTC")
|
|
7607
|
+
description: 'Optional instrument filter. Accepts either full instId (e.g. "BTC-USDT-SWAP") or bare base currency (e.g. "BTC") - the handler extracts the base currency for the upstream filter.'
|
|
7605
7608
|
}
|
|
7606
7609
|
},
|
|
7607
7610
|
required: ["authorId"]
|
|
@@ -7631,7 +7634,7 @@ function registerSmartmoneyTools() {
|
|
|
7631
7634
|
{
|
|
7632
7635
|
name: "smartmoney_get_trader_positions_history",
|
|
7633
7636
|
module: "smartmoney",
|
|
7634
|
-
description: "Closed-position history of a single trader, paginated by `posId` cursor. Use when: studying realized PnL pattern, holding duration, win/loss streaks, or how positions ended (closed vs liquidated). See also: `smartmoney_get_trader_positions` (currently-open), `smartmoney_search_trader` (nickname
|
|
7637
|
+
description: "Closed-position history of a single trader, paginated by `posId` cursor. Use when: studying realized PnL pattern, holding duration, win/loss streaks, or how positions ended (closed vs liquidated). See also: `smartmoney_get_trader_positions` (currently-open), `smartmoney_search_trader` (nickname -> authorId), `smartmoney_get_traders_by_filter` (discover trader).",
|
|
7635
7638
|
isWrite: false,
|
|
7636
7639
|
outputSchema: envelope(
|
|
7637
7640
|
{
|
|
@@ -7647,7 +7650,7 @@ function registerSmartmoneyTools() {
|
|
|
7647
7650
|
},
|
|
7648
7651
|
ctVal: {
|
|
7649
7652
|
type: "string",
|
|
7650
|
-
description: "Contract face value
|
|
7653
|
+
description: "Contract face value - USD value of a single contract (\u5F20). Numeric string. Empty/0 for non-contract instruments."
|
|
7651
7654
|
},
|
|
7652
7655
|
posSide: {
|
|
7653
7656
|
type: "string",
|
|
@@ -7714,15 +7717,15 @@ function registerSmartmoneyTools() {
|
|
|
7714
7717
|
},
|
|
7715
7718
|
instId: {
|
|
7716
7719
|
type: "string",
|
|
7717
|
-
description: 'Optional instrument filter. Accepts either full instId (e.g. "BTC-USDT-SWAP") or bare base currency (e.g. "BTC")
|
|
7720
|
+
description: 'Optional instrument filter. Accepts either full instId (e.g. "BTC-USDT-SWAP") or bare base currency (e.g. "BTC") - the handler extracts the base currency for the upstream filter.'
|
|
7718
7721
|
},
|
|
7719
7722
|
after: {
|
|
7720
7723
|
type: "string",
|
|
7721
|
-
description: 'Pagination cursor (older)
|
|
7724
|
+
description: 'Pagination cursor (older) - returns positions with `posId` smaller than this value. Pass the `posId` as a string, e.g. `"872913470357110787"`.'
|
|
7722
7725
|
},
|
|
7723
7726
|
before: {
|
|
7724
7727
|
type: "string",
|
|
7725
|
-
description: 'Pagination cursor (newer)
|
|
7728
|
+
description: 'Pagination cursor (newer) - returns positions with `posId` greater than this value. Pass the `posId` as a string, e.g. `"872913470357110787"`.'
|
|
7726
7729
|
},
|
|
7727
7730
|
limit: {
|
|
7728
7731
|
type: "integer",
|
|
@@ -7768,7 +7771,7 @@ function registerSmartmoneyTools() {
|
|
|
7768
7771
|
{
|
|
7769
7772
|
name: "smartmoney_get_trader_orders_history",
|
|
7770
7773
|
module: "smartmoney",
|
|
7771
|
-
description: "Recent orders/fills placed by a single trader (direction, size, price, leverage), paginated by `ordId` cursor. Aligned with the cross-module `*_get_orders` family. Use when: tracking a top trader's latest trade activity. See also: `smartmoney_search_trader` (nickname
|
|
7774
|
+
description: "Recent orders/fills placed by a single trader (direction, size, price, leverage), paginated by `ordId` cursor. Aligned with the cross-module `*_get_orders` family. Use when: tracking a top trader's latest trade activity. See also: `smartmoney_search_trader` (nickname -> authorId), `smartmoney_get_traders_by_filter` (discover trader).",
|
|
7772
7775
|
isWrite: false,
|
|
7773
7776
|
outputSchema: envelope(
|
|
7774
7777
|
{
|
|
@@ -7832,15 +7835,15 @@ function registerSmartmoneyTools() {
|
|
|
7832
7835
|
},
|
|
7833
7836
|
instId: {
|
|
7834
7837
|
type: "string",
|
|
7835
|
-
description: 'Optional instrument filter. Accepts either full instId (e.g. "BTC-USDT-SWAP") or bare base currency (e.g. "BTC")
|
|
7838
|
+
description: 'Optional instrument filter. Accepts either full instId (e.g. "BTC-USDT-SWAP") or bare base currency (e.g. "BTC") - the handler extracts the base currency for the upstream filter.'
|
|
7836
7839
|
},
|
|
7837
7840
|
after: {
|
|
7838
7841
|
type: "string",
|
|
7839
|
-
description: 'Pagination cursor (older)
|
|
7842
|
+
description: 'Pagination cursor (older) - returns trades with `ordId` smaller than this value. Pass the `ordId` as a string, e.g. `"872913470357110787"`.'
|
|
7840
7843
|
},
|
|
7841
7844
|
before: {
|
|
7842
7845
|
type: "string",
|
|
7843
|
-
description: 'Pagination cursor (newer)
|
|
7846
|
+
description: 'Pagination cursor (newer) - returns trades with `ordId` greater than this value. Pass the `ordId` as a string, e.g. `"872913470357110787"`.'
|
|
7844
7847
|
},
|
|
7845
7848
|
limit: {
|
|
7846
7849
|
type: "integer",
|
|
@@ -7894,7 +7897,7 @@ function registerSmartmoneyTools() {
|
|
|
7894
7897
|
items: {
|
|
7895
7898
|
type: "object",
|
|
7896
7899
|
properties: {
|
|
7897
|
-
authorId: { type: "string", description: "Trader's unique ID
|
|
7900
|
+
authorId: { type: "string", description: "Trader's unique ID - pass to other `smartmoney_get_trader_*` tools." },
|
|
7898
7901
|
nickName: { type: "string", description: "Display nickname matched against the keyword." },
|
|
7899
7902
|
followerCount: { type: "string", description: "OKX-platform follower count (numeric string; Twitter followers excluded). Sort key." }
|
|
7900
7903
|
}
|
|
@@ -7936,7 +7939,7 @@ function registerSmartmoneyTools() {
|
|
|
7936
7939
|
{
|
|
7937
7940
|
name: "smartmoney_get_signal_overview_by_filter",
|
|
7938
7941
|
module: "smartmoney",
|
|
7939
|
-
description: "Multi-asset smart-money consensus signals (long/short ratio, weighted entry, capital flow, deltas vs 1h/24h/7d), aggregated over a tier-filtered trader pool (PnL / win-rate / drawdown / AUM). Pick instruments via `topInstruments` OR `instCcyList`
|
|
7942
|
+
description: "Multi-asset smart-money consensus signals (long/short ratio, weighted entry, capital flow, deltas vs 1h/24h/7d), aggregated over a tier-filtered trader pool (PnL / win-rate / drawdown / AUM). Pick instruments via `topInstruments` OR `instCcyList` - exactly one. Snapshot time auto-resolved to current hour. **Linear (USDT/USDS-margined) contracts only - coin-margined (`-USD-SWAP` / `-USD-DELIVERY`) positions are excluded by upstream and silently omitted from the aggregation.** Use when: latest cross-asset consensus from a criteria-defined pool. See also: `smartmoney_get_signal_overview_by_trader` (restrict pool to specific traders), `smartmoney_get_signal_trend_by_filter` (time-series instead of latest snapshot).",
|
|
7940
7943
|
isWrite: false,
|
|
7941
7944
|
outputSchema: envelope({
|
|
7942
7945
|
type: "array",
|
|
@@ -7957,7 +7960,7 @@ function registerSmartmoneyTools() {
|
|
|
7957
7960
|
type: "array",
|
|
7958
7961
|
items: { type: "string" },
|
|
7959
7962
|
minItems: 1,
|
|
7960
|
-
description: 'Base currencies to aggregate, e.g. `["BTC", "ETH", "SOL"]`. Mutually exclusive with `topInstruments`. Scope: only USDT-margined and USDS-margined (linear) instruments
|
|
7963
|
+
description: 'Base currencies to aggregate, e.g. `["BTC", "ETH", "SOL"]`. Mutually exclusive with `topInstruments`. Scope: only USDT-margined and USDS-margined (linear) instruments - e.g. `BTC` covers `BTC-USDT-SWAP` + `BTC-USDS-SWAP`. Coin-margined contracts (`BTC-USD-SWAP`, `BTC-USD-DELIVERY`) are NOT included; positions a trader holds in those instruments are silently dropped from the aggregation.'
|
|
7961
7964
|
},
|
|
7962
7965
|
...SIGNAL_POOL_FILTER_PROPS,
|
|
7963
7966
|
lmtNum: {
|
|
@@ -7965,7 +7968,7 @@ function registerSmartmoneyTools() {
|
|
|
7965
7968
|
minimum: 1,
|
|
7966
7969
|
maximum: 2e3,
|
|
7967
7970
|
default: 100,
|
|
7968
|
-
description: "
|
|
7971
|
+
description: "Upper bound on `tradersQualified` (final aggregation pool size). Candidates pass through tier filters (`pnlTier` / `winRateTier` / `aumTier` / `maxDrawdownTier`), then are truncated to top-N by `sortBy` (DESC). `tradersQualified` \u2264 `lmtNum` always; equals `lmtNum` unless candidate pool underflows (rare ccy / strict tier combos). Default 100; values above ~1500 add latency without benefit (exceeds typical candidate pool size)."
|
|
7969
7972
|
}
|
|
7970
7973
|
},
|
|
7971
7974
|
required: ["sortBy", "period"]
|
|
@@ -7977,7 +7980,7 @@ function registerSmartmoneyTools() {
|
|
|
7977
7980
|
if (instCcyList && topInstrumentsRaw !== void 0) {
|
|
7978
7981
|
throw actionableError(
|
|
7979
7982
|
'"topInstruments" and "instCcyList" are mutually exclusive.',
|
|
7980
|
-
"Pass exactly one
|
|
7983
|
+
"Pass exactly one - `topInstruments` for top-N hottest coins, or `instCcyList` for specific coins."
|
|
7981
7984
|
);
|
|
7982
7985
|
}
|
|
7983
7986
|
const response = await context.client.privateGet(
|
|
@@ -7996,7 +7999,7 @@ function registerSmartmoneyTools() {
|
|
|
7996
7999
|
{
|
|
7997
8000
|
name: "smartmoney_get_signal_overview_by_trader",
|
|
7998
8001
|
module: "smartmoney",
|
|
7999
|
-
description: "Multi-asset smart-money signals aggregated over a hand-picked set of traders (`authorIds`). Pick instruments via `topInstruments` OR `instCcyList`. Capability tier filters (pnlTier / winRateTier / etc.) not exposed
|
|
8002
|
+
description: "Multi-asset smart-money signals aggregated over a hand-picked set of traders (`authorIds`). Pick instruments via `topInstruments` OR `instCcyList`. Capability tier filters (pnlTier / winRateTier / etc.) not exposed - backend uses defaults for direct-lookup scenarios. **Linear (USDT/USDS-margined) contracts only - a trader's coin-margined (`-USD-SWAP` / `-USD-DELIVERY`) positions are silently excluded from the aggregation, even when those positions are large.** Use `smartmoney_get_trader_positions` if the full position book is needed. Use when: caller already knows which traders to follow and wants their cross-asset consensus at the latest hour. See also: `smartmoney_get_signal_overview_by_filter` (criteria-defined pool), `smartmoney_get_signal_trend_by_trader` (time-series), `smartmoney_get_traders_by_filter` / `smartmoney_search_trader` (discover authorIds).",
|
|
8000
8003
|
isWrite: false,
|
|
8001
8004
|
outputSchema: envelope({
|
|
8002
8005
|
type: "array",
|
|
@@ -8023,7 +8026,7 @@ function registerSmartmoneyTools() {
|
|
|
8023
8026
|
type: "array",
|
|
8024
8027
|
items: { type: "string" },
|
|
8025
8028
|
minItems: 1,
|
|
8026
|
-
description: 'Base currencies to aggregate, e.g. `["BTC", "ETH", "SOL"]`. Mutually exclusive with `topInstruments`. Scope: only USDT-margined and USDS-margined (linear) instruments
|
|
8029
|
+
description: 'Base currencies to aggregate, e.g. `["BTC", "ETH", "SOL"]`. Mutually exclusive with `topInstruments`. Scope: only USDT-margined and USDS-margined (linear) instruments - e.g. `BTC` covers `BTC-USDT-SWAP` + `BTC-USDS-SWAP`. Coin-margined contracts (`BTC-USD-SWAP`, `BTC-USD-DELIVERY`) are NOT included; the trader\'s positions in those instruments are silently dropped.'
|
|
8027
8030
|
},
|
|
8028
8031
|
sortBy: {
|
|
8029
8032
|
type: "string",
|
|
@@ -8056,7 +8059,7 @@ function registerSmartmoneyTools() {
|
|
|
8056
8059
|
if (instCcyList && topInstrumentsRaw !== void 0) {
|
|
8057
8060
|
throw actionableError(
|
|
8058
8061
|
'"topInstruments" and "instCcyList" are mutually exclusive.',
|
|
8059
|
-
"Pass exactly one
|
|
8062
|
+
"Pass exactly one - `topInstruments` for top-N hottest coins, or `instCcyList` for specific coins."
|
|
8060
8063
|
);
|
|
8061
8064
|
}
|
|
8062
8065
|
const response = await context.client.privateGet(
|
|
@@ -8078,7 +8081,7 @@ function registerSmartmoneyTools() {
|
|
|
8078
8081
|
{
|
|
8079
8082
|
name: "smartmoney_get_signal_trend_by_filter",
|
|
8080
8083
|
module: "smartmoney",
|
|
8081
|
-
description: "Time-series of single-asset smart-money signal across hourly/daily buckets, aggregated over a tier-filtered trader pool. Returns the latest `limit` buckets ending at `asOfTime` (defaults to current UTC hour). **Linear (USDT/USDS-margined) contracts only
|
|
8084
|
+
description: "Time-series of single-asset smart-money signal across hourly/daily buckets, aggregated over a tier-filtered trader pool. Returns the latest `limit` buckets ending at `asOfTime` (defaults to current UTC hour). **Linear (USDT/USDS-margined) contracts only - coin-margined (`-USD-SWAP` / `-USD-DELIVERY`) positions are excluded by upstream and silently omitted.** Use when: tracking how long/short conviction and capital evolve over time (smart money adding exposure or retreating). See also: `smartmoney_get_signal_overview_by_filter` (latest snapshot only), `smartmoney_get_signal_trend_by_trader` (restrict to specific traders). Note: `asOfTime` is 10-digit `yyyyMMddHH` UTC, different from leaderboard tools' 12-digit UTC+8 `updateTime` - do not cross-pass.",
|
|
8082
8085
|
isWrite: false,
|
|
8083
8086
|
outputSchema: envelope({
|
|
8084
8087
|
type: "array",
|
|
@@ -8090,11 +8093,11 @@ function registerSmartmoneyTools() {
|
|
|
8090
8093
|
properties: {
|
|
8091
8094
|
instCcy: {
|
|
8092
8095
|
type: "string",
|
|
8093
|
-
description: 'Base currency to scope the time-series, e.g. "BTC". Required. Scope: USDT-margined and USDS-margined (linear) instruments only
|
|
8096
|
+
description: 'Base currency to scope the time-series, e.g. "BTC". Required. Scope: USDT-margined and USDS-margined (linear) instruments only - coin-margined (`-USD-SWAP` / `-USD-DELIVERY`) positions are NOT included.'
|
|
8094
8097
|
},
|
|
8095
8098
|
asOfTime: {
|
|
8096
8099
|
type: "string",
|
|
8097
|
-
description: 'Anchor snapshot time
|
|
8100
|
+
description: 'Anchor snapshot time - 10-digit `yyyyMMddHH` UTC as a string, e.g. `"2026050100"`. Returns the latest `limit` buckets ending at this anchor. Omit to use the current UTC hour.'
|
|
8098
8101
|
},
|
|
8099
8102
|
granularity: {
|
|
8100
8103
|
type: "string",
|
|
@@ -8115,7 +8118,7 @@ function registerSmartmoneyTools() {
|
|
|
8115
8118
|
minimum: 1,
|
|
8116
8119
|
maximum: 2e3,
|
|
8117
8120
|
default: 100,
|
|
8118
|
-
description: "
|
|
8121
|
+
description: "Upper bound on `tradersQualified` per bucket (final aggregation pool size). Candidates pass through tier filters (`pnlTier` / `winRateTier` / `aumTier` / `maxDrawdownTier`), then are truncated to top-N by `sortBy` (DESC). `tradersQualified` \u2264 `lmtNum` always; equals `lmtNum` unless candidate pool underflows (rare ccy / strict tier combos). Default 100; values above ~1500 add latency without benefit (exceeds typical candidate pool size)."
|
|
8119
8122
|
}
|
|
8120
8123
|
},
|
|
8121
8124
|
required: ["instCcy", "granularity", "sortBy", "period"]
|
|
@@ -8150,7 +8153,7 @@ function registerSmartmoneyTools() {
|
|
|
8150
8153
|
{
|
|
8151
8154
|
name: "smartmoney_get_signal_trend_by_trader",
|
|
8152
8155
|
module: "smartmoney",
|
|
8153
|
-
description: "Time-series of single-asset smart-money signal aggregated over a hand-picked set of traders (`authorIds`). Returns the latest `limit` buckets ending at `asOfTime` (defaults to current UTC hour). Capability tier filters (pnlTier / winRateTier / etc.) not exposed
|
|
8156
|
+
description: "Time-series of single-asset smart-money signal aggregated over a hand-picked set of traders (`authorIds`). Returns the latest `limit` buckets ending at `asOfTime` (defaults to current UTC hour). Capability tier filters (pnlTier / winRateTier / etc.) not exposed - backend uses defaults for direct-lookup scenarios. **Linear (USDT/USDS-margined) contracts only - a trader's coin-margined (`-USD-SWAP` / `-USD-DELIVERY`) positions on the requested base ccy are silently excluded from each bucket.** Use `smartmoney_get_trader_positions` to inspect the full position book. Use when: tracking how a specific group of traders has evolved their long/short consensus over time on one coin. See also: `smartmoney_get_signal_trend_by_filter` (criteria-defined pool), `smartmoney_get_signal_overview_by_trader` (latest snapshot only), `smartmoney_get_traders_by_filter` / `smartmoney_search_trader` (discover authorIds). Note: `asOfTime` is 10-digit `yyyyMMddHH` UTC, different from leaderboard tools' 12-digit UTC+8 `updateTime` - do not cross-pass.",
|
|
8154
8157
|
isWrite: false,
|
|
8155
8158
|
outputSchema: envelope({
|
|
8156
8159
|
type: "array",
|
|
@@ -8168,11 +8171,11 @@ function registerSmartmoneyTools() {
|
|
|
8168
8171
|
},
|
|
8169
8172
|
instCcy: {
|
|
8170
8173
|
type: "string",
|
|
8171
|
-
description: 'Base currency to scope the time-series, e.g. "BTC". Required. Scope: USDT-margined and USDS-margined (linear) instruments only
|
|
8174
|
+
description: 'Base currency to scope the time-series, e.g. "BTC". Required. Scope: USDT-margined and USDS-margined (linear) instruments only - coin-margined (`-USD-SWAP` / `-USD-DELIVERY`) positions held by the trader set are NOT included.'
|
|
8172
8175
|
},
|
|
8173
8176
|
asOfTime: {
|
|
8174
8177
|
type: "string",
|
|
8175
|
-
description: 'Anchor snapshot time
|
|
8178
|
+
description: 'Anchor snapshot time - 10-digit `yyyyMMddHH` UTC as a string, e.g. `"2026050100"`. Returns the latest `limit` buckets ending at this anchor. Omit to use the current UTC hour.'
|
|
8176
8179
|
},
|
|
8177
8180
|
granularity: {
|
|
8178
8181
|
type: "string",
|
|
@@ -8252,7 +8255,7 @@ function buildContractTradeTools(cfg) {
|
|
|
8252
8255
|
{
|
|
8253
8256
|
name: n("place_order"),
|
|
8254
8257
|
module,
|
|
8255
|
-
description: `Place ${label} order. Attach TP/SL via tpTriggerPx/slTriggerPx. Before placing, use market_get_instruments to get ctVal (contract face value)
|
|
8258
|
+
description: `Place ${label} order. Attach TP/SL via tpTriggerPx/slTriggerPx. Before placing, use market_get_instruments to get ctVal (contract face value) - do NOT assume contract sizes. [CAUTION] Executes real trades.`,
|
|
8256
8259
|
isWrite: true,
|
|
8257
8260
|
inputSchema: {
|
|
8258
8261
|
type: "object",
|
|
@@ -8592,10 +8595,10 @@ function buildContractTradeTools(cfg) {
|
|
|
8592
8595
|
module,
|
|
8593
8596
|
description: `Set leverage for a ${label} instrument or position. [CAUTION] Changes risk parameters.
|
|
8594
8597
|
Scenarios (SWAP/FUTURES only):
|
|
8595
|
-
\u2022 cross + any instId under the index
|
|
8596
|
-
\u2022 isolated + buy-sell (net) posMode
|
|
8597
|
-
\u2022 isolated + long-short (hedge) posMode
|
|
8598
|
-
Not supported: PORTFOLIO MARGIN accounts cannot adjust cross leverage for SWAP/FUTURES
|
|
8598
|
+
\u2022 cross + any instId under the index -> sets leverage at the index level
|
|
8599
|
+
\u2022 isolated + buy-sell (net) posMode -> instId only
|
|
8600
|
+
\u2022 isolated + long-short (hedge) posMode -> instId + posSide=long|short (BOTH directions must be set separately)
|
|
8601
|
+
Not supported: PORTFOLIO MARGIN accounts cannot adjust cross leverage for SWAP/FUTURES - the request will be rejected by OKX. Use account_get_config first if unsure of the account's margin mode.`,
|
|
8599
8602
|
isWrite: true,
|
|
8600
8603
|
inputSchema: {
|
|
8601
8604
|
type: "object",
|
|
@@ -8603,13 +8606,13 @@ Not supported: PORTFOLIO MARGIN accounts cannot adjust cross leverage for SWAP/F
|
|
|
8603
8606
|
instId: { type: "string", description: instIdExample },
|
|
8604
8607
|
lever: {
|
|
8605
8608
|
type: "string",
|
|
8606
|
-
description: "Leverage multiplier as a positive number string, e.g. '10'. Max value depends on the instrument (query market_get_instruments
|
|
8609
|
+
description: "Leverage multiplier as a positive number string, e.g. '10'. Max value depends on the instrument (query market_get_instruments -> lever)."
|
|
8607
8610
|
},
|
|
8608
8611
|
mgnMode: { type: "string", enum: ["cross", "isolated"] },
|
|
8609
8612
|
posSide: {
|
|
8610
8613
|
type: "string",
|
|
8611
8614
|
enum: ["long", "short"],
|
|
8612
|
-
description: "REQUIRED when mgnMode=isolated AND the account is in hedge (long/short) position mode. Use 'long' or 'short'
|
|
8615
|
+
description: "REQUIRED when mgnMode=isolated AND the account is in hedge (long/short) position mode. Use 'long' or 'short' - setting one side does NOT auto-apply to the other. Omit entirely for one-way (net) position mode or for cross margin."
|
|
8613
8616
|
}
|
|
8614
8617
|
},
|
|
8615
8618
|
required: ["instId", "lever", "mgnMode"]
|
|
@@ -9425,12 +9428,12 @@ var OI_BARS = ["5m", "15m", "1H", "4H", "1D"];
|
|
|
9425
9428
|
function registerMarketFilterTools() {
|
|
9426
9429
|
return [
|
|
9427
9430
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9428
|
-
// market_filter
|
|
9431
|
+
// market_filter - /api/v5/aigc/mcp/market-filter
|
|
9429
9432
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9430
9433
|
{
|
|
9431
9434
|
name: "market_filter",
|
|
9432
9435
|
module: "market",
|
|
9433
|
-
description: "Screen / rank instruments across SPOT, SWAP, or FUTURES by multi-dimensional criteria: price range, 24h change %, market cap, 24h volume (USD), funding rate (SWAP), open interest (USD), listing time. Returns ranked rows with full ticker snapshot. Use to find top movers, high-OI contracts, newly listed tokens, etc. No credentials required. Do NOT use to get OI change rankings across contracts
|
|
9436
|
+
description: "Screen / rank instruments across SPOT, SWAP, or FUTURES by multi-dimensional criteria: price range, 24h change %, market cap, 24h volume (USD), funding rate (SWAP), open interest (USD), listing time. Returns ranked rows with full ticker snapshot. Use to find top movers, high-OI contracts, newly listed tokens, etc. No credentials required. Do NOT use to get OI change rankings across contracts - use market_filter_oi_change instead. Do NOT use to get OI time series for a single instrument - use market_get_oi_history instead.",
|
|
9434
9437
|
isWrite: false,
|
|
9435
9438
|
inputSchema: {
|
|
9436
9439
|
type: "object",
|
|
@@ -9514,7 +9517,7 @@ function registerMarketFilterTools() {
|
|
|
9514
9517
|
sortBy: {
|
|
9515
9518
|
type: "string",
|
|
9516
9519
|
enum: ["last", "chg24hPct", "marketCapUsd", "volUsd24h", "fundingRate", "oiUsd", "listTime"],
|
|
9517
|
-
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
|
|
9520
|
+
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 - market_filter only sorts by the current snapshot."
|
|
9518
9521
|
},
|
|
9519
9522
|
sortOrder: {
|
|
9520
9523
|
type: "string",
|
|
@@ -9562,12 +9565,12 @@ function registerMarketFilterTools() {
|
|
|
9562
9565
|
}
|
|
9563
9566
|
},
|
|
9564
9567
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9565
|
-
// market_get_oi_history
|
|
9568
|
+
// market_get_oi_history - /api/v5/aigc/mcp/oi-history
|
|
9566
9569
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9567
9570
|
{
|
|
9568
9571
|
name: "market_get_oi_history",
|
|
9569
9572
|
module: "market",
|
|
9570
|
-
description: "Get open interest (OI) history time series for a single SWAP or FUTURES instrument. Returns per-bar OI in contracts, base currency and USD, plus bar-over-bar delta and delta %. Useful for tracking how OI evolves around price moves. No credentials required. Do NOT use to compare OI changes across multiple contracts
|
|
9573
|
+
description: "Get open interest (OI) history time series for a single SWAP or FUTURES instrument. Returns per-bar OI in contracts, base currency and USD, plus bar-over-bar delta and delta %. Useful for tracking how OI evolves around price moves. No credentials required. Do NOT use to compare OI changes across multiple contracts - use market_filter_oi_change instead. Do NOT use to screen instruments by current OI level - use market_filter instead.",
|
|
9571
9574
|
isWrite: false,
|
|
9572
9575
|
inputSchema: {
|
|
9573
9576
|
type: "object",
|
|
@@ -9609,12 +9612,12 @@ function registerMarketFilterTools() {
|
|
|
9609
9612
|
}
|
|
9610
9613
|
},
|
|
9611
9614
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9612
|
-
// market_filter_oi_change
|
|
9615
|
+
// market_filter_oi_change - /api/v5/aigc/mcp/oi-change-filter
|
|
9613
9616
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9614
9617
|
{
|
|
9615
9618
|
name: "market_filter_oi_change",
|
|
9616
9619
|
module: "market",
|
|
9617
|
-
description: "Find SWAP or FUTURES instruments with significant open interest changes over a given bar window. Returns ranked rows with current OI (USD), previous OI (USD), OI delta (USD and %), price change %, 24h volume and funding rate. Ideal for spotting unusual accumulation/distribution or confirming trend momentum. No credentials required. Do NOT use to get OI time series for a single instrument
|
|
9620
|
+
description: "Find SWAP or FUTURES instruments with significant open interest changes over a given bar window. Returns ranked rows with current OI (USD), previous OI (USD), OI delta (USD and %), price change %, 24h volume and funding rate. Ideal for spotting unusual accumulation/distribution or confirming trend momentum. No credentials required. Do NOT use to get OI time series for a single instrument - use market_get_oi_history instead. Do NOT use to screen by current OI absolute level or other non-OI metrics - use market_filter instead.",
|
|
9618
9621
|
isWrite: false,
|
|
9619
9622
|
inputSchema: {
|
|
9620
9623
|
type: "object",
|
|
@@ -9646,7 +9649,7 @@ function registerMarketFilterTools() {
|
|
|
9646
9649
|
sortBy: {
|
|
9647
9650
|
type: "string",
|
|
9648
9651
|
enum: ["oiUsd", "oiDeltaUsd", "oiDeltaPct", "absOiDeltaPct", "volUsd24h", "fundingRate", "last"],
|
|
9649
|
-
description: "Sort field. Default: oiDeltaPct (largest movers first, signed
|
|
9652
|
+
description: "Sort field. Default: oiDeltaPct (largest movers first, signed - 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 - they are not in the OI-change Row."
|
|
9650
9653
|
},
|
|
9651
9654
|
sortOrder: {
|
|
9652
9655
|
type: "string",
|
|
@@ -9681,7 +9684,7 @@ function registerMarketFilterTools() {
|
|
|
9681
9684
|
}
|
|
9682
9685
|
},
|
|
9683
9686
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9684
|
-
// market_get_pair_spread
|
|
9687
|
+
// market_get_pair_spread - /api/v5/aigc/mcp/pair-spread
|
|
9685
9688
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9686
9689
|
{
|
|
9687
9690
|
name: "market_get_pair_spread",
|
|
@@ -9967,7 +9970,7 @@ var D_COINS_SENTIMENT = 'Comma-separated uppercase ticker symbols, max 20 (e.g.
|
|
|
9967
9970
|
var D_LANGUAGE = "Content language: zh-CN or en-US. Infer from user's message. No server default.";
|
|
9968
9971
|
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.";
|
|
9969
9972
|
var D_END = "End time, Unix epoch milliseconds. Parse relative time if given. Omit for no upper bound.";
|
|
9970
|
-
var D_IMPORTANCE = "Importance filter: 'low' returns all news (both low and high importance); 'high' narrows to major/breaking news only. Omitted
|
|
9973
|
+
var D_IMPORTANCE = "Importance filter: 'low' returns all news (both low and high importance); 'high' narrows to major/breaking news only. Omitted -> server default (high-only). Default to 'low' for broad browsing; pass 'high' only when the user explicitly asks for major news.";
|
|
9971
9974
|
var D_PLATFORM = "Filter by news source. Use values from news_get_domains (e.g. blockbeats, odaily_flash). Omit for all sources.";
|
|
9972
9975
|
var D_LIMIT = "Number of results (default 10, max 50).";
|
|
9973
9976
|
function registerNewsTools() {
|
|
@@ -10066,7 +10069,7 @@ function registerNewsTools() {
|
|
|
10066
10069
|
{
|
|
10067
10070
|
name: "news_search",
|
|
10068
10071
|
module: "news",
|
|
10069
|
-
description: "Search crypto news by keyword with optional filters. Use when user provides specific search terms: 'SEC ETF news', 'stablecoin regulation'. Keyword is optional
|
|
10072
|
+
description: "Search crypto news by keyword with optional filters. Use when user provides specific search terms: 'SEC ETF news', 'stablecoin regulation'. Keyword is optional - pass sentiment alone to browse by sentiment direction. For coin-only queries prefer news_get_by_coin.",
|
|
10070
10073
|
isWrite: false,
|
|
10071
10074
|
inputSchema: {
|
|
10072
10075
|
type: "object",
|
|
@@ -10176,7 +10179,7 @@ function registerNewsTools() {
|
|
|
10176
10179
|
{
|
|
10177
10180
|
name: "news_get_coin_sentiment",
|
|
10178
10181
|
module: "news",
|
|
10179
|
-
description: "Get sentiment snapshot or time-series trend for coins. Returns bullish/bearish ratios and mention counts. Pass trendPoints for trend data (1h
|
|
10182
|
+
description: "Get sentiment snapshot or time-series trend for coins. Returns bullish/bearish ratios and mention counts. Pass trendPoints for trend data (1h->24 points, 4h->6, 24h->7). Use when user asks about coin sentiment, sentiment trend, or how bullish/bearish a coin is. For ranking all coins by sentiment, use news_get_sentiment_ranking instead.",
|
|
10180
10183
|
isWrite: false,
|
|
10181
10184
|
inputSchema: {
|
|
10182
10185
|
type: "object",
|
|
@@ -10189,7 +10192,7 @@ function registerNewsTools() {
|
|
|
10189
10192
|
},
|
|
10190
10193
|
trendPoints: {
|
|
10191
10194
|
type: "number",
|
|
10192
|
-
description: "Trend data points. Pass for time-series trend; omit for snapshot. Guide: 1h
|
|
10195
|
+
description: "Trend data points. Pass for time-series trend; omit for snapshot. Guide: 1h->24, 4h->6, 24h->7."
|
|
10193
10196
|
}
|
|
10194
10197
|
},
|
|
10195
10198
|
required: ["coins"]
|
|
@@ -10256,7 +10259,7 @@ function registerNewsTools() {
|
|
|
10256
10259
|
{
|
|
10257
10260
|
name: "news_list_calendar_regions",
|
|
10258
10261
|
module: "news",
|
|
10259
|
-
description: "List all valid region values for the economic calendar. Returns a string array of snake_case region codes. Call this when economic-calendar returns empty results to verify the region value, or to help the user pick a valid region. Do NOT use to list news source platforms
|
|
10262
|
+
description: "List all valid region values for the economic calendar. Returns a string array of snake_case region codes. Call this when economic-calendar returns empty results to verify the region value, or to help the user pick a valid region. Do NOT use to list news source platforms - use news_get_domains instead.",
|
|
10260
10263
|
isWrite: false,
|
|
10261
10264
|
inputSchema: { type: "object", properties: {}, required: [] },
|
|
10262
10265
|
handler: async () => ({ data: CALENDAR_REGIONS })
|
|
@@ -10264,15 +10267,15 @@ function registerNewsTools() {
|
|
|
10264
10267
|
{
|
|
10265
10268
|
name: "news_get_economic_calendar",
|
|
10266
10269
|
module: "news",
|
|
10267
|
-
description: "Get macro-economic calendar data (GDP, CPI, NFP, interest rate decisions, PMI, etc.). Returns scheduled and released economic events with forecast, previous, and actual values. Use when user asks about economic calendar, macro data, or specific indicators like NFP/CPI/GDP/FOMC. Do NOT use for news articles or sentiment
|
|
10270
|
+
description: "Get macro-economic calendar data (GDP, CPI, NFP, interest rate decisions, PMI, etc.). Returns scheduled and released economic events with forecast, previous, and actual values. Use when user asks about economic calendar, macro data, or specific indicators like NFP/CPI/GDP/FOMC. Do NOT use for news articles or sentiment - use news_get_latest or news_search instead.",
|
|
10268
10271
|
isWrite: false,
|
|
10269
10272
|
inputSchema: {
|
|
10270
10273
|
type: "object",
|
|
10271
10274
|
properties: {
|
|
10272
10275
|
region: { type: "string", description: "Country/region filter in snake_case (e.g. united_states, euro_area, japan). Invalid values return empty results silently. If empty results, call news_list_calendar_regions to verify the value." },
|
|
10273
10276
|
importance: { type: "string", enum: ["1", "2", "3"], description: "Importance level: 1=low, 2=medium, 3=high. Omit for all levels." },
|
|
10274
|
-
before: { type: "string", description: "Lower time bound
|
|
10275
|
-
after: { type: "string", description: "Upper time bound
|
|
10277
|
+
before: { type: "string", description: "Lower time bound - returns events NEWER than this timestamp (reversed semantics). Pair with 'after' for future-event windows. Unix ms." },
|
|
10278
|
+
after: { type: "string", description: "Upper time bound - returns events OLDER than this timestamp (reversed semantics). Default=now (returns past events). Pair with 'before' for a bounded window. Unix ms." },
|
|
10276
10279
|
limit: { type: "number", minimum: 1, maximum: 100, description: "Number of results (default 100, max 100)." }
|
|
10277
10280
|
},
|
|
10278
10281
|
required: []
|
|
@@ -10430,7 +10433,7 @@ function registerOptionAlgoTools() {
|
|
|
10430
10433
|
{
|
|
10431
10434
|
name: "option_amend_algo_order",
|
|
10432
10435
|
module: "option",
|
|
10433
|
-
description: "Amend a pending OPTION algo order (modify TP/SL prices or size). Also covers TP/SL orders attached when placing the main order
|
|
10436
|
+
description: "Amend a pending OPTION algo order (modify TP/SL prices or size). Also covers TP/SL orders attached when placing the main order - look up algoId via option_get_algo_orders first.",
|
|
10434
10437
|
isWrite: true,
|
|
10435
10438
|
inputSchema: {
|
|
10436
10439
|
type: "object",
|
|
@@ -10593,7 +10596,7 @@ function registerOptionTools() {
|
|
|
10593
10596
|
{
|
|
10594
10597
|
name: "option_place_order",
|
|
10595
10598
|
module: "option",
|
|
10596
|
-
description: "Place OPTION order. instId: {uly}-{expiry}-{strike}-C/P, e.g. BTC-USD-241227-50000-C. Before placing, use market_get_instruments to get ctVal (contract face value)
|
|
10599
|
+
description: "Place OPTION order. instId: {uly}-{expiry}-{strike}-C/P, e.g. BTC-USD-241227-50000-C. Before placing, use market_get_instruments to get ctVal (contract face value) - do NOT assume contract sizes. [CAUTION] Executes real trades.",
|
|
10597
10600
|
isWrite: true,
|
|
10598
10601
|
inputSchema: {
|
|
10599
10602
|
type: "object",
|
|
@@ -11367,7 +11370,7 @@ function registerSpotTradeTools() {
|
|
|
11367
11370
|
{
|
|
11368
11371
|
name: "spot_amend_algo_order",
|
|
11369
11372
|
module: "spot",
|
|
11370
|
-
description: "Amend a pending spot algo order (modify TP/SL prices or size). Also covers TP/SL orders attached when placing the main order
|
|
11373
|
+
description: "Amend a pending spot algo order (modify TP/SL prices or size). Also covers TP/SL orders attached when placing the main order - look up algoId via spot_get_algo_orders first.",
|
|
11371
11374
|
isWrite: true,
|
|
11372
11375
|
inputSchema: {
|
|
11373
11376
|
type: "object",
|
|
@@ -11436,7 +11439,7 @@ function registerSpotTradeTools() {
|
|
|
11436
11439
|
{
|
|
11437
11440
|
name: "spot_get_algo_orders",
|
|
11438
11441
|
module: "spot",
|
|
11439
|
-
description: "Query spot algo orders (TP/SL)
|
|
11442
|
+
description: "Query spot algo orders (TP/SL) - pending or history.",
|
|
11440
11443
|
isWrite: false,
|
|
11441
11444
|
inputSchema: {
|
|
11442
11445
|
type: "object",
|
|
@@ -11729,16 +11732,16 @@ function registerSpotTradeTools() {
|
|
|
11729
11732
|
}
|
|
11730
11733
|
},
|
|
11731
11734
|
// ── set_leverage (SPOT margin: instId-level isolated OR ccy-level cross) ──
|
|
11732
|
-
// Covers OKX scenarios 1
|
|
11735
|
+
// Covers OKX scenarios 1-5 (everything except SWAP/FUTURES, which are in
|
|
11733
11736
|
// contract-trade.ts). Callers supply exactly one of {instId, ccy}:
|
|
11734
|
-
// • instId + isolated
|
|
11735
|
-
// • instId + cross
|
|
11736
|
-
// • ccy + cross
|
|
11737
|
+
// • instId + isolated -> scenario 1 (pair-level margin)
|
|
11738
|
+
// • instId + cross -> scenario 3 (contract-mode pair-level cross margin)
|
|
11739
|
+
// • ccy + cross -> scenarios 2 / 4 / 5 (spot/multi-ccy/PM currency-level cross)
|
|
11737
11740
|
// Not applicable: posSide (spot has no long/short hedge).
|
|
11738
11741
|
{
|
|
11739
11742
|
name: "spot_set_leverage",
|
|
11740
11743
|
module: "spot",
|
|
11741
|
-
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
|
|
11744
|
+
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 -> pair-level isolated margin\n \u2022 instId + mgnMode=cross -> pair-level cross margin (contract-mode account)\n \u2022 ccy + mgnMode=cross -> 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.",
|
|
11742
11745
|
isWrite: true,
|
|
11743
11746
|
inputSchema: {
|
|
11744
11747
|
type: "object",
|
|
@@ -11753,7 +11756,7 @@ function registerSpotTradeTools() {
|
|
|
11753
11756
|
},
|
|
11754
11757
|
lever: {
|
|
11755
11758
|
type: "string",
|
|
11756
|
-
description: "Leverage multiplier as a positive number string, e.g. '3'. Max depends on the pair (query market_get_instruments
|
|
11759
|
+
description: "Leverage multiplier as a positive number string, e.g. '3'. Max depends on the pair (query market_get_instruments -> lever) or the account policy for ccy-level."
|
|
11757
11760
|
},
|
|
11758
11761
|
mgnMode: {
|
|
11759
11762
|
type: "string",
|
|
@@ -11774,7 +11777,7 @@ function registerSpotTradeTools() {
|
|
|
11774
11777
|
}
|
|
11775
11778
|
if (instId && ccy) {
|
|
11776
11779
|
throw new ValidationError(
|
|
11777
|
-
`Parameters "instId" and "ccy" are mutually exclusive
|
|
11780
|
+
`Parameters "instId" and "ccy" are mutually exclusive - provide only one. instId sets pair-level leverage; ccy sets currency-level cross margin leverage.`
|
|
11778
11781
|
);
|
|
11779
11782
|
}
|
|
11780
11783
|
const leverRaw = requireString(args, "lever");
|
|
@@ -11821,7 +11824,7 @@ function registerSwapTradeTools() {
|
|
|
11821
11824
|
{
|
|
11822
11825
|
name: "swap_amend_algo_order",
|
|
11823
11826
|
module: "swap",
|
|
11824
|
-
description: "Amend a pending SWAP/FUTURES algo order (modify TP/SL prices or size). Also covers TP/SL orders attached when placing the main order
|
|
11827
|
+
description: "Amend a pending SWAP/FUTURES algo order (modify TP/SL prices or size). Also covers TP/SL orders attached when placing the main order - look up algoId via swap_get_algo_orders first.",
|
|
11825
11828
|
isWrite: true,
|
|
11826
11829
|
inputSchema: {
|
|
11827
11830
|
type: "object",
|
|
@@ -11963,9 +11966,9 @@ function readFullConfig() {
|
|
|
11963
11966
|
throw new ConfigError(
|
|
11964
11967
|
`Failed to parse ${path42}: ${err instanceof Error ? err.message : String(err)}`,
|
|
11965
11968
|
`If your passphrase or keys contain special characters:
|
|
11966
|
-
- Contains # \\ "
|
|
11967
|
-
- Contains '
|
|
11968
|
-
- Contains both
|
|
11969
|
+
- Contains # \\ " -> use single quotes: passphrase = 'your#pass'
|
|
11970
|
+
- Contains ' -> use double quotes: passphrase = "your'pass"
|
|
11971
|
+
- Contains both -> use triple quotes: passphrase = '''your'#pass'''
|
|
11969
11972
|
Or re-run: okx config init`
|
|
11970
11973
|
);
|
|
11971
11974
|
}
|
|
@@ -12108,6 +12111,9 @@ async function loadConfig(cli) {
|
|
|
12108
12111
|
}
|
|
12109
12112
|
var CACHE_FILE = join8(homedir6(), ".okx", "update-check.json");
|
|
12110
12113
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
12114
|
+
var NEGATIVE_CHECK_INTERVAL_MS = 60 * 60 * 1e3;
|
|
12115
|
+
var DEFAULT_REGISTRY = "https://registry.npmjs.org/";
|
|
12116
|
+
var FETCH_TIMEOUT_MS = 3e3;
|
|
12111
12117
|
function readCache2() {
|
|
12112
12118
|
try {
|
|
12113
12119
|
if (existsSync4(CACHE_FILE)) {
|
|
@@ -12124,7 +12130,73 @@ function writeCache2(cache) {
|
|
|
12124
12130
|
} catch {
|
|
12125
12131
|
}
|
|
12126
12132
|
}
|
|
12133
|
+
function resolveNpmRegistry() {
|
|
12134
|
+
const envRegistry = process.env.npm_config_registry;
|
|
12135
|
+
if (envRegistry) {
|
|
12136
|
+
return envRegistry.endsWith("/") ? envRegistry : `${envRegistry}/`;
|
|
12137
|
+
}
|
|
12138
|
+
for (const filePath of buildNpmrcCandidates()) {
|
|
12139
|
+
const registry = readNpmrcRegistry(filePath);
|
|
12140
|
+
if (registry) {
|
|
12141
|
+
return registry.endsWith("/") ? registry : `${registry}/`;
|
|
12142
|
+
}
|
|
12143
|
+
}
|
|
12144
|
+
return DEFAULT_REGISTRY;
|
|
12145
|
+
}
|
|
12146
|
+
function buildNpmrcCandidates() {
|
|
12147
|
+
const paths = [];
|
|
12148
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12149
|
+
const add = (p) => {
|
|
12150
|
+
if (!seen.has(p)) {
|
|
12151
|
+
seen.add(p);
|
|
12152
|
+
paths.push(p);
|
|
12153
|
+
}
|
|
12154
|
+
};
|
|
12155
|
+
let dir = process.cwd();
|
|
12156
|
+
const root = dir.startsWith("/") ? "/" : dir.slice(0, 3);
|
|
12157
|
+
while (true) {
|
|
12158
|
+
add(join8(dir, ".npmrc"));
|
|
12159
|
+
if (dir === root) break;
|
|
12160
|
+
const parent = join8(dir, "..");
|
|
12161
|
+
if (parent === dir) break;
|
|
12162
|
+
dir = parent;
|
|
12163
|
+
}
|
|
12164
|
+
add(join8(homedir6(), ".npmrc"));
|
|
12165
|
+
if (process.platform !== "win32") {
|
|
12166
|
+
add("/etc/npmrc");
|
|
12167
|
+
}
|
|
12168
|
+
return paths;
|
|
12169
|
+
}
|
|
12170
|
+
function readNpmrcRegistry(filePath) {
|
|
12171
|
+
try {
|
|
12172
|
+
if (!existsSync4(filePath)) return null;
|
|
12173
|
+
const lines = readFileSync5(filePath, "utf-8").split(/\r?\n/);
|
|
12174
|
+
for (const line of lines) {
|
|
12175
|
+
const trimmed = line.trim();
|
|
12176
|
+
if (trimmed.startsWith("#") || !trimmed.includes("=")) continue;
|
|
12177
|
+
const eqIdx = trimmed.indexOf("=");
|
|
12178
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
12179
|
+
const value = trimmed.slice(eqIdx + 1).trim();
|
|
12180
|
+
if (key === "registry" && value) return value;
|
|
12181
|
+
}
|
|
12182
|
+
} catch {
|
|
12183
|
+
}
|
|
12184
|
+
return null;
|
|
12185
|
+
}
|
|
12186
|
+
async function fetchFromRegistry(packageName, suffix = "") {
|
|
12187
|
+
const registry = resolveNpmRegistry();
|
|
12188
|
+
const url = `${registry}${encodeURIComponent(packageName)}${suffix}`;
|
|
12189
|
+
try {
|
|
12190
|
+
return await fetch(url, {
|
|
12191
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
12192
|
+
headers: { accept: "application/json" }
|
|
12193
|
+
});
|
|
12194
|
+
} catch {
|
|
12195
|
+
return null;
|
|
12196
|
+
}
|
|
12197
|
+
}
|
|
12127
12198
|
function isNewerVersion(current, latest) {
|
|
12199
|
+
if (!latest) return false;
|
|
12128
12200
|
const parse2 = (v) => v.replace(/^v/, "").split(".").map((n) => parseInt(n, 10));
|
|
12129
12201
|
const [cMaj, cMin, cPat] = parse2(current);
|
|
12130
12202
|
const [lMaj, lMin, lPat] = parse2(latest);
|
|
@@ -12134,14 +12206,8 @@ function isNewerVersion(current, latest) {
|
|
|
12134
12206
|
}
|
|
12135
12207
|
async function fetchDistTags(packageName) {
|
|
12136
12208
|
try {
|
|
12137
|
-
const
|
|
12138
|
-
|
|
12139
|
-
const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}`, {
|
|
12140
|
-
signal: controller.signal,
|
|
12141
|
-
headers: { accept: "application/json" }
|
|
12142
|
-
});
|
|
12143
|
-
clearTimeout(timeout);
|
|
12144
|
-
if (!res.ok) return null;
|
|
12209
|
+
const res = await fetchFromRegistry(packageName);
|
|
12210
|
+
if (!res || !res.ok) return null;
|
|
12145
12211
|
const data = await res.json();
|
|
12146
12212
|
return data["dist-tags"] ?? null;
|
|
12147
12213
|
} catch {
|
|
@@ -12150,14 +12216,8 @@ async function fetchDistTags(packageName) {
|
|
|
12150
12216
|
}
|
|
12151
12217
|
async function fetchLatestVersion(packageName) {
|
|
12152
12218
|
try {
|
|
12153
|
-
const
|
|
12154
|
-
|
|
12155
|
-
const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`, {
|
|
12156
|
-
signal: controller.signal,
|
|
12157
|
-
headers: { accept: "application/json" }
|
|
12158
|
-
});
|
|
12159
|
-
clearTimeout(timeout);
|
|
12160
|
-
if (!res.ok) return null;
|
|
12219
|
+
const res = await fetchFromRegistry(packageName, "/latest");
|
|
12220
|
+
if (!res || !res.ok) return null;
|
|
12161
12221
|
const data = await res.json();
|
|
12162
12222
|
return data.version ?? null;
|
|
12163
12223
|
} catch {
|
|
@@ -12166,26 +12226,31 @@ async function fetchLatestVersion(packageName) {
|
|
|
12166
12226
|
}
|
|
12167
12227
|
function refreshCacheInBackground(packageName) {
|
|
12168
12228
|
fetchLatestVersion(packageName).then((latest) => {
|
|
12169
|
-
if (!latest) return;
|
|
12170
12229
|
const cache = readCache2();
|
|
12171
|
-
|
|
12230
|
+
if (latest) {
|
|
12231
|
+
cache[packageName] = { latestVersion: latest, checkedAt: Date.now() };
|
|
12232
|
+
} else {
|
|
12233
|
+
cache[packageName] = { latestVersion: null, checkedAt: Date.now(), failed: true };
|
|
12234
|
+
}
|
|
12172
12235
|
writeCache2(cache);
|
|
12173
12236
|
}).catch(() => {
|
|
12174
12237
|
});
|
|
12175
12238
|
}
|
|
12176
12239
|
function checkForUpdates(packageName, currentVersion) {
|
|
12240
|
+
if (process.env.OKX_UPDATE_CHECK === "false") return;
|
|
12177
12241
|
const cache = readCache2();
|
|
12178
12242
|
const entry = cache[packageName];
|
|
12179
|
-
if (entry && isNewerVersion(currentVersion, entry.latestVersion)) {
|
|
12243
|
+
if (entry && entry.latestVersion && isNewerVersion(currentVersion, entry.latestVersion)) {
|
|
12180
12244
|
process.stderr.write(
|
|
12181
12245
|
`
|
|
12182
|
-
Update available for ${packageName}: ${currentVersion}
|
|
12246
|
+
Update available for ${packageName}: ${currentVersion} -> ${entry.latestVersion}
|
|
12183
12247
|
Run: npm install -g ${packageName}
|
|
12184
12248
|
|
|
12185
12249
|
`
|
|
12186
12250
|
);
|
|
12187
12251
|
}
|
|
12188
|
-
|
|
12252
|
+
const ttl = entry?.failed ? NEGATIVE_CHECK_INTERVAL_MS : CHECK_INTERVAL_MS;
|
|
12253
|
+
if (!entry || Date.now() - entry.checkedAt > ttl) {
|
|
12189
12254
|
refreshCacheInBackground(packageName);
|
|
12190
12255
|
}
|
|
12191
12256
|
}
|
|
@@ -12370,7 +12435,7 @@ function mergeJsonConfig(configPath, serverName, entry) {
|
|
|
12370
12435
|
}
|
|
12371
12436
|
const backupPath = configPath + ".bak";
|
|
12372
12437
|
fs3.copyFileSync(configPath, backupPath);
|
|
12373
|
-
process.stdout.write(` Backup
|
|
12438
|
+
process.stdout.write(` Backup -> ${backupPath}
|
|
12374
12439
|
`);
|
|
12375
12440
|
}
|
|
12376
12441
|
if (typeof data.mcpServers !== "object" || data.mcpServers === null) {
|
|
@@ -12441,7 +12506,7 @@ function validateRedirect(res, requestUrl, redirectCount, maxRedirects) {
|
|
|
12441
12506
|
}
|
|
12442
12507
|
const location = res.headers.location;
|
|
12443
12508
|
if (requestUrl.startsWith("https") && !location.startsWith("https")) {
|
|
12444
|
-
throw new Error("Refused HTTPS
|
|
12509
|
+
throw new Error("Refused HTTPS -> HTTP redirect downgrade");
|
|
12445
12510
|
}
|
|
12446
12511
|
return location;
|
|
12447
12512
|
}
|
|
@@ -13039,10 +13104,10 @@ async function cmdAuthLogin(args) {
|
|
|
13039
13104
|
status: "skipped",
|
|
13040
13105
|
reason: "api_key_configured",
|
|
13041
13106
|
profile: apiKeyProfile,
|
|
13042
|
-
message: `API key already configured (profile: ${apiKeyProfile}). OAuth login skipped
|
|
13107
|
+
message: `API key already configured (profile: ${apiKeyProfile}). OAuth login skipped - API key will be used automatically.`
|
|
13043
13108
|
}));
|
|
13044
13109
|
} else {
|
|
13045
|
-
outputLine(`API key already configured (profile: ${apiKeyProfile}). OAuth login skipped
|
|
13110
|
+
outputLine(`API key already configured (profile: ${apiKeyProfile}). OAuth login skipped - API key will be used automatically.`);
|
|
13046
13111
|
}
|
|
13047
13112
|
return;
|
|
13048
13113
|
}
|
|
@@ -13561,7 +13626,7 @@ function checkToolCount(report, configuredClients, getSpecs = allToolSpecs) {
|
|
|
13561
13626
|
if (totalCount > limits.total) {
|
|
13562
13627
|
warn(
|
|
13563
13628
|
"tool count",
|
|
13564
|
-
`${totalCount} tools loaded
|
|
13629
|
+
`${totalCount} tools loaded - exceeds ${name} limit (${limits.total} total / ${limits.perServer} per server)`,
|
|
13565
13630
|
[
|
|
13566
13631
|
`Use --modules to reduce: okx-trade-mcp --modules ${defaultModulesArg} (${defaultCount} tools)`
|
|
13567
13632
|
]
|
|
@@ -13571,7 +13636,7 @@ function checkToolCount(report, configuredClients, getSpecs = allToolSpecs) {
|
|
|
13571
13636
|
} else if (totalCount > limits.perServer) {
|
|
13572
13637
|
warn(
|
|
13573
13638
|
"tool count",
|
|
13574
|
-
`${totalCount} tools loaded
|
|
13639
|
+
`${totalCount} tools loaded - exceeds ${name} per-server limit (${limits.perServer})`,
|
|
13575
13640
|
[
|
|
13576
13641
|
`Use --modules to reduce: okx-trade-mcp --modules ${defaultModulesArg} (${defaultCount} tools)`
|
|
13577
13642
|
]
|
|
@@ -13638,7 +13703,7 @@ function checkMcpLogs(report) {
|
|
|
13638
13703
|
} catch (_e) {
|
|
13639
13704
|
}
|
|
13640
13705
|
}
|
|
13641
|
-
ok("log file", "(not found
|
|
13706
|
+
ok("log file", "(not found - logs only appear after MCP server has been started)");
|
|
13642
13707
|
report.add("mcp_log", "not_found");
|
|
13643
13708
|
}
|
|
13644
13709
|
function parseHandshakeResponse(line) {
|
|
@@ -13714,7 +13779,7 @@ async function checkStdioHandshake(entryPath, report) {
|
|
|
13714
13779
|
const parsed = parseHandshakeResponse(line);
|
|
13715
13780
|
if (!parsed) continue;
|
|
13716
13781
|
if (parsed.ok) {
|
|
13717
|
-
ok("handshake", `OK
|
|
13782
|
+
ok("handshake", `OK - ${parsed.serverName} v${parsed.serverVer}`);
|
|
13718
13783
|
report.add("handshake", `OK ${parsed.serverName}@${parsed.serverVer}`);
|
|
13719
13784
|
} else {
|
|
13720
13785
|
fail("handshake", `JSON-RPC error: ${parsed.errMsg}`, [
|
|
@@ -13741,7 +13806,7 @@ async function checkStdioHandshake(entryPath, report) {
|
|
|
13741
13806
|
function checkModuleLoading(entryPath, report) {
|
|
13742
13807
|
section("Module Loading");
|
|
13743
13808
|
if (!entryPath) {
|
|
13744
|
-
ok("module load", "(skipped
|
|
13809
|
+
ok("module load", "(skipped - entry point not found)");
|
|
13745
13810
|
report.add("module_load", "skipped");
|
|
13746
13811
|
return true;
|
|
13747
13812
|
}
|
|
@@ -13784,7 +13849,7 @@ async function cmdDiagnoseMcp(options = {}) {
|
|
|
13784
13849
|
handshakePassed = await checkStdioHandshake(entryPath, report);
|
|
13785
13850
|
} else {
|
|
13786
13851
|
section("stdio Handshake");
|
|
13787
|
-
ok("handshake", "(skipped
|
|
13852
|
+
ok("handshake", "(skipped - entry point not available)");
|
|
13788
13853
|
report.add("handshake", "skipped");
|
|
13789
13854
|
handshakePassed = true;
|
|
13790
13855
|
}
|
|
@@ -13803,7 +13868,7 @@ async function cmdDiagnoseMcp(options = {}) {
|
|
|
13803
13868
|
|
|
13804
13869
|
// src/commands/diagnose.ts
|
|
13805
13870
|
var CLI_VERSION = readCliVersion();
|
|
13806
|
-
var GIT_HASH = true ? "
|
|
13871
|
+
var GIT_HASH = true ? "ce35abd7" : "dev";
|
|
13807
13872
|
function maskKey2(key) {
|
|
13808
13873
|
if (!key) return "(not set)";
|
|
13809
13874
|
if (key.length <= 8) return "****";
|
|
@@ -14060,13 +14125,13 @@ async function checkPilot(report) {
|
|
|
14060
14125
|
report.add("pilot_binary", `installed (${local.platform ?? "unknown"})`);
|
|
14061
14126
|
const cdnChecksum = await fetchCdnChecksum(void 0, 5e3);
|
|
14062
14127
|
if (!cdnChecksum) {
|
|
14063
|
-
warn("Pilot checksum", "CDN unreachable
|
|
14128
|
+
warn("Pilot checksum", "CDN unreachable - cannot verify");
|
|
14064
14129
|
report.add("pilot_checksum", "CDN unreachable");
|
|
14065
14130
|
} else if (cdnChecksum.sha256 === local.sha256) {
|
|
14066
14131
|
ok("Pilot checksum", `match (${cdnChecksum.source})`);
|
|
14067
14132
|
report.add("pilot_checksum", `match (${cdnChecksum.source})`);
|
|
14068
14133
|
} else {
|
|
14069
|
-
warn("Pilot checksum", "mismatch
|
|
14134
|
+
warn("Pilot checksum", "mismatch - update available", ["Run: okx pilot install"]);
|
|
14070
14135
|
report.add("pilot_checksum", "mismatch");
|
|
14071
14136
|
}
|
|
14072
14137
|
try {
|
|
@@ -14095,9 +14160,9 @@ function checkConfigFile(report) {
|
|
|
14095
14160
|
const msg = e instanceof Error ? e.message : String(e);
|
|
14096
14161
|
fail("Config parse", msg, [
|
|
14097
14162
|
`If passphrase contains special characters (# \\ " '), wrap in quotes:`,
|
|
14098
|
-
` Contains # \\ "
|
|
14099
|
-
` Contains '
|
|
14100
|
-
" Contains both
|
|
14163
|
+
` Contains # \\ " -> passphrase = 'value'`,
|
|
14164
|
+
` Contains ' -> passphrase = "value"`,
|
|
14165
|
+
" Contains both -> passphrase = '''value'''",
|
|
14101
14166
|
"Or re-run: okx config init"
|
|
14102
14167
|
]);
|
|
14103
14168
|
report.add("config_parse", `FAIL ${msg}`);
|
|
@@ -14196,13 +14261,13 @@ function printResult(result, json) {
|
|
|
14196
14261
|
break;
|
|
14197
14262
|
case "update-available":
|
|
14198
14263
|
process.stderr.write(
|
|
14199
|
-
`[info] Update available: ${result.currentVersion}
|
|
14264
|
+
`[info] Update available: ${result.currentVersion} -> ${result.latestVersion}
|
|
14200
14265
|
Run: okx upgrade
|
|
14201
14266
|
`
|
|
14202
14267
|
);
|
|
14203
14268
|
break;
|
|
14204
14269
|
case "updated":
|
|
14205
|
-
process.stderr.write(`[ok] Upgraded: ${result.currentVersion}
|
|
14270
|
+
process.stderr.write(`[ok] Upgraded: ${result.currentVersion} -> ${result.latestVersion}
|
|
14206
14271
|
`);
|
|
14207
14272
|
break;
|
|
14208
14273
|
case "error":
|
|
@@ -14606,7 +14671,7 @@ var CLI_REGISTRY = {
|
|
|
14606
14671
|
leverage: {
|
|
14607
14672
|
toolName: "swap_set_leverage",
|
|
14608
14673
|
usage: "okx swap leverage --instId <id> --lever <positive-number> --mgnMode <cross|isolated> [--posSide <long|short>]",
|
|
14609
|
-
description: "Set leverage for a swap instrument. posSide is REQUIRED when mgnMode=isolated and account is in hedge mode
|
|
14674
|
+
description: "Set leverage for a swap instrument. posSide is REQUIRED when mgnMode=isolated and account is in hedge mode - must be set for BOTH long and short separately. Not supported for portfolio margin + cross."
|
|
14610
14675
|
},
|
|
14611
14676
|
"get-leverage": {
|
|
14612
14677
|
toolName: "swap_get_leverage",
|
|
@@ -14705,7 +14770,7 @@ var CLI_REGISTRY = {
|
|
|
14705
14770
|
leverage: {
|
|
14706
14771
|
toolName: "futures_set_leverage",
|
|
14707
14772
|
usage: "okx futures leverage --instId <id> --lever <positive-number> --mgnMode <cross|isolated> [--posSide <long|short>]",
|
|
14708
|
-
description: "Set leverage for a futures instrument. posSide is REQUIRED when mgnMode=isolated and account is in hedge mode
|
|
14773
|
+
description: "Set leverage for a futures instrument. posSide is REQUIRED when mgnMode=isolated and account is in hedge mode - must be set for BOTH long and short separately. Not supported for portfolio margin + cross."
|
|
14709
14774
|
},
|
|
14710
14775
|
batch: {
|
|
14711
14776
|
toolName: "futures_batch_orders",
|
|
@@ -14832,10 +14897,10 @@ var CLI_REGISTRY = {
|
|
|
14832
14897
|
},
|
|
14833
14898
|
// ── earn ───────────────────────────────────────────────────────────────────
|
|
14834
14899
|
earn: {
|
|
14835
|
-
description: "Earn products
|
|
14900
|
+
description: "Earn products - Simple Earn, On-chain Earn, DCD, Flash Earn, and Auto-Earn",
|
|
14836
14901
|
subgroups: {
|
|
14837
14902
|
savings: {
|
|
14838
|
-
description: "Simple Earn
|
|
14903
|
+
description: "Simple Earn - flexible savings, fixed-term, and lending",
|
|
14839
14904
|
commands: {
|
|
14840
14905
|
balance: {
|
|
14841
14906
|
toolName: "earn_get_savings_balance",
|
|
@@ -14885,7 +14950,7 @@ var CLI_REGISTRY = {
|
|
|
14885
14950
|
}
|
|
14886
14951
|
},
|
|
14887
14952
|
onchain: {
|
|
14888
|
-
description: "On-chain Earn
|
|
14953
|
+
description: "On-chain Earn - staking and DeFi products",
|
|
14889
14954
|
commands: {
|
|
14890
14955
|
offers: {
|
|
14891
14956
|
toolName: "onchain_earn_get_offers",
|
|
@@ -14920,7 +14985,7 @@ var CLI_REGISTRY = {
|
|
|
14920
14985
|
}
|
|
14921
14986
|
},
|
|
14922
14987
|
"auto-earn": {
|
|
14923
|
-
description: "Auto-earn
|
|
14988
|
+
description: "Auto-earn - automatically lend, stake, or earn on idle assets",
|
|
14924
14989
|
commands: {
|
|
14925
14990
|
status: {
|
|
14926
14991
|
// CLI reads from account_get_balance; earn_auto_set is covered by 'on' command below
|
|
@@ -14942,7 +15007,7 @@ var CLI_REGISTRY = {
|
|
|
14942
15007
|
}
|
|
14943
15008
|
},
|
|
14944
15009
|
"flash-earn": {
|
|
14945
|
-
description: "Flash Earn
|
|
15010
|
+
description: "Flash Earn - browse short-window earn projects by status",
|
|
14946
15011
|
commands: {
|
|
14947
15012
|
projects: {
|
|
14948
15013
|
toolName: "earn_get_flash_earn_projects",
|
|
@@ -14952,7 +15017,7 @@ var CLI_REGISTRY = {
|
|
|
14952
15017
|
}
|
|
14953
15018
|
},
|
|
14954
15019
|
dcd: {
|
|
14955
|
-
description: "DCD (Dual Currency Deposit)
|
|
15020
|
+
description: "DCD (Dual Currency Deposit) - structured products with fixed yield",
|
|
14956
15021
|
commands: {
|
|
14957
15022
|
pairs: {
|
|
14958
15023
|
toolName: "dcd_get_currency_pairs",
|
|
@@ -14993,7 +15058,7 @@ var CLI_REGISTRY = {
|
|
|
14993
15058
|
description: "Trading bot strategies (grid, dca)",
|
|
14994
15059
|
subgroups: {
|
|
14995
15060
|
grid: {
|
|
14996
|
-
description: "Grid trading bot
|
|
15061
|
+
description: "Grid trading bot - create, monitor, and stop grid orders",
|
|
14997
15062
|
commands: {
|
|
14998
15063
|
orders: {
|
|
14999
15064
|
toolName: "grid_get_orders",
|
|
@@ -15028,7 +15093,7 @@ var CLI_REGISTRY = {
|
|
|
15028
15093
|
}
|
|
15029
15094
|
},
|
|
15030
15095
|
dca: {
|
|
15031
|
-
description: "DCA (Martingale) bot
|
|
15096
|
+
description: "DCA (Martingale) bot - spot or contract recurring buys",
|
|
15032
15097
|
commands: {
|
|
15033
15098
|
orders: {
|
|
15034
15099
|
toolName: "dca_get_orders",
|
|
@@ -15061,7 +15126,7 @@ var CLI_REGISTRY = {
|
|
|
15061
15126
|
},
|
|
15062
15127
|
// ── event ──────────────────────────────────────────────────────────────────
|
|
15063
15128
|
event: {
|
|
15064
|
-
description: "Event contracts
|
|
15129
|
+
description: "Event contracts - binary prediction markets (YES/NO, UP/DOWN)",
|
|
15065
15130
|
commands: {
|
|
15066
15131
|
browse: {
|
|
15067
15132
|
toolName: "event_browse",
|
|
@@ -15112,7 +15177,7 @@ var CLI_REGISTRY = {
|
|
|
15112
15177
|
},
|
|
15113
15178
|
// ── smartmoney ─────────────────────────────────────────────────────────────
|
|
15114
15179
|
smartmoney: {
|
|
15115
|
-
description: "Smart money analytics
|
|
15180
|
+
description: "Smart money analytics - trader leaderboard, consensus signals, and position analysis",
|
|
15116
15181
|
commands: {
|
|
15117
15182
|
"traders-by-filter": {
|
|
15118
15183
|
toolName: "smartmoney_get_traders_by_filter",
|
|
@@ -15284,7 +15349,7 @@ var CLI_REGISTRY = {
|
|
|
15284
15349
|
},
|
|
15285
15350
|
// ── skill ──────────────────────────────────────────────────────────────────
|
|
15286
15351
|
skill: {
|
|
15287
|
-
description: "OKX Skills Marketplace
|
|
15352
|
+
description: "OKX Skills Marketplace - search, install, and manage agent skills",
|
|
15288
15353
|
commands: {
|
|
15289
15354
|
search: {
|
|
15290
15355
|
toolName: "skills_search",
|
|
@@ -15450,7 +15515,7 @@ function cmdListTools(json) {
|
|
|
15450
15515
|
}
|
|
15451
15516
|
const lines = [
|
|
15452
15517
|
"",
|
|
15453
|
-
`OKX CLI v${data.version}
|
|
15518
|
+
`OKX CLI v${data.version} - ${data.totalTools} tool-backed commands across ${data.modules.length} modules`,
|
|
15454
15519
|
"",
|
|
15455
15520
|
"Modules:"
|
|
15456
15521
|
];
|
|
@@ -16046,12 +16111,12 @@ var CLI_OPTIONS = {
|
|
|
16046
16111
|
instCcyList: { type: "string" },
|
|
16047
16112
|
topInstruments: { type: "string" },
|
|
16048
16113
|
asOfTime: { type: "string" },
|
|
16049
|
-
// smartmoney pool filters
|
|
16114
|
+
// smartmoney pool filters - leaderboard (numeric thresholds)
|
|
16050
16115
|
minPnl: { type: "string" },
|
|
16051
16116
|
minWinRate: { type: "string" },
|
|
16052
16117
|
maxDrawdown: { type: "string" },
|
|
16053
16118
|
minAum: { type: "string" },
|
|
16054
|
-
// smartmoney pool filters
|
|
16119
|
+
// smartmoney pool filters - signal endpoints (enum tiers)
|
|
16055
16120
|
pnlTier: { type: "string" },
|
|
16056
16121
|
winRateTier: { type: "string" },
|
|
16057
16122
|
maxDrawdownTier: { type: "string" },
|
|
@@ -16134,7 +16199,7 @@ var CLI_OPTIONS = {
|
|
|
16134
16199
|
settleCcy: { type: "string" },
|
|
16135
16200
|
ts: { type: "string" },
|
|
16136
16201
|
minAbsOiDeltaPct: { type: "string" },
|
|
16137
|
-
// diagnostics
|
|
16202
|
+
// diagnostics - cli/mcp/all/output are diagnose-specific; verbose is shared
|
|
16138
16203
|
verbose: { type: "boolean", default: false },
|
|
16139
16204
|
mcp: { type: "boolean", default: false },
|
|
16140
16205
|
// diagnose --mcp only: MCP server checks
|
|
@@ -16474,7 +16539,7 @@ async function cmdMarketInstrumentsByCategory(run, opts) {
|
|
|
16474
16539
|
"7": "Bonds"
|
|
16475
16540
|
};
|
|
16476
16541
|
const label = CATEGORY_LABELS[opts.instCategory] ?? opts.instCategory;
|
|
16477
|
-
process.stdout.write(`instCategory=${opts.instCategory} (${label})
|
|
16542
|
+
process.stdout.write(`instCategory=${opts.instCategory} (${label}) - ${items?.length ?? 0} instruments
|
|
16478
16543
|
|
|
16479
16544
|
`);
|
|
16480
16545
|
printTable(
|
|
@@ -18113,7 +18178,7 @@ import { createInterface } from "readline";
|
|
|
18113
18178
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
18114
18179
|
var messages = {
|
|
18115
18180
|
en: {
|
|
18116
|
-
title: "OKX Trade CLI
|
|
18181
|
+
title: "OKX Trade CLI - Configuration Wizard",
|
|
18117
18182
|
selectSite: "Select site:",
|
|
18118
18183
|
sitePrompt: "Site (1/2/3, default: 1): ",
|
|
18119
18184
|
demoPrompt: "Use demo trading? (Y/n) ",
|
|
@@ -18147,7 +18212,7 @@ Config saved to ${p}
|
|
|
18147
18212
|
`
|
|
18148
18213
|
},
|
|
18149
18214
|
zh: {
|
|
18150
|
-
title: "OKX Trade CLI
|
|
18215
|
+
title: "OKX Trade CLI - \u914D\u7F6E\u5411\u5BFC",
|
|
18151
18216
|
selectSite: "\u8BF7\u9009\u62E9\u7AD9\u70B9:",
|
|
18152
18217
|
sitePrompt: "\u7AD9\u70B9 (1/2/3, \u9ED8\u8BA4: 1): ",
|
|
18153
18218
|
demoPrompt: "\u4F7F\u7528\u6A21\u62DF\u76D8\uFF1F(Y/n) ",
|
|
@@ -18494,7 +18559,7 @@ async function cmdEarnSetLendingRate(run, opts) {
|
|
|
18494
18559
|
return;
|
|
18495
18560
|
}
|
|
18496
18561
|
const r = data[0];
|
|
18497
|
-
outputLine(`Lending rate set: ${r?.["ccy"]}
|
|
18562
|
+
outputLine(`Lending rate set: ${r?.["ccy"]} -> ${r?.["rate"]}`);
|
|
18498
18563
|
}
|
|
18499
18564
|
async function cmdEarnLendingHistory(run, opts) {
|
|
18500
18565
|
const data = extractData(await run("earn_get_lending_history", { ccy: opts.ccy, limit: opts.limit }));
|
|
@@ -18629,7 +18694,7 @@ function printPaginationHint(result) {
|
|
|
18629
18694
|
const { hasMore, nextAfter } = pagination;
|
|
18630
18695
|
if (hasMore !== true) return;
|
|
18631
18696
|
const cursor = typeof nextAfter === "string" || typeof nextAfter === "number" ? String(nextAfter) : "";
|
|
18632
|
-
errorLine(cursor ? `more results
|
|
18697
|
+
errorLine(cursor ? `more results - pass --after ${cursor} for next page` : "more results - pass --after <cursor> for next page");
|
|
18633
18698
|
}
|
|
18634
18699
|
function signalPoolFilterArgs(o) {
|
|
18635
18700
|
const result = {};
|
|
@@ -19444,8 +19509,8 @@ async function cmdDcdProducts(run, opts) {
|
|
|
19444
19509
|
quoteCcy: r["quoteCcy"],
|
|
19445
19510
|
optType: r["optType"],
|
|
19446
19511
|
strike: r["strike"],
|
|
19447
|
-
// products endpoint returns decimal (e.g. 0.3423 = 34.23%)
|
|
19448
|
-
annualizedYield: r["annualizedYield"] ? `${(parseFloat(r["annualizedYield"]) * 100).toFixed(2)}%` : "
|
|
19512
|
+
// products endpoint returns decimal (e.g. 0.3423 = 34.23%) - multiply by 100
|
|
19513
|
+
annualizedYield: r["annualizedYield"] ? `${(parseFloat(r["annualizedYield"]) * 100).toFixed(2)}%` : "-",
|
|
19449
19514
|
minSize: r["minSize"],
|
|
19450
19515
|
expTime: r["expTime"] ? new Date(Number(r["expTime"])).toLocaleDateString() : ""
|
|
19451
19516
|
})));
|
|
@@ -19475,8 +19540,8 @@ async function cmdDcdRedeemExecute(run, opts) {
|
|
|
19475
19540
|
printKv({
|
|
19476
19541
|
ordId: r["ordId"],
|
|
19477
19542
|
state: r["state"],
|
|
19478
|
-
redeemSz: q["redeemSz"] ? `${parseFloat(q["redeemSz"]).toFixed(8)} ${q["redeemCcy"]}` : "
|
|
19479
|
-
termRate: q["termRate"] ? `${(parseFloat(q["termRate"]) * 100).toFixed(2)}%` : "
|
|
19543
|
+
redeemSz: q["redeemSz"] ? `${parseFloat(q["redeemSz"]).toFixed(8)} ${q["redeemCcy"]}` : "-",
|
|
19544
|
+
termRate: q["termRate"] ? `${(parseFloat(q["termRate"]) * 100).toFixed(2)}%` : "-"
|
|
19480
19545
|
});
|
|
19481
19546
|
}
|
|
19482
19547
|
async function cmdDcdOrderState(run, opts) {
|
|
@@ -19529,7 +19594,7 @@ async function cmdDcdOrders(run, opts) {
|
|
|
19529
19594
|
quoteCcy: r["quoteCcy"],
|
|
19530
19595
|
strike: r["strike"],
|
|
19531
19596
|
notionalSz: r["notionalSz"],
|
|
19532
|
-
annualizedYield: r["annualizedYield"] ? `${(parseFloat(r["annualizedYield"]) * 100).toFixed(2)}%` : "
|
|
19597
|
+
annualizedYield: r["annualizedYield"] ? `${(parseFloat(r["annualizedYield"]) * 100).toFixed(2)}%` : "-",
|
|
19533
19598
|
yieldSz: r["yieldSz"],
|
|
19534
19599
|
settleTime: r["settleTime"] ? new Date(Number(r["settleTime"])).toLocaleDateString() : "",
|
|
19535
19600
|
// scheduled settlement time
|
|
@@ -19569,7 +19634,7 @@ async function cmdDcdQuoteAndBuy(run, opts) {
|
|
|
19569
19634
|
outputLine("Quote:");
|
|
19570
19635
|
printKv({
|
|
19571
19636
|
quoteId: q["quoteId"],
|
|
19572
|
-
annualizedYield: q["annualizedYield"] ? `${(parseFloat(q["annualizedYield"]) * 100).toFixed(2)}%` : "
|
|
19637
|
+
annualizedYield: q["annualizedYield"] ? `${(parseFloat(q["annualizedYield"]) * 100).toFixed(2)}%` : "-",
|
|
19573
19638
|
absYield: q["absYield"],
|
|
19574
19639
|
notionalSz: q["notionalSz"],
|
|
19575
19640
|
notionalCcy: q["notionalCcy"]
|
|
@@ -19744,9 +19809,9 @@ async function cmdSkillCheck(run, name, json) {
|
|
|
19744
19809
|
upToDate
|
|
19745
19810
|
}, null, 2));
|
|
19746
19811
|
} else if (upToDate) {
|
|
19747
|
-
outputLine(`${name}: installed v${local.version}
|
|
19812
|
+
outputLine(`${name}: installed v${local.version} -> latest v${remote.latestVersion} (up to date)`);
|
|
19748
19813
|
} else {
|
|
19749
|
-
outputLine(`${name}: installed v${local.version}
|
|
19814
|
+
outputLine(`${name}: installed v${local.version} -> latest v${remote.latestVersion} (update available)`);
|
|
19750
19815
|
outputLine(` Use \`okx skill add ${name}\` to update.`);
|
|
19751
19816
|
}
|
|
19752
19817
|
}
|
|
@@ -20023,9 +20088,9 @@ async function cmdEventBrowse(run, opts) {
|
|
|
20023
20088
|
contracts.map((c) => ({
|
|
20024
20089
|
"Contract": formatDisplayTitle(String(c["instId"] ?? "")),
|
|
20025
20090
|
"Expiry": c["expTime"] ?? "",
|
|
20026
|
-
"Target Price": c["floorStrike"] ? String(c["floorStrike"]) : "
|
|
20091
|
+
"Target Price": c["floorStrike"] ? String(c["floorStrike"]) : "-",
|
|
20027
20092
|
"Probability": fmtProbability(c["px"]),
|
|
20028
|
-
"Outcome": fmtOutcome(c["outcome"]) || "
|
|
20093
|
+
"Outcome": fmtOutcome(c["outcome"]) || "-",
|
|
20029
20094
|
"instId": c["instId"]
|
|
20030
20095
|
}))
|
|
20031
20096
|
);
|
|
@@ -20162,7 +20227,7 @@ async function cmdEventMarkets(run, opts) {
|
|
|
20162
20227
|
expTime: m["expTime"] ?? "",
|
|
20163
20228
|
targetPrice: m["floorStrike"] ?? "",
|
|
20164
20229
|
probability: fmtProbability(m["px"]),
|
|
20165
|
-
outcome: outcome.toLowerCase() === "pending" ? "
|
|
20230
|
+
outcome: outcome.toLowerCase() === "pending" ? "-" : outcome,
|
|
20166
20231
|
settleValue: m["settleValue"] ?? "",
|
|
20167
20232
|
instId: id
|
|
20168
20233
|
};
|
|
@@ -20215,7 +20280,7 @@ async function cmdEventFills(run, opts) {
|
|
|
20215
20280
|
const side = String(f["side"] ?? "").toUpperCase();
|
|
20216
20281
|
const outcome = fmtOrderOutcome(f["instId"], f["outcome"]).toUpperCase();
|
|
20217
20282
|
const dir = `${side} ${outcome}`.trim();
|
|
20218
|
-
return dir || "
|
|
20283
|
+
return dir || "-";
|
|
20219
20284
|
})(),
|
|
20220
20285
|
"Fill Price": f["fillPx"],
|
|
20221
20286
|
"Fill Size": f["fillSz"],
|
|
@@ -20317,7 +20382,7 @@ async function cmdEventPlace(run, opts) {
|
|
|
20317
20382
|
const data = getData9(result);
|
|
20318
20383
|
if (opts.json) return printJson(data);
|
|
20319
20384
|
const order = data?.[0];
|
|
20320
|
-
const stateHint = ordType === "market" ? "market order
|
|
20385
|
+
const stateHint = ordType === "market" ? "market order - typically fills immediately" : `${ordType} order - may still be live; verify with: okx event orders --instId ${opts.instId} --state live`;
|
|
20321
20386
|
const period = fmtPeriodFromInstId(opts.instId);
|
|
20322
20387
|
const pxPart = opts.px ? ` px: ${opts.px}` : "";
|
|
20323
20388
|
process.stdout.write(
|
|
@@ -20363,7 +20428,7 @@ function handleCancelCatchError(instId, ordId, err) {
|
|
|
20363
20428
|
if (isExpired) {
|
|
20364
20429
|
process.stdout.write(
|
|
20365
20430
|
`Cannot cancel: contract ${instId} has already expired.
|
|
20366
|
-
The order was auto-cancelled at settlement
|
|
20431
|
+
The order was auto-cancelled at settlement - no action needed.
|
|
20367
20432
|
`
|
|
20368
20433
|
);
|
|
20369
20434
|
} else {
|
|
@@ -20392,7 +20457,7 @@ async function cmdEventCancel(run, opts) {
|
|
|
20392
20457
|
// src/index.ts
|
|
20393
20458
|
var _require3 = createRequire3(import.meta.url);
|
|
20394
20459
|
var CLI_VERSION2 = _require3("../package.json").version;
|
|
20395
|
-
var GIT_HASH2 = true ? "
|
|
20460
|
+
var GIT_HASH2 = true ? "ce35abd7" : "dev";
|
|
20396
20461
|
function handlePilotCommand(action, json, force, binaryPath) {
|
|
20397
20462
|
if (action === "status") return cmdPilotStatus(json, binaryPath);
|
|
20398
20463
|
if (action === "install") return cmdPilotInstall(json, binaryPath);
|
|
@@ -20704,7 +20769,7 @@ function assertNoTpConflict(tpLevel, singleFields) {
|
|
|
20704
20769
|
if (conflicting.length > 0) {
|
|
20705
20770
|
const flagNames = conflicting.map((k) => `--${k}`).join(", ");
|
|
20706
20771
|
throw new Error(
|
|
20707
|
-
`Cannot use --tpLevel together with ${flagNames}. Use --tpLevel for split multi-tier take-profit, or single-TP flags for a single TP
|
|
20772
|
+
`Cannot use --tpLevel together with ${flagNames}. Use --tpLevel for split multi-tier take-profit, or single-TP flags for a single TP - not both.`
|
|
20708
20773
|
);
|
|
20709
20774
|
}
|
|
20710
20775
|
}
|
|
@@ -21501,7 +21566,7 @@ function handleSmartmoneyCommand(run, action, rest, v, json) {
|
|
|
21501
21566
|
if (action === "signal-overview-by-filter") {
|
|
21502
21567
|
if (v.topInstruments && v.instCcyList) {
|
|
21503
21568
|
errorLine(
|
|
21504
|
-
"--topInstruments and --instCcyList are mutually exclusive. Pass exactly one
|
|
21569
|
+
"--topInstruments and --instCcyList are mutually exclusive. Pass exactly one - `--topInstruments` for top-N hottest coins, or `--instCcyList` for specific coins."
|
|
21505
21570
|
);
|
|
21506
21571
|
process.exitCode = 1;
|
|
21507
21572
|
return;
|
|
@@ -21522,7 +21587,7 @@ function handleSmartmoneyCommand(run, action, rest, v, json) {
|
|
|
21522
21587
|
}
|
|
21523
21588
|
if (v.topInstruments && v.instCcyList) {
|
|
21524
21589
|
errorLine(
|
|
21525
|
-
"--topInstruments and --instCcyList are mutually exclusive. Pass exactly one
|
|
21590
|
+
"--topInstruments and --instCcyList are mutually exclusive. Pass exactly one - `--topInstruments` for top-N hottest coins, or `--instCcyList` for specific coins."
|
|
21526
21591
|
);
|
|
21527
21592
|
process.exitCode = 1;
|
|
21528
21593
|
return;
|