@okx_ai/okx-trade-cli 1.2.4-beta.4 → 1.2.4-beta.6
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 +1656 -428
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2200,6 +2200,11 @@ function registerAlgoTradeTools() {
|
|
|
2200
2200
|
enum: ["pending", "history"],
|
|
2201
2201
|
description: "pending=active (default); history=completed"
|
|
2202
2202
|
},
|
|
2203
|
+
instType: {
|
|
2204
|
+
type: "string",
|
|
2205
|
+
enum: ["SWAP", "FUTURES"],
|
|
2206
|
+
description: "SWAP (default) or FUTURES"
|
|
2207
|
+
},
|
|
2203
2208
|
ordType: {
|
|
2204
2209
|
type: "string",
|
|
2205
2210
|
enum: ["conditional", "oco", "move_order_stop"],
|
|
@@ -2239,8 +2244,9 @@ function registerAlgoTradeTools() {
|
|
|
2239
2244
|
const path4 = isHistory ? "/api/v5/trade/orders-algo-history" : "/api/v5/trade/orders-algo-pending";
|
|
2240
2245
|
const ordType = readString(args, "ordType");
|
|
2241
2246
|
const state = isHistory ? readString(args, "state") ?? "effective" : void 0;
|
|
2247
|
+
const instType = readString(args, "instType") ?? "SWAP";
|
|
2242
2248
|
const baseParams = compactObject({
|
|
2243
|
-
instType
|
|
2249
|
+
instType,
|
|
2244
2250
|
instId: readString(args, "instId"),
|
|
2245
2251
|
algoId: readString(args, "algoId"),
|
|
2246
2252
|
after: readString(args, "after"),
|
|
@@ -2271,216 +2277,567 @@ function registerAlgoTradeTools() {
|
|
|
2271
2277
|
}
|
|
2272
2278
|
];
|
|
2273
2279
|
}
|
|
2274
|
-
|
|
2275
|
-
function getLogPaths(logDir, days = 7) {
|
|
2276
|
-
const paths = [];
|
|
2277
|
-
const now = /* @__PURE__ */ new Date();
|
|
2278
|
-
for (let i = 0; i < days; i++) {
|
|
2279
|
-
const d = new Date(now);
|
|
2280
|
-
d.setUTCDate(now.getUTCDate() - i);
|
|
2281
|
-
const yyyy = d.getUTCFullYear();
|
|
2282
|
-
const mm = String(d.getUTCMonth() + 1).padStart(2, "0");
|
|
2283
|
-
const dd = String(d.getUTCDate()).padStart(2, "0");
|
|
2284
|
-
paths.push(path.join(logDir, `trade-${yyyy}-${mm}-${dd}.log`));
|
|
2285
|
-
}
|
|
2286
|
-
return paths;
|
|
2287
|
-
}
|
|
2288
|
-
function readEntries(logDir) {
|
|
2289
|
-
const entries = [];
|
|
2290
|
-
for (const filePath of getLogPaths(logDir)) {
|
|
2291
|
-
let content;
|
|
2292
|
-
try {
|
|
2293
|
-
content = fs.readFileSync(filePath, "utf8");
|
|
2294
|
-
} catch {
|
|
2295
|
-
continue;
|
|
2296
|
-
}
|
|
2297
|
-
for (const line of content.split("\n")) {
|
|
2298
|
-
const trimmed = line.trim();
|
|
2299
|
-
if (!trimmed) continue;
|
|
2300
|
-
try {
|
|
2301
|
-
entries.push(JSON.parse(trimmed));
|
|
2302
|
-
} catch {
|
|
2303
|
-
}
|
|
2304
|
-
}
|
|
2305
|
-
}
|
|
2306
|
-
return entries;
|
|
2307
|
-
}
|
|
2308
|
-
function registerAuditTools() {
|
|
2280
|
+
function registerFuturesAlgoTools() {
|
|
2309
2281
|
return [
|
|
2310
2282
|
{
|
|
2311
|
-
name: "
|
|
2312
|
-
module: "
|
|
2313
|
-
description: "
|
|
2314
|
-
isWrite:
|
|
2283
|
+
name: "futures_place_algo_order",
|
|
2284
|
+
module: "futures",
|
|
2285
|
+
description: "Place a FUTURES delivery algo order: TP/SL (conditional/oco) or trailing stop (move_order_stop). [CAUTION] Executes real trades. conditional: single TP, single SL, or both on one order. oco: TP+SL simultaneously \u2014 first trigger cancels the other. move_order_stop: provide callbackRatio (e.g. '0.01'=1%) OR callbackSpread, and optionally activePx. Set tpOrdPx='-1' or slOrdPx='-1' for market execution.",
|
|
2286
|
+
isWrite: true,
|
|
2315
2287
|
inputSchema: {
|
|
2316
2288
|
type: "object",
|
|
2317
2289
|
properties: {
|
|
2318
|
-
|
|
2319
|
-
type: "
|
|
2320
|
-
description: "
|
|
2290
|
+
instId: {
|
|
2291
|
+
type: "string",
|
|
2292
|
+
description: "e.g. BTC-USDT-240329"
|
|
2321
2293
|
},
|
|
2322
|
-
|
|
2294
|
+
tdMode: {
|
|
2323
2295
|
type: "string",
|
|
2324
|
-
|
|
2296
|
+
enum: ["cross", "isolated"],
|
|
2297
|
+
description: "cross|isolated margin"
|
|
2325
2298
|
},
|
|
2326
|
-
|
|
2299
|
+
side: {
|
|
2327
2300
|
type: "string",
|
|
2328
|
-
enum: ["
|
|
2301
|
+
enum: ["buy", "sell"],
|
|
2302
|
+
description: "sell=close long, buy=close short"
|
|
2329
2303
|
},
|
|
2330
|
-
|
|
2304
|
+
posSide: {
|
|
2331
2305
|
type: "string",
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
handler: async (rawArgs) => {
|
|
2337
|
-
const args = asRecord(rawArgs);
|
|
2338
|
-
const limit = Math.min(readNumber(args, "limit") ?? 20, 100);
|
|
2339
|
-
const toolFilter = readString(args, "tool");
|
|
2340
|
-
const levelFilter = readString(args, "level")?.toUpperCase();
|
|
2341
|
-
const since = readString(args, "since");
|
|
2342
|
-
const sinceTime = since ? new Date(since).getTime() : void 0;
|
|
2343
|
-
let entries = readEntries(DEFAULT_LOG_DIR);
|
|
2344
|
-
if (toolFilter) {
|
|
2345
|
-
entries = entries.filter((e) => e.tool === toolFilter);
|
|
2346
|
-
}
|
|
2347
|
-
if (levelFilter) {
|
|
2348
|
-
entries = entries.filter((e) => e.level === levelFilter);
|
|
2349
|
-
}
|
|
2350
|
-
if (sinceTime !== void 0) {
|
|
2351
|
-
entries = entries.filter((e) => new Date(e.timestamp).getTime() >= sinceTime);
|
|
2352
|
-
}
|
|
2353
|
-
entries.sort(
|
|
2354
|
-
(a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
|
2355
|
-
);
|
|
2356
|
-
entries = entries.slice(0, limit);
|
|
2357
|
-
return { entries, total: entries.length };
|
|
2358
|
-
}
|
|
2359
|
-
}
|
|
2360
|
-
];
|
|
2361
|
-
}
|
|
2362
|
-
function normalizeWrite(response) {
|
|
2363
|
-
const data = response.data;
|
|
2364
|
-
if (Array.isArray(data) && data.length > 0) {
|
|
2365
|
-
const failed = data.filter(
|
|
2366
|
-
(item) => item !== null && typeof item === "object" && "sCode" in item && item["sCode"] !== "0"
|
|
2367
|
-
);
|
|
2368
|
-
if (failed.length > 0) {
|
|
2369
|
-
const messages2 = failed.map(
|
|
2370
|
-
(item) => `[${item["sCode"]}] ${item["sMsg"] ?? "Operation failed"}`
|
|
2371
|
-
);
|
|
2372
|
-
throw new OkxApiError(messages2.join("; "), {
|
|
2373
|
-
code: String(failed[0]["sCode"] ?? ""),
|
|
2374
|
-
endpoint: response.endpoint
|
|
2375
|
-
});
|
|
2376
|
-
}
|
|
2377
|
-
}
|
|
2378
|
-
return {
|
|
2379
|
-
endpoint: response.endpoint,
|
|
2380
|
-
requestTime: response.requestTime,
|
|
2381
|
-
data
|
|
2382
|
-
};
|
|
2383
|
-
}
|
|
2384
|
-
function registerGridTools() {
|
|
2385
|
-
return [
|
|
2386
|
-
{
|
|
2387
|
-
name: "grid_get_orders",
|
|
2388
|
-
module: "bot.grid",
|
|
2389
|
-
description: "Query grid trading bot list. status='active' for running bots; status='history' for completed/stopped. Covers Spot Grid, Contract Grid, and Moon Grid.",
|
|
2390
|
-
isWrite: false,
|
|
2391
|
-
inputSchema: {
|
|
2392
|
-
type: "object",
|
|
2393
|
-
properties: {
|
|
2394
|
-
algoOrdType: {
|
|
2306
|
+
enum: ["long", "short", "net"],
|
|
2307
|
+
description: "net=one-way (default); long/short=hedge mode"
|
|
2308
|
+
},
|
|
2309
|
+
ordType: {
|
|
2395
2310
|
type: "string",
|
|
2396
|
-
enum: ["
|
|
2397
|
-
description: "
|
|
2311
|
+
enum: ["conditional", "oco", "move_order_stop"],
|
|
2312
|
+
description: "conditional=single TP/SL or both; oco=TP+SL pair; move_order_stop=trailing stop"
|
|
2398
2313
|
},
|
|
2399
|
-
|
|
2314
|
+
sz: {
|
|
2400
2315
|
type: "string",
|
|
2401
|
-
|
|
2402
|
-
description: "active=running (default); history=stopped"
|
|
2316
|
+
description: "Number of contracts (NOT USDT amount)."
|
|
2403
2317
|
},
|
|
2404
|
-
|
|
2318
|
+
tpTriggerPx: {
|
|
2405
2319
|
type: "string",
|
|
2406
|
-
description: "
|
|
2320
|
+
description: "TP trigger price (conditional/oco only)"
|
|
2407
2321
|
},
|
|
2408
|
-
|
|
2322
|
+
tpOrdPx: {
|
|
2409
2323
|
type: "string",
|
|
2410
|
-
description: "
|
|
2324
|
+
description: "TP order price; -1=market (conditional/oco only)"
|
|
2411
2325
|
},
|
|
2412
|
-
|
|
2326
|
+
tpTriggerPxType: {
|
|
2413
2327
|
type: "string",
|
|
2414
|
-
|
|
2328
|
+
enum: ["last", "index", "mark"],
|
|
2329
|
+
description: "last(default)|index|mark (conditional/oco only)"
|
|
2415
2330
|
},
|
|
2416
|
-
|
|
2331
|
+
slTriggerPx: {
|
|
2417
2332
|
type: "string",
|
|
2418
|
-
description: "
|
|
2333
|
+
description: "SL trigger price (conditional/oco only)"
|
|
2419
2334
|
},
|
|
2420
|
-
|
|
2421
|
-
type: "
|
|
2422
|
-
description: "
|
|
2335
|
+
slOrdPx: {
|
|
2336
|
+
type: "string",
|
|
2337
|
+
description: "SL order price; -1=market (conditional/oco only)"
|
|
2338
|
+
},
|
|
2339
|
+
slTriggerPxType: {
|
|
2340
|
+
type: "string",
|
|
2341
|
+
enum: ["last", "index", "mark"],
|
|
2342
|
+
description: "last(default)|index|mark (conditional/oco only)"
|
|
2343
|
+
},
|
|
2344
|
+
callbackRatio: {
|
|
2345
|
+
type: "string",
|
|
2346
|
+
description: "Callback ratio (e.g. '0.01'=1%); provide either ratio or spread (move_order_stop only)"
|
|
2347
|
+
},
|
|
2348
|
+
callbackSpread: {
|
|
2349
|
+
type: "string",
|
|
2350
|
+
description: "Callback spread in price units (move_order_stop only)"
|
|
2351
|
+
},
|
|
2352
|
+
activePx: {
|
|
2353
|
+
type: "string",
|
|
2354
|
+
description: "Activation price; tracking starts after market reaches this level (move_order_stop only)"
|
|
2355
|
+
},
|
|
2356
|
+
reduceOnly: {
|
|
2357
|
+
type: "boolean",
|
|
2358
|
+
description: "Ensure order only reduces position"
|
|
2359
|
+
},
|
|
2360
|
+
clOrdId: {
|
|
2361
|
+
type: "string",
|
|
2362
|
+
description: "Client order ID (max 32 chars)"
|
|
2423
2363
|
}
|
|
2424
2364
|
},
|
|
2425
|
-
required: ["
|
|
2365
|
+
required: ["instId", "tdMode", "side", "ordType", "sz"]
|
|
2426
2366
|
},
|
|
2427
2367
|
handler: async (rawArgs, context) => {
|
|
2428
2368
|
const args = asRecord(rawArgs);
|
|
2429
|
-
const
|
|
2430
|
-
const
|
|
2431
|
-
|
|
2432
|
-
const response = await context.client.privateGet(
|
|
2433
|
-
path4,
|
|
2369
|
+
const reduceOnly = args.reduceOnly;
|
|
2370
|
+
const response = await context.client.privatePost(
|
|
2371
|
+
"/api/v5/trade/order-algo",
|
|
2434
2372
|
compactObject({
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2373
|
+
instId: requireString(args, "instId"),
|
|
2374
|
+
tdMode: requireString(args, "tdMode"),
|
|
2375
|
+
side: requireString(args, "side"),
|
|
2376
|
+
posSide: readString(args, "posSide"),
|
|
2377
|
+
ordType: requireString(args, "ordType"),
|
|
2378
|
+
sz: requireString(args, "sz"),
|
|
2379
|
+
tpTriggerPx: readString(args, "tpTriggerPx"),
|
|
2380
|
+
tpOrdPx: readString(args, "tpOrdPx"),
|
|
2381
|
+
tpTriggerPxType: readString(args, "tpTriggerPxType"),
|
|
2382
|
+
slTriggerPx: readString(args, "slTriggerPx"),
|
|
2383
|
+
slOrdPx: readString(args, "slOrdPx"),
|
|
2384
|
+
slTriggerPxType: readString(args, "slTriggerPxType"),
|
|
2385
|
+
callBackRatio: readString(args, "callbackRatio"),
|
|
2386
|
+
callBackSpread: readString(args, "callbackSpread"),
|
|
2387
|
+
activePx: readString(args, "activePx"),
|
|
2388
|
+
reduceOnly: typeof reduceOnly === "boolean" ? String(reduceOnly) : void 0,
|
|
2389
|
+
clOrdId: readString(args, "clOrdId"),
|
|
2390
|
+
tag: context.config.sourceTag
|
|
2441
2391
|
}),
|
|
2442
|
-
privateRateLimit("
|
|
2392
|
+
privateRateLimit("futures_place_algo_order", 20)
|
|
2443
2393
|
);
|
|
2444
2394
|
return normalizeResponse(response);
|
|
2445
2395
|
}
|
|
2446
2396
|
},
|
|
2447
2397
|
{
|
|
2448
|
-
name: "
|
|
2449
|
-
module: "
|
|
2450
|
-
description: "
|
|
2451
|
-
isWrite:
|
|
2398
|
+
name: "futures_place_move_stop_order",
|
|
2399
|
+
module: "futures",
|
|
2400
|
+
description: "[DEPRECATED] Use futures_place_algo_order with ordType='move_order_stop' instead. Place a FUTURES delivery trailing stop order. [CAUTION] Executes real trades.",
|
|
2401
|
+
isWrite: true,
|
|
2452
2402
|
inputSchema: {
|
|
2453
2403
|
type: "object",
|
|
2454
2404
|
properties: {
|
|
2455
|
-
|
|
2405
|
+
instId: {
|
|
2456
2406
|
type: "string",
|
|
2457
|
-
|
|
2458
|
-
description: "Must match the bot's actual type (use the algoOrdType value returned by grid_get_orders). grid=Spot, contract_grid=Contract, moon_grid=Moon."
|
|
2407
|
+
description: "e.g. BTC-USDT-240329"
|
|
2459
2408
|
},
|
|
2460
|
-
|
|
2409
|
+
tdMode: {
|
|
2461
2410
|
type: "string",
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
},
|
|
2465
|
-
required: ["algoOrdType", "algoId"]
|
|
2466
|
-
},
|
|
2467
|
-
handler: async (rawArgs, context) => {
|
|
2468
|
-
const args = asRecord(rawArgs);
|
|
2469
|
-
const response = await context.client.privateGet(
|
|
2470
|
-
"/api/v5/tradingBot/grid/orders-algo-details",
|
|
2471
|
-
{
|
|
2472
|
-
algoOrdType: requireString(args, "algoOrdType"),
|
|
2473
|
-
algoId: requireString(args, "algoId")
|
|
2411
|
+
enum: ["cross", "isolated"],
|
|
2412
|
+
description: "cross|isolated margin"
|
|
2474
2413
|
},
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2414
|
+
side: {
|
|
2415
|
+
type: "string",
|
|
2416
|
+
enum: ["buy", "sell"],
|
|
2417
|
+
description: "sell=close long, buy=close short"
|
|
2418
|
+
},
|
|
2419
|
+
posSide: {
|
|
2420
|
+
type: "string",
|
|
2421
|
+
enum: ["long", "short", "net"],
|
|
2422
|
+
description: "net=one-way (default); long/short=hedge mode"
|
|
2423
|
+
},
|
|
2424
|
+
sz: {
|
|
2425
|
+
type: "string",
|
|
2426
|
+
description: "Number of contracts (NOT USDT amount)."
|
|
2427
|
+
},
|
|
2428
|
+
callbackRatio: {
|
|
2429
|
+
type: "string",
|
|
2430
|
+
description: "Callback ratio (e.g. '0.01'=1%); provide either ratio or spread"
|
|
2431
|
+
},
|
|
2432
|
+
callbackSpread: {
|
|
2433
|
+
type: "string",
|
|
2434
|
+
description: "Callback spread in price units; provide either ratio or spread"
|
|
2435
|
+
},
|
|
2436
|
+
activePx: {
|
|
2437
|
+
type: "string",
|
|
2438
|
+
description: "Activation price"
|
|
2439
|
+
},
|
|
2440
|
+
reduceOnly: {
|
|
2441
|
+
type: "boolean",
|
|
2442
|
+
description: "Ensure order only reduces position"
|
|
2443
|
+
},
|
|
2444
|
+
clOrdId: {
|
|
2445
|
+
type: "string",
|
|
2446
|
+
description: "Client order ID (max 32 chars)"
|
|
2447
|
+
}
|
|
2448
|
+
},
|
|
2449
|
+
required: ["instId", "tdMode", "side", "sz"]
|
|
2450
|
+
},
|
|
2451
|
+
handler: async (rawArgs, context) => {
|
|
2452
|
+
const args = asRecord(rawArgs);
|
|
2453
|
+
const reduceOnly = args.reduceOnly;
|
|
2454
|
+
const response = await context.client.privatePost(
|
|
2455
|
+
"/api/v5/trade/order-algo",
|
|
2456
|
+
compactObject({
|
|
2457
|
+
instId: requireString(args, "instId"),
|
|
2458
|
+
tdMode: requireString(args, "tdMode"),
|
|
2459
|
+
side: requireString(args, "side"),
|
|
2460
|
+
posSide: readString(args, "posSide"),
|
|
2461
|
+
ordType: "move_order_stop",
|
|
2462
|
+
sz: requireString(args, "sz"),
|
|
2463
|
+
callBackRatio: readString(args, "callbackRatio"),
|
|
2464
|
+
callBackSpread: readString(args, "callbackSpread"),
|
|
2465
|
+
activePx: readString(args, "activePx"),
|
|
2466
|
+
reduceOnly: typeof reduceOnly === "boolean" ? String(reduceOnly) : void 0,
|
|
2467
|
+
clOrdId: readString(args, "clOrdId")
|
|
2468
|
+
}),
|
|
2469
|
+
privateRateLimit("futures_place_move_stop_order", 20)
|
|
2470
|
+
);
|
|
2471
|
+
return normalizeResponse(response);
|
|
2472
|
+
}
|
|
2473
|
+
},
|
|
2474
|
+
{
|
|
2475
|
+
name: "futures_amend_algo_order",
|
|
2476
|
+
module: "futures",
|
|
2477
|
+
description: "Amend a pending FUTURES delivery algo order (modify TP/SL prices or size).",
|
|
2478
|
+
isWrite: true,
|
|
2479
|
+
inputSchema: {
|
|
2480
|
+
type: "object",
|
|
2481
|
+
properties: {
|
|
2482
|
+
instId: { type: "string", description: "e.g. BTC-USDT-240329" },
|
|
2483
|
+
algoId: { type: "string", description: "Algo order ID" },
|
|
2484
|
+
newSz: { type: "string", description: "New number of contracts" },
|
|
2485
|
+
newTpTriggerPx: { type: "string", description: "New TP trigger price" },
|
|
2486
|
+
newTpOrdPx: { type: "string", description: "New TP order price; -1=market" },
|
|
2487
|
+
newSlTriggerPx: { type: "string", description: "New SL trigger price" },
|
|
2488
|
+
newSlOrdPx: { type: "string", description: "New SL order price; -1=market" }
|
|
2489
|
+
},
|
|
2490
|
+
required: ["instId", "algoId"]
|
|
2491
|
+
},
|
|
2492
|
+
handler: async (rawArgs, context) => {
|
|
2493
|
+
const args = asRecord(rawArgs);
|
|
2494
|
+
const response = await context.client.privatePost(
|
|
2495
|
+
"/api/v5/trade/amend-algos",
|
|
2496
|
+
compactObject({
|
|
2497
|
+
instId: requireString(args, "instId"),
|
|
2498
|
+
algoId: requireString(args, "algoId"),
|
|
2499
|
+
newSz: readString(args, "newSz"),
|
|
2500
|
+
newTpTriggerPx: readString(args, "newTpTriggerPx"),
|
|
2501
|
+
newTpOrdPx: readString(args, "newTpOrdPx"),
|
|
2502
|
+
newSlTriggerPx: readString(args, "newSlTriggerPx"),
|
|
2503
|
+
newSlOrdPx: readString(args, "newSlOrdPx")
|
|
2504
|
+
}),
|
|
2505
|
+
privateRateLimit("futures_amend_algo_order", 20)
|
|
2506
|
+
);
|
|
2507
|
+
return normalizeResponse(response);
|
|
2508
|
+
}
|
|
2509
|
+
},
|
|
2510
|
+
{
|
|
2511
|
+
name: "futures_cancel_algo_orders",
|
|
2512
|
+
module: "futures",
|
|
2513
|
+
description: "Cancel one or more pending FUTURES delivery algo orders (TP/SL). Accepts a list of {algoId, instId} objects.",
|
|
2514
|
+
isWrite: true,
|
|
2515
|
+
inputSchema: {
|
|
2516
|
+
type: "object",
|
|
2517
|
+
properties: {
|
|
2518
|
+
orders: {
|
|
2519
|
+
type: "array",
|
|
2520
|
+
description: "List of algo orders to cancel. Each item: {algoId, instId}.",
|
|
2521
|
+
items: {
|
|
2522
|
+
type: "object",
|
|
2523
|
+
properties: {
|
|
2524
|
+
algoId: { type: "string", description: "Algo order ID" },
|
|
2525
|
+
instId: { type: "string", description: "e.g. BTC-USDT-240329" }
|
|
2526
|
+
},
|
|
2527
|
+
required: ["algoId", "instId"]
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
},
|
|
2531
|
+
required: ["orders"]
|
|
2532
|
+
},
|
|
2533
|
+
handler: async (rawArgs, context) => {
|
|
2534
|
+
const args = asRecord(rawArgs);
|
|
2535
|
+
const orders = args.orders;
|
|
2536
|
+
if (!Array.isArray(orders) || orders.length === 0) {
|
|
2537
|
+
throw new Error("orders must be a non-empty array.");
|
|
2538
|
+
}
|
|
2539
|
+
const response = await context.client.privatePost(
|
|
2540
|
+
"/api/v5/trade/cancel-algos",
|
|
2541
|
+
orders,
|
|
2542
|
+
privateRateLimit("futures_cancel_algo_orders", 20)
|
|
2543
|
+
);
|
|
2544
|
+
return normalizeResponse(response);
|
|
2545
|
+
}
|
|
2546
|
+
},
|
|
2547
|
+
{
|
|
2548
|
+
name: "futures_get_algo_orders",
|
|
2549
|
+
module: "futures",
|
|
2550
|
+
description: "Query pending or completed FUTURES delivery algo orders (TP/SL, OCO, trailing stop).",
|
|
2551
|
+
isWrite: false,
|
|
2552
|
+
inputSchema: {
|
|
2553
|
+
type: "object",
|
|
2554
|
+
properties: {
|
|
2555
|
+
status: {
|
|
2556
|
+
type: "string",
|
|
2557
|
+
enum: ["pending", "history"],
|
|
2558
|
+
description: "pending=active (default); history=completed"
|
|
2559
|
+
},
|
|
2560
|
+
ordType: {
|
|
2561
|
+
type: "string",
|
|
2562
|
+
enum: ["conditional", "oco", "move_order_stop"],
|
|
2563
|
+
description: "Filter by type; omit for all"
|
|
2564
|
+
},
|
|
2565
|
+
instId: {
|
|
2566
|
+
type: "string",
|
|
2567
|
+
description: "Instrument ID filter"
|
|
2568
|
+
},
|
|
2569
|
+
algoId: {
|
|
2570
|
+
type: "string",
|
|
2571
|
+
description: "Filter by algo order ID"
|
|
2572
|
+
},
|
|
2573
|
+
after: {
|
|
2574
|
+
type: "string",
|
|
2575
|
+
description: "Pagination: before this algo ID"
|
|
2576
|
+
},
|
|
2577
|
+
before: {
|
|
2578
|
+
type: "string",
|
|
2579
|
+
description: "Pagination: after this algo ID"
|
|
2580
|
+
},
|
|
2581
|
+
limit: {
|
|
2582
|
+
type: "number",
|
|
2583
|
+
description: "Max results (default 100)"
|
|
2584
|
+
},
|
|
2585
|
+
state: {
|
|
2586
|
+
type: "string",
|
|
2587
|
+
enum: ["effective", "canceled", "order_failed"],
|
|
2588
|
+
description: "Required when status=history. effective=triggered, canceled, order_failed. Defaults to effective."
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
},
|
|
2592
|
+
handler: async (rawArgs, context) => {
|
|
2593
|
+
const args = asRecord(rawArgs);
|
|
2594
|
+
const status = readString(args, "status") ?? "pending";
|
|
2595
|
+
const isHistory = status === "history";
|
|
2596
|
+
const path4 = isHistory ? "/api/v5/trade/orders-algo-history" : "/api/v5/trade/orders-algo-pending";
|
|
2597
|
+
const ordType = readString(args, "ordType");
|
|
2598
|
+
const state = isHistory ? readString(args, "state") ?? "effective" : void 0;
|
|
2599
|
+
const baseParams = compactObject({
|
|
2600
|
+
instType: "FUTURES",
|
|
2601
|
+
instId: readString(args, "instId"),
|
|
2602
|
+
algoId: readString(args, "algoId"),
|
|
2603
|
+
after: readString(args, "after"),
|
|
2604
|
+
before: readString(args, "before"),
|
|
2605
|
+
limit: readNumber(args, "limit"),
|
|
2606
|
+
state
|
|
2607
|
+
});
|
|
2608
|
+
if (ordType) {
|
|
2609
|
+
const response = await context.client.privateGet(
|
|
2610
|
+
path4,
|
|
2611
|
+
{ ...baseParams, ordType },
|
|
2612
|
+
privateRateLimit("futures_get_algo_orders", 20)
|
|
2613
|
+
);
|
|
2614
|
+
return normalizeResponse(response);
|
|
2615
|
+
}
|
|
2616
|
+
const [r1, r2, r3] = await Promise.all([
|
|
2617
|
+
context.client.privateGet(path4, { ...baseParams, ordType: "conditional" }, privateRateLimit("futures_get_algo_orders", 20)),
|
|
2618
|
+
context.client.privateGet(path4, { ...baseParams, ordType: "oco" }, privateRateLimit("futures_get_algo_orders", 20)),
|
|
2619
|
+
context.client.privateGet(path4, { ...baseParams, ordType: "move_order_stop" }, privateRateLimit("futures_get_algo_orders", 20))
|
|
2620
|
+
]);
|
|
2621
|
+
const merged = [
|
|
2622
|
+
...r1.data ?? [],
|
|
2623
|
+
...r2.data ?? [],
|
|
2624
|
+
...r3.data ?? []
|
|
2625
|
+
];
|
|
2626
|
+
return { endpoint: r1.endpoint, requestTime: r1.requestTime, data: merged };
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
];
|
|
2630
|
+
}
|
|
2631
|
+
var DEFAULT_LOG_DIR = path.join(os.homedir(), ".okx", "logs");
|
|
2632
|
+
function getLogPaths(logDir, days = 7) {
|
|
2633
|
+
const paths = [];
|
|
2634
|
+
const now = /* @__PURE__ */ new Date();
|
|
2635
|
+
for (let i = 0; i < days; i++) {
|
|
2636
|
+
const d = new Date(now);
|
|
2637
|
+
d.setUTCDate(now.getUTCDate() - i);
|
|
2638
|
+
const yyyy = d.getUTCFullYear();
|
|
2639
|
+
const mm = String(d.getUTCMonth() + 1).padStart(2, "0");
|
|
2640
|
+
const dd = String(d.getUTCDate()).padStart(2, "0");
|
|
2641
|
+
paths.push(path.join(logDir, `trade-${yyyy}-${mm}-${dd}.log`));
|
|
2642
|
+
}
|
|
2643
|
+
return paths;
|
|
2644
|
+
}
|
|
2645
|
+
function readEntries(logDir) {
|
|
2646
|
+
const entries = [];
|
|
2647
|
+
for (const filePath of getLogPaths(logDir)) {
|
|
2648
|
+
let content;
|
|
2649
|
+
try {
|
|
2650
|
+
content = fs.readFileSync(filePath, "utf8");
|
|
2651
|
+
} catch {
|
|
2652
|
+
continue;
|
|
2653
|
+
}
|
|
2654
|
+
for (const line of content.split("\n")) {
|
|
2655
|
+
const trimmed = line.trim();
|
|
2656
|
+
if (!trimmed) continue;
|
|
2657
|
+
try {
|
|
2658
|
+
entries.push(JSON.parse(trimmed));
|
|
2659
|
+
} catch {
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
return entries;
|
|
2664
|
+
}
|
|
2665
|
+
function registerAuditTools() {
|
|
2666
|
+
return [
|
|
2667
|
+
{
|
|
2668
|
+
name: "trade_get_history",
|
|
2669
|
+
module: "account",
|
|
2670
|
+
description: "Query local audit log of tool calls made through this MCP server. Returns recent operations with timestamps, duration, params, and results. Use to review what trades or queries were executed in this session or past sessions.",
|
|
2671
|
+
isWrite: false,
|
|
2672
|
+
inputSchema: {
|
|
2673
|
+
type: "object",
|
|
2674
|
+
properties: {
|
|
2675
|
+
limit: {
|
|
2676
|
+
type: "number",
|
|
2677
|
+
description: "Max results (default 20)"
|
|
2678
|
+
},
|
|
2679
|
+
tool: {
|
|
2680
|
+
type: "string",
|
|
2681
|
+
description: "e.g. swap_place_order"
|
|
2682
|
+
},
|
|
2683
|
+
level: {
|
|
2684
|
+
type: "string",
|
|
2685
|
+
enum: ["INFO", "WARN", "ERROR", "DEBUG"]
|
|
2686
|
+
},
|
|
2687
|
+
since: {
|
|
2688
|
+
type: "string",
|
|
2689
|
+
description: "ISO 8601 timestamp lower bound"
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
},
|
|
2693
|
+
handler: async (rawArgs) => {
|
|
2694
|
+
const args = asRecord(rawArgs);
|
|
2695
|
+
const limit = Math.min(readNumber(args, "limit") ?? 20, 100);
|
|
2696
|
+
const toolFilter = readString(args, "tool");
|
|
2697
|
+
const levelFilter = readString(args, "level")?.toUpperCase();
|
|
2698
|
+
const since = readString(args, "since");
|
|
2699
|
+
const sinceTime = since ? new Date(since).getTime() : void 0;
|
|
2700
|
+
let entries = readEntries(DEFAULT_LOG_DIR);
|
|
2701
|
+
if (toolFilter) {
|
|
2702
|
+
entries = entries.filter((e) => e.tool === toolFilter);
|
|
2703
|
+
}
|
|
2704
|
+
if (levelFilter) {
|
|
2705
|
+
entries = entries.filter((e) => e.level === levelFilter);
|
|
2706
|
+
}
|
|
2707
|
+
if (sinceTime !== void 0) {
|
|
2708
|
+
entries = entries.filter((e) => new Date(e.timestamp).getTime() >= sinceTime);
|
|
2709
|
+
}
|
|
2710
|
+
entries.sort(
|
|
2711
|
+
(a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
|
2712
|
+
);
|
|
2713
|
+
entries = entries.slice(0, limit);
|
|
2714
|
+
return { entries, total: entries.length };
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
];
|
|
2718
|
+
}
|
|
2719
|
+
function normalizeWrite(response) {
|
|
2720
|
+
const data = response.data;
|
|
2721
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
2722
|
+
const failed = data.filter(
|
|
2723
|
+
(item) => item !== null && typeof item === "object" && "sCode" in item && item["sCode"] !== "0"
|
|
2724
|
+
);
|
|
2725
|
+
if (failed.length > 0) {
|
|
2726
|
+
const messages2 = failed.map(
|
|
2727
|
+
(item) => `[${item["sCode"]}] ${item["sMsg"] ?? "Operation failed"}`
|
|
2728
|
+
);
|
|
2729
|
+
throw new OkxApiError(messages2.join("; "), {
|
|
2730
|
+
code: String(failed[0]["sCode"] ?? ""),
|
|
2731
|
+
endpoint: response.endpoint
|
|
2732
|
+
});
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
return {
|
|
2736
|
+
endpoint: response.endpoint,
|
|
2737
|
+
requestTime: response.requestTime,
|
|
2738
|
+
data
|
|
2739
|
+
};
|
|
2740
|
+
}
|
|
2741
|
+
function registerGridTools() {
|
|
2742
|
+
return [
|
|
2743
|
+
{
|
|
2744
|
+
name: "grid_get_orders",
|
|
2745
|
+
module: "bot.grid",
|
|
2746
|
+
description: "Query grid trading bot list. status='active' for running bots; status='history' for completed/stopped. Covers Spot Grid, Contract Grid, and Moon Grid.",
|
|
2747
|
+
isWrite: false,
|
|
2748
|
+
inputSchema: {
|
|
2749
|
+
type: "object",
|
|
2750
|
+
properties: {
|
|
2751
|
+
algoOrdType: {
|
|
2752
|
+
type: "string",
|
|
2753
|
+
enum: ["grid", "contract_grid", "moon_grid"],
|
|
2754
|
+
description: "Grid bot type. grid=Spot, contract_grid=Contract, moon_grid=Moon. Must match the bot's actual type when filtering by algoId."
|
|
2755
|
+
},
|
|
2756
|
+
status: {
|
|
2757
|
+
type: "string",
|
|
2758
|
+
enum: ["active", "history"],
|
|
2759
|
+
description: "active=running (default); history=stopped"
|
|
2760
|
+
},
|
|
2761
|
+
instId: {
|
|
2762
|
+
type: "string",
|
|
2763
|
+
description: "e.g. BTC-USDT"
|
|
2764
|
+
},
|
|
2765
|
+
algoId: {
|
|
2766
|
+
type: "string",
|
|
2767
|
+
description: "Grid bot algo order ID (returned by grid_create_order or grid_get_orders). This is NOT a normal trade order ID."
|
|
2768
|
+
},
|
|
2769
|
+
after: {
|
|
2770
|
+
type: "string",
|
|
2771
|
+
description: "Pagination: before this algo ID"
|
|
2772
|
+
},
|
|
2773
|
+
before: {
|
|
2774
|
+
type: "string",
|
|
2775
|
+
description: "Pagination: after this algo ID"
|
|
2776
|
+
},
|
|
2777
|
+
limit: {
|
|
2778
|
+
type: "number",
|
|
2779
|
+
description: "Max results (default 100)"
|
|
2780
|
+
}
|
|
2781
|
+
},
|
|
2782
|
+
required: ["algoOrdType"]
|
|
2783
|
+
},
|
|
2784
|
+
handler: async (rawArgs, context) => {
|
|
2785
|
+
const args = asRecord(rawArgs);
|
|
2786
|
+
const algoOrdType = requireString(args, "algoOrdType");
|
|
2787
|
+
const status = readString(args, "status") ?? "active";
|
|
2788
|
+
const path4 = status === "history" ? "/api/v5/tradingBot/grid/orders-algo-history" : "/api/v5/tradingBot/grid/orders-algo-pending";
|
|
2789
|
+
const response = await context.client.privateGet(
|
|
2790
|
+
path4,
|
|
2791
|
+
compactObject({
|
|
2792
|
+
algoOrdType,
|
|
2793
|
+
instId: readString(args, "instId"),
|
|
2794
|
+
algoId: readString(args, "algoId"),
|
|
2795
|
+
after: readString(args, "after"),
|
|
2796
|
+
before: readString(args, "before"),
|
|
2797
|
+
limit: readNumber(args, "limit")
|
|
2798
|
+
}),
|
|
2799
|
+
privateRateLimit("grid_get_orders", 20)
|
|
2800
|
+
);
|
|
2801
|
+
return normalizeResponse(response);
|
|
2802
|
+
}
|
|
2803
|
+
},
|
|
2804
|
+
{
|
|
2805
|
+
name: "grid_get_order_details",
|
|
2806
|
+
module: "bot.grid",
|
|
2807
|
+
description: "Query details of a single grid trading bot by its algo ID. Returns configuration, current status, PnL, and position info.",
|
|
2808
|
+
isWrite: false,
|
|
2809
|
+
inputSchema: {
|
|
2810
|
+
type: "object",
|
|
2811
|
+
properties: {
|
|
2812
|
+
algoOrdType: {
|
|
2813
|
+
type: "string",
|
|
2814
|
+
enum: ["grid", "contract_grid", "moon_grid"],
|
|
2815
|
+
description: "Must match the bot's actual type (use the algoOrdType value returned by grid_get_orders). grid=Spot, contract_grid=Contract, moon_grid=Moon."
|
|
2816
|
+
},
|
|
2817
|
+
algoId: {
|
|
2818
|
+
type: "string",
|
|
2819
|
+
description: "Grid bot algo order ID (returned by grid_create_order or grid_get_orders). This is NOT a normal trade order ID."
|
|
2820
|
+
}
|
|
2821
|
+
},
|
|
2822
|
+
required: ["algoOrdType", "algoId"]
|
|
2823
|
+
},
|
|
2824
|
+
handler: async (rawArgs, context) => {
|
|
2825
|
+
const args = asRecord(rawArgs);
|
|
2826
|
+
const response = await context.client.privateGet(
|
|
2827
|
+
"/api/v5/tradingBot/grid/orders-algo-details",
|
|
2828
|
+
{
|
|
2829
|
+
algoOrdType: requireString(args, "algoOrdType"),
|
|
2830
|
+
algoId: requireString(args, "algoId")
|
|
2831
|
+
},
|
|
2832
|
+
privateRateLimit("grid_get_order_details", 20)
|
|
2833
|
+
);
|
|
2834
|
+
return normalizeResponse(response);
|
|
2835
|
+
}
|
|
2836
|
+
},
|
|
2837
|
+
{
|
|
2838
|
+
name: "grid_get_sub_orders",
|
|
2839
|
+
module: "bot.grid",
|
|
2840
|
+
description: "Query individual sub-orders (grid trades) generated by a grid bot. type='filled' for executed trades; type='live' for pending orders.",
|
|
2484
2841
|
isWrite: false,
|
|
2485
2842
|
inputSchema: {
|
|
2486
2843
|
type: "object",
|
|
@@ -3801,9 +4158,266 @@ function registerFuturesTools() {
|
|
|
3801
4158
|
}
|
|
3802
4159
|
},
|
|
3803
4160
|
{
|
|
3804
|
-
name: "futures_cancel_order",
|
|
4161
|
+
name: "futures_cancel_order",
|
|
4162
|
+
module: "futures",
|
|
4163
|
+
description: "Cancel an unfilled FUTURES delivery order.",
|
|
4164
|
+
isWrite: true,
|
|
4165
|
+
inputSchema: {
|
|
4166
|
+
type: "object",
|
|
4167
|
+
properties: {
|
|
4168
|
+
instId: {
|
|
4169
|
+
type: "string",
|
|
4170
|
+
description: "e.g. BTC-USDT-240329"
|
|
4171
|
+
},
|
|
4172
|
+
ordId: {
|
|
4173
|
+
type: "string"
|
|
4174
|
+
},
|
|
4175
|
+
clOrdId: {
|
|
4176
|
+
type: "string",
|
|
4177
|
+
description: "Client order ID"
|
|
4178
|
+
}
|
|
4179
|
+
},
|
|
4180
|
+
required: ["instId"]
|
|
4181
|
+
},
|
|
4182
|
+
handler: async (rawArgs, context) => {
|
|
4183
|
+
const args = asRecord(rawArgs);
|
|
4184
|
+
const response = await context.client.privatePost(
|
|
4185
|
+
"/api/v5/trade/cancel-order",
|
|
4186
|
+
compactObject({
|
|
4187
|
+
instId: requireString(args, "instId"),
|
|
4188
|
+
ordId: readString(args, "ordId"),
|
|
4189
|
+
clOrdId: readString(args, "clOrdId")
|
|
4190
|
+
}),
|
|
4191
|
+
privateRateLimit("futures_cancel_order", 60)
|
|
4192
|
+
);
|
|
4193
|
+
return normalizeResponse(response);
|
|
4194
|
+
}
|
|
4195
|
+
},
|
|
4196
|
+
{
|
|
4197
|
+
name: "futures_get_order",
|
|
4198
|
+
module: "futures",
|
|
4199
|
+
description: "Get details of a single FUTURES delivery order by ordId or clOrdId.",
|
|
4200
|
+
isWrite: false,
|
|
4201
|
+
inputSchema: {
|
|
4202
|
+
type: "object",
|
|
4203
|
+
properties: {
|
|
4204
|
+
instId: {
|
|
4205
|
+
type: "string",
|
|
4206
|
+
description: "e.g. BTC-USDT-240329"
|
|
4207
|
+
},
|
|
4208
|
+
ordId: {
|
|
4209
|
+
type: "string",
|
|
4210
|
+
description: "Provide ordId or clOrdId"
|
|
4211
|
+
},
|
|
4212
|
+
clOrdId: {
|
|
4213
|
+
type: "string",
|
|
4214
|
+
description: "Provide ordId or clOrdId"
|
|
4215
|
+
}
|
|
4216
|
+
},
|
|
4217
|
+
required: ["instId"]
|
|
4218
|
+
},
|
|
4219
|
+
handler: async (rawArgs, context) => {
|
|
4220
|
+
const args = asRecord(rawArgs);
|
|
4221
|
+
const response = await context.client.privateGet(
|
|
4222
|
+
"/api/v5/trade/order",
|
|
4223
|
+
compactObject({
|
|
4224
|
+
instId: requireString(args, "instId"),
|
|
4225
|
+
ordId: readString(args, "ordId"),
|
|
4226
|
+
clOrdId: readString(args, "clOrdId")
|
|
4227
|
+
}),
|
|
4228
|
+
privateRateLimit("futures_get_order", 60)
|
|
4229
|
+
);
|
|
4230
|
+
return normalizeResponse(response);
|
|
4231
|
+
}
|
|
4232
|
+
},
|
|
4233
|
+
{
|
|
4234
|
+
name: "futures_get_orders",
|
|
4235
|
+
module: "futures",
|
|
4236
|
+
description: "Query FUTURES open orders, history (last 7 days), or archive (up to 3 months).",
|
|
4237
|
+
isWrite: false,
|
|
4238
|
+
inputSchema: {
|
|
4239
|
+
type: "object",
|
|
4240
|
+
properties: {
|
|
4241
|
+
status: {
|
|
4242
|
+
type: "string",
|
|
4243
|
+
enum: ["open", "history", "archive"],
|
|
4244
|
+
description: "open=active, history=7d, archive=3mo"
|
|
4245
|
+
},
|
|
4246
|
+
instType: {
|
|
4247
|
+
type: "string",
|
|
4248
|
+
enum: [...FUTURES_INST_TYPES],
|
|
4249
|
+
description: "FUTURES (default) or SWAP"
|
|
4250
|
+
},
|
|
4251
|
+
instId: {
|
|
4252
|
+
type: "string",
|
|
4253
|
+
description: "e.g. BTC-USDT-240329"
|
|
4254
|
+
},
|
|
4255
|
+
ordType: {
|
|
4256
|
+
type: "string",
|
|
4257
|
+
description: "Order type filter"
|
|
4258
|
+
},
|
|
4259
|
+
state: {
|
|
4260
|
+
type: "string",
|
|
4261
|
+
description: "canceled|filled"
|
|
4262
|
+
},
|
|
4263
|
+
after: {
|
|
4264
|
+
type: "string",
|
|
4265
|
+
description: "Pagination: before this order ID"
|
|
4266
|
+
},
|
|
4267
|
+
before: {
|
|
4268
|
+
type: "string",
|
|
4269
|
+
description: "Pagination: after this order ID"
|
|
4270
|
+
},
|
|
4271
|
+
begin: {
|
|
4272
|
+
type: "string",
|
|
4273
|
+
description: "Start time (ms)"
|
|
4274
|
+
},
|
|
4275
|
+
end: {
|
|
4276
|
+
type: "string",
|
|
4277
|
+
description: "End time (ms)"
|
|
4278
|
+
},
|
|
4279
|
+
limit: {
|
|
4280
|
+
type: "number",
|
|
4281
|
+
description: "Max results (default 100)"
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
},
|
|
4285
|
+
handler: async (rawArgs, context) => {
|
|
4286
|
+
const args = asRecord(rawArgs);
|
|
4287
|
+
const status = readString(args, "status") ?? "open";
|
|
4288
|
+
const instType = readString(args, "instType") ?? "FUTURES";
|
|
4289
|
+
assertEnum(instType, "instType", FUTURES_INST_TYPES);
|
|
4290
|
+
const path4 = status === "archive" ? "/api/v5/trade/orders-history-archive" : status === "history" ? "/api/v5/trade/orders-history" : "/api/v5/trade/orders-pending";
|
|
4291
|
+
const response = await context.client.privateGet(
|
|
4292
|
+
path4,
|
|
4293
|
+
compactObject({
|
|
4294
|
+
instType,
|
|
4295
|
+
instId: readString(args, "instId"),
|
|
4296
|
+
ordType: readString(args, "ordType"),
|
|
4297
|
+
state: readString(args, "state"),
|
|
4298
|
+
after: readString(args, "after"),
|
|
4299
|
+
before: readString(args, "before"),
|
|
4300
|
+
begin: readString(args, "begin"),
|
|
4301
|
+
end: readString(args, "end"),
|
|
4302
|
+
limit: readNumber(args, "limit")
|
|
4303
|
+
}),
|
|
4304
|
+
privateRateLimit("futures_get_orders", 20)
|
|
4305
|
+
);
|
|
4306
|
+
return normalizeResponse(response);
|
|
4307
|
+
}
|
|
4308
|
+
},
|
|
4309
|
+
{
|
|
4310
|
+
name: "futures_get_positions",
|
|
4311
|
+
module: "futures",
|
|
4312
|
+
description: "Get current FUTURES delivery contract positions.",
|
|
4313
|
+
isWrite: false,
|
|
4314
|
+
inputSchema: {
|
|
4315
|
+
type: "object",
|
|
4316
|
+
properties: {
|
|
4317
|
+
instType: {
|
|
4318
|
+
type: "string",
|
|
4319
|
+
enum: [...FUTURES_INST_TYPES],
|
|
4320
|
+
description: "FUTURES (default) or SWAP"
|
|
4321
|
+
},
|
|
4322
|
+
instId: {
|
|
4323
|
+
type: "string",
|
|
4324
|
+
description: "e.g. BTC-USDT-240329"
|
|
4325
|
+
},
|
|
4326
|
+
posId: {
|
|
4327
|
+
type: "string"
|
|
4328
|
+
}
|
|
4329
|
+
}
|
|
4330
|
+
},
|
|
4331
|
+
handler: async (rawArgs, context) => {
|
|
4332
|
+
const args = asRecord(rawArgs);
|
|
4333
|
+
const instType = readString(args, "instType") ?? "FUTURES";
|
|
4334
|
+
assertEnum(instType, "instType", FUTURES_INST_TYPES);
|
|
4335
|
+
const response = await context.client.privateGet(
|
|
4336
|
+
"/api/v5/account/positions",
|
|
4337
|
+
compactObject({
|
|
4338
|
+
instType,
|
|
4339
|
+
instId: readString(args, "instId"),
|
|
4340
|
+
posId: readString(args, "posId")
|
|
4341
|
+
}),
|
|
4342
|
+
privateRateLimit("futures_get_positions", 10)
|
|
4343
|
+
);
|
|
4344
|
+
return normalizeResponse(response);
|
|
4345
|
+
}
|
|
4346
|
+
},
|
|
4347
|
+
{
|
|
4348
|
+
name: "futures_get_fills",
|
|
4349
|
+
module: "futures",
|
|
4350
|
+
description: "Get FUTURES fill details. archive=false: last 3 days; archive=true: up to 3 months.",
|
|
4351
|
+
isWrite: false,
|
|
4352
|
+
inputSchema: {
|
|
4353
|
+
type: "object",
|
|
4354
|
+
properties: {
|
|
4355
|
+
archive: {
|
|
4356
|
+
type: "boolean",
|
|
4357
|
+
description: "true=up to 3 months; false=last 3 days (default)"
|
|
4358
|
+
},
|
|
4359
|
+
instType: {
|
|
4360
|
+
type: "string",
|
|
4361
|
+
enum: [...FUTURES_INST_TYPES],
|
|
4362
|
+
description: "FUTURES (default) or SWAP"
|
|
4363
|
+
},
|
|
4364
|
+
instId: {
|
|
4365
|
+
type: "string",
|
|
4366
|
+
description: "Instrument ID filter"
|
|
4367
|
+
},
|
|
4368
|
+
ordId: {
|
|
4369
|
+
type: "string",
|
|
4370
|
+
description: "Order ID filter"
|
|
4371
|
+
},
|
|
4372
|
+
after: {
|
|
4373
|
+
type: "string",
|
|
4374
|
+
description: "Pagination: before this bill ID"
|
|
4375
|
+
},
|
|
4376
|
+
before: {
|
|
4377
|
+
type: "string",
|
|
4378
|
+
description: "Pagination: after this bill ID"
|
|
4379
|
+
},
|
|
4380
|
+
begin: {
|
|
4381
|
+
type: "string",
|
|
4382
|
+
description: "Start time (ms)"
|
|
4383
|
+
},
|
|
4384
|
+
end: {
|
|
4385
|
+
type: "string",
|
|
4386
|
+
description: "End time (ms)"
|
|
4387
|
+
},
|
|
4388
|
+
limit: {
|
|
4389
|
+
type: "number",
|
|
4390
|
+
description: "Max results (default 100 or 20 for archive)"
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4393
|
+
},
|
|
4394
|
+
handler: async (rawArgs, context) => {
|
|
4395
|
+
const args = asRecord(rawArgs);
|
|
4396
|
+
const archive = readBoolean(args, "archive") ?? false;
|
|
4397
|
+
const instType = readString(args, "instType") ?? "FUTURES";
|
|
4398
|
+
assertEnum(instType, "instType", FUTURES_INST_TYPES);
|
|
4399
|
+
const path4 = archive ? "/api/v5/trade/fills-history" : "/api/v5/trade/fills";
|
|
4400
|
+
const response = await context.client.privateGet(
|
|
4401
|
+
path4,
|
|
4402
|
+
compactObject({
|
|
4403
|
+
instType,
|
|
4404
|
+
instId: readString(args, "instId"),
|
|
4405
|
+
ordId: readString(args, "ordId"),
|
|
4406
|
+
after: readString(args, "after"),
|
|
4407
|
+
before: readString(args, "before"),
|
|
4408
|
+
begin: readString(args, "begin"),
|
|
4409
|
+
end: readString(args, "end"),
|
|
4410
|
+
limit: readNumber(args, "limit") ?? (archive ? 20 : void 0)
|
|
4411
|
+
}),
|
|
4412
|
+
privateRateLimit("futures_get_fills", 20)
|
|
4413
|
+
);
|
|
4414
|
+
return normalizeResponse(response);
|
|
4415
|
+
}
|
|
4416
|
+
},
|
|
4417
|
+
{
|
|
4418
|
+
name: "futures_amend_order",
|
|
3805
4419
|
module: "futures",
|
|
3806
|
-
description: "
|
|
4420
|
+
description: "Amend an unfilled FUTURES delivery order (modify price and/or size).",
|
|
3807
4421
|
isWrite: true,
|
|
3808
4422
|
inputSchema: {
|
|
3809
4423
|
type: "object",
|
|
@@ -3813,11 +4427,20 @@ function registerFuturesTools() {
|
|
|
3813
4427
|
description: "e.g. BTC-USDT-240329"
|
|
3814
4428
|
},
|
|
3815
4429
|
ordId: {
|
|
3816
|
-
type: "string"
|
|
4430
|
+
type: "string",
|
|
4431
|
+
description: "Provide ordId or clOrdId"
|
|
3817
4432
|
},
|
|
3818
4433
|
clOrdId: {
|
|
3819
4434
|
type: "string",
|
|
3820
|
-
description: "
|
|
4435
|
+
description: "Provide ordId or clOrdId"
|
|
4436
|
+
},
|
|
4437
|
+
newSz: {
|
|
4438
|
+
type: "string",
|
|
4439
|
+
description: "New number of contracts"
|
|
4440
|
+
},
|
|
4441
|
+
newPx: {
|
|
4442
|
+
type: "string",
|
|
4443
|
+
description: "New price"
|
|
3821
4444
|
}
|
|
3822
4445
|
},
|
|
3823
4446
|
required: ["instId"]
|
|
@@ -3825,22 +4448,24 @@ function registerFuturesTools() {
|
|
|
3825
4448
|
handler: async (rawArgs, context) => {
|
|
3826
4449
|
const args = asRecord(rawArgs);
|
|
3827
4450
|
const response = await context.client.privatePost(
|
|
3828
|
-
"/api/v5/trade/
|
|
4451
|
+
"/api/v5/trade/amend-order",
|
|
3829
4452
|
compactObject({
|
|
3830
4453
|
instId: requireString(args, "instId"),
|
|
3831
4454
|
ordId: readString(args, "ordId"),
|
|
3832
|
-
clOrdId: readString(args, "clOrdId")
|
|
4455
|
+
clOrdId: readString(args, "clOrdId"),
|
|
4456
|
+
newSz: readString(args, "newSz"),
|
|
4457
|
+
newPx: readString(args, "newPx")
|
|
3833
4458
|
}),
|
|
3834
|
-
privateRateLimit("
|
|
4459
|
+
privateRateLimit("futures_amend_order", 60)
|
|
3835
4460
|
);
|
|
3836
4461
|
return normalizeResponse(response);
|
|
3837
4462
|
}
|
|
3838
4463
|
},
|
|
3839
4464
|
{
|
|
3840
|
-
name: "
|
|
4465
|
+
name: "futures_close_position",
|
|
3841
4466
|
module: "futures",
|
|
3842
|
-
description: "
|
|
3843
|
-
isWrite:
|
|
4467
|
+
description: "[CAUTION] Close an entire FUTURES delivery position at market. Private. Rate limit: 20 req/s.",
|
|
4468
|
+
isWrite: true,
|
|
3844
4469
|
inputSchema: {
|
|
3845
4470
|
type: "object",
|
|
3846
4471
|
properties: {
|
|
@@ -3848,211 +4473,225 @@ function registerFuturesTools() {
|
|
|
3848
4473
|
type: "string",
|
|
3849
4474
|
description: "e.g. BTC-USDT-240329"
|
|
3850
4475
|
},
|
|
3851
|
-
|
|
4476
|
+
mgnMode: {
|
|
3852
4477
|
type: "string",
|
|
3853
|
-
|
|
4478
|
+
enum: ["cross", "isolated"]
|
|
4479
|
+
},
|
|
4480
|
+
posSide: {
|
|
4481
|
+
type: "string",
|
|
4482
|
+
enum: ["long", "short", "net"],
|
|
4483
|
+
description: "long/short=hedge mode; omit for one-way (net)"
|
|
4484
|
+
},
|
|
4485
|
+
autoCxl: {
|
|
4486
|
+
type: "boolean",
|
|
4487
|
+
description: "Cancel pending orders for this instrument on close"
|
|
3854
4488
|
},
|
|
3855
4489
|
clOrdId: {
|
|
3856
4490
|
type: "string",
|
|
3857
|
-
description: "
|
|
4491
|
+
description: "Client order ID for close order"
|
|
3858
4492
|
}
|
|
3859
4493
|
},
|
|
3860
|
-
required: ["instId"]
|
|
4494
|
+
required: ["instId", "mgnMode"]
|
|
3861
4495
|
},
|
|
3862
4496
|
handler: async (rawArgs, context) => {
|
|
3863
4497
|
const args = asRecord(rawArgs);
|
|
3864
|
-
const
|
|
3865
|
-
|
|
4498
|
+
const autoCxl = args.autoCxl;
|
|
4499
|
+
const response = await context.client.privatePost(
|
|
4500
|
+
"/api/v5/trade/close-position",
|
|
3866
4501
|
compactObject({
|
|
3867
4502
|
instId: requireString(args, "instId"),
|
|
3868
|
-
|
|
3869
|
-
|
|
4503
|
+
mgnMode: requireString(args, "mgnMode"),
|
|
4504
|
+
posSide: readString(args, "posSide"),
|
|
4505
|
+
autoCxl: typeof autoCxl === "boolean" ? String(autoCxl) : void 0,
|
|
4506
|
+
clOrdId: readString(args, "clOrdId"),
|
|
4507
|
+
tag: context.config.sourceTag
|
|
3870
4508
|
}),
|
|
3871
|
-
privateRateLimit("
|
|
4509
|
+
privateRateLimit("futures_close_position", 20)
|
|
3872
4510
|
);
|
|
3873
4511
|
return normalizeResponse(response);
|
|
3874
4512
|
}
|
|
3875
4513
|
},
|
|
3876
4514
|
{
|
|
3877
|
-
name: "
|
|
4515
|
+
name: "futures_set_leverage",
|
|
3878
4516
|
module: "futures",
|
|
3879
|
-
description: "
|
|
3880
|
-
isWrite:
|
|
4517
|
+
description: "Set leverage for a FUTURES delivery instrument or position. [CAUTION] Changes risk parameters.",
|
|
4518
|
+
isWrite: true,
|
|
3881
4519
|
inputSchema: {
|
|
3882
4520
|
type: "object",
|
|
3883
4521
|
properties: {
|
|
3884
|
-
status: {
|
|
3885
|
-
type: "string",
|
|
3886
|
-
enum: ["open", "history", "archive"],
|
|
3887
|
-
description: "open=active, history=7d, archive=3mo"
|
|
3888
|
-
},
|
|
3889
|
-
instType: {
|
|
3890
|
-
type: "string",
|
|
3891
|
-
enum: [...FUTURES_INST_TYPES],
|
|
3892
|
-
description: "FUTURES (default) or SWAP"
|
|
3893
|
-
},
|
|
3894
4522
|
instId: {
|
|
3895
4523
|
type: "string",
|
|
3896
4524
|
description: "e.g. BTC-USDT-240329"
|
|
3897
4525
|
},
|
|
3898
|
-
|
|
3899
|
-
type: "string",
|
|
3900
|
-
description: "Order type filter"
|
|
3901
|
-
},
|
|
3902
|
-
state: {
|
|
3903
|
-
type: "string",
|
|
3904
|
-
description: "canceled|filled"
|
|
3905
|
-
},
|
|
3906
|
-
after: {
|
|
3907
|
-
type: "string",
|
|
3908
|
-
description: "Pagination: before this order ID"
|
|
3909
|
-
},
|
|
3910
|
-
before: {
|
|
4526
|
+
lever: {
|
|
3911
4527
|
type: "string",
|
|
3912
|
-
description: "
|
|
4528
|
+
description: "Leverage, e.g. '10'"
|
|
3913
4529
|
},
|
|
3914
|
-
|
|
4530
|
+
mgnMode: {
|
|
3915
4531
|
type: "string",
|
|
3916
|
-
|
|
4532
|
+
enum: ["cross", "isolated"]
|
|
3917
4533
|
},
|
|
3918
|
-
|
|
4534
|
+
posSide: {
|
|
3919
4535
|
type: "string",
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
limit: {
|
|
3923
|
-
type: "number",
|
|
3924
|
-
description: "Max results (default 100)"
|
|
4536
|
+
enum: ["long", "short", "net"],
|
|
4537
|
+
description: "Required for isolated margin in hedge mode"
|
|
3925
4538
|
}
|
|
3926
|
-
}
|
|
4539
|
+
},
|
|
4540
|
+
required: ["instId", "lever", "mgnMode"]
|
|
3927
4541
|
},
|
|
3928
4542
|
handler: async (rawArgs, context) => {
|
|
3929
4543
|
const args = asRecord(rawArgs);
|
|
3930
|
-
const
|
|
3931
|
-
|
|
3932
|
-
assertEnum(instType, "instType", FUTURES_INST_TYPES);
|
|
3933
|
-
const path4 = status === "archive" ? "/api/v5/trade/orders-history-archive" : status === "history" ? "/api/v5/trade/orders-history" : "/api/v5/trade/orders-pending";
|
|
3934
|
-
const response = await context.client.privateGet(
|
|
3935
|
-
path4,
|
|
4544
|
+
const response = await context.client.privatePost(
|
|
4545
|
+
"/api/v5/account/set-leverage",
|
|
3936
4546
|
compactObject({
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
after: readString(args, "after"),
|
|
3942
|
-
before: readString(args, "before"),
|
|
3943
|
-
begin: readString(args, "begin"),
|
|
3944
|
-
end: readString(args, "end"),
|
|
3945
|
-
limit: readNumber(args, "limit")
|
|
4547
|
+
instId: requireString(args, "instId"),
|
|
4548
|
+
lever: requireString(args, "lever"),
|
|
4549
|
+
mgnMode: requireString(args, "mgnMode"),
|
|
4550
|
+
posSide: readString(args, "posSide")
|
|
3946
4551
|
}),
|
|
3947
|
-
privateRateLimit("
|
|
4552
|
+
privateRateLimit("futures_set_leverage", 20)
|
|
3948
4553
|
);
|
|
3949
4554
|
return normalizeResponse(response);
|
|
3950
4555
|
}
|
|
3951
4556
|
},
|
|
3952
4557
|
{
|
|
3953
|
-
name: "
|
|
4558
|
+
name: "futures_get_leverage",
|
|
3954
4559
|
module: "futures",
|
|
3955
|
-
description: "Get current FUTURES delivery
|
|
4560
|
+
description: "Get current leverage for a FUTURES delivery instrument.",
|
|
3956
4561
|
isWrite: false,
|
|
3957
4562
|
inputSchema: {
|
|
3958
4563
|
type: "object",
|
|
3959
4564
|
properties: {
|
|
3960
|
-
instType: {
|
|
3961
|
-
type: "string",
|
|
3962
|
-
enum: [...FUTURES_INST_TYPES],
|
|
3963
|
-
description: "FUTURES (default) or SWAP"
|
|
3964
|
-
},
|
|
3965
4565
|
instId: {
|
|
3966
4566
|
type: "string",
|
|
3967
4567
|
description: "e.g. BTC-USDT-240329"
|
|
3968
4568
|
},
|
|
3969
|
-
|
|
3970
|
-
type: "string"
|
|
4569
|
+
mgnMode: {
|
|
4570
|
+
type: "string",
|
|
4571
|
+
enum: ["cross", "isolated"]
|
|
3971
4572
|
}
|
|
3972
|
-
}
|
|
4573
|
+
},
|
|
4574
|
+
required: ["instId", "mgnMode"]
|
|
3973
4575
|
},
|
|
3974
4576
|
handler: async (rawArgs, context) => {
|
|
3975
4577
|
const args = asRecord(rawArgs);
|
|
3976
|
-
const instType = readString(args, "instType") ?? "FUTURES";
|
|
3977
|
-
assertEnum(instType, "instType", FUTURES_INST_TYPES);
|
|
3978
4578
|
const response = await context.client.privateGet(
|
|
3979
|
-
"/api/v5/account/
|
|
4579
|
+
"/api/v5/account/leverage-info",
|
|
3980
4580
|
compactObject({
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
posId: readString(args, "posId")
|
|
4581
|
+
instId: requireString(args, "instId"),
|
|
4582
|
+
mgnMode: requireString(args, "mgnMode")
|
|
3984
4583
|
}),
|
|
3985
|
-
privateRateLimit("
|
|
4584
|
+
privateRateLimit("futures_get_leverage", 20)
|
|
3986
4585
|
);
|
|
3987
4586
|
return normalizeResponse(response);
|
|
3988
4587
|
}
|
|
3989
4588
|
},
|
|
3990
4589
|
{
|
|
3991
|
-
name: "
|
|
4590
|
+
name: "futures_batch_orders",
|
|
3992
4591
|
module: "futures",
|
|
3993
|
-
description: "
|
|
3994
|
-
isWrite:
|
|
4592
|
+
description: "[CAUTION] Batch place up to 20 FUTURES delivery orders in one request. Private. Rate limit: 60 req/s.",
|
|
4593
|
+
isWrite: true,
|
|
3995
4594
|
inputSchema: {
|
|
3996
4595
|
type: "object",
|
|
3997
4596
|
properties: {
|
|
3998
|
-
|
|
3999
|
-
type: "
|
|
4000
|
-
description: "
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
}
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4597
|
+
orders: {
|
|
4598
|
+
type: "array",
|
|
4599
|
+
description: "Array (max 20): {instId,tdMode,side,ordType,sz,px?,posSide?,reduceOnly?,clOrdId?,tpTriggerPx?,tpOrdPx?,slTriggerPx?,slOrdPx?}",
|
|
4600
|
+
items: {
|
|
4601
|
+
type: "object"
|
|
4602
|
+
}
|
|
4603
|
+
}
|
|
4604
|
+
},
|
|
4605
|
+
required: ["orders"]
|
|
4606
|
+
},
|
|
4607
|
+
handler: async (rawArgs, context) => {
|
|
4608
|
+
const args = asRecord(rawArgs);
|
|
4609
|
+
const orders = args.orders;
|
|
4610
|
+
if (!Array.isArray(orders) || orders.length === 0) {
|
|
4611
|
+
throw new Error("orders must be a non-empty array.");
|
|
4612
|
+
}
|
|
4613
|
+
const body = orders.map((order) => {
|
|
4614
|
+
const o = asRecord(order);
|
|
4615
|
+
const attachAlgoOrds = buildAttachAlgoOrds(o);
|
|
4616
|
+
const reduceOnly = o.reduceOnly;
|
|
4617
|
+
return compactObject({
|
|
4618
|
+
instId: requireString(o, "instId"),
|
|
4619
|
+
tdMode: requireString(o, "tdMode"),
|
|
4620
|
+
side: requireString(o, "side"),
|
|
4621
|
+
ordType: requireString(o, "ordType"),
|
|
4622
|
+
sz: requireString(o, "sz"),
|
|
4623
|
+
px: readString(o, "px"),
|
|
4624
|
+
posSide: readString(o, "posSide"),
|
|
4625
|
+
reduceOnly: typeof reduceOnly === "boolean" ? String(reduceOnly) : void 0,
|
|
4626
|
+
clOrdId: readString(o, "clOrdId"),
|
|
4627
|
+
tag: context.config.sourceTag,
|
|
4628
|
+
attachAlgoOrds
|
|
4629
|
+
});
|
|
4630
|
+
});
|
|
4631
|
+
const response = await context.client.privatePost(
|
|
4632
|
+
"/api/v5/trade/batch-orders",
|
|
4633
|
+
body,
|
|
4634
|
+
privateRateLimit("futures_batch_orders", 60)
|
|
4635
|
+
);
|
|
4636
|
+
return normalizeResponse(response);
|
|
4637
|
+
}
|
|
4638
|
+
},
|
|
4639
|
+
{
|
|
4640
|
+
name: "futures_batch_amend",
|
|
4641
|
+
module: "futures",
|
|
4642
|
+
description: "[CAUTION] Batch amend up to 20 unfilled FUTURES delivery orders in one request.",
|
|
4643
|
+
isWrite: true,
|
|
4644
|
+
inputSchema: {
|
|
4645
|
+
type: "object",
|
|
4646
|
+
properties: {
|
|
4647
|
+
orders: {
|
|
4648
|
+
type: "array",
|
|
4649
|
+
description: "Array (max 20): {instId, ordId?, clOrdId?, newSz?, newPx?}",
|
|
4650
|
+
items: { type: "object" }
|
|
4651
|
+
}
|
|
4652
|
+
},
|
|
4653
|
+
required: ["orders"]
|
|
4654
|
+
},
|
|
4655
|
+
handler: async (rawArgs, context) => {
|
|
4656
|
+
const args = asRecord(rawArgs);
|
|
4657
|
+
const orders = args.orders;
|
|
4658
|
+
if (!Array.isArray(orders) || orders.length === 0) {
|
|
4659
|
+
throw new Error("orders must be a non-empty array.");
|
|
4660
|
+
}
|
|
4661
|
+
const response = await context.client.privatePost(
|
|
4662
|
+
"/api/v5/trade/amend-batch-orders",
|
|
4663
|
+
orders,
|
|
4664
|
+
privateRateLimit("futures_batch_amend", 60)
|
|
4665
|
+
);
|
|
4666
|
+
return normalizeResponse(response);
|
|
4667
|
+
}
|
|
4668
|
+
},
|
|
4669
|
+
{
|
|
4670
|
+
name: "futures_batch_cancel",
|
|
4671
|
+
module: "futures",
|
|
4672
|
+
description: "[CAUTION] Batch cancel up to 20 FUTURES delivery orders in one request.",
|
|
4673
|
+
isWrite: true,
|
|
4674
|
+
inputSchema: {
|
|
4675
|
+
type: "object",
|
|
4676
|
+
properties: {
|
|
4677
|
+
orders: {
|
|
4678
|
+
type: "array",
|
|
4679
|
+
description: "Array (max 20): {instId, ordId?, clOrdId?}",
|
|
4680
|
+
items: { type: "object" }
|
|
4034
4681
|
}
|
|
4035
|
-
}
|
|
4682
|
+
},
|
|
4683
|
+
required: ["orders"]
|
|
4036
4684
|
},
|
|
4037
4685
|
handler: async (rawArgs, context) => {
|
|
4038
4686
|
const args = asRecord(rawArgs);
|
|
4039
|
-
const
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
const response = await context.client.
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
instId: readString(args, "instId"),
|
|
4048
|
-
ordId: readString(args, "ordId"),
|
|
4049
|
-
after: readString(args, "after"),
|
|
4050
|
-
before: readString(args, "before"),
|
|
4051
|
-
begin: readString(args, "begin"),
|
|
4052
|
-
end: readString(args, "end"),
|
|
4053
|
-
limit: readNumber(args, "limit") ?? (archive ? 20 : void 0)
|
|
4054
|
-
}),
|
|
4055
|
-
privateRateLimit("futures_get_fills", 20)
|
|
4687
|
+
const orders = args.orders;
|
|
4688
|
+
if (!Array.isArray(orders) || orders.length === 0) {
|
|
4689
|
+
throw new Error("orders must be a non-empty array.");
|
|
4690
|
+
}
|
|
4691
|
+
const response = await context.client.privatePost(
|
|
4692
|
+
"/api/v5/trade/cancel-batch-orders",
|
|
4693
|
+
orders,
|
|
4694
|
+
privateRateLimit("futures_batch_cancel", 60)
|
|
4056
4695
|
);
|
|
4057
4696
|
return normalizeResponse(response);
|
|
4058
4697
|
}
|
|
@@ -4465,103 +5104,360 @@ function registerMarketTools() {
|
|
|
4465
5104
|
}
|
|
4466
5105
|
},
|
|
4467
5106
|
{
|
|
4468
|
-
name: "market_get_price_limit",
|
|
4469
|
-
module: "market",
|
|
4470
|
-
description: "Get the current price limit (upper and lower bands) for a SWAP or FUTURES instrument. Orders outside these limits will be rejected.",
|
|
4471
|
-
isWrite: false,
|
|
5107
|
+
name: "market_get_price_limit",
|
|
5108
|
+
module: "market",
|
|
5109
|
+
description: "Get the current price limit (upper and lower bands) for a SWAP or FUTURES instrument. Orders outside these limits will be rejected.",
|
|
5110
|
+
isWrite: false,
|
|
5111
|
+
inputSchema: {
|
|
5112
|
+
type: "object",
|
|
5113
|
+
properties: {
|
|
5114
|
+
instId: {
|
|
5115
|
+
type: "string",
|
|
5116
|
+
description: "SWAP or FUTURES ID, e.g. BTC-USDT-SWAP"
|
|
5117
|
+
}
|
|
5118
|
+
},
|
|
5119
|
+
required: ["instId"]
|
|
5120
|
+
},
|
|
5121
|
+
handler: async (rawArgs, context) => {
|
|
5122
|
+
const args = asRecord(rawArgs);
|
|
5123
|
+
const response = await context.client.publicGet(
|
|
5124
|
+
"/api/v5/public/price-limit",
|
|
5125
|
+
{ instId: requireString(args, "instId") },
|
|
5126
|
+
publicRateLimit("market_get_price_limit", 20)
|
|
5127
|
+
);
|
|
5128
|
+
return normalizeResponse(response);
|
|
5129
|
+
}
|
|
5130
|
+
},
|
|
5131
|
+
{
|
|
5132
|
+
name: "market_get_open_interest",
|
|
5133
|
+
module: "market",
|
|
5134
|
+
description: "Get open interest for SWAP, FUTURES, or OPTION instruments. Useful for gauging market sentiment and positioning.",
|
|
5135
|
+
isWrite: false,
|
|
5136
|
+
inputSchema: {
|
|
5137
|
+
type: "object",
|
|
5138
|
+
properties: {
|
|
5139
|
+
instType: {
|
|
5140
|
+
type: "string",
|
|
5141
|
+
enum: ["SWAP", "FUTURES", "OPTION"]
|
|
5142
|
+
},
|
|
5143
|
+
instId: {
|
|
5144
|
+
type: "string",
|
|
5145
|
+
description: "e.g. BTC-USDT-SWAP"
|
|
5146
|
+
},
|
|
5147
|
+
uly: {
|
|
5148
|
+
type: "string",
|
|
5149
|
+
description: "e.g. BTC-USD"
|
|
5150
|
+
},
|
|
5151
|
+
instFamily: {
|
|
5152
|
+
type: "string"
|
|
5153
|
+
}
|
|
5154
|
+
},
|
|
5155
|
+
required: ["instType"]
|
|
5156
|
+
},
|
|
5157
|
+
handler: async (rawArgs, context) => {
|
|
5158
|
+
const args = asRecord(rawArgs);
|
|
5159
|
+
const response = await context.client.publicGet(
|
|
5160
|
+
"/api/v5/public/open-interest",
|
|
5161
|
+
compactObject({
|
|
5162
|
+
instType: requireString(args, "instType"),
|
|
5163
|
+
instId: readString(args, "instId"),
|
|
5164
|
+
uly: readString(args, "uly"),
|
|
5165
|
+
instFamily: readString(args, "instFamily")
|
|
5166
|
+
}),
|
|
5167
|
+
publicRateLimit("market_get_open_interest", 20)
|
|
5168
|
+
);
|
|
5169
|
+
return normalizeResponse(response);
|
|
5170
|
+
}
|
|
5171
|
+
},
|
|
5172
|
+
{
|
|
5173
|
+
name: "market_get_stock_tokens",
|
|
5174
|
+
module: "market",
|
|
5175
|
+
description: "Get all stock token instruments (instCategory=3). Stock tokens track real-world stock prices on OKX (e.g. AAPL-USDT-SWAP). Filters client-side by instCategory=3.",
|
|
5176
|
+
isWrite: false,
|
|
5177
|
+
inputSchema: {
|
|
5178
|
+
type: "object",
|
|
5179
|
+
properties: {
|
|
5180
|
+
instType: {
|
|
5181
|
+
type: "string",
|
|
5182
|
+
enum: ["SPOT", "SWAP"],
|
|
5183
|
+
description: "Instrument type. Default: SWAP"
|
|
5184
|
+
},
|
|
5185
|
+
instId: {
|
|
5186
|
+
type: "string",
|
|
5187
|
+
description: "Optional: filter by specific instrument ID, e.g. AAPL-USDT-SWAP"
|
|
5188
|
+
}
|
|
5189
|
+
},
|
|
5190
|
+
required: []
|
|
5191
|
+
},
|
|
5192
|
+
handler: async (rawArgs, context) => {
|
|
5193
|
+
const args = asRecord(rawArgs);
|
|
5194
|
+
const instType = readString(args, "instType") ?? "SWAP";
|
|
5195
|
+
const instId = readString(args, "instId");
|
|
5196
|
+
const response = await context.client.publicGet(
|
|
5197
|
+
"/api/v5/public/instruments",
|
|
5198
|
+
compactObject({ instType, instId }),
|
|
5199
|
+
publicRateLimit("market_get_stock_tokens", 20)
|
|
5200
|
+
);
|
|
5201
|
+
const data = response.data;
|
|
5202
|
+
const filtered = Array.isArray(data) ? data.filter((item) => item.instCategory === "3") : data;
|
|
5203
|
+
return normalizeResponse({ ...response, data: filtered });
|
|
5204
|
+
}
|
|
5205
|
+
}
|
|
5206
|
+
];
|
|
5207
|
+
}
|
|
5208
|
+
function registerOptionAlgoTools() {
|
|
5209
|
+
return [
|
|
5210
|
+
{
|
|
5211
|
+
name: "option_place_algo_order",
|
|
5212
|
+
module: "option",
|
|
5213
|
+
description: "Place an OPTION algo order: TP/SL (conditional/oco). [CAUTION] Executes real trades. conditional: single TP, single SL, or both on one order. oco: TP+SL simultaneously \u2014 first trigger cancels the other. Set tpOrdPx='-1' or slOrdPx='-1' for market execution.",
|
|
5214
|
+
isWrite: true,
|
|
5215
|
+
inputSchema: {
|
|
5216
|
+
type: "object",
|
|
5217
|
+
properties: {
|
|
5218
|
+
instId: {
|
|
5219
|
+
type: "string",
|
|
5220
|
+
description: "e.g. BTC-USD-241227-50000-C"
|
|
5221
|
+
},
|
|
5222
|
+
tdMode: {
|
|
5223
|
+
type: "string",
|
|
5224
|
+
enum: ["cash", "cross", "isolated"],
|
|
5225
|
+
description: "cash=buyer full premium; cross/isolated=seller margin"
|
|
5226
|
+
},
|
|
5227
|
+
side: {
|
|
5228
|
+
type: "string",
|
|
5229
|
+
enum: ["buy", "sell"],
|
|
5230
|
+
description: "sell=close long, buy=close short"
|
|
5231
|
+
},
|
|
5232
|
+
ordType: {
|
|
5233
|
+
type: "string",
|
|
5234
|
+
enum: ["conditional", "oco"],
|
|
5235
|
+
description: "conditional=single TP/SL or both; oco=TP+SL pair (first trigger cancels other)"
|
|
5236
|
+
},
|
|
5237
|
+
sz: {
|
|
5238
|
+
type: "string",
|
|
5239
|
+
description: "Number of contracts (NOT USDT amount). Use market_get_instruments to get ctVal for conversion."
|
|
5240
|
+
},
|
|
5241
|
+
tpTriggerPx: {
|
|
5242
|
+
type: "string",
|
|
5243
|
+
description: "TP trigger price (conditional/oco only)"
|
|
5244
|
+
},
|
|
5245
|
+
tpOrdPx: {
|
|
5246
|
+
type: "string",
|
|
5247
|
+
description: "TP order price; -1=market (conditional/oco only)"
|
|
5248
|
+
},
|
|
5249
|
+
tpTriggerPxType: {
|
|
5250
|
+
type: "string",
|
|
5251
|
+
enum: ["last", "index", "mark"],
|
|
5252
|
+
description: "last(default)|index|mark (conditional/oco only)"
|
|
5253
|
+
},
|
|
5254
|
+
slTriggerPx: {
|
|
5255
|
+
type: "string",
|
|
5256
|
+
description: "SL trigger price (conditional/oco only)"
|
|
5257
|
+
},
|
|
5258
|
+
slOrdPx: {
|
|
5259
|
+
type: "string",
|
|
5260
|
+
description: "SL order price; -1=market (recommended) (conditional/oco only)"
|
|
5261
|
+
},
|
|
5262
|
+
slTriggerPxType: {
|
|
5263
|
+
type: "string",
|
|
5264
|
+
enum: ["last", "index", "mark"],
|
|
5265
|
+
description: "last(default)|index|mark (conditional/oco only)"
|
|
5266
|
+
},
|
|
5267
|
+
reduceOnly: {
|
|
5268
|
+
type: "boolean",
|
|
5269
|
+
description: "Ensure order only reduces position"
|
|
5270
|
+
},
|
|
5271
|
+
clOrdId: {
|
|
5272
|
+
type: "string",
|
|
5273
|
+
description: "Client order ID (max 32 chars)"
|
|
5274
|
+
}
|
|
5275
|
+
},
|
|
5276
|
+
required: ["instId", "tdMode", "side", "ordType", "sz"]
|
|
5277
|
+
},
|
|
5278
|
+
handler: async (rawArgs, context) => {
|
|
5279
|
+
const args = asRecord(rawArgs);
|
|
5280
|
+
const reduceOnly = readBoolean(args, "reduceOnly");
|
|
5281
|
+
const response = await context.client.privatePost(
|
|
5282
|
+
"/api/v5/trade/order-algo",
|
|
5283
|
+
compactObject({
|
|
5284
|
+
instId: requireString(args, "instId"),
|
|
5285
|
+
tdMode: requireString(args, "tdMode"),
|
|
5286
|
+
side: requireString(args, "side"),
|
|
5287
|
+
ordType: requireString(args, "ordType"),
|
|
5288
|
+
sz: requireString(args, "sz"),
|
|
5289
|
+
tpTriggerPx: readString(args, "tpTriggerPx"),
|
|
5290
|
+
tpOrdPx: readString(args, "tpOrdPx"),
|
|
5291
|
+
tpTriggerPxType: readString(args, "tpTriggerPxType"),
|
|
5292
|
+
slTriggerPx: readString(args, "slTriggerPx"),
|
|
5293
|
+
slOrdPx: readString(args, "slOrdPx"),
|
|
5294
|
+
slTriggerPxType: readString(args, "slTriggerPxType"),
|
|
5295
|
+
reduceOnly: reduceOnly !== void 0 ? String(reduceOnly) : void 0,
|
|
5296
|
+
clOrdId: readString(args, "clOrdId"),
|
|
5297
|
+
tag: context.config.sourceTag
|
|
5298
|
+
}),
|
|
5299
|
+
privateRateLimit("option_place_algo_order", 20)
|
|
5300
|
+
);
|
|
5301
|
+
return normalizeResponse(response);
|
|
5302
|
+
}
|
|
5303
|
+
},
|
|
5304
|
+
{
|
|
5305
|
+
name: "option_amend_algo_order",
|
|
5306
|
+
module: "option",
|
|
5307
|
+
description: "Amend a pending OPTION algo order (modify TP/SL prices or size).",
|
|
5308
|
+
isWrite: true,
|
|
5309
|
+
inputSchema: {
|
|
5310
|
+
type: "object",
|
|
5311
|
+
properties: {
|
|
5312
|
+
instId: { type: "string", description: "e.g. BTC-USD-241227-50000-C" },
|
|
5313
|
+
algoId: { type: "string", description: "Algo order ID" },
|
|
5314
|
+
newSz: { type: "string", description: "New number of contracts" },
|
|
5315
|
+
newTpTriggerPx: { type: "string", description: "New TP trigger price" },
|
|
5316
|
+
newTpOrdPx: { type: "string", description: "New TP order price; -1=market" },
|
|
5317
|
+
newSlTriggerPx: { type: "string", description: "New SL trigger price" },
|
|
5318
|
+
newSlOrdPx: { type: "string", description: "New SL order price; -1=market" }
|
|
5319
|
+
},
|
|
5320
|
+
required: ["instId", "algoId"]
|
|
5321
|
+
},
|
|
5322
|
+
handler: async (rawArgs, context) => {
|
|
5323
|
+
const args = asRecord(rawArgs);
|
|
5324
|
+
const response = await context.client.privatePost(
|
|
5325
|
+
"/api/v5/trade/amend-algos",
|
|
5326
|
+
compactObject({
|
|
5327
|
+
instId: requireString(args, "instId"),
|
|
5328
|
+
algoId: requireString(args, "algoId"),
|
|
5329
|
+
newSz: readString(args, "newSz"),
|
|
5330
|
+
newTpTriggerPx: readString(args, "newTpTriggerPx"),
|
|
5331
|
+
newTpOrdPx: readString(args, "newTpOrdPx"),
|
|
5332
|
+
newSlTriggerPx: readString(args, "newSlTriggerPx"),
|
|
5333
|
+
newSlOrdPx: readString(args, "newSlOrdPx")
|
|
5334
|
+
}),
|
|
5335
|
+
privateRateLimit("option_amend_algo_order", 20)
|
|
5336
|
+
);
|
|
5337
|
+
return normalizeResponse(response);
|
|
5338
|
+
}
|
|
5339
|
+
},
|
|
5340
|
+
{
|
|
5341
|
+
name: "option_cancel_algo_orders",
|
|
5342
|
+
module: "option",
|
|
5343
|
+
description: "Cancel one or more pending OPTION algo orders (TP/SL). Accepts a list of {algoId, instId} objects.",
|
|
5344
|
+
isWrite: true,
|
|
4472
5345
|
inputSchema: {
|
|
4473
5346
|
type: "object",
|
|
4474
5347
|
properties: {
|
|
4475
|
-
|
|
4476
|
-
type: "
|
|
4477
|
-
description: "
|
|
5348
|
+
orders: {
|
|
5349
|
+
type: "array",
|
|
5350
|
+
description: "List of algo orders to cancel. Each item: {algoId, instId}.",
|
|
5351
|
+
items: {
|
|
5352
|
+
type: "object",
|
|
5353
|
+
properties: {
|
|
5354
|
+
algoId: {
|
|
5355
|
+
type: "string",
|
|
5356
|
+
description: "Algo order ID"
|
|
5357
|
+
},
|
|
5358
|
+
instId: {
|
|
5359
|
+
type: "string",
|
|
5360
|
+
description: "e.g. BTC-USD-241227-50000-C"
|
|
5361
|
+
}
|
|
5362
|
+
},
|
|
5363
|
+
required: ["algoId", "instId"]
|
|
5364
|
+
}
|
|
4478
5365
|
}
|
|
4479
5366
|
},
|
|
4480
|
-
required: ["
|
|
5367
|
+
required: ["orders"]
|
|
4481
5368
|
},
|
|
4482
5369
|
handler: async (rawArgs, context) => {
|
|
4483
5370
|
const args = asRecord(rawArgs);
|
|
4484
|
-
const
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
5371
|
+
const orders = args.orders;
|
|
5372
|
+
if (!Array.isArray(orders) || orders.length === 0) {
|
|
5373
|
+
throw new Error("orders must be a non-empty array.");
|
|
5374
|
+
}
|
|
5375
|
+
const response = await context.client.privatePost(
|
|
5376
|
+
"/api/v5/trade/cancel-algos",
|
|
5377
|
+
orders,
|
|
5378
|
+
privateRateLimit("option_cancel_algo_orders", 20)
|
|
4488
5379
|
);
|
|
4489
5380
|
return normalizeResponse(response);
|
|
4490
5381
|
}
|
|
4491
5382
|
},
|
|
4492
5383
|
{
|
|
4493
|
-
name: "
|
|
4494
|
-
module: "
|
|
4495
|
-
description: "
|
|
5384
|
+
name: "option_get_algo_orders",
|
|
5385
|
+
module: "option",
|
|
5386
|
+
description: "Query pending or completed OPTION algo orders (TP/SL, OCO).",
|
|
4496
5387
|
isWrite: false,
|
|
4497
5388
|
inputSchema: {
|
|
4498
5389
|
type: "object",
|
|
4499
5390
|
properties: {
|
|
4500
|
-
|
|
5391
|
+
status: {
|
|
4501
5392
|
type: "string",
|
|
4502
|
-
enum: ["
|
|
5393
|
+
enum: ["pending", "history"],
|
|
5394
|
+
description: "pending=active (default); history=completed"
|
|
5395
|
+
},
|
|
5396
|
+
ordType: {
|
|
5397
|
+
type: "string",
|
|
5398
|
+
enum: ["conditional", "oco"],
|
|
5399
|
+
description: "Filter by type; omit for all"
|
|
4503
5400
|
},
|
|
4504
5401
|
instId: {
|
|
4505
5402
|
type: "string",
|
|
4506
|
-
description: "
|
|
5403
|
+
description: "Instrument ID filter"
|
|
4507
5404
|
},
|
|
4508
|
-
|
|
5405
|
+
algoId: {
|
|
4509
5406
|
type: "string",
|
|
4510
|
-
description: "
|
|
5407
|
+
description: "Filter by algo order ID"
|
|
4511
5408
|
},
|
|
4512
|
-
|
|
4513
|
-
type: "string"
|
|
4514
|
-
}
|
|
4515
|
-
},
|
|
4516
|
-
required: ["instType"]
|
|
4517
|
-
},
|
|
4518
|
-
handler: async (rawArgs, context) => {
|
|
4519
|
-
const args = asRecord(rawArgs);
|
|
4520
|
-
const response = await context.client.publicGet(
|
|
4521
|
-
"/api/v5/public/open-interest",
|
|
4522
|
-
compactObject({
|
|
4523
|
-
instType: requireString(args, "instType"),
|
|
4524
|
-
instId: readString(args, "instId"),
|
|
4525
|
-
uly: readString(args, "uly"),
|
|
4526
|
-
instFamily: readString(args, "instFamily")
|
|
4527
|
-
}),
|
|
4528
|
-
publicRateLimit("market_get_open_interest", 20)
|
|
4529
|
-
);
|
|
4530
|
-
return normalizeResponse(response);
|
|
4531
|
-
}
|
|
4532
|
-
},
|
|
4533
|
-
{
|
|
4534
|
-
name: "market_get_stock_tokens",
|
|
4535
|
-
module: "market",
|
|
4536
|
-
description: "Get all stock token instruments (instCategory=3). Stock tokens track real-world stock prices on OKX (e.g. AAPL-USDT-SWAP). Filters client-side by instCategory=3.",
|
|
4537
|
-
isWrite: false,
|
|
4538
|
-
inputSchema: {
|
|
4539
|
-
type: "object",
|
|
4540
|
-
properties: {
|
|
4541
|
-
instType: {
|
|
5409
|
+
after: {
|
|
4542
5410
|
type: "string",
|
|
4543
|
-
|
|
4544
|
-
description: "Instrument type. Default: SWAP"
|
|
5411
|
+
description: "Pagination: before this algo ID"
|
|
4545
5412
|
},
|
|
4546
|
-
|
|
5413
|
+
before: {
|
|
4547
5414
|
type: "string",
|
|
4548
|
-
description: "
|
|
5415
|
+
description: "Pagination: after this algo ID"
|
|
5416
|
+
},
|
|
5417
|
+
limit: {
|
|
5418
|
+
type: "number",
|
|
5419
|
+
description: "Max results (default 100)"
|
|
5420
|
+
},
|
|
5421
|
+
state: {
|
|
5422
|
+
type: "string",
|
|
5423
|
+
enum: ["effective", "canceled", "order_failed"],
|
|
5424
|
+
description: "Required when status=history. effective=triggered, canceled, order_failed. Defaults to effective."
|
|
4549
5425
|
}
|
|
4550
|
-
}
|
|
4551
|
-
required: []
|
|
5426
|
+
}
|
|
4552
5427
|
},
|
|
4553
5428
|
handler: async (rawArgs, context) => {
|
|
4554
5429
|
const args = asRecord(rawArgs);
|
|
4555
|
-
const
|
|
4556
|
-
const
|
|
4557
|
-
const
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
5430
|
+
const status = readString(args, "status") ?? "pending";
|
|
5431
|
+
const isHistory = status === "history";
|
|
5432
|
+
const path4 = isHistory ? "/api/v5/trade/orders-algo-history" : "/api/v5/trade/orders-algo-pending";
|
|
5433
|
+
const ordType = readString(args, "ordType");
|
|
5434
|
+
const state = isHistory ? readString(args, "state") ?? "effective" : void 0;
|
|
5435
|
+
const baseParams = compactObject({
|
|
5436
|
+
instType: "OPTION",
|
|
5437
|
+
instId: readString(args, "instId"),
|
|
5438
|
+
algoId: readString(args, "algoId"),
|
|
5439
|
+
after: readString(args, "after"),
|
|
5440
|
+
before: readString(args, "before"),
|
|
5441
|
+
limit: readNumber(args, "limit"),
|
|
5442
|
+
state
|
|
5443
|
+
});
|
|
5444
|
+
if (ordType) {
|
|
5445
|
+
const response = await context.client.privateGet(
|
|
5446
|
+
path4,
|
|
5447
|
+
{ ...baseParams, ordType },
|
|
5448
|
+
privateRateLimit("option_get_algo_orders", 20)
|
|
5449
|
+
);
|
|
5450
|
+
return normalizeResponse(response);
|
|
5451
|
+
}
|
|
5452
|
+
const [r1, r2] = await Promise.all([
|
|
5453
|
+
context.client.privateGet(path4, { ...baseParams, ordType: "conditional" }, privateRateLimit("option_get_algo_orders", 20)),
|
|
5454
|
+
context.client.privateGet(path4, { ...baseParams, ordType: "oco" }, privateRateLimit("option_get_algo_orders", 20))
|
|
5455
|
+
]);
|
|
5456
|
+
const merged = [
|
|
5457
|
+
...r1.data ?? [],
|
|
5458
|
+
...r2.data ?? []
|
|
5459
|
+
];
|
|
5460
|
+
return { endpoint: r1.endpoint, requestTime: r1.requestTime, data: merged };
|
|
4565
5461
|
}
|
|
4566
5462
|
}
|
|
4567
5463
|
];
|
|
@@ -4609,6 +5505,22 @@ function registerOptionTools() {
|
|
|
4609
5505
|
clOrdId: {
|
|
4610
5506
|
type: "string",
|
|
4611
5507
|
description: "Client order ID (max 32 chars)"
|
|
5508
|
+
},
|
|
5509
|
+
tpTriggerPx: {
|
|
5510
|
+
type: "string",
|
|
5511
|
+
description: "TP trigger price; attaches a take-profit algo order"
|
|
5512
|
+
},
|
|
5513
|
+
tpOrdPx: {
|
|
5514
|
+
type: "string",
|
|
5515
|
+
description: "TP order price; -1=market"
|
|
5516
|
+
},
|
|
5517
|
+
slTriggerPx: {
|
|
5518
|
+
type: "string",
|
|
5519
|
+
description: "SL trigger price; attaches a stop-loss algo order"
|
|
5520
|
+
},
|
|
5521
|
+
slOrdPx: {
|
|
5522
|
+
type: "string",
|
|
5523
|
+
description: "SL order price; -1=market (recommended)"
|
|
4612
5524
|
}
|
|
4613
5525
|
},
|
|
4614
5526
|
required: ["instId", "tdMode", "side", "ordType", "sz"]
|
|
@@ -4616,6 +5528,7 @@ function registerOptionTools() {
|
|
|
4616
5528
|
handler: async (rawArgs, context) => {
|
|
4617
5529
|
const args = asRecord(rawArgs);
|
|
4618
5530
|
const reduceOnly = args.reduceOnly;
|
|
5531
|
+
const attachAlgoOrds = buildAttachAlgoOrds(args);
|
|
4619
5532
|
const response = await context.client.privatePost(
|
|
4620
5533
|
"/api/v5/trade/order",
|
|
4621
5534
|
compactObject({
|
|
@@ -4627,7 +5540,8 @@ function registerOptionTools() {
|
|
|
4627
5540
|
px: readString(args, "px"),
|
|
4628
5541
|
reduceOnly: typeof reduceOnly === "boolean" ? String(reduceOnly) : void 0,
|
|
4629
5542
|
clOrdId: readString(args, "clOrdId"),
|
|
4630
|
-
tag: context.config.sourceTag
|
|
5543
|
+
tag: context.config.sourceTag,
|
|
5544
|
+
attachAlgoOrds
|
|
4631
5545
|
}),
|
|
4632
5546
|
privateRateLimit("option_place_order", 60)
|
|
4633
5547
|
);
|
|
@@ -6265,7 +7179,9 @@ function allToolSpecs() {
|
|
|
6265
7179
|
...registerSpotTradeTools(),
|
|
6266
7180
|
...registerSwapTradeTools(),
|
|
6267
7181
|
...registerFuturesTools(),
|
|
7182
|
+
...registerFuturesAlgoTools(),
|
|
6268
7183
|
...registerOptionTools(),
|
|
7184
|
+
...registerOptionAlgoTools(),
|
|
6269
7185
|
...registerAlgoTradeTools(),
|
|
6270
7186
|
...registerAccountTools(),
|
|
6271
7187
|
...registerBotTools(),
|
|
@@ -6637,7 +7553,7 @@ function readCliVersion() {
|
|
|
6637
7553
|
return "0.0.0";
|
|
6638
7554
|
}
|
|
6639
7555
|
var CLI_VERSION = readCliVersion();
|
|
6640
|
-
var GIT_HASH = true ? "
|
|
7556
|
+
var GIT_HASH = true ? "d20347a" : "dev";
|
|
6641
7557
|
var Report = class {
|
|
6642
7558
|
lines = [];
|
|
6643
7559
|
add(key, value) {
|
|
@@ -8353,7 +9269,10 @@ async function cmdSpotAlgoPlace(run, opts) {
|
|
|
8353
9269
|
tpTriggerPx: opts.tpTriggerPx,
|
|
8354
9270
|
tpOrdPx: opts.tpOrdPx,
|
|
8355
9271
|
slTriggerPx: opts.slTriggerPx,
|
|
8356
|
-
slOrdPx: opts.slOrdPx
|
|
9272
|
+
slOrdPx: opts.slOrdPx,
|
|
9273
|
+
callbackRatio: opts.callbackRatio,
|
|
9274
|
+
callbackSpread: opts.callbackSpread,
|
|
9275
|
+
activePx: opts.activePx
|
|
8357
9276
|
});
|
|
8358
9277
|
const data = getData3(result);
|
|
8359
9278
|
if (opts.json) return printJson(data);
|
|
@@ -8603,7 +9522,10 @@ async function cmdSwapAlgoPlace(run, opts) {
|
|
|
8603
9522
|
tpOrdPx: opts.tpOrdPx,
|
|
8604
9523
|
slTriggerPx: opts.slTriggerPx,
|
|
8605
9524
|
slOrdPx: opts.slOrdPx,
|
|
8606
|
-
reduceOnly: opts.reduceOnly
|
|
9525
|
+
reduceOnly: opts.reduceOnly,
|
|
9526
|
+
callbackRatio: opts.callbackRatio,
|
|
9527
|
+
callbackSpread: opts.callbackSpread,
|
|
9528
|
+
activePx: opts.activePx
|
|
8607
9529
|
});
|
|
8608
9530
|
const data = getData4(result);
|
|
8609
9531
|
if (opts.json) return printJson(data);
|
|
@@ -8868,68 +9790,243 @@ async function cmdFuturesFills(run, opts) {
|
|
|
8868
9790
|
}))
|
|
8869
9791
|
);
|
|
8870
9792
|
}
|
|
8871
|
-
async function cmdFuturesPlace(run, opts) {
|
|
8872
|
-
const result = await run("futures_place_order", {
|
|
9793
|
+
async function cmdFuturesPlace(run, opts) {
|
|
9794
|
+
const result = await run("futures_place_order", {
|
|
9795
|
+
instId: opts.instId,
|
|
9796
|
+
tdMode: opts.tdMode,
|
|
9797
|
+
side: opts.side,
|
|
9798
|
+
ordType: opts.ordType,
|
|
9799
|
+
sz: opts.sz,
|
|
9800
|
+
posSide: opts.posSide,
|
|
9801
|
+
px: opts.px,
|
|
9802
|
+
reduceOnly: opts.reduceOnly,
|
|
9803
|
+
tpTriggerPx: opts.tpTriggerPx,
|
|
9804
|
+
tpOrdPx: opts.tpOrdPx,
|
|
9805
|
+
slTriggerPx: opts.slTriggerPx,
|
|
9806
|
+
slOrdPx: opts.slOrdPx
|
|
9807
|
+
});
|
|
9808
|
+
const data = getData5(result);
|
|
9809
|
+
if (opts.json) return printJson(data);
|
|
9810
|
+
const order = data?.[0];
|
|
9811
|
+
process.stdout.write(`Order placed: ${order?.["ordId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9812
|
+
`);
|
|
9813
|
+
}
|
|
9814
|
+
async function cmdFuturesCancel(run, instId, ordId, json) {
|
|
9815
|
+
const result = await run("futures_cancel_order", { instId, ordId });
|
|
9816
|
+
const data = getData5(result);
|
|
9817
|
+
if (json) return printJson(data);
|
|
9818
|
+
const r = data?.[0];
|
|
9819
|
+
process.stdout.write(`Cancelled: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9820
|
+
`);
|
|
9821
|
+
}
|
|
9822
|
+
async function cmdFuturesGet(run, opts) {
|
|
9823
|
+
const result = await run("futures_get_order", { instId: opts.instId, ordId: opts.ordId });
|
|
9824
|
+
const data = getData5(result);
|
|
9825
|
+
if (opts.json) return printJson(data);
|
|
9826
|
+
const o = data?.[0];
|
|
9827
|
+
if (!o) {
|
|
9828
|
+
process.stdout.write("No data\n");
|
|
9829
|
+
return;
|
|
9830
|
+
}
|
|
9831
|
+
printKv({
|
|
9832
|
+
ordId: o["ordId"],
|
|
9833
|
+
instId: o["instId"],
|
|
9834
|
+
side: o["side"],
|
|
9835
|
+
posSide: o["posSide"],
|
|
9836
|
+
ordType: o["ordType"],
|
|
9837
|
+
px: o["px"],
|
|
9838
|
+
sz: o["sz"],
|
|
9839
|
+
fillSz: o["fillSz"],
|
|
9840
|
+
avgPx: o["avgPx"],
|
|
9841
|
+
state: o["state"],
|
|
9842
|
+
cTime: new Date(Number(o["cTime"])).toLocaleString()
|
|
9843
|
+
});
|
|
9844
|
+
}
|
|
9845
|
+
async function cmdFuturesAmend(run, opts) {
|
|
9846
|
+
const result = await run("futures_amend_order", {
|
|
9847
|
+
instId: opts.instId,
|
|
9848
|
+
ordId: opts.ordId,
|
|
9849
|
+
clOrdId: opts.clOrdId,
|
|
9850
|
+
newSz: opts.newSz,
|
|
9851
|
+
newPx: opts.newPx
|
|
9852
|
+
});
|
|
9853
|
+
const data = getData5(result);
|
|
9854
|
+
if (opts.json) return printJson(data);
|
|
9855
|
+
const r = data?.[0];
|
|
9856
|
+
process.stdout.write(`Order amended: ${r?.["ordId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9857
|
+
`);
|
|
9858
|
+
}
|
|
9859
|
+
async function cmdFuturesClose(run, opts) {
|
|
9860
|
+
const result = await run("futures_close_position", {
|
|
9861
|
+
instId: opts.instId,
|
|
9862
|
+
mgnMode: opts.mgnMode,
|
|
9863
|
+
posSide: opts.posSide,
|
|
9864
|
+
autoCxl: opts.autoCxl
|
|
9865
|
+
});
|
|
9866
|
+
const data = getData5(result);
|
|
9867
|
+
if (opts.json) return printJson(data);
|
|
9868
|
+
const r = data?.[0];
|
|
9869
|
+
process.stdout.write(`Position closed: ${r?.["instId"]} ${r?.["posSide"] ?? ""}
|
|
9870
|
+
`);
|
|
9871
|
+
}
|
|
9872
|
+
async function cmdFuturesSetLeverage(run, opts) {
|
|
9873
|
+
const result = await run("futures_set_leverage", {
|
|
9874
|
+
instId: opts.instId,
|
|
9875
|
+
lever: opts.lever,
|
|
9876
|
+
mgnMode: opts.mgnMode,
|
|
9877
|
+
posSide: opts.posSide
|
|
9878
|
+
});
|
|
9879
|
+
const data = getData5(result);
|
|
9880
|
+
if (opts.json) return printJson(data);
|
|
9881
|
+
const r = data?.[0];
|
|
9882
|
+
process.stdout.write(`Leverage set: ${r?.["lever"]}x ${r?.["instId"]}
|
|
9883
|
+
`);
|
|
9884
|
+
}
|
|
9885
|
+
async function cmdFuturesGetLeverage(run, opts) {
|
|
9886
|
+
const result = await run("futures_get_leverage", { instId: opts.instId, mgnMode: opts.mgnMode });
|
|
9887
|
+
const data = getData5(result);
|
|
9888
|
+
if (opts.json) return printJson(data);
|
|
9889
|
+
printTable(
|
|
9890
|
+
(data ?? []).map((r) => ({
|
|
9891
|
+
instId: r["instId"],
|
|
9892
|
+
mgnMode: r["mgnMode"],
|
|
9893
|
+
posSide: r["posSide"],
|
|
9894
|
+
lever: r["lever"]
|
|
9895
|
+
}))
|
|
9896
|
+
);
|
|
9897
|
+
}
|
|
9898
|
+
async function cmdFuturesBatch(run, opts) {
|
|
9899
|
+
let parsed;
|
|
9900
|
+
try {
|
|
9901
|
+
parsed = JSON.parse(opts.orders);
|
|
9902
|
+
} catch {
|
|
9903
|
+
process.stderr.write("Error: --orders must be a valid JSON array\n");
|
|
9904
|
+
process.exitCode = 1;
|
|
9905
|
+
return;
|
|
9906
|
+
}
|
|
9907
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
9908
|
+
process.stderr.write("Error: --orders must be a non-empty JSON array\n");
|
|
9909
|
+
process.exitCode = 1;
|
|
9910
|
+
return;
|
|
9911
|
+
}
|
|
9912
|
+
const toolMap = {
|
|
9913
|
+
place: "futures_batch_orders",
|
|
9914
|
+
amend: "futures_batch_amend",
|
|
9915
|
+
cancel: "futures_batch_cancel"
|
|
9916
|
+
};
|
|
9917
|
+
const tool = toolMap[opts.action];
|
|
9918
|
+
if (!tool) {
|
|
9919
|
+
process.stderr.write(`Error: --action must be one of: place, amend, cancel
|
|
9920
|
+
`);
|
|
9921
|
+
process.exitCode = 1;
|
|
9922
|
+
return;
|
|
9923
|
+
}
|
|
9924
|
+
const result = await run(tool, tool === "futures_batch_orders" ? { orders: parsed } : { orders: parsed });
|
|
9925
|
+
const data = getData5(result);
|
|
9926
|
+
if (opts.json) return printJson(data);
|
|
9927
|
+
for (const r of data ?? []) {
|
|
9928
|
+
process.stdout.write(`${r["ordId"] ?? r["clOrdId"] ?? "?"}: ${r["sCode"] === "0" ? "OK" : r["sMsg"]}
|
|
9929
|
+
`);
|
|
9930
|
+
}
|
|
9931
|
+
}
|
|
9932
|
+
async function cmdFuturesAlgoPlace(run, opts) {
|
|
9933
|
+
const result = await run("futures_place_algo_order", {
|
|
8873
9934
|
instId: opts.instId,
|
|
8874
9935
|
tdMode: opts.tdMode,
|
|
8875
9936
|
side: opts.side,
|
|
8876
9937
|
ordType: opts.ordType,
|
|
8877
9938
|
sz: opts.sz,
|
|
8878
9939
|
posSide: opts.posSide,
|
|
8879
|
-
px: opts.px,
|
|
8880
|
-
reduceOnly: opts.reduceOnly,
|
|
8881
9940
|
tpTriggerPx: opts.tpTriggerPx,
|
|
8882
9941
|
tpOrdPx: opts.tpOrdPx,
|
|
8883
9942
|
slTriggerPx: opts.slTriggerPx,
|
|
8884
|
-
slOrdPx: opts.slOrdPx
|
|
9943
|
+
slOrdPx: opts.slOrdPx,
|
|
9944
|
+
reduceOnly: opts.reduceOnly,
|
|
9945
|
+
callbackRatio: opts.callbackRatio,
|
|
9946
|
+
callbackSpread: opts.callbackSpread,
|
|
9947
|
+
activePx: opts.activePx
|
|
8885
9948
|
});
|
|
8886
9949
|
const data = getData5(result);
|
|
8887
9950
|
if (opts.json) return printJson(data);
|
|
8888
9951
|
const order = data?.[0];
|
|
8889
|
-
process.stdout.write(
|
|
8890
|
-
`)
|
|
9952
|
+
process.stdout.write(
|
|
9953
|
+
`Algo order placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9954
|
+
`
|
|
9955
|
+
);
|
|
8891
9956
|
}
|
|
8892
|
-
async function
|
|
8893
|
-
const result = await run("
|
|
9957
|
+
async function cmdFuturesAlgoTrailPlace(run, opts) {
|
|
9958
|
+
const result = await run("futures_place_move_stop_order", {
|
|
9959
|
+
instId: opts.instId,
|
|
9960
|
+
tdMode: opts.tdMode,
|
|
9961
|
+
side: opts.side,
|
|
9962
|
+
sz: opts.sz,
|
|
9963
|
+
callbackRatio: opts.callbackRatio,
|
|
9964
|
+
callbackSpread: opts.callbackSpread,
|
|
9965
|
+
activePx: opts.activePx,
|
|
9966
|
+
posSide: opts.posSide,
|
|
9967
|
+
reduceOnly: opts.reduceOnly
|
|
9968
|
+
});
|
|
8894
9969
|
const data = getData5(result);
|
|
8895
|
-
if (json) return printJson(data);
|
|
8896
|
-
const
|
|
8897
|
-
process.stdout.write(
|
|
8898
|
-
`)
|
|
9970
|
+
if (opts.json) return printJson(data);
|
|
9971
|
+
const order = data?.[0];
|
|
9972
|
+
process.stdout.write(
|
|
9973
|
+
`Trailing stop placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
9974
|
+
`
|
|
9975
|
+
);
|
|
8899
9976
|
}
|
|
8900
|
-
async function
|
|
8901
|
-
const result = await run("
|
|
9977
|
+
async function cmdFuturesAlgoAmend(run, opts) {
|
|
9978
|
+
const result = await run("futures_amend_algo_order", {
|
|
9979
|
+
instId: opts.instId,
|
|
9980
|
+
algoId: opts.algoId,
|
|
9981
|
+
newSz: opts.newSz,
|
|
9982
|
+
newTpTriggerPx: opts.newTpTriggerPx,
|
|
9983
|
+
newTpOrdPx: opts.newTpOrdPx,
|
|
9984
|
+
newSlTriggerPx: opts.newSlTriggerPx,
|
|
9985
|
+
newSlOrdPx: opts.newSlOrdPx
|
|
9986
|
+
});
|
|
8902
9987
|
const data = getData5(result);
|
|
8903
9988
|
if (opts.json) return printJson(data);
|
|
8904
|
-
const
|
|
8905
|
-
|
|
8906
|
-
|
|
9989
|
+
const r = data?.[0];
|
|
9990
|
+
process.stdout.write(
|
|
9991
|
+
`Algo order amended: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
9992
|
+
`
|
|
9993
|
+
);
|
|
9994
|
+
}
|
|
9995
|
+
async function cmdFuturesAlgoCancel(run, instId, algoId, json) {
|
|
9996
|
+
const result = await run("futures_cancel_algo_orders", { orders: [{ instId, algoId }] });
|
|
9997
|
+
const data = getData5(result);
|
|
9998
|
+
if (json) return printJson(data);
|
|
9999
|
+
const r = data?.[0];
|
|
10000
|
+
process.stdout.write(
|
|
10001
|
+
`Algo order cancelled: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
10002
|
+
`
|
|
10003
|
+
);
|
|
10004
|
+
}
|
|
10005
|
+
async function cmdFuturesAlgoOrders(run, opts) {
|
|
10006
|
+
const result = await run("futures_get_algo_orders", {
|
|
10007
|
+
instId: opts.instId,
|
|
10008
|
+
status: opts.status,
|
|
10009
|
+
ordType: opts.ordType
|
|
10010
|
+
});
|
|
10011
|
+
const orders = getData5(result);
|
|
10012
|
+
if (opts.json) return printJson(orders);
|
|
10013
|
+
if (!(orders ?? []).length) {
|
|
10014
|
+
process.stdout.write("No algo orders\n");
|
|
8907
10015
|
return;
|
|
8908
10016
|
}
|
|
8909
|
-
|
|
8910
|
-
|
|
8911
|
-
|
|
8912
|
-
|
|
8913
|
-
|
|
8914
|
-
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
|
|
8921
|
-
});
|
|
10017
|
+
printTable(
|
|
10018
|
+
orders.map((o) => ({
|
|
10019
|
+
algoId: o["algoId"],
|
|
10020
|
+
instId: o["instId"],
|
|
10021
|
+
type: o["ordType"],
|
|
10022
|
+
side: o["side"],
|
|
10023
|
+
sz: o["sz"],
|
|
10024
|
+
tpTrigger: o["tpTriggerPx"],
|
|
10025
|
+
slTrigger: o["slTriggerPx"],
|
|
10026
|
+
state: o["state"]
|
|
10027
|
+
}))
|
|
10028
|
+
);
|
|
8922
10029
|
}
|
|
8923
|
-
var cmdFuturesAmend = cmdSwapAmend;
|
|
8924
|
-
var cmdFuturesAlgoPlace = cmdSwapAlgoPlace;
|
|
8925
|
-
var cmdFuturesAlgoAmend = cmdSwapAlgoAmend;
|
|
8926
|
-
var cmdFuturesAlgoCancel = cmdSwapAlgoCancel;
|
|
8927
|
-
var cmdFuturesAlgoOrders = cmdSwapAlgoOrders;
|
|
8928
|
-
var cmdFuturesBatch = cmdSwapBatch;
|
|
8929
|
-
var cmdFuturesClose = cmdSwapClose;
|
|
8930
|
-
var cmdFuturesGetLeverage = cmdSwapGetLeverage;
|
|
8931
|
-
var cmdFuturesSetLeverage = cmdSwapSetLeverage;
|
|
8932
|
-
var cmdFuturesAlgoTrailPlace = cmdSwapAlgoTrailPlace;
|
|
8933
10030
|
|
|
8934
10031
|
// src/commands/option.ts
|
|
8935
10032
|
function getData6(result) {
|
|
@@ -9072,7 +10169,11 @@ async function cmdOptionPlace(run, opts) {
|
|
|
9072
10169
|
sz: opts.sz,
|
|
9073
10170
|
px: opts.px,
|
|
9074
10171
|
reduceOnly: opts.reduceOnly,
|
|
9075
|
-
clOrdId: opts.clOrdId
|
|
10172
|
+
clOrdId: opts.clOrdId,
|
|
10173
|
+
tpTriggerPx: opts.tpTriggerPx,
|
|
10174
|
+
tpOrdPx: opts.tpOrdPx,
|
|
10175
|
+
slTriggerPx: opts.slTriggerPx,
|
|
10176
|
+
slOrdPx: opts.slOrdPx
|
|
9076
10177
|
});
|
|
9077
10178
|
const data = getData6(result);
|
|
9078
10179
|
if (opts.json) return printJson(data);
|
|
@@ -9128,6 +10229,81 @@ async function cmdOptionBatchCancel(run, opts) {
|
|
|
9128
10229
|
`);
|
|
9129
10230
|
}
|
|
9130
10231
|
}
|
|
10232
|
+
async function cmdOptionAlgoPlace(run, opts) {
|
|
10233
|
+
const result = await run("option_place_algo_order", {
|
|
10234
|
+
instId: opts.instId,
|
|
10235
|
+
tdMode: opts.tdMode,
|
|
10236
|
+
side: opts.side,
|
|
10237
|
+
ordType: opts.ordType,
|
|
10238
|
+
sz: opts.sz,
|
|
10239
|
+
tpTriggerPx: opts.tpTriggerPx,
|
|
10240
|
+
tpOrdPx: opts.tpOrdPx,
|
|
10241
|
+
slTriggerPx: opts.slTriggerPx,
|
|
10242
|
+
slOrdPx: opts.slOrdPx,
|
|
10243
|
+
reduceOnly: opts.reduceOnly,
|
|
10244
|
+
clOrdId: opts.clOrdId
|
|
10245
|
+
});
|
|
10246
|
+
const data = getData6(result);
|
|
10247
|
+
if (opts.json) return printJson(data);
|
|
10248
|
+
const order = data?.[0];
|
|
10249
|
+
process.stdout.write(
|
|
10250
|
+
`Algo order placed: ${order?.["algoId"]} (${order?.["sCode"] === "0" ? "OK" : order?.["sMsg"]})
|
|
10251
|
+
`
|
|
10252
|
+
);
|
|
10253
|
+
}
|
|
10254
|
+
async function cmdOptionAlgoAmend(run, opts) {
|
|
10255
|
+
const result = await run("option_amend_algo_order", {
|
|
10256
|
+
instId: opts.instId,
|
|
10257
|
+
algoId: opts.algoId,
|
|
10258
|
+
newSz: opts.newSz,
|
|
10259
|
+
newTpTriggerPx: opts.newTpTriggerPx,
|
|
10260
|
+
newTpOrdPx: opts.newTpOrdPx,
|
|
10261
|
+
newSlTriggerPx: opts.newSlTriggerPx,
|
|
10262
|
+
newSlOrdPx: opts.newSlOrdPx
|
|
10263
|
+
});
|
|
10264
|
+
const data = getData6(result);
|
|
10265
|
+
if (opts.json) return printJson(data);
|
|
10266
|
+
const r = data?.[0];
|
|
10267
|
+
process.stdout.write(
|
|
10268
|
+
`Algo order amended: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
10269
|
+
`
|
|
10270
|
+
);
|
|
10271
|
+
}
|
|
10272
|
+
async function cmdOptionAlgoCancel(run, opts) {
|
|
10273
|
+
const result = await run("option_cancel_algo_orders", { orders: [{ instId: opts.instId, algoId: opts.algoId }] });
|
|
10274
|
+
const data = getData6(result);
|
|
10275
|
+
if (opts.json) return printJson(data);
|
|
10276
|
+
const r = data?.[0];
|
|
10277
|
+
process.stdout.write(
|
|
10278
|
+
`Algo order cancelled: ${r?.["algoId"]} (${r?.["sCode"] === "0" ? "OK" : r?.["sMsg"]})
|
|
10279
|
+
`
|
|
10280
|
+
);
|
|
10281
|
+
}
|
|
10282
|
+
async function cmdOptionAlgoOrders(run, opts) {
|
|
10283
|
+
const result = await run("option_get_algo_orders", {
|
|
10284
|
+
instId: opts.instId,
|
|
10285
|
+
status: opts.status,
|
|
10286
|
+
ordType: opts.ordType
|
|
10287
|
+
});
|
|
10288
|
+
const orders = getData6(result);
|
|
10289
|
+
if (opts.json) return printJson(orders);
|
|
10290
|
+
if (!(orders ?? []).length) {
|
|
10291
|
+
process.stdout.write("No algo orders\n");
|
|
10292
|
+
return;
|
|
10293
|
+
}
|
|
10294
|
+
printTable(
|
|
10295
|
+
orders.map((o) => ({
|
|
10296
|
+
algoId: o["algoId"],
|
|
10297
|
+
instId: o["instId"],
|
|
10298
|
+
type: o["ordType"],
|
|
10299
|
+
side: o["side"],
|
|
10300
|
+
sz: o["sz"],
|
|
10301
|
+
tpTrigger: o["tpTriggerPx"],
|
|
10302
|
+
slTrigger: o["slTriggerPx"],
|
|
10303
|
+
state: o["state"]
|
|
10304
|
+
}))
|
|
10305
|
+
);
|
|
10306
|
+
}
|
|
9131
10307
|
|
|
9132
10308
|
// src/config/toml.ts
|
|
9133
10309
|
function writeCliConfig(config) {
|
|
@@ -10190,7 +11366,7 @@ async function cmdDcdQuoteAndBuy(run, opts) {
|
|
|
10190
11366
|
// src/index.ts
|
|
10191
11367
|
var _require2 = createRequire2(import.meta.url);
|
|
10192
11368
|
var CLI_VERSION2 = _require2("../package.json").version;
|
|
10193
|
-
var GIT_HASH2 = true ? "
|
|
11369
|
+
var GIT_HASH2 = true ? "d20347a" : "dev";
|
|
10194
11370
|
function handleConfigCommand(action, rest, json, lang, force) {
|
|
10195
11371
|
if (action === "init") return cmdConfigInit(lang === "zh" ? "zh" : "en");
|
|
10196
11372
|
if (action === "show") return cmdConfigShow(json);
|
|
@@ -10324,6 +11500,9 @@ function handleSpotAlgoCommand(run, subAction, v, json) {
|
|
|
10324
11500
|
tpOrdPx: v.tpOrdPx,
|
|
10325
11501
|
slTriggerPx: v.slTriggerPx,
|
|
10326
11502
|
slOrdPx: v.slOrdPx,
|
|
11503
|
+
callbackRatio: v.callbackRatio,
|
|
11504
|
+
callbackSpread: v.callbackSpread,
|
|
11505
|
+
activePx: v.activePx,
|
|
10327
11506
|
json
|
|
10328
11507
|
});
|
|
10329
11508
|
if (subAction === "amend")
|
|
@@ -10415,6 +11594,9 @@ function handleSwapAlgoCommand(run, subAction, v, json) {
|
|
|
10415
11594
|
slTriggerPx: v.slTriggerPx,
|
|
10416
11595
|
slOrdPx: v.slOrdPx,
|
|
10417
11596
|
reduceOnly: v.reduceOnly,
|
|
11597
|
+
callbackRatio: v.callbackRatio,
|
|
11598
|
+
callbackSpread: v.callbackSpread,
|
|
11599
|
+
activePx: v.activePx,
|
|
10418
11600
|
json
|
|
10419
11601
|
});
|
|
10420
11602
|
if (subAction === "amend")
|
|
@@ -10505,7 +11687,44 @@ function handleSwapCommand(run, action, rest, v, json) {
|
|
|
10505
11687
|
if (action === "batch")
|
|
10506
11688
|
return cmdSwapBatch(run, { action: v.action, orders: v.orders, json });
|
|
10507
11689
|
}
|
|
10508
|
-
function
|
|
11690
|
+
function handleOptionAlgoCommand(run, subAction, v, json) {
|
|
11691
|
+
if (subAction === "place")
|
|
11692
|
+
return cmdOptionAlgoPlace(run, {
|
|
11693
|
+
instId: v.instId,
|
|
11694
|
+
tdMode: v.tdMode,
|
|
11695
|
+
side: v.side,
|
|
11696
|
+
ordType: v.ordType ?? "conditional",
|
|
11697
|
+
sz: v.sz,
|
|
11698
|
+
tpTriggerPx: v.tpTriggerPx,
|
|
11699
|
+
tpOrdPx: v.tpOrdPx,
|
|
11700
|
+
slTriggerPx: v.slTriggerPx,
|
|
11701
|
+
slOrdPx: v.slOrdPx,
|
|
11702
|
+
reduceOnly: v.reduceOnly,
|
|
11703
|
+
clOrdId: v.clOrdId,
|
|
11704
|
+
json
|
|
11705
|
+
});
|
|
11706
|
+
if (subAction === "amend")
|
|
11707
|
+
return cmdOptionAlgoAmend(run, {
|
|
11708
|
+
instId: v.instId,
|
|
11709
|
+
algoId: v.algoId,
|
|
11710
|
+
newSz: v.newSz,
|
|
11711
|
+
newTpTriggerPx: v.newTpTriggerPx,
|
|
11712
|
+
newTpOrdPx: v.newTpOrdPx,
|
|
11713
|
+
newSlTriggerPx: v.newSlTriggerPx,
|
|
11714
|
+
newSlOrdPx: v.newSlOrdPx,
|
|
11715
|
+
json
|
|
11716
|
+
});
|
|
11717
|
+
if (subAction === "cancel")
|
|
11718
|
+
return cmdOptionAlgoCancel(run, { instId: v.instId, algoId: v.algoId, json });
|
|
11719
|
+
if (subAction === "orders")
|
|
11720
|
+
return cmdOptionAlgoOrders(run, {
|
|
11721
|
+
instId: v.instId,
|
|
11722
|
+
status: v.history ? "history" : "pending",
|
|
11723
|
+
ordType: v.ordType,
|
|
11724
|
+
json
|
|
11725
|
+
});
|
|
11726
|
+
}
|
|
11727
|
+
function handleOptionCommand(run, action, rest, v, json) {
|
|
10509
11728
|
if (action === "orders") {
|
|
10510
11729
|
let status = "live";
|
|
10511
11730
|
if (v.archive) status = "archive";
|
|
@@ -10532,6 +11751,10 @@ function handleOptionCommand(run, action, _rest, v, json) {
|
|
|
10532
11751
|
px: v.px,
|
|
10533
11752
|
reduceOnly: v.reduceOnly,
|
|
10534
11753
|
clOrdId: v.clOrdId,
|
|
11754
|
+
tpTriggerPx: v.tpTriggerPx,
|
|
11755
|
+
tpOrdPx: v.tpOrdPx,
|
|
11756
|
+
slTriggerPx: v.slTriggerPx,
|
|
11757
|
+
slOrdPx: v.slOrdPx,
|
|
10535
11758
|
json
|
|
10536
11759
|
});
|
|
10537
11760
|
if (action === "cancel")
|
|
@@ -10547,6 +11770,8 @@ function handleOptionCommand(run, action, _rest, v, json) {
|
|
|
10547
11770
|
});
|
|
10548
11771
|
if (action === "batch-cancel")
|
|
10549
11772
|
return cmdOptionBatchCancel(run, { orders: v.orders, json });
|
|
11773
|
+
if (action === "algo")
|
|
11774
|
+
return handleOptionAlgoCommand(run, rest[0], v, json);
|
|
10550
11775
|
}
|
|
10551
11776
|
function handleFuturesAlgoCommand(run, subAction, v, json) {
|
|
10552
11777
|
if (subAction === "trail")
|
|
@@ -10575,6 +11800,9 @@ function handleFuturesAlgoCommand(run, subAction, v, json) {
|
|
|
10575
11800
|
slTriggerPx: v.slTriggerPx,
|
|
10576
11801
|
slOrdPx: v.slOrdPx,
|
|
10577
11802
|
reduceOnly: v.reduceOnly,
|
|
11803
|
+
callbackRatio: v.callbackRatio,
|
|
11804
|
+
callbackSpread: v.callbackSpread,
|
|
11805
|
+
activePx: v.activePx,
|
|
10578
11806
|
json
|
|
10579
11807
|
});
|
|
10580
11808
|
if (subAction === "amend")
|