@okx_ai/okx-trade-mcp 1.3.4-beta.2 → 1.3.5
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 +233 -162
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -988,8 +988,8 @@ var PilotManager = class {
|
|
|
988
988
|
* Apply a Pilot node: set up the custom Agent + base URL.
|
|
989
989
|
*
|
|
990
990
|
* node.ip may be a real IP or a domain (CNAME like *.aliyunddos1021.com).
|
|
991
|
-
* - Real IP
|
|
992
|
-
* - Domain
|
|
991
|
+
* - Real IP -> use directly in lookup callback
|
|
992
|
+
* - Domain -> dns.lookup on every connection to get a fresh IP
|
|
993
993
|
*/
|
|
994
994
|
applyNode(node, protocol) {
|
|
995
995
|
this.pilotNode = node;
|
|
@@ -1339,29 +1339,29 @@ var RateLimiter = class {
|
|
|
1339
1339
|
}
|
|
1340
1340
|
};
|
|
1341
1341
|
var OKX_CODE_BEHAVIORS = {
|
|
1342
|
-
// Rate limit
|
|
1342
|
+
// Rate limit -> throw RateLimitError
|
|
1343
1343
|
"50011": { retry: true, suggestion: "Rate limited. Back off and retry after a delay." },
|
|
1344
1344
|
"50061": { retry: true, suggestion: "Too many connections. Reduce request frequency and retry." },
|
|
1345
|
-
// Server temporarily unavailable
|
|
1345
|
+
// Server temporarily unavailable -> retryable
|
|
1346
1346
|
"50001": { retry: true, suggestion: "Service temporarily unavailable. Retry in a few minutes." },
|
|
1347
1347
|
"50004": { retry: true, suggestion: "Endpoint request timeout. Retry later." },
|
|
1348
1348
|
"50013": { retry: true, suggestion: "System busy. Retry after 1-2 seconds." },
|
|
1349
1349
|
"50026": { retry: true, suggestion: "System error. Retry in a few minutes." },
|
|
1350
|
-
// Region / compliance restriction
|
|
1350
|
+
// Region / compliance restriction -> do not retry
|
|
1351
1351
|
"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." },
|
|
1352
1352
|
"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." },
|
|
1353
|
-
// Account issues
|
|
1353
|
+
// Account issues -> do not retry
|
|
1354
1354
|
"50007": { retry: false, suggestion: "Account suspended. Contact OKX support. Do not retry." },
|
|
1355
1355
|
"50009": { retry: false, suggestion: "Account blocked by risk control. Contact OKX support. Do not retry." },
|
|
1356
1356
|
"51009": { retry: false, suggestion: "Account mode not supported for this operation. Check account settings." },
|
|
1357
|
-
// API key permission / expiry
|
|
1357
|
+
// API key permission / expiry -> do not retry
|
|
1358
1358
|
"50100": { retry: false, suggestion: "API key lacks required permissions. Update API key permissions." },
|
|
1359
1359
|
"50110": { retry: false, suggestion: "API key expired. Generate a new API key." },
|
|
1360
|
-
// Insufficient funds / margin
|
|
1361
|
-
"51008": { retry: false, suggestion: "Insufficient balance in trading account. Check funding account via account_get_asset_balance
|
|
1360
|
+
// Insufficient funds / margin -> do not retry
|
|
1361
|
+
"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." },
|
|
1362
1362
|
"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." },
|
|
1363
1363
|
"51127": { retry: false, suggestion: "Insufficient available margin. Reduce position, add margin, or transfer from funding account (account_transfer from=18 to=6)." },
|
|
1364
|
-
// Instrument unavailable
|
|
1364
|
+
// Instrument unavailable -> do not retry
|
|
1365
1365
|
"51021": { retry: false, suggestion: "Instrument does not exist. Check instId." },
|
|
1366
1366
|
"51022": { retry: false, suggestion: "Instrument not available for trading." },
|
|
1367
1367
|
"51027": { retry: false, suggestion: "Contract has expired." }
|
|
@@ -1445,11 +1445,11 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1445
1445
|
}
|
|
1446
1446
|
}
|
|
1447
1447
|
/**
|
|
1448
|
-
* Dynamic auth
|
|
1448
|
+
* Dynamic auth - determines auth method per request.
|
|
1449
1449
|
*
|
|
1450
|
-
* 1. API key in config
|
|
1451
|
-
* 2. OAuth token via okx-auth binary
|
|
1452
|
-
* 3. Neither
|
|
1450
|
+
* 1. API key in config -> HMAC signing (no OAuth fallback)
|
|
1451
|
+
* 2. OAuth token via okx-auth binary -> Bearer token
|
|
1452
|
+
* 3. Neither -> throw ConfigError
|
|
1453
1453
|
*/
|
|
1454
1454
|
async applyAuth(headers, method, requestPath, bodyJson, timestamp) {
|
|
1455
1455
|
if (this.config.apiKey && this.config.secretKey && this.config.passphrase) {
|
|
@@ -1603,7 +1603,7 @@ var OkxRestClient = class _OkxRestClient {
|
|
|
1603
1603
|
};
|
|
1604
1604
|
}
|
|
1605
1605
|
// ---------------------------------------------------------------------------
|
|
1606
|
-
// Binary (non-JSON) download
|
|
1606
|
+
// Binary (non-JSON) download - reuses auth, proxy, rate-limit, verbose
|
|
1607
1607
|
// ---------------------------------------------------------------------------
|
|
1608
1608
|
static DEFAULT_MAX_BYTES = 50 * 1024 * 1024;
|
|
1609
1609
|
// 50 MB
|
|
@@ -2215,7 +2215,7 @@ var INDICATOR_CODE_OVERRIDES = {
|
|
|
2215
2215
|
// default: NVI_PVI
|
|
2216
2216
|
"top-long-short": "TOPLONGSHORT"
|
|
2217
2217
|
// default: TOP_LONG_SHORT
|
|
2218
|
-
// Note: range-filter
|
|
2218
|
+
// Note: range-filter -> RANGE_FILTER is correct via the default rule; no override needed.
|
|
2219
2219
|
};
|
|
2220
2220
|
var KNOWN_INDICATORS = [
|
|
2221
2221
|
// Moving Averages
|
|
@@ -2516,7 +2516,7 @@ function registerAccountTools() {
|
|
|
2516
2516
|
},
|
|
2517
2517
|
type: {
|
|
2518
2518
|
type: "string",
|
|
2519
|
-
description: "0=main account (default), 1=main
|
|
2519
|
+
description: "0=main account (default), 1=main->sub, 2=sub->main, 3=sub->sub"
|
|
2520
2520
|
},
|
|
2521
2521
|
subAcct: {
|
|
2522
2522
|
type: "string",
|
|
@@ -3100,7 +3100,7 @@ function computeContracts(p) {
|
|
|
3100
3100
|
);
|
|
3101
3101
|
}
|
|
3102
3102
|
const contractsStr = contractsRounded.toFixed(lotSzDecimals);
|
|
3103
|
-
const conversionNote = isMarginMode ? `Converting ${sz} USDT margin (${leverStr}x leverage)
|
|
3103
|
+
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})`;
|
|
3104
3104
|
return { contractsStr, conversionNote };
|
|
3105
3105
|
}
|
|
3106
3106
|
async function resolveQuoteCcySz(instId, sz, tgtCcy, instType, client, tdMode) {
|
|
@@ -3148,7 +3148,7 @@ function registerAlgoTradeTools() {
|
|
|
3148
3148
|
{
|
|
3149
3149
|
name: "swap_place_algo_order",
|
|
3150
3150
|
module: "swap",
|
|
3151
|
-
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
|
|
3151
|
+
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.",
|
|
3152
3152
|
isWrite: true,
|
|
3153
3153
|
inputSchema: {
|
|
3154
3154
|
type: "object",
|
|
@@ -3508,7 +3508,7 @@ function registerFuturesAlgoTools() {
|
|
|
3508
3508
|
{
|
|
3509
3509
|
name: "futures_place_algo_order",
|
|
3510
3510
|
module: "futures",
|
|
3511
|
-
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
|
|
3511
|
+
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.",
|
|
3512
3512
|
isWrite: true,
|
|
3513
3513
|
inputSchema: {
|
|
3514
3514
|
type: "object",
|
|
@@ -3733,7 +3733,7 @@ function registerFuturesAlgoTools() {
|
|
|
3733
3733
|
{
|
|
3734
3734
|
name: "futures_amend_algo_order",
|
|
3735
3735
|
module: "futures",
|
|
3736
|
-
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
|
|
3736
|
+
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.",
|
|
3737
3737
|
isWrite: true,
|
|
3738
3738
|
inputSchema: {
|
|
3739
3739
|
type: "object",
|
|
@@ -4030,7 +4030,7 @@ function registerSkillsTools() {
|
|
|
4030
4030
|
{
|
|
4031
4031
|
name: "skills_get_categories",
|
|
4032
4032
|
module: "skills",
|
|
4033
|
-
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
|
|
4033
|
+
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.",
|
|
4034
4034
|
inputSchema: {
|
|
4035
4035
|
type: "object",
|
|
4036
4036
|
properties: {},
|
|
@@ -4042,7 +4042,7 @@ function registerSkillsTools() {
|
|
|
4042
4042
|
{
|
|
4043
4043
|
name: "skills_search",
|
|
4044
4044
|
module: "skills",
|
|
4045
|
-
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
|
|
4045
|
+
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.",
|
|
4046
4046
|
inputSchema: {
|
|
4047
4047
|
type: "object",
|
|
4048
4048
|
properties: {
|
|
@@ -4071,7 +4071,7 @@ function registerSkillsTools() {
|
|
|
4071
4071
|
{
|
|
4072
4072
|
name: "skills_download",
|
|
4073
4073
|
module: "skills",
|
|
4074
|
-
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
|
|
4074
|
+
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.",
|
|
4075
4075
|
inputSchema: {
|
|
4076
4076
|
type: "object",
|
|
4077
4077
|
properties: {
|
|
@@ -4352,7 +4352,7 @@ function registerGridTools() {
|
|
|
4352
4352
|
{
|
|
4353
4353
|
name: "grid_amend_order",
|
|
4354
4354
|
module: "bot.grid",
|
|
4355
|
-
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
|
|
4355
|
+
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.",
|
|
4356
4356
|
isWrite: true,
|
|
4357
4357
|
inputSchema: {
|
|
4358
4358
|
type: "object",
|
|
@@ -4430,7 +4430,7 @@ function registerGridTools() {
|
|
|
4430
4430
|
maxPx,
|
|
4431
4431
|
minPx: requireString(args, "minPx"),
|
|
4432
4432
|
gridNum: requireString(args, "gridNum"),
|
|
4433
|
-
// API field is "topupAmount" (lowercase u)
|
|
4433
|
+
// API field is "topupAmount" (lowercase u) - different from TP/SL mode's "topUpAmt"
|
|
4434
4434
|
// Contract grid only; omitting lets the API use the minimum required
|
|
4435
4435
|
topupAmount: readString(args, "topUpAmt")
|
|
4436
4436
|
}),
|
|
@@ -4451,7 +4451,7 @@ function registerGridTools() {
|
|
|
4451
4451
|
tpRatio: readString(args, "tpRatio"),
|
|
4452
4452
|
slRatio: readString(args, "slRatio"),
|
|
4453
4453
|
topUpAmt: readString(args, "topUpAmt")
|
|
4454
|
-
// API field is "topUpAmt" (uppercase U)
|
|
4454
|
+
// API field is "topUpAmt" (uppercase U) - different from price-range mode's "topupAmount"
|
|
4455
4455
|
}),
|
|
4456
4456
|
privateRateLimit("grid_amend_order", 20),
|
|
4457
4457
|
true
|
|
@@ -4475,7 +4475,7 @@ function registerGridTools() {
|
|
|
4475
4475
|
{
|
|
4476
4476
|
name: "grid_stop_order",
|
|
4477
4477
|
module: "bot.grid",
|
|
4478
|
-
description: "Stop a
|
|
4478
|
+
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.",
|
|
4479
4479
|
isWrite: true,
|
|
4480
4480
|
inputSchema: {
|
|
4481
4481
|
type: "object",
|
|
@@ -4490,7 +4490,7 @@ function registerGridTools() {
|
|
|
4490
4490
|
stopType: {
|
|
4491
4491
|
type: "string",
|
|
4492
4492
|
enum: ["1", "2"],
|
|
4493
|
-
description: "'1' (default): stop strategy and sell
|
|
4493
|
+
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."
|
|
4494
4494
|
}
|
|
4495
4495
|
},
|
|
4496
4496
|
required: ["algoId", "algoOrdType", "instId"]
|
|
@@ -4507,7 +4507,7 @@ function registerGridTools() {
|
|
|
4507
4507
|
})],
|
|
4508
4508
|
privateRateLimit("grid_stop_order", 20),
|
|
4509
4509
|
true
|
|
4510
|
-
// retryOnNetworkError: safe to retry
|
|
4510
|
+
// retryOnNetworkError: safe to retry - already-stopped returns an error but does not harm state
|
|
4511
4511
|
);
|
|
4512
4512
|
return normalizeWrite(response);
|
|
4513
4513
|
}
|
|
@@ -4653,7 +4653,7 @@ function registerDcaTools() {
|
|
|
4653
4653
|
{
|
|
4654
4654
|
name: "dca_stop_order",
|
|
4655
4655
|
module: "bot.dca",
|
|
4656
|
-
description: "Stop a
|
|
4656
|
+
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.",
|
|
4657
4657
|
isWrite: true,
|
|
4658
4658
|
inputSchema: {
|
|
4659
4659
|
type: "object",
|
|
@@ -4808,7 +4808,7 @@ function registerEarnTools() {
|
|
|
4808
4808
|
{
|
|
4809
4809
|
name: "earn_get_savings_balance",
|
|
4810
4810
|
module: "earn.savings",
|
|
4811
|
-
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
|
|
4811
|
+
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.",
|
|
4812
4812
|
isWrite: false,
|
|
4813
4813
|
inputSchema: {
|
|
4814
4814
|
type: "object",
|
|
@@ -4832,7 +4832,7 @@ function registerEarnTools() {
|
|
|
4832
4832
|
{
|
|
4833
4833
|
name: "earn_get_fixed_order_list",
|
|
4834
4834
|
module: "earn.savings",
|
|
4835
|
-
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
|
|
4835
|
+
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.",
|
|
4836
4836
|
isWrite: false,
|
|
4837
4837
|
inputSchema: {
|
|
4838
4838
|
type: "object",
|
|
@@ -4884,7 +4884,7 @@ function registerEarnTools() {
|
|
|
4884
4884
|
},
|
|
4885
4885
|
rate: {
|
|
4886
4886
|
type: "string",
|
|
4887
|
-
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
|
|
4887
|
+
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."
|
|
4888
4888
|
}
|
|
4889
4889
|
},
|
|
4890
4890
|
required: ["ccy", "amt"]
|
|
@@ -4951,7 +4951,7 @@ function registerEarnTools() {
|
|
|
4951
4951
|
},
|
|
4952
4952
|
rate: {
|
|
4953
4953
|
type: "string",
|
|
4954
|
-
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
|
|
4954
|
+
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."
|
|
4955
4955
|
}
|
|
4956
4956
|
},
|
|
4957
4957
|
required: ["ccy", "rate"]
|
|
@@ -5013,7 +5013,7 @@ function registerEarnTools() {
|
|
|
5013
5013
|
{
|
|
5014
5014
|
name: "earn_fixed_purchase",
|
|
5015
5015
|
module: "earn.savings",
|
|
5016
|
-
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
|
|
5016
|
+
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.",
|
|
5017
5017
|
isWrite: true,
|
|
5018
5018
|
inputSchema: {
|
|
5019
5019
|
type: "object",
|
|
@@ -5072,7 +5072,7 @@ function registerEarnTools() {
|
|
|
5072
5072
|
term,
|
|
5073
5073
|
offer: offerWithSoldOut,
|
|
5074
5074
|
currentFlexibleRate: rateArr[0]?.["lendingRate"] ?? null,
|
|
5075
|
-
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
|
|
5075
|
+
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."
|
|
5076
5076
|
};
|
|
5077
5077
|
}
|
|
5078
5078
|
assertNotDemo(context.config, "earn_fixed_purchase");
|
|
@@ -5087,7 +5087,7 @@ function registerEarnTools() {
|
|
|
5087
5087
|
{
|
|
5088
5088
|
name: "earn_fixed_redeem",
|
|
5089
5089
|
module: "earn.savings",
|
|
5090
|
-
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
|
|
5090
|
+
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.",
|
|
5091
5091
|
isWrite: true,
|
|
5092
5092
|
inputSchema: {
|
|
5093
5093
|
type: "object",
|
|
@@ -5115,7 +5115,7 @@ function registerEarnTools() {
|
|
|
5115
5115
|
{
|
|
5116
5116
|
name: "earn_get_lending_rate_history",
|
|
5117
5117
|
module: "earn.savings",
|
|
5118
|
-
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
|
|
5118
|
+
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.",
|
|
5119
5119
|
isWrite: false,
|
|
5120
5120
|
inputSchema: {
|
|
5121
5121
|
type: "object",
|
|
@@ -5448,7 +5448,7 @@ function registerOnchainEarnTools() {
|
|
|
5448
5448
|
}
|
|
5449
5449
|
var DCD_CODE_BEHAVIORS = {
|
|
5450
5450
|
"50001": { retry: true, suggestion: "Service temporarily unavailable. Retry in a few minutes." },
|
|
5451
|
-
"50002": { retry: false, suggestion: "Invalid JSON in request body. This is likely a bug
|
|
5451
|
+
"50002": { retry: false, suggestion: "Invalid JSON in request body. This is likely a bug - check request parameters." },
|
|
5452
5452
|
"50014": { retry: false, suggestion: "Missing required parameter. Check that all required fields are provided." },
|
|
5453
5453
|
"50016": { retry: false, suggestion: "notionalCcy does not match productId option type. Use baseCcy for CALL, quoteCcy for PUT." },
|
|
5454
5454
|
"50026": { retry: true, suggestion: "DCD system error. Retry in a few minutes." },
|
|
@@ -5823,7 +5823,7 @@ function registerFlashEarnTools() {
|
|
|
5823
5823
|
{
|
|
5824
5824
|
name: "earn_get_flash_earn_projects",
|
|
5825
5825
|
module: "earn.flash",
|
|
5826
|
-
description: "Get Flash Earn projects. Use this to browse upcoming or in-progress Flash Earn opportunities. Do NOT use for purchase or redeem actions
|
|
5826
|
+
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.",
|
|
5827
5827
|
isWrite: false,
|
|
5828
5828
|
inputSchema: {
|
|
5829
5829
|
type: "object",
|
|
@@ -6219,7 +6219,7 @@ function handlePlaceOrderError(base, rawArgs, endpoint) {
|
|
|
6219
6219
|
const seriesId = extractSeriesId(instId);
|
|
6220
6220
|
const expiryMs = inferExpiryMsFromInstId(instId);
|
|
6221
6221
|
const isExpired = expiryMs !== null && expiryMs < Date.now();
|
|
6222
|
-
const reason = isExpired ? `The contract (${instId}) has expired.` : `The contract (${instId}) was not found
|
|
6222
|
+
const reason = isExpired ? `The contract (${instId}) has expired.` : `The contract (${instId}) was not found - it may not exist or has not started yet.`;
|
|
6223
6223
|
throw new OkxApiError(
|
|
6224
6224
|
`${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.`,
|
|
6225
6225
|
{ code: sCode, endpoint }
|
|
@@ -6235,17 +6235,17 @@ var OUTCOME_SCHEMA = {
|
|
|
6235
6235
|
UP/DOWN direction contracts: UP (price rises during the period) or DOWN (price falls).
|
|
6236
6236
|
YES/NO price-target or touch contracts: YES (condition met) or NO (condition not met).
|
|
6237
6237
|
Check the series type from event_get_series to determine which applies.
|
|
6238
|
-
NOTE: px is the event contract price (0.01
|
|
6238
|
+
NOTE: px is the event contract price (0.01-0.99), NOT the underlying asset price. It reflects market-implied probability when actively trading.`
|
|
6239
6239
|
};
|
|
6240
6240
|
function registerEventContractTools() {
|
|
6241
6241
|
return [
|
|
6242
6242
|
// -----------------------------------------------------------------------
|
|
6243
|
-
// Read-only
|
|
6243
|
+
// Read-only - browse (user-facing) + series / events / markets (internal)
|
|
6244
6244
|
// -----------------------------------------------------------------------
|
|
6245
6245
|
{
|
|
6246
6246
|
name: "event_browse",
|
|
6247
6247
|
module: "event",
|
|
6248
|
-
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
|
|
6248
|
+
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.",
|
|
6249
6249
|
isWrite: false,
|
|
6250
6250
|
inputSchema: {
|
|
6251
6251
|
type: "object",
|
|
@@ -6364,7 +6364,7 @@ function registerEventContractTools() {
|
|
|
6364
6364
|
{
|
|
6365
6365
|
name: "event_get_markets",
|
|
6366
6366
|
module: "event",
|
|
6367
|
-
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
|
|
6367
|
+
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.",
|
|
6368
6368
|
isWrite: false,
|
|
6369
6369
|
inputSchema: {
|
|
6370
6370
|
type: "object",
|
|
@@ -6445,7 +6445,7 @@ function registerEventContractTools() {
|
|
|
6445
6445
|
{
|
|
6446
6446
|
name: "event_get_orders",
|
|
6447
6447
|
module: "event",
|
|
6448
|
-
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
|
|
6448
|
+
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.",
|
|
6449
6449
|
isWrite: false,
|
|
6450
6450
|
inputSchema: {
|
|
6451
6451
|
type: "object",
|
|
@@ -6503,7 +6503,7 @@ function registerEventContractTools() {
|
|
|
6503
6503
|
{
|
|
6504
6504
|
name: "event_get_fills",
|
|
6505
6505
|
module: "event",
|
|
6506
|
-
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
|
|
6506
|
+
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.",
|
|
6507
6507
|
isWrite: false,
|
|
6508
6508
|
inputSchema: {
|
|
6509
6509
|
type: "object",
|
|
@@ -6545,15 +6545,15 @@ function registerEventContractTools() {
|
|
|
6545
6545
|
}
|
|
6546
6546
|
},
|
|
6547
6547
|
// -----------------------------------------------------------------------
|
|
6548
|
-
// Private
|
|
6548
|
+
// Private - write
|
|
6549
6549
|
// -----------------------------------------------------------------------
|
|
6550
6550
|
{
|
|
6551
6551
|
name: "event_place_order",
|
|
6552
6552
|
module: "event",
|
|
6553
6553
|
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.
|
|
6554
6554
|
- outcome: UP/YES (bet price goes up/condition met) or DOWN/NO (bet price goes down/condition not met)
|
|
6555
|
-
- For limit orders: px is the event contract price (0.01
|
|
6556
|
-
- tdMode is always isolated; speedBump is auto-set per exchange requirement
|
|
6555
|
+
- 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
|
|
6556
|
+
- tdMode is always isolated; speedBump is auto-set per exchange requirement - do not pass either`,
|
|
6557
6557
|
isWrite: true,
|
|
6558
6558
|
inputSchema: {
|
|
6559
6559
|
type: "object",
|
|
@@ -6579,7 +6579,7 @@ function registerEventContractTools() {
|
|
|
6579
6579
|
},
|
|
6580
6580
|
px: {
|
|
6581
6581
|
type: "string",
|
|
6582
|
-
description: "Event contract price (0.01
|
|
6582
|
+
description: "Event contract price (0.01-0.99). Required when ordType=limit. Do NOT use for market orders."
|
|
6583
6583
|
}
|
|
6584
6584
|
},
|
|
6585
6585
|
required: ["instId", "side", "outcome", "sz"]
|
|
@@ -6632,7 +6632,7 @@ function registerEventContractTools() {
|
|
|
6632
6632
|
properties: {
|
|
6633
6633
|
instId: { type: "string", description: "Event contract instrument ID" },
|
|
6634
6634
|
ordId: { type: "string", description: "Order ID to amend" },
|
|
6635
|
-
newPx: { type: "string", description: "New event contract price (0.01
|
|
6635
|
+
newPx: { type: "string", description: "New event contract price (0.01-0.99). Omit to keep current." },
|
|
6636
6636
|
newSz: { type: "string", description: "New size in contracts (omit to keep current)" }
|
|
6637
6637
|
},
|
|
6638
6638
|
required: ["instId", "ordId"]
|
|
@@ -6686,7 +6686,7 @@ function registerEventContractTools() {
|
|
|
6686
6686
|
if (sCode === "51001") {
|
|
6687
6687
|
const expiryMs = inferExpiryMsFromInstId(instId);
|
|
6688
6688
|
const isExpired = expiryMs !== null && expiryMs < Date.now();
|
|
6689
|
-
const reason = isExpired ? `The contract (${instId}) has already expired
|
|
6689
|
+
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.`;
|
|
6690
6690
|
throw new OkxApiError(reason, { code: sCode, endpoint: response.endpoint });
|
|
6691
6691
|
}
|
|
6692
6692
|
}
|
|
@@ -6721,25 +6721,25 @@ var SIGNAL_POOL_FILTER_PROPS = {
|
|
|
6721
6721
|
type: "string",
|
|
6722
6722
|
enum: ["PNL_ANY", "PNL_TOP50", "PNL_TOP20", "PNL_TOP5"],
|
|
6723
6723
|
default: "PNL_ANY",
|
|
6724
|
-
description: "PnL percentile gate
|
|
6724
|
+
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."
|
|
6725
6725
|
},
|
|
6726
6726
|
winRateTier: {
|
|
6727
6727
|
type: "string",
|
|
6728
6728
|
enum: ["WR_ANY", "WR_GE_50", "WR_GE_80"],
|
|
6729
6729
|
default: "WR_ANY",
|
|
6730
|
-
description: "Minimum win-rate gate (absolute thresholds, NOT percentile). Naming: `GE_{N}` = career win-rate \u2265 N%
|
|
6730
|
+
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%."
|
|
6731
6731
|
},
|
|
6732
6732
|
maxDrawdownTier: {
|
|
6733
6733
|
type: "string",
|
|
6734
6734
|
enum: ["MR_ANY", "MR_LE_20", "MR_LE_50"],
|
|
6735
6735
|
default: "MR_ANY",
|
|
6736
|
-
description: "Maximum-drawdown gate (absolute thresholds, NOT percentile; smaller drawdown = lower risk). Naming: `LE_{N}` = drawdown \u2264 N%
|
|
6736
|
+
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%."
|
|
6737
6737
|
},
|
|
6738
6738
|
aumTier: {
|
|
6739
6739
|
type: "string",
|
|
6740
6740
|
enum: ["AUM_ANY", "AUM_TOP50", "AUM_TOP20", "AUM_TOP5"],
|
|
6741
6741
|
default: "AUM_ANY",
|
|
6742
|
-
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
|
|
6742
|
+
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."
|
|
6743
6743
|
}
|
|
6744
6744
|
};
|
|
6745
6745
|
var LEADERBOARD_POOL_FILTER_PROPS = {
|
|
@@ -6757,19 +6757,19 @@ var LEADERBOARD_POOL_FILTER_PROPS = {
|
|
|
6757
6757
|
},
|
|
6758
6758
|
minPnl: {
|
|
6759
6759
|
type: "string",
|
|
6760
|
-
description: 'Minimum absolute PnL in USD as a string, e.g. `"10000"`
|
|
6760
|
+
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.'
|
|
6761
6761
|
},
|
|
6762
6762
|
minWinRate: {
|
|
6763
6763
|
type: "string",
|
|
6764
|
-
description: 'Minimum win-rate as a decimal in 0~1 range, passed as a string, e.g. `"0.8"`
|
|
6764
|
+
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.'
|
|
6765
6765
|
},
|
|
6766
6766
|
maxDrawdown: {
|
|
6767
6767
|
type: "string",
|
|
6768
|
-
description: 'Maximum drawdown as a decimal, passed as a string, e.g. `"0.1"`
|
|
6768
|
+
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.'
|
|
6769
6769
|
},
|
|
6770
6770
|
minAum: {
|
|
6771
6771
|
type: "string",
|
|
6772
|
-
description: 'Minimum AUM (Assets Under Management) in USD as a string, e.g. `"1000"`
|
|
6772
|
+
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.'
|
|
6773
6773
|
}
|
|
6774
6774
|
};
|
|
6775
6775
|
var LEADERBOARD_FILTER_UPSTREAM_NAMES = {
|
|
@@ -6903,11 +6903,11 @@ var PAGINATION_PROP = {
|
|
|
6903
6903
|
}
|
|
6904
6904
|
};
|
|
6905
6905
|
var TRADER_ITEM_PROPS = {
|
|
6906
|
-
authorId: { type: "string", description: "Trader's unique ID
|
|
6906
|
+
authorId: { type: "string", description: "Trader's unique ID - pass to other smartmoney_get_trader_* tools." },
|
|
6907
6907
|
nickName: { type: "string", description: "Display nickname." },
|
|
6908
6908
|
pnl: { type: "string", description: "Absolute PnL in USD over the requested `period` (numeric string)." },
|
|
6909
6909
|
pnlRatio: { type: "string", description: 'PnL as a decimal ratio over the requested `period` (e.g. "0.35" = +35%).' },
|
|
6910
|
-
asset: { type: "string", description: "AUM (Assets Under Management) in USD
|
|
6910
|
+
asset: { type: "string", description: "AUM (Assets Under Management) in USD - same field that the input `minAum` filter applies to." },
|
|
6911
6911
|
winRate: { type: "string", description: "Lifetime win-rate as a decimal (0~1)." },
|
|
6912
6912
|
maxDrawdown: { type: "string", description: 'Max drawdown as a decimal (e.g. "0.2" = 20%). Lower = lower risk.' },
|
|
6913
6913
|
onboardDuration: { type: "string", description: "Days the trader has been onboarded on the leaderboard (numeric string)." },
|
|
@@ -6936,7 +6936,7 @@ var SIGNAL_ITEM_PROPS = {
|
|
|
6936
6936
|
},
|
|
6937
6937
|
tradersQualified: {
|
|
6938
6938
|
type: "integer",
|
|
6939
|
-
description: "
|
|
6939
|
+
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."
|
|
6940
6940
|
},
|
|
6941
6941
|
longTraders: { type: "integer", description: "Number of pool traders currently long this asset (incl. double-sided)." },
|
|
6942
6942
|
shortTraders: { type: "integer", description: "Number of pool traders currently short this asset (incl. double-sided)." },
|
|
@@ -6946,19 +6946,19 @@ var SIGNAL_ITEM_PROPS = {
|
|
|
6946
6946
|
properties: {
|
|
6947
6947
|
longNotionalUsdt: {
|
|
6948
6948
|
type: "string",
|
|
6949
|
-
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
|
|
6949
|
+
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."
|
|
6950
6950
|
},
|
|
6951
6951
|
shortNotionalUsdt: {
|
|
6952
6952
|
type: "string",
|
|
6953
|
-
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
|
|
6953
|
+
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."
|
|
6954
6954
|
},
|
|
6955
6955
|
netNotionalUsdt: {
|
|
6956
6956
|
type: "string",
|
|
6957
|
-
description: "Net directional notional in USDT = long \u2212 short. Weighted by each trader's ENTRY PRICE (price_avg), not mark price
|
|
6957
|
+
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."
|
|
6958
6958
|
},
|
|
6959
6959
|
totalNotionalUsdt: {
|
|
6960
6960
|
type: "string",
|
|
6961
|
-
description: "Gross notional in USDT = long + short. Weighted by each trader's ENTRY PRICE (price_avg), not mark price
|
|
6961
|
+
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."
|
|
6962
6962
|
},
|
|
6963
6963
|
totalNotionalVs24h: {
|
|
6964
6964
|
type: "string",
|
|
@@ -6988,7 +6988,7 @@ var SIGNAL_ITEM_PROPS = {
|
|
|
6988
6988
|
},
|
|
6989
6989
|
weightedLongRatio: {
|
|
6990
6990
|
type: "string",
|
|
6991
|
-
description: "Notional-weighted long ratio = \u03A3(long_notional) / \u03A3(notional). Notional uses each trader's ENTRY PRICE (price_avg), not mark price
|
|
6991
|
+
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."
|
|
6992
6992
|
},
|
|
6993
6993
|
weightedShortRatio: {
|
|
6994
6994
|
type: "string",
|
|
@@ -7023,7 +7023,7 @@ var SIGNAL_HISTORY_ITEM_PROPS = {
|
|
|
7023
7023
|
},
|
|
7024
7024
|
weightedLongRatio: {
|
|
7025
7025
|
type: "string",
|
|
7026
|
-
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
|
|
7026
|
+
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."
|
|
7027
7027
|
},
|
|
7028
7028
|
weightedShortRatio: {
|
|
7029
7029
|
type: "string",
|
|
@@ -7043,13 +7043,16 @@ var SIGNAL_HISTORY_ITEM_PROPS = {
|
|
|
7043
7043
|
},
|
|
7044
7044
|
netNotionalUsdt: {
|
|
7045
7045
|
type: "string",
|
|
7046
|
-
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
|
|
7046
|
+
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."
|
|
7047
7047
|
},
|
|
7048
7048
|
totalNotionalUsdt: {
|
|
7049
7049
|
type: "string",
|
|
7050
|
-
description: "Gross notional in USDT at this bucket = long notional + short notional. Weighted by each trader's ENTRY PRICE (price_avg), not mark price
|
|
7050
|
+
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."
|
|
7051
|
+
},
|
|
7052
|
+
tradersQualified: {
|
|
7053
|
+
type: "integer",
|
|
7054
|
+
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."
|
|
7051
7055
|
},
|
|
7052
|
-
tradersQualified: { type: "integer", description: "Pool size after applying tier filters (includes traders without a position)." },
|
|
7053
7056
|
dataVersion: { type: "string", description: "Snapshot version key in `yyyyMMddHH` UTC (10-digit, e.g. `2026042820`)." }
|
|
7054
7057
|
};
|
|
7055
7058
|
function registerSmartmoneyTools() {
|
|
@@ -7061,7 +7064,7 @@ function registerSmartmoneyTools() {
|
|
|
7061
7064
|
{
|
|
7062
7065
|
name: "smartmoney_get_traders_by_filter",
|
|
7063
7066
|
module: "smartmoney",
|
|
7064
|
-
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`
|
|
7067
|
+
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.",
|
|
7065
7068
|
isWrite: false,
|
|
7066
7069
|
outputSchema: envelope(
|
|
7067
7070
|
{ type: "array", items: { type: "object", properties: TRADER_ITEM_PROPS } },
|
|
@@ -7078,16 +7081,16 @@ function registerSmartmoneyTools() {
|
|
|
7078
7081
|
properties: {
|
|
7079
7082
|
updateTime: {
|
|
7080
7083
|
type: "string",
|
|
7081
|
-
description: 'Snapshot version key
|
|
7084
|
+
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).'
|
|
7082
7085
|
},
|
|
7083
7086
|
...LEADERBOARD_POOL_FILTER_PROPS,
|
|
7084
7087
|
after: {
|
|
7085
7088
|
type: "string",
|
|
7086
|
-
description: 'Pagination cursor (older page)
|
|
7089
|
+
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.'
|
|
7087
7090
|
},
|
|
7088
7091
|
before: {
|
|
7089
7092
|
type: "string",
|
|
7090
|
-
description: 'Pagination cursor (newer page)
|
|
7093
|
+
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.'
|
|
7091
7094
|
},
|
|
7092
7095
|
limit: {
|
|
7093
7096
|
type: "integer",
|
|
@@ -7127,7 +7130,7 @@ function registerSmartmoneyTools() {
|
|
|
7127
7130
|
{
|
|
7128
7131
|
name: "smartmoney_get_performance_by_trader",
|
|
7129
7132
|
module: "smartmoney",
|
|
7130
|
-
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
|
|
7133
|
+
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).",
|
|
7131
7134
|
isWrite: false,
|
|
7132
7135
|
outputSchema: envelope(
|
|
7133
7136
|
{ type: "array", items: { type: "object", properties: TRADER_ITEM_PROPS } },
|
|
@@ -7197,7 +7200,7 @@ function registerSmartmoneyTools() {
|
|
|
7197
7200
|
{
|
|
7198
7201
|
name: "smartmoney_get_trader_positions",
|
|
7199
7202
|
module: "smartmoney",
|
|
7200
|
-
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
|
|
7203
|
+
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).",
|
|
7201
7204
|
isWrite: false,
|
|
7202
7205
|
outputSchema: envelope({
|
|
7203
7206
|
type: "array",
|
|
@@ -7217,9 +7220,9 @@ function registerSmartmoneyTools() {
|
|
|
7217
7220
|
direction: {
|
|
7218
7221
|
type: "string",
|
|
7219
7222
|
enum: ["long", "short"],
|
|
7220
|
-
description: 'Derived clean direction (`long` | `short`)
|
|
7223
|
+
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.'
|
|
7221
7224
|
},
|
|
7222
|
-
posCcy: { type: "string", description: 'Position currency
|
|
7225
|
+
posCcy: { type: "string", description: 'Position currency - the asset being held, e.g. "BTC".' },
|
|
7223
7226
|
quoteCcy: { type: "string", description: 'Quote currency the position is priced/settled in, e.g. "USDT".' },
|
|
7224
7227
|
pos: {
|
|
7225
7228
|
type: "string",
|
|
@@ -7248,7 +7251,7 @@ function registerSmartmoneyTools() {
|
|
|
7248
7251
|
},
|
|
7249
7252
|
instId: {
|
|
7250
7253
|
type: "string",
|
|
7251
|
-
description: 'Optional instrument filter. Accepts either full instId (e.g. "BTC-USDT-SWAP") or bare base currency (e.g. "BTC")
|
|
7254
|
+
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.'
|
|
7252
7255
|
}
|
|
7253
7256
|
},
|
|
7254
7257
|
required: ["authorId"]
|
|
@@ -7278,7 +7281,7 @@ function registerSmartmoneyTools() {
|
|
|
7278
7281
|
{
|
|
7279
7282
|
name: "smartmoney_get_trader_positions_history",
|
|
7280
7283
|
module: "smartmoney",
|
|
7281
|
-
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
|
|
7284
|
+
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).",
|
|
7282
7285
|
isWrite: false,
|
|
7283
7286
|
outputSchema: envelope(
|
|
7284
7287
|
{
|
|
@@ -7294,7 +7297,7 @@ function registerSmartmoneyTools() {
|
|
|
7294
7297
|
},
|
|
7295
7298
|
ctVal: {
|
|
7296
7299
|
type: "string",
|
|
7297
|
-
description: "Contract face value
|
|
7300
|
+
description: "Contract face value - USD value of a single contract (\u5F20). Numeric string. Empty/0 for non-contract instruments."
|
|
7298
7301
|
},
|
|
7299
7302
|
posSide: {
|
|
7300
7303
|
type: "string",
|
|
@@ -7361,15 +7364,15 @@ function registerSmartmoneyTools() {
|
|
|
7361
7364
|
},
|
|
7362
7365
|
instId: {
|
|
7363
7366
|
type: "string",
|
|
7364
|
-
description: 'Optional instrument filter. Accepts either full instId (e.g. "BTC-USDT-SWAP") or bare base currency (e.g. "BTC")
|
|
7367
|
+
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.'
|
|
7365
7368
|
},
|
|
7366
7369
|
after: {
|
|
7367
7370
|
type: "string",
|
|
7368
|
-
description: 'Pagination cursor (older)
|
|
7371
|
+
description: 'Pagination cursor (older) - returns positions with `posId` smaller than this value. Pass the `posId` as a string, e.g. `"872913470357110787"`.'
|
|
7369
7372
|
},
|
|
7370
7373
|
before: {
|
|
7371
7374
|
type: "string",
|
|
7372
|
-
description: 'Pagination cursor (newer)
|
|
7375
|
+
description: 'Pagination cursor (newer) - returns positions with `posId` greater than this value. Pass the `posId` as a string, e.g. `"872913470357110787"`.'
|
|
7373
7376
|
},
|
|
7374
7377
|
limit: {
|
|
7375
7378
|
type: "integer",
|
|
@@ -7415,7 +7418,7 @@ function registerSmartmoneyTools() {
|
|
|
7415
7418
|
{
|
|
7416
7419
|
name: "smartmoney_get_trader_orders_history",
|
|
7417
7420
|
module: "smartmoney",
|
|
7418
|
-
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
|
|
7421
|
+
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).",
|
|
7419
7422
|
isWrite: false,
|
|
7420
7423
|
outputSchema: envelope(
|
|
7421
7424
|
{
|
|
@@ -7479,15 +7482,15 @@ function registerSmartmoneyTools() {
|
|
|
7479
7482
|
},
|
|
7480
7483
|
instId: {
|
|
7481
7484
|
type: "string",
|
|
7482
|
-
description: 'Optional instrument filter. Accepts either full instId (e.g. "BTC-USDT-SWAP") or bare base currency (e.g. "BTC")
|
|
7485
|
+
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.'
|
|
7483
7486
|
},
|
|
7484
7487
|
after: {
|
|
7485
7488
|
type: "string",
|
|
7486
|
-
description: 'Pagination cursor (older)
|
|
7489
|
+
description: 'Pagination cursor (older) - returns trades with `ordId` smaller than this value. Pass the `ordId` as a string, e.g. `"872913470357110787"`.'
|
|
7487
7490
|
},
|
|
7488
7491
|
before: {
|
|
7489
7492
|
type: "string",
|
|
7490
|
-
description: 'Pagination cursor (newer)
|
|
7493
|
+
description: 'Pagination cursor (newer) - returns trades with `ordId` greater than this value. Pass the `ordId` as a string, e.g. `"872913470357110787"`.'
|
|
7491
7494
|
},
|
|
7492
7495
|
limit: {
|
|
7493
7496
|
type: "integer",
|
|
@@ -7541,7 +7544,7 @@ function registerSmartmoneyTools() {
|
|
|
7541
7544
|
items: {
|
|
7542
7545
|
type: "object",
|
|
7543
7546
|
properties: {
|
|
7544
|
-
authorId: { type: "string", description: "Trader's unique ID
|
|
7547
|
+
authorId: { type: "string", description: "Trader's unique ID - pass to other `smartmoney_get_trader_*` tools." },
|
|
7545
7548
|
nickName: { type: "string", description: "Display nickname matched against the keyword." },
|
|
7546
7549
|
followerCount: { type: "string", description: "OKX-platform follower count (numeric string; Twitter followers excluded). Sort key." }
|
|
7547
7550
|
}
|
|
@@ -7583,7 +7586,7 @@ function registerSmartmoneyTools() {
|
|
|
7583
7586
|
{
|
|
7584
7587
|
name: "smartmoney_get_signal_overview_by_filter",
|
|
7585
7588
|
module: "smartmoney",
|
|
7586
|
-
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`
|
|
7589
|
+
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).",
|
|
7587
7590
|
isWrite: false,
|
|
7588
7591
|
outputSchema: envelope({
|
|
7589
7592
|
type: "array",
|
|
@@ -7604,7 +7607,7 @@ function registerSmartmoneyTools() {
|
|
|
7604
7607
|
type: "array",
|
|
7605
7608
|
items: { type: "string" },
|
|
7606
7609
|
minItems: 1,
|
|
7607
|
-
description: 'Base currencies to aggregate, e.g. `["BTC", "ETH", "SOL"]`. Mutually exclusive with `topInstruments`. Scope: only USDT-margined and USDS-margined (linear) instruments
|
|
7610
|
+
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.'
|
|
7608
7611
|
},
|
|
7609
7612
|
...SIGNAL_POOL_FILTER_PROPS,
|
|
7610
7613
|
lmtNum: {
|
|
@@ -7612,7 +7615,7 @@ function registerSmartmoneyTools() {
|
|
|
7612
7615
|
minimum: 1,
|
|
7613
7616
|
maximum: 2e3,
|
|
7614
7617
|
default: 100,
|
|
7615
|
-
description: "
|
|
7618
|
+
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)."
|
|
7616
7619
|
}
|
|
7617
7620
|
},
|
|
7618
7621
|
required: ["sortBy", "period"]
|
|
@@ -7624,7 +7627,7 @@ function registerSmartmoneyTools() {
|
|
|
7624
7627
|
if (instCcyList && topInstrumentsRaw !== void 0) {
|
|
7625
7628
|
throw actionableError(
|
|
7626
7629
|
'"topInstruments" and "instCcyList" are mutually exclusive.',
|
|
7627
|
-
"Pass exactly one
|
|
7630
|
+
"Pass exactly one - `topInstruments` for top-N hottest coins, or `instCcyList` for specific coins."
|
|
7628
7631
|
);
|
|
7629
7632
|
}
|
|
7630
7633
|
const response = await context.client.privateGet(
|
|
@@ -7643,7 +7646,7 @@ function registerSmartmoneyTools() {
|
|
|
7643
7646
|
{
|
|
7644
7647
|
name: "smartmoney_get_signal_overview_by_trader",
|
|
7645
7648
|
module: "smartmoney",
|
|
7646
|
-
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
|
|
7649
|
+
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).",
|
|
7647
7650
|
isWrite: false,
|
|
7648
7651
|
outputSchema: envelope({
|
|
7649
7652
|
type: "array",
|
|
@@ -7670,7 +7673,7 @@ function registerSmartmoneyTools() {
|
|
|
7670
7673
|
type: "array",
|
|
7671
7674
|
items: { type: "string" },
|
|
7672
7675
|
minItems: 1,
|
|
7673
|
-
description: 'Base currencies to aggregate, e.g. `["BTC", "ETH", "SOL"]`. Mutually exclusive with `topInstruments`. Scope: only USDT-margined and USDS-margined (linear) instruments
|
|
7676
|
+
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.'
|
|
7674
7677
|
},
|
|
7675
7678
|
sortBy: {
|
|
7676
7679
|
type: "string",
|
|
@@ -7703,7 +7706,7 @@ function registerSmartmoneyTools() {
|
|
|
7703
7706
|
if (instCcyList && topInstrumentsRaw !== void 0) {
|
|
7704
7707
|
throw actionableError(
|
|
7705
7708
|
'"topInstruments" and "instCcyList" are mutually exclusive.',
|
|
7706
|
-
"Pass exactly one
|
|
7709
|
+
"Pass exactly one - `topInstruments` for top-N hottest coins, or `instCcyList` for specific coins."
|
|
7707
7710
|
);
|
|
7708
7711
|
}
|
|
7709
7712
|
const response = await context.client.privateGet(
|
|
@@ -7725,7 +7728,7 @@ function registerSmartmoneyTools() {
|
|
|
7725
7728
|
{
|
|
7726
7729
|
name: "smartmoney_get_signal_trend_by_filter",
|
|
7727
7730
|
module: "smartmoney",
|
|
7728
|
-
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
|
|
7731
|
+
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.",
|
|
7729
7732
|
isWrite: false,
|
|
7730
7733
|
outputSchema: envelope({
|
|
7731
7734
|
type: "array",
|
|
@@ -7737,11 +7740,11 @@ function registerSmartmoneyTools() {
|
|
|
7737
7740
|
properties: {
|
|
7738
7741
|
instCcy: {
|
|
7739
7742
|
type: "string",
|
|
7740
|
-
description: 'Base currency to scope the time-series, e.g. "BTC". Required. Scope: USDT-margined and USDS-margined (linear) instruments only
|
|
7743
|
+
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.'
|
|
7741
7744
|
},
|
|
7742
7745
|
asOfTime: {
|
|
7743
7746
|
type: "string",
|
|
7744
|
-
description: 'Anchor snapshot time
|
|
7747
|
+
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.'
|
|
7745
7748
|
},
|
|
7746
7749
|
granularity: {
|
|
7747
7750
|
type: "string",
|
|
@@ -7762,7 +7765,7 @@ function registerSmartmoneyTools() {
|
|
|
7762
7765
|
minimum: 1,
|
|
7763
7766
|
maximum: 2e3,
|
|
7764
7767
|
default: 100,
|
|
7765
|
-
description: "
|
|
7768
|
+
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)."
|
|
7766
7769
|
}
|
|
7767
7770
|
},
|
|
7768
7771
|
required: ["instCcy", "granularity", "sortBy", "period"]
|
|
@@ -7797,7 +7800,7 @@ function registerSmartmoneyTools() {
|
|
|
7797
7800
|
{
|
|
7798
7801
|
name: "smartmoney_get_signal_trend_by_trader",
|
|
7799
7802
|
module: "smartmoney",
|
|
7800
|
-
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
|
|
7803
|
+
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.",
|
|
7801
7804
|
isWrite: false,
|
|
7802
7805
|
outputSchema: envelope({
|
|
7803
7806
|
type: "array",
|
|
@@ -7815,11 +7818,11 @@ function registerSmartmoneyTools() {
|
|
|
7815
7818
|
},
|
|
7816
7819
|
instCcy: {
|
|
7817
7820
|
type: "string",
|
|
7818
|
-
description: 'Base currency to scope the time-series, e.g. "BTC". Required. Scope: USDT-margined and USDS-margined (linear) instruments only
|
|
7821
|
+
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.'
|
|
7819
7822
|
},
|
|
7820
7823
|
asOfTime: {
|
|
7821
7824
|
type: "string",
|
|
7822
|
-
description: 'Anchor snapshot time
|
|
7825
|
+
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.'
|
|
7823
7826
|
},
|
|
7824
7827
|
granularity: {
|
|
7825
7828
|
type: "string",
|
|
@@ -7899,7 +7902,7 @@ function buildContractTradeTools(cfg) {
|
|
|
7899
7902
|
{
|
|
7900
7903
|
name: n("place_order"),
|
|
7901
7904
|
module,
|
|
7902
|
-
description: `Place ${label} order. Attach TP/SL via tpTriggerPx/slTriggerPx. Before placing, use market_get_instruments to get ctVal (contract face value)
|
|
7905
|
+
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.`,
|
|
7903
7906
|
isWrite: true,
|
|
7904
7907
|
inputSchema: {
|
|
7905
7908
|
type: "object",
|
|
@@ -8239,10 +8242,10 @@ function buildContractTradeTools(cfg) {
|
|
|
8239
8242
|
module,
|
|
8240
8243
|
description: `Set leverage for a ${label} instrument or position. [CAUTION] Changes risk parameters.
|
|
8241
8244
|
Scenarios (SWAP/FUTURES only):
|
|
8242
|
-
\u2022 cross + any instId under the index
|
|
8243
|
-
\u2022 isolated + buy-sell (net) posMode
|
|
8244
|
-
\u2022 isolated + long-short (hedge) posMode
|
|
8245
|
-
Not supported: PORTFOLIO MARGIN accounts cannot adjust cross leverage for SWAP/FUTURES
|
|
8245
|
+
\u2022 cross + any instId under the index -> sets leverage at the index level
|
|
8246
|
+
\u2022 isolated + buy-sell (net) posMode -> instId only
|
|
8247
|
+
\u2022 isolated + long-short (hedge) posMode -> instId + posSide=long|short (BOTH directions must be set separately)
|
|
8248
|
+
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.`,
|
|
8246
8249
|
isWrite: true,
|
|
8247
8250
|
inputSchema: {
|
|
8248
8251
|
type: "object",
|
|
@@ -8250,13 +8253,13 @@ Not supported: PORTFOLIO MARGIN accounts cannot adjust cross leverage for SWAP/F
|
|
|
8250
8253
|
instId: { type: "string", description: instIdExample },
|
|
8251
8254
|
lever: {
|
|
8252
8255
|
type: "string",
|
|
8253
|
-
description: "Leverage multiplier as a positive number string, e.g. '10'. Max value depends on the instrument (query market_get_instruments
|
|
8256
|
+
description: "Leverage multiplier as a positive number string, e.g. '10'. Max value depends on the instrument (query market_get_instruments -> lever)."
|
|
8254
8257
|
},
|
|
8255
8258
|
mgnMode: { type: "string", enum: ["cross", "isolated"] },
|
|
8256
8259
|
posSide: {
|
|
8257
8260
|
type: "string",
|
|
8258
8261
|
enum: ["long", "short"],
|
|
8259
|
-
description: "REQUIRED when mgnMode=isolated AND the account is in hedge (long/short) position mode. Use 'long' or 'short'
|
|
8262
|
+
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."
|
|
8260
8263
|
}
|
|
8261
8264
|
},
|
|
8262
8265
|
required: ["instId", "lever", "mgnMode"]
|
|
@@ -9072,12 +9075,12 @@ var OI_BARS = ["5m", "15m", "1H", "4H", "1D"];
|
|
|
9072
9075
|
function registerMarketFilterTools() {
|
|
9073
9076
|
return [
|
|
9074
9077
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9075
|
-
// market_filter
|
|
9078
|
+
// market_filter - /api/v5/aigc/mcp/market-filter
|
|
9076
9079
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9077
9080
|
{
|
|
9078
9081
|
name: "market_filter",
|
|
9079
9082
|
module: "market",
|
|
9080
|
-
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
|
|
9083
|
+
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.",
|
|
9081
9084
|
isWrite: false,
|
|
9082
9085
|
inputSchema: {
|
|
9083
9086
|
type: "object",
|
|
@@ -9161,7 +9164,7 @@ function registerMarketFilterTools() {
|
|
|
9161
9164
|
sortBy: {
|
|
9162
9165
|
type: "string",
|
|
9163
9166
|
enum: ["last", "chg24hPct", "marketCapUsd", "volUsd24h", "fundingRate", "oiUsd", "listTime"],
|
|
9164
|
-
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
|
|
9167
|
+
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."
|
|
9165
9168
|
},
|
|
9166
9169
|
sortOrder: {
|
|
9167
9170
|
type: "string",
|
|
@@ -9209,12 +9212,12 @@ function registerMarketFilterTools() {
|
|
|
9209
9212
|
}
|
|
9210
9213
|
},
|
|
9211
9214
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9212
|
-
// market_get_oi_history
|
|
9215
|
+
// market_get_oi_history - /api/v5/aigc/mcp/oi-history
|
|
9213
9216
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9214
9217
|
{
|
|
9215
9218
|
name: "market_get_oi_history",
|
|
9216
9219
|
module: "market",
|
|
9217
|
-
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
|
|
9220
|
+
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.",
|
|
9218
9221
|
isWrite: false,
|
|
9219
9222
|
inputSchema: {
|
|
9220
9223
|
type: "object",
|
|
@@ -9256,12 +9259,12 @@ function registerMarketFilterTools() {
|
|
|
9256
9259
|
}
|
|
9257
9260
|
},
|
|
9258
9261
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9259
|
-
// market_filter_oi_change
|
|
9262
|
+
// market_filter_oi_change - /api/v5/aigc/mcp/oi-change-filter
|
|
9260
9263
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9261
9264
|
{
|
|
9262
9265
|
name: "market_filter_oi_change",
|
|
9263
9266
|
module: "market",
|
|
9264
|
-
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
|
|
9267
|
+
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.",
|
|
9265
9268
|
isWrite: false,
|
|
9266
9269
|
inputSchema: {
|
|
9267
9270
|
type: "object",
|
|
@@ -9293,7 +9296,7 @@ function registerMarketFilterTools() {
|
|
|
9293
9296
|
sortBy: {
|
|
9294
9297
|
type: "string",
|
|
9295
9298
|
enum: ["oiUsd", "oiDeltaUsd", "oiDeltaPct", "absOiDeltaPct", "volUsd24h", "fundingRate", "last"],
|
|
9296
|
-
description: "Sort field. Default: oiDeltaPct (largest movers first, signed
|
|
9299
|
+
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."
|
|
9297
9300
|
},
|
|
9298
9301
|
sortOrder: {
|
|
9299
9302
|
type: "string",
|
|
@@ -9328,7 +9331,7 @@ function registerMarketFilterTools() {
|
|
|
9328
9331
|
}
|
|
9329
9332
|
},
|
|
9330
9333
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9331
|
-
// market_get_pair_spread
|
|
9334
|
+
// market_get_pair_spread - /api/v5/aigc/mcp/pair-spread
|
|
9332
9335
|
// ─────────────────────────────────────────────────────────────────────────
|
|
9333
9336
|
{
|
|
9334
9337
|
name: "market_get_pair_spread",
|
|
@@ -9614,7 +9617,7 @@ var D_COINS_SENTIMENT = 'Comma-separated uppercase ticker symbols, max 20 (e.g.
|
|
|
9614
9617
|
var D_LANGUAGE = "Content language: zh-CN or en-US. Infer from user's message. No server default.";
|
|
9615
9618
|
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.";
|
|
9616
9619
|
var D_END = "End time, Unix epoch milliseconds. Parse relative time if given. Omit for no upper bound.";
|
|
9617
|
-
var D_IMPORTANCE = "Importance filter: 'low' returns all news (both low and high importance); 'high' narrows to major/breaking news only. Omitted
|
|
9620
|
+
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.";
|
|
9618
9621
|
var D_PLATFORM = "Filter by news source. Use values from news_get_domains (e.g. blockbeats, odaily_flash). Omit for all sources.";
|
|
9619
9622
|
var D_LIMIT = "Number of results (default 10, max 50).";
|
|
9620
9623
|
function registerNewsTools() {
|
|
@@ -9713,7 +9716,7 @@ function registerNewsTools() {
|
|
|
9713
9716
|
{
|
|
9714
9717
|
name: "news_search",
|
|
9715
9718
|
module: "news",
|
|
9716
|
-
description: "Search crypto news by keyword with optional filters. Use when user provides specific search terms: 'SEC ETF news', 'stablecoin regulation'. Keyword is optional
|
|
9719
|
+
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.",
|
|
9717
9720
|
isWrite: false,
|
|
9718
9721
|
inputSchema: {
|
|
9719
9722
|
type: "object",
|
|
@@ -9823,7 +9826,7 @@ function registerNewsTools() {
|
|
|
9823
9826
|
{
|
|
9824
9827
|
name: "news_get_coin_sentiment",
|
|
9825
9828
|
module: "news",
|
|
9826
|
-
description: "Get sentiment snapshot or time-series trend for coins. Returns bullish/bearish ratios and mention counts. Pass trendPoints for trend data (1h
|
|
9829
|
+
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.",
|
|
9827
9830
|
isWrite: false,
|
|
9828
9831
|
inputSchema: {
|
|
9829
9832
|
type: "object",
|
|
@@ -9836,7 +9839,7 @@ function registerNewsTools() {
|
|
|
9836
9839
|
},
|
|
9837
9840
|
trendPoints: {
|
|
9838
9841
|
type: "number",
|
|
9839
|
-
description: "Trend data points. Pass for time-series trend; omit for snapshot. Guide: 1h
|
|
9842
|
+
description: "Trend data points. Pass for time-series trend; omit for snapshot. Guide: 1h->24, 4h->6, 24h->7."
|
|
9840
9843
|
}
|
|
9841
9844
|
},
|
|
9842
9845
|
required: ["coins"]
|
|
@@ -9903,7 +9906,7 @@ function registerNewsTools() {
|
|
|
9903
9906
|
{
|
|
9904
9907
|
name: "news_list_calendar_regions",
|
|
9905
9908
|
module: "news",
|
|
9906
|
-
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
|
|
9909
|
+
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.",
|
|
9907
9910
|
isWrite: false,
|
|
9908
9911
|
inputSchema: { type: "object", properties: {}, required: [] },
|
|
9909
9912
|
handler: async () => ({ data: CALENDAR_REGIONS })
|
|
@@ -9911,15 +9914,15 @@ function registerNewsTools() {
|
|
|
9911
9914
|
{
|
|
9912
9915
|
name: "news_get_economic_calendar",
|
|
9913
9916
|
module: "news",
|
|
9914
|
-
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
|
|
9917
|
+
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.",
|
|
9915
9918
|
isWrite: false,
|
|
9916
9919
|
inputSchema: {
|
|
9917
9920
|
type: "object",
|
|
9918
9921
|
properties: {
|
|
9919
9922
|
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." },
|
|
9920
9923
|
importance: { type: "string", enum: ["1", "2", "3"], description: "Importance level: 1=low, 2=medium, 3=high. Omit for all levels." },
|
|
9921
|
-
before: { type: "string", description: "Lower time bound
|
|
9922
|
-
after: { type: "string", description: "Upper time bound
|
|
9924
|
+
before: { type: "string", description: "Lower time bound - returns events NEWER than this timestamp (reversed semantics). Pair with 'after' for future-event windows. Unix ms." },
|
|
9925
|
+
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." },
|
|
9923
9926
|
limit: { type: "number", minimum: 1, maximum: 100, description: "Number of results (default 100, max 100)." }
|
|
9924
9927
|
},
|
|
9925
9928
|
required: []
|
|
@@ -10077,7 +10080,7 @@ function registerOptionAlgoTools() {
|
|
|
10077
10080
|
{
|
|
10078
10081
|
name: "option_amend_algo_order",
|
|
10079
10082
|
module: "option",
|
|
10080
|
-
description: "Amend a pending OPTION algo order (modify TP/SL prices or size). Also covers TP/SL orders attached when placing the main order
|
|
10083
|
+
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.",
|
|
10081
10084
|
isWrite: true,
|
|
10082
10085
|
inputSchema: {
|
|
10083
10086
|
type: "object",
|
|
@@ -10240,7 +10243,7 @@ function registerOptionTools() {
|
|
|
10240
10243
|
{
|
|
10241
10244
|
name: "option_place_order",
|
|
10242
10245
|
module: "option",
|
|
10243
|
-
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)
|
|
10246
|
+
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.",
|
|
10244
10247
|
isWrite: true,
|
|
10245
10248
|
inputSchema: {
|
|
10246
10249
|
type: "object",
|
|
@@ -11014,7 +11017,7 @@ function registerSpotTradeTools() {
|
|
|
11014
11017
|
{
|
|
11015
11018
|
name: "spot_amend_algo_order",
|
|
11016
11019
|
module: "spot",
|
|
11017
|
-
description: "Amend a pending spot algo order (modify TP/SL prices or size). Also covers TP/SL orders attached when placing the main order
|
|
11020
|
+
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.",
|
|
11018
11021
|
isWrite: true,
|
|
11019
11022
|
inputSchema: {
|
|
11020
11023
|
type: "object",
|
|
@@ -11083,7 +11086,7 @@ function registerSpotTradeTools() {
|
|
|
11083
11086
|
{
|
|
11084
11087
|
name: "spot_get_algo_orders",
|
|
11085
11088
|
module: "spot",
|
|
11086
|
-
description: "Query spot algo orders (TP/SL)
|
|
11089
|
+
description: "Query spot algo orders (TP/SL) - pending or history.",
|
|
11087
11090
|
isWrite: false,
|
|
11088
11091
|
inputSchema: {
|
|
11089
11092
|
type: "object",
|
|
@@ -11376,16 +11379,16 @@ function registerSpotTradeTools() {
|
|
|
11376
11379
|
}
|
|
11377
11380
|
},
|
|
11378
11381
|
// ── set_leverage (SPOT margin: instId-level isolated OR ccy-level cross) ──
|
|
11379
|
-
// Covers OKX scenarios 1
|
|
11382
|
+
// Covers OKX scenarios 1-5 (everything except SWAP/FUTURES, which are in
|
|
11380
11383
|
// contract-trade.ts). Callers supply exactly one of {instId, ccy}:
|
|
11381
|
-
// • instId + isolated
|
|
11382
|
-
// • instId + cross
|
|
11383
|
-
// • ccy + cross
|
|
11384
|
+
// • instId + isolated -> scenario 1 (pair-level margin)
|
|
11385
|
+
// • instId + cross -> scenario 3 (contract-mode pair-level cross margin)
|
|
11386
|
+
// • ccy + cross -> scenarios 2 / 4 / 5 (spot/multi-ccy/PM currency-level cross)
|
|
11384
11387
|
// Not applicable: posSide (spot has no long/short hedge).
|
|
11385
11388
|
{
|
|
11386
11389
|
name: "spot_set_leverage",
|
|
11387
11390
|
module: "spot",
|
|
11388
|
-
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
|
|
11391
|
+
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.",
|
|
11389
11392
|
isWrite: true,
|
|
11390
11393
|
inputSchema: {
|
|
11391
11394
|
type: "object",
|
|
@@ -11400,7 +11403,7 @@ function registerSpotTradeTools() {
|
|
|
11400
11403
|
},
|
|
11401
11404
|
lever: {
|
|
11402
11405
|
type: "string",
|
|
11403
|
-
description: "Leverage multiplier as a positive number string, e.g. '3'. Max depends on the pair (query market_get_instruments
|
|
11406
|
+
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."
|
|
11404
11407
|
},
|
|
11405
11408
|
mgnMode: {
|
|
11406
11409
|
type: "string",
|
|
@@ -11421,7 +11424,7 @@ function registerSpotTradeTools() {
|
|
|
11421
11424
|
}
|
|
11422
11425
|
if (instId && ccy) {
|
|
11423
11426
|
throw new ValidationError(
|
|
11424
|
-
`Parameters "instId" and "ccy" are mutually exclusive
|
|
11427
|
+
`Parameters "instId" and "ccy" are mutually exclusive - provide only one. instId sets pair-level leverage; ccy sets currency-level cross margin leverage.`
|
|
11425
11428
|
);
|
|
11426
11429
|
}
|
|
11427
11430
|
const leverRaw = requireString(args, "lever");
|
|
@@ -11468,7 +11471,7 @@ function registerSwapTradeTools() {
|
|
|
11468
11471
|
{
|
|
11469
11472
|
name: "swap_amend_algo_order",
|
|
11470
11473
|
module: "swap",
|
|
11471
|
-
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
|
|
11474
|
+
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.",
|
|
11472
11475
|
isWrite: true,
|
|
11473
11476
|
inputSchema: {
|
|
11474
11477
|
type: "object",
|
|
@@ -11621,9 +11624,9 @@ function readFullConfig() {
|
|
|
11621
11624
|
throw new ConfigError(
|
|
11622
11625
|
`Failed to parse ${path4}: ${err instanceof Error ? err.message : String(err)}`,
|
|
11623
11626
|
`If your passphrase or keys contain special characters:
|
|
11624
|
-
- Contains # \\ "
|
|
11625
|
-
- Contains '
|
|
11626
|
-
- Contains both
|
|
11627
|
+
- Contains # \\ " -> use single quotes: passphrase = 'your#pass'
|
|
11628
|
+
- Contains ' -> use double quotes: passphrase = "your'pass"
|
|
11629
|
+
- Contains both -> use triple quotes: passphrase = '''your'#pass'''
|
|
11627
11630
|
Or re-run: okx config init`
|
|
11628
11631
|
);
|
|
11629
11632
|
}
|
|
@@ -11751,6 +11754,9 @@ async function loadConfig(cli) {
|
|
|
11751
11754
|
}
|
|
11752
11755
|
var CACHE_FILE = join8(homedir6(), ".okx", "update-check.json");
|
|
11753
11756
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
11757
|
+
var NEGATIVE_CHECK_INTERVAL_MS = 60 * 60 * 1e3;
|
|
11758
|
+
var DEFAULT_REGISTRY = "https://registry.npmjs.org/";
|
|
11759
|
+
var FETCH_TIMEOUT_MS = 3e3;
|
|
11754
11760
|
function readCache2() {
|
|
11755
11761
|
try {
|
|
11756
11762
|
if (existsSync4(CACHE_FILE)) {
|
|
@@ -11767,7 +11773,73 @@ function writeCache2(cache) {
|
|
|
11767
11773
|
} catch {
|
|
11768
11774
|
}
|
|
11769
11775
|
}
|
|
11776
|
+
function resolveNpmRegistry() {
|
|
11777
|
+
const envRegistry = process.env.npm_config_registry;
|
|
11778
|
+
if (envRegistry) {
|
|
11779
|
+
return envRegistry.endsWith("/") ? envRegistry : `${envRegistry}/`;
|
|
11780
|
+
}
|
|
11781
|
+
for (const filePath of buildNpmrcCandidates()) {
|
|
11782
|
+
const registry = readNpmrcRegistry(filePath);
|
|
11783
|
+
if (registry) {
|
|
11784
|
+
return registry.endsWith("/") ? registry : `${registry}/`;
|
|
11785
|
+
}
|
|
11786
|
+
}
|
|
11787
|
+
return DEFAULT_REGISTRY;
|
|
11788
|
+
}
|
|
11789
|
+
function buildNpmrcCandidates() {
|
|
11790
|
+
const paths = [];
|
|
11791
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11792
|
+
const add = (p) => {
|
|
11793
|
+
if (!seen.has(p)) {
|
|
11794
|
+
seen.add(p);
|
|
11795
|
+
paths.push(p);
|
|
11796
|
+
}
|
|
11797
|
+
};
|
|
11798
|
+
let dir = process.cwd();
|
|
11799
|
+
const root = dir.startsWith("/") ? "/" : dir.slice(0, 3);
|
|
11800
|
+
while (true) {
|
|
11801
|
+
add(join8(dir, ".npmrc"));
|
|
11802
|
+
if (dir === root) break;
|
|
11803
|
+
const parent = join8(dir, "..");
|
|
11804
|
+
if (parent === dir) break;
|
|
11805
|
+
dir = parent;
|
|
11806
|
+
}
|
|
11807
|
+
add(join8(homedir6(), ".npmrc"));
|
|
11808
|
+
if (process.platform !== "win32") {
|
|
11809
|
+
add("/etc/npmrc");
|
|
11810
|
+
}
|
|
11811
|
+
return paths;
|
|
11812
|
+
}
|
|
11813
|
+
function readNpmrcRegistry(filePath) {
|
|
11814
|
+
try {
|
|
11815
|
+
if (!existsSync4(filePath)) return null;
|
|
11816
|
+
const lines = readFileSync5(filePath, "utf-8").split(/\r?\n/);
|
|
11817
|
+
for (const line of lines) {
|
|
11818
|
+
const trimmed = line.trim();
|
|
11819
|
+
if (trimmed.startsWith("#") || !trimmed.includes("=")) continue;
|
|
11820
|
+
const eqIdx = trimmed.indexOf("=");
|
|
11821
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
11822
|
+
const value = trimmed.slice(eqIdx + 1).trim();
|
|
11823
|
+
if (key === "registry" && value) return value;
|
|
11824
|
+
}
|
|
11825
|
+
} catch {
|
|
11826
|
+
}
|
|
11827
|
+
return null;
|
|
11828
|
+
}
|
|
11829
|
+
async function fetchFromRegistry(packageName, suffix = "") {
|
|
11830
|
+
const registry = resolveNpmRegistry();
|
|
11831
|
+
const url = `${registry}${encodeURIComponent(packageName)}${suffix}`;
|
|
11832
|
+
try {
|
|
11833
|
+
return await fetch(url, {
|
|
11834
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
11835
|
+
headers: { accept: "application/json" }
|
|
11836
|
+
});
|
|
11837
|
+
} catch {
|
|
11838
|
+
return null;
|
|
11839
|
+
}
|
|
11840
|
+
}
|
|
11770
11841
|
function isNewerVersion(current, latest) {
|
|
11842
|
+
if (!latest) return false;
|
|
11771
11843
|
const parse2 = (v) => v.replace(/^v/, "").split(".").map((n) => parseInt(n, 10));
|
|
11772
11844
|
const [cMaj, cMin, cPat] = parse2(current);
|
|
11773
11845
|
const [lMaj, lMin, lPat] = parse2(latest);
|
|
@@ -11777,14 +11849,8 @@ function isNewerVersion(current, latest) {
|
|
|
11777
11849
|
}
|
|
11778
11850
|
async function fetchLatestVersion(packageName) {
|
|
11779
11851
|
try {
|
|
11780
|
-
const
|
|
11781
|
-
|
|
11782
|
-
const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`, {
|
|
11783
|
-
signal: controller.signal,
|
|
11784
|
-
headers: { accept: "application/json" }
|
|
11785
|
-
});
|
|
11786
|
-
clearTimeout(timeout);
|
|
11787
|
-
if (!res.ok) return null;
|
|
11852
|
+
const res = await fetchFromRegistry(packageName, "/latest");
|
|
11853
|
+
if (!res || !res.ok) return null;
|
|
11788
11854
|
const data = await res.json();
|
|
11789
11855
|
return data.version ?? null;
|
|
11790
11856
|
} catch {
|
|
@@ -11793,26 +11859,31 @@ async function fetchLatestVersion(packageName) {
|
|
|
11793
11859
|
}
|
|
11794
11860
|
function refreshCacheInBackground(packageName) {
|
|
11795
11861
|
fetchLatestVersion(packageName).then((latest) => {
|
|
11796
|
-
if (!latest) return;
|
|
11797
11862
|
const cache = readCache2();
|
|
11798
|
-
|
|
11863
|
+
if (latest) {
|
|
11864
|
+
cache[packageName] = { latestVersion: latest, checkedAt: Date.now() };
|
|
11865
|
+
} else {
|
|
11866
|
+
cache[packageName] = { latestVersion: null, checkedAt: Date.now(), failed: true };
|
|
11867
|
+
}
|
|
11799
11868
|
writeCache2(cache);
|
|
11800
11869
|
}).catch(() => {
|
|
11801
11870
|
});
|
|
11802
11871
|
}
|
|
11803
11872
|
function checkForUpdates(packageName, currentVersion) {
|
|
11873
|
+
if (process.env.OKX_UPDATE_CHECK === "false") return;
|
|
11804
11874
|
const cache = readCache2();
|
|
11805
11875
|
const entry = cache[packageName];
|
|
11806
|
-
if (entry && isNewerVersion(currentVersion, entry.latestVersion)) {
|
|
11876
|
+
if (entry && entry.latestVersion && isNewerVersion(currentVersion, entry.latestVersion)) {
|
|
11807
11877
|
process.stderr.write(
|
|
11808
11878
|
`
|
|
11809
|
-
Update available for ${packageName}: ${currentVersion}
|
|
11879
|
+
Update available for ${packageName}: ${currentVersion} -> ${entry.latestVersion}
|
|
11810
11880
|
Run: npm install -g ${packageName}
|
|
11811
11881
|
|
|
11812
11882
|
`
|
|
11813
11883
|
);
|
|
11814
11884
|
}
|
|
11815
|
-
|
|
11885
|
+
const ttl = entry?.failed ? NEGATIVE_CHECK_INTERVAL_MS : CHECK_INTERVAL_MS;
|
|
11886
|
+
if (!entry || Date.now() - entry.checkedAt > ttl) {
|
|
11816
11887
|
refreshCacheInBackground(packageName);
|
|
11817
11888
|
}
|
|
11818
11889
|
}
|
|
@@ -11997,7 +12068,7 @@ function mergeJsonConfig(configPath, serverName, entry) {
|
|
|
11997
12068
|
}
|
|
11998
12069
|
const backupPath = configPath + ".bak";
|
|
11999
12070
|
fs3.copyFileSync(configPath, backupPath);
|
|
12000
|
-
process.stdout.write(` Backup
|
|
12071
|
+
process.stdout.write(` Backup -> ${backupPath}
|
|
12001
12072
|
`);
|
|
12002
12073
|
}
|
|
12003
12074
|
if (typeof data.mcpServers !== "object" || data.mcpServers === null) {
|
|
@@ -12068,7 +12139,7 @@ var _require = createRequire(import.meta.url);
|
|
|
12068
12139
|
var pkg = _require("../package.json");
|
|
12069
12140
|
var SERVER_NAME = "okx-trade-mcp";
|
|
12070
12141
|
var SERVER_VERSION = pkg.version;
|
|
12071
|
-
var GIT_HASH = true ? "
|
|
12142
|
+
var GIT_HASH = true ? "c34b282c" : "dev";
|
|
12072
12143
|
|
|
12073
12144
|
// src/server.ts
|
|
12074
12145
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -12250,7 +12321,7 @@ Options:
|
|
|
12250
12321
|
--profile <name> Profile to load from ${configFilePath()}
|
|
12251
12322
|
Falls back to default_profile in config, then "default"
|
|
12252
12323
|
--site <site> OKX site to connect to: global, eea, us (default: global)
|
|
12253
|
-
global
|
|
12324
|
+
global -> www.okx.com, eea -> eea.okx.com, us -> app.okx.com
|
|
12254
12325
|
--read-only Expose only read/query tools and disable write operations
|
|
12255
12326
|
--demo Enable simulated trading (injects x-simulated-trading: 1)
|
|
12256
12327
|
--live Force live trading mode (overrides profile demo=true; mutually exclusive with --demo)
|