@nemesis-oss/binance-sdk 1.0.0

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.
@@ -0,0 +1,1494 @@
1
+ // src/tools/account.tools.ts
2
+ import { z as z2 } from "zod";
3
+
4
+ // src/tools/types.ts
5
+ import { z } from "zod";
6
+ function normalizeSymbol(value) {
7
+ return String(value ?? "").trim().toUpperCase();
8
+ }
9
+ function toJsonSchema(inputSchema) {
10
+ return z.toJSONSchema(inputSchema, { target: "json" });
11
+ }
12
+ function toOpenAITool(tool) {
13
+ return {
14
+ type: "function",
15
+ function: {
16
+ name: tool.name,
17
+ description: tool.description,
18
+ parameters: toJsonSchema(tool.inputSchema)
19
+ }
20
+ };
21
+ }
22
+ function toAnthropicTool(tool) {
23
+ return {
24
+ name: tool.name,
25
+ description: tool.description,
26
+ input_schema: toJsonSchema(tool.inputSchema)
27
+ };
28
+ }
29
+ function toMCPTool(tool) {
30
+ return {
31
+ name: tool.name,
32
+ description: tool.description,
33
+ inputSchema: toJsonSchema(tool.inputSchema)
34
+ };
35
+ }
36
+ function toToolList(tools, format) {
37
+ const adapter = format === "openai" ? toOpenAITool : format === "anthropic" ? toAnthropicTool : toMCPTool;
38
+ return tools.map(adapter);
39
+ }
40
+ function textResult(data) {
41
+ return JSON.stringify(data, null, 2);
42
+ }
43
+
44
+ // src/tools/account.tools.ts
45
+ var optionalSymbol = z2.string().min(1).describe("USD-M pair, e.g. BTCUSDT").optional();
46
+ var limit = z2.number().int().positive().max(1e3).default(100);
47
+ var startTime = z2.number().int().positive().optional();
48
+ var endTime = z2.number().int().positive().optional();
49
+ function accountTools(client) {
50
+ const a = client.futures.account;
51
+ return [
52
+ {
53
+ name: "futures_balance",
54
+ description: "Get futures account balances (v3): asset, wallet balance, unrealized profit, margin balance, available balance (signed).",
55
+ inputSchema: z2.object({}),
56
+ handler: async () => textResult(await a.balanceV3())
57
+ },
58
+ {
59
+ name: "futures_account",
60
+ description: "Get full account information (v3): total wallet/margin balance, unrealized profit, available balance, assets & positions (signed).",
61
+ inputSchema: z2.object({}),
62
+ handler: async () => textResult(await a.accountV3())
63
+ },
64
+ {
65
+ name: "futures_balance_v2",
66
+ description: "Get futures account balance (v2 legacy) per asset (signed).",
67
+ inputSchema: z2.object({}),
68
+ handler: async () => textResult(await a.balance())
69
+ },
70
+ {
71
+ name: "futures_account_v2",
72
+ description: "Get futures account information (v2 legacy) (signed).",
73
+ inputSchema: z2.object({}),
74
+ handler: async () => textResult(await a.account())
75
+ },
76
+ {
77
+ name: "futures_position_risk",
78
+ description: "Get current open positions (v3): symbol, side, size, entry price, mark price, liquidation price, leverage, unrealized PnL, margin (signed).",
79
+ inputSchema: z2.object({ symbol: optionalSymbol }),
80
+ handler: async ({ symbol: symbol3 }) => textResult(await a.positionRiskV3(symbol3 ? normalizeSymbol(symbol3) : void 0))
81
+ },
82
+ {
83
+ name: "futures_income_history",
84
+ description: "Get futures income history (realized PnL, funding fees, commissions, transfers, insurance clearing). incomeType examples: TRANSFER, REALIZED_PNL, FUNDING_FEE, COMMISSION, INSURANCE_CLEAR, REFERRAL_KICKBACK (signed).",
85
+ inputSchema: z2.object({ symbol: optionalSymbol, incomeType: z2.string().optional().describe("e.g. TRANSFER, REALIZED_PNL, FUNDING_FEE, COMMISSION"), startTime, endTime, limit: limit.default(100) }),
86
+ handler: async ({ symbol: symbol3, incomeType, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await a.incomeHistory({ symbol: symbol3 ? normalizeSymbol(symbol3) : void 0, incomeType, startTime: startTime5, endTime: endTime5, limit: Number(limit4) }))
87
+ },
88
+ {
89
+ name: "futures_user_trades",
90
+ description: "Get account trade list (filled trades) for a symbol with optional time range (signed).",
91
+ inputSchema: z2.object({ symbol: z2.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), startTime, endTime, limit: limit.default(100), fromId: z2.number().int().positive().optional() }),
92
+ handler: async ({ symbol: symbol3, startTime: startTime5, endTime: endTime5, limit: limit4, fromId }) => textResult(await a.userTrades({ symbol: normalizeSymbol(symbol3), startTime: startTime5, endTime: endTime5, limit: Number(limit4), fromId }))
93
+ },
94
+ {
95
+ name: "futures_leverage_brackets",
96
+ description: "Get notional and leverage brackets for one symbol or all: tier caps, maintenance margin rate, max leverage (signed).",
97
+ inputSchema: z2.object({ symbol: optionalSymbol }),
98
+ handler: async ({ symbol: symbol3 }) => textResult(await a.leverageBrackets(symbol3 ? normalizeSymbol(symbol3) : void 0))
99
+ },
100
+ {
101
+ name: "futures_commission_rate",
102
+ description: "Get user commission rate (taker & maker fee) for a symbol (signed).",
103
+ inputSchema: z2.object({ symbol: z2.string().min(1).describe("USD-M pair, e.g. ETHUSDT") }),
104
+ handler: async ({ symbol: symbol3 }) => textResult(await a.commissionRate(normalizeSymbol(symbol3)))
105
+ },
106
+ {
107
+ name: "futures_multi_assets_mode",
108
+ description: "Get current multi-assets margin mode status (signed).",
109
+ inputSchema: z2.object({}),
110
+ handler: async () => textResult(await a.multiAssetsMargin())
111
+ },
112
+ {
113
+ name: "futures_set_multi_assets_mode",
114
+ description: "Enable or disable multi-assets mode (signed; 7-day cooldown between toggles).",
115
+ inputSchema: z2.object({ enabled: z2.boolean().describe("true to enable, false to disable") }),
116
+ handler: async ({ enabled }) => textResult(await a.setMultiAssetsMargin(enabled))
117
+ },
118
+ {
119
+ name: "futures_fee_burn_status",
120
+ description: "Get BNB fee burn status for futures trades (signed).",
121
+ inputSchema: z2.object({}),
122
+ handler: async () => textResult(await a.feeBurnStatus())
123
+ },
124
+ {
125
+ name: "futures_set_fee_burn",
126
+ description: "Toggle BNB fee burn on futures trades (signed).",
127
+ inputSchema: z2.object({ enabled: z2.boolean().describe("true to enable fee burn") }),
128
+ handler: async ({ enabled }) => textResult(await a.setFeeBurnStatus(enabled))
129
+ },
130
+ {
131
+ name: "futures_position_mode",
132
+ description: "Get current position mode: one-way (BOTH) or hedge mode (LONG/SHORT) (signed).",
133
+ inputSchema: z2.object({}),
134
+ handler: async () => textResult(await a.positionMode())
135
+ },
136
+ {
137
+ name: "futures_set_position_mode",
138
+ description: "Change position mode: hedgeMode true = dual side (hedge), false = one-way (signed; 30-day cooldown).",
139
+ inputSchema: z2.object({ hedgeMode: z2.boolean().describe("true = hedge mode, false = one-way") }),
140
+ handler: async ({ hedgeMode }) => textResult(await a.setPositionMode(hedgeMode))
141
+ },
142
+ {
143
+ name: "futures_api_trading_status",
144
+ description: "Get futures trading quantitative rules indicators and disable intervals (signed).",
145
+ inputSchema: z2.object({}),
146
+ handler: async () => textResult(await a.apiTradingStatus())
147
+ },
148
+ {
149
+ name: "futures_position_margin_history",
150
+ description: "Get isolated position margin change history. type: 1 = add margin, 2 = reduce margin (signed).",
151
+ inputSchema: z2.object({ symbol: z2.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), type: z2.enum(["1", "2"]).describe("1 = add margin, 2 = reduce margin"), startTime, endTime, limit: limit.default(50) }),
152
+ handler: async ({ symbol: symbol3, type, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await a.positionMarginHistory({ symbol: normalizeSymbol(symbol3), type: Number(type), startTime: startTime5, endTime: endTime5, limit: Number(limit4) }))
153
+ },
154
+ {
155
+ name: "futures_rate_limit_order",
156
+ description: "Query the current user order rate limit usage (signed).",
157
+ inputSchema: z2.object({}),
158
+ handler: async () => textResult(await a.rateLimitOrder())
159
+ },
160
+ {
161
+ name: "futures_request_order_download",
162
+ description: "Request a futures order-history download (async, 7-day window). Returns a downloadId (signed).",
163
+ inputSchema: z2.object({ symbol: optionalSymbol, startTime, endTime }),
164
+ handler: async ({ symbol: symbol3, startTime: startTime5, endTime: endTime5 }) => textResult(await a.requestOrderDownload({ symbol: symbol3 ? normalizeSymbol(symbol3) : void 0, startTime: startTime5, endTime: endTime5 }))
165
+ },
166
+ {
167
+ name: "futures_order_download_status",
168
+ description: "Get the futures order-history download link by downloadId (signed).",
169
+ inputSchema: z2.object({ downloadId: z2.string().min(1) }),
170
+ handler: async ({ downloadId }) => textResult(await a.getOrderDownloadStatus(downloadId))
171
+ },
172
+ {
173
+ name: "futures_request_trade_download",
174
+ description: "Request a futures trade-history download (async, 7-day window). Returns a downloadId (signed).",
175
+ inputSchema: z2.object({ symbol: optionalSymbol, startTime, endTime }),
176
+ handler: async ({ symbol: symbol3, startTime: startTime5, endTime: endTime5 }) => textResult(await a.requestTradeDownload({ symbol: symbol3 ? normalizeSymbol(symbol3) : void 0, startTime: startTime5, endTime: endTime5 }))
177
+ },
178
+ {
179
+ name: "futures_trade_download_status",
180
+ description: "Get the futures trade-history download link by downloadId (signed).",
181
+ inputSchema: z2.object({ downloadId: z2.string().min(1) }),
182
+ handler: async ({ downloadId }) => textResult(await a.getTradeDownloadStatus(downloadId))
183
+ },
184
+ {
185
+ name: "futures_account_config",
186
+ description: "Get futures account configuration: fee tier, trading permissions, dual-side position setting (signed).",
187
+ inputSchema: z2.object({}),
188
+ handler: async () => textResult(await a.accountConfig())
189
+ },
190
+ {
191
+ name: "futures_portfolio_margin_account_info",
192
+ description: "Get Portfolio Margin account info for an asset: cross margin balance and liability (signed).",
193
+ inputSchema: z2.object({ asset: z2.string().min(1).describe("Asset, e.g. USDT") }),
194
+ handler: async ({ asset }) => textResult(await a.pmAccountInfo(asset))
195
+ },
196
+ {
197
+ name: "futures_request_income_download",
198
+ description: "Request a futures income/transaction-history download (async). Returns a downloadId (signed).",
199
+ inputSchema: z2.object({ startTime: startTime.unwrap(), endTime: endTime.unwrap() }),
200
+ handler: async ({ startTime: startTime5, endTime: endTime5 }) => textResult(await a.requestIncomeDownload({ startTime: startTime5, endTime: endTime5 }))
201
+ },
202
+ {
203
+ name: "futures_income_download_status",
204
+ description: "Get the futures income/transaction-history download link by downloadId (signed).",
205
+ inputSchema: z2.object({ downloadId: z2.string().min(1) }),
206
+ handler: async ({ downloadId }) => textResult(await a.getIncomeDownloadStatus(downloadId))
207
+ }
208
+ ];
209
+ }
210
+
211
+ // src/tools/derived.tools.ts
212
+ import { z as z3 } from "zod";
213
+ var symbol = z3.string().min(1).describe("USD-M pair, e.g. BTCUSDT");
214
+ function derivedTools(client) {
215
+ const ops = client.futures.ops;
216
+ return [
217
+ {
218
+ name: "futures_symbol_rules",
219
+ description: "Get the tradeable rules for a symbol in one call: tick size, step size, min/max quantity, market-order lot bounds and minimum notional, flattened out of exchangeInfo filters. Call this before sizing or pricing any order.",
220
+ inputSchema: z3.object({ symbol, refresh: z3.boolean().default(false).describe("Bypass the 60s cache") }),
221
+ handler: async ({ symbol: s, refresh }) => textResult(await ops.symbolRules(normalizeSymbol(s), { refresh }))
222
+ },
223
+ {
224
+ name: "futures_quantize",
225
+ description: "Round a price to the symbol's tick size and a quantity to its step size, returning exchange-ready strings. Use this instead of rounding numbers yourself \u2014 Binance rejects off-tick prices (-1111).",
226
+ inputSchema: z3.object({
227
+ symbol,
228
+ price: z3.number().positive().optional(),
229
+ quantity: z3.number().positive().optional(),
230
+ marketOrder: z3.boolean().default(false).describe("Use MARKET_LOT_SIZE bounds instead of LOT_SIZE")
231
+ }),
232
+ handler: async ({ symbol: s, price, quantity, marketOrder }) => textResult(await ops.quantize(normalizeSymbol(s), { price, quantity, marketOrder }))
233
+ },
234
+ {
235
+ name: "futures_size_position",
236
+ description: "Convert a risk budget into an exchange-ready order quantity. Given a stop price and either riskAmount (quote currency) or riskPct (percent of available balance), returns the quantity rounded down to the symbol step size, plus the notional, required margin and every constraint that failed (min notional, lot bounds, wrong-side stop). Never increases risk to satisfy a minimum \u2014 it reports instead.",
237
+ inputSchema: z3.object({
238
+ symbol,
239
+ side: z3.enum(["BUY", "SELL"]),
240
+ stopPrice: z3.number().positive().describe("Protective stop price"),
241
+ entryPrice: z3.number().positive().optional().describe("Defaults to current mark price"),
242
+ riskAmount: z3.number().positive().optional().describe("Quote-currency amount to risk, e.g. 50 USDT"),
243
+ riskPct: z3.number().positive().max(100).optional().describe("Percent of available balance to risk (signed call)"),
244
+ leverage: z3.number().int().min(1).max(125).optional().describe("Used to report required margin"),
245
+ marketOrder: z3.boolean().default(false)
246
+ }),
247
+ handler: async (args) => textResult(await ops.sizePosition({ ...args, symbol: normalizeSymbol(args.symbol) }))
248
+ },
249
+ {
250
+ name: "futures_close_position",
251
+ description: "Flatten an open position with a reduce-only market order. Reads the current position, derives the closing side from its sign, and automatically uses reduceOnly in one-way mode vs positionSide in hedge mode (Binance rejects the wrong one). Set dryRun to preview the order without sending it. Signed, destructive.",
252
+ inputSchema: z3.object({
253
+ symbol,
254
+ positionSide: z3.enum(["BOTH", "LONG", "SHORT"]).optional().describe("Required when hedge mode has both sides open"),
255
+ portion: z3.number().positive().max(1).default(1).describe("Fraction of the position to close, e.g. 0.5 for half"),
256
+ dryRun: z3.boolean().default(false)
257
+ }),
258
+ handler: async (args) => textResult(await ops.closePosition({ ...args, symbol: normalizeSymbol(args.symbol) }))
259
+ },
260
+ {
261
+ name: "futures_market_snapshot",
262
+ description: "One-call market picture for a symbol: 24h stats, mark/index price with funding, open interest and long/short positioning. Replaces four separate primitive calls; individual feeds degrade to an error field rather than failing the whole snapshot.",
263
+ inputSchema: z3.object({
264
+ symbol,
265
+ period: z3.enum(["5m", "15m", "30m", "1h", "2h", "4h", "6h", "12h", "1d"]).default("1h")
266
+ }),
267
+ handler: async ({ symbol: s, period: period2 }) => textResult(await ops.marketSnapshot(normalizeSymbol(s), { period: period2 }))
268
+ },
269
+ {
270
+ name: "futures_account_overview",
271
+ description: "One-call account picture: funded balances, open positions only (zero-size entries filtered out), working orders, and totals for unrealized PnL and gross notional. Signed.",
272
+ inputSchema: z3.object({}),
273
+ handler: async () => textResult(await ops.accountOverview())
274
+ },
275
+ {
276
+ name: "futures_place_bracket_order",
277
+ description: "Place an entry order together with its protective stop-loss and optional take-profit, with all prices quantized to the symbol tick. Returns each leg separately; if a protective leg fails the response is flagged protectionComplete=false and the entry is NOT auto-cancelled (it may already have filled). Signed, destructive.",
278
+ inputSchema: z3.object({
279
+ symbol,
280
+ side: z3.enum(["BUY", "SELL"]),
281
+ quantity: z3.union([z3.string(), z3.number()]),
282
+ entryPrice: z3.number().positive().optional().describe("Omit for a MARKET entry"),
283
+ stopLossPrice: z3.number().positive(),
284
+ takeProfitPrice: z3.number().positive().optional(),
285
+ positionSide: z3.enum(["BOTH", "LONG", "SHORT"]).optional(),
286
+ workingType: z3.enum(["MARK_PRICE", "CONTRACT_PRICE"]).default("MARK_PRICE")
287
+ }),
288
+ handler: async (args) => textResult(await ops.placeBracketOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
289
+ }
290
+ ];
291
+ }
292
+
293
+ // src/tools/market-data.tools.ts
294
+ import { z as z5 } from "zod";
295
+
296
+ // src/types/market.types.ts
297
+ import { z as z4 } from "zod";
298
+ var KlineIntervalSchema = z4.enum([
299
+ "1m",
300
+ "3m",
301
+ "5m",
302
+ "15m",
303
+ "30m",
304
+ "1h",
305
+ "2h",
306
+ "4h",
307
+ "6h",
308
+ "8h",
309
+ "12h",
310
+ "1d",
311
+ "3d",
312
+ "1w",
313
+ "1M"
314
+ ]);
315
+ var RawKlineSchema = z4.tuple([
316
+ z4.number(),
317
+ z4.string(),
318
+ z4.string(),
319
+ z4.string(),
320
+ z4.string(),
321
+ z4.string(),
322
+ z4.number(),
323
+ z4.string(),
324
+ z4.number(),
325
+ z4.string(),
326
+ z4.string(),
327
+ z4.string()
328
+ ]);
329
+ var KlineSchema = RawKlineSchema.transform(
330
+ ([openTime, open, high, low, close, volume, closeTime, quoteAssetVolume, trades, takerBuyBaseVolume, takerBuyQuoteVolume]) => ({
331
+ openTime,
332
+ open: Number(open),
333
+ high: Number(high),
334
+ low: Number(low),
335
+ close: Number(close),
336
+ volume: Number(volume),
337
+ closeTime,
338
+ quoteAssetVolume: Number(quoteAssetVolume),
339
+ trades,
340
+ takerBuyBaseVolume: Number(takerBuyBaseVolume),
341
+ takerBuyQuoteVolume: Number(takerBuyQuoteVolume)
342
+ })
343
+ );
344
+ var KlinesResponseSchema = z4.array(KlineSchema);
345
+ var TickerPriceSchema = z4.object({
346
+ symbol: z4.string(),
347
+ price: z4.string().transform(Number),
348
+ time: z4.number().optional()
349
+ });
350
+ var Ticker24hrSchema = z4.object({
351
+ symbol: z4.string(),
352
+ priceChange: z4.string().transform(Number),
353
+ priceChangePercent: z4.string().transform(Number),
354
+ weightedAvgPrice: z4.string().transform(Number),
355
+ lastPrice: z4.string().transform(Number),
356
+ lastQty: z4.string().transform(Number),
357
+ openPrice: z4.string().transform(Number),
358
+ highPrice: z4.string().transform(Number),
359
+ lowPrice: z4.string().transform(Number),
360
+ volume: z4.string().transform(Number),
361
+ quoteVolume: z4.string().transform(Number),
362
+ openTime: z4.number(),
363
+ closeTime: z4.number(),
364
+ firstId: z4.number(),
365
+ lastId: z4.number(),
366
+ count: z4.number()
367
+ });
368
+ var BookTickerSchema = z4.object({
369
+ symbol: z4.string(),
370
+ bidPrice: z4.string().transform(Number),
371
+ bidQty: z4.string().transform(Number),
372
+ askPrice: z4.string().transform(Number),
373
+ askQty: z4.string().transform(Number),
374
+ time: z4.number().optional()
375
+ });
376
+ var DepthLevelSchema = z4.tuple([z4.string(), z4.string()]).transform(([price, qty]) => ({ price: Number(price), qty: Number(qty) }));
377
+ var DepthSnapshotSchema = z4.object({
378
+ lastUpdateId: z4.number(),
379
+ bids: z4.array(DepthLevelSchema),
380
+ asks: z4.array(DepthLevelSchema)
381
+ });
382
+ var TradeSchema = z4.object({
383
+ id: z4.number(),
384
+ price: z4.string().transform(Number),
385
+ qty: z4.string().transform(Number),
386
+ quoteQty: z4.string().transform(Number),
387
+ time: z4.number(),
388
+ isBuyerMaker: z4.boolean()
389
+ });
390
+ var TradesResponseSchema = z4.array(TradeSchema);
391
+ var AggTradeSchema = z4.object({
392
+ a: z4.number(),
393
+ p: z4.string().transform(Number),
394
+ q: z4.string().transform(Number),
395
+ f: z4.number(),
396
+ l: z4.number(),
397
+ T: z4.number(),
398
+ m: z4.boolean()
399
+ });
400
+ var AggTradesResponseSchema = z4.array(AggTradeSchema);
401
+ var AvgPriceSchema = z4.object({
402
+ mins: z4.number(),
403
+ price: z4.string().transform(Number)
404
+ });
405
+ var ExchangeSymbolSchema = z4.object({
406
+ symbol: z4.string(),
407
+ status: z4.string(),
408
+ baseAsset: z4.string(),
409
+ quoteAsset: z4.string()
410
+ }).loose();
411
+ var ExchangeInfoSchema = z4.object({
412
+ timezone: z4.string(),
413
+ serverTime: z4.number(),
414
+ symbols: z4.array(ExchangeSymbolSchema)
415
+ }).loose();
416
+
417
+ // src/tools/market-data.tools.ts
418
+ var u = (s) => s.optional();
419
+ var optSymbol = u(z5.string().min(1)).describe("USD-M pair, e.g. BTCUSDT");
420
+ var limitDefault = z5.number().int().positive().max(1500).default(100);
421
+ var startTime2 = z5.number().int().positive().optional();
422
+ var endTime2 = z5.number().int().positive().optional();
423
+ var period = z5.enum(["5m", "15m", "30m", "1h", "2h", "4h", "6h", "12h", "1d"]).default("1h");
424
+ var contractType = z5.enum(["perpetual", "current_quarter", "next_quarter"]).default("perpetual");
425
+ function marketDataTools(client) {
426
+ const m = client.futures.market;
427
+ const d = client.futures.data;
428
+ const tools = [
429
+ {
430
+ name: "futures_ping",
431
+ description: "Test connectivity to the Binance USD-M futures REST API. Returns empty object {} on success.",
432
+ inputSchema: z5.object({}),
433
+ handler: async () => textResult(await m.ping())
434
+ },
435
+ {
436
+ name: "futures_server_time",
437
+ description: "Get the current Binance USD-M futures server time in milliseconds since epoch.",
438
+ inputSchema: z5.object({}),
439
+ handler: async () => textResult(await m.serverTime())
440
+ },
441
+ {
442
+ name: "futures_exchange_info",
443
+ description: "Get exchange trading rules and symbol metadata: contract type, status, base/quote assets, price/quantity filters, tick size, step size, notional and leverage brackets, delivery dates.",
444
+ inputSchema: z5.object({}),
445
+ handler: async () => textResult(await m.exchangeInfo())
446
+ },
447
+ {
448
+ name: "futures_ticker_price",
449
+ description: "Get latest price for one symbol (v1).",
450
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
451
+ handler: async ({ symbol: symbol3 }) => textResult(await m.tickerPrice(normalizeSymbol(symbol3)))
452
+ },
453
+ {
454
+ name: "futures_ticker_price_v2",
455
+ description: "Get latest price for one symbol, or for all symbols when symbol is omitted (v2 endpoint). Use all-symbols mode for market overviews.",
456
+ inputSchema: z5.object({ symbol: optSymbol }),
457
+ handler: async ({ symbol: symbol3 }) => textResult(await m.tickerPriceV2(symbol3 ? normalizeSymbol(symbol3) : void 0))
458
+ },
459
+ {
460
+ name: "futures_ticker_24hr",
461
+ description: "Get 24-hour rolling price change statistics for a symbol: price change %, high, low, volume, quote volume, open interest.",
462
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
463
+ handler: async ({ symbol: symbol3 }) => textResult(await m.ticker24hr(normalizeSymbol(symbol3)))
464
+ },
465
+ {
466
+ name: "futures_book_ticker",
467
+ description: "Get best bid/ask (top of book) for a single symbol (v1).",
468
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
469
+ handler: async ({ symbol: symbol3 }) => textResult(await m.bookTicker(normalizeSymbol(symbol3)))
470
+ },
471
+ {
472
+ name: "futures_book_ticker_v2",
473
+ description: "Get best bid/ask (top of book) for one symbol, or all symbols when omitted (v2 endpoint).",
474
+ inputSchema: z5.object({ symbol: optSymbol }),
475
+ handler: async ({ symbol: symbol3 }) => textResult(await m.bookTickerV2(symbol3 ? normalizeSymbol(symbol3) : void 0))
476
+ },
477
+ {
478
+ name: "futures_order_book",
479
+ description: "Get order book depth for a symbol. Limits: 5, 10, 20, 50, 100, 500, 1000.",
480
+ inputSchema: z5.object({
481
+ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
482
+ limit: z5.enum(["5", "10", "20", "50", "100", "500", "1000"]).default("100")
483
+ }),
484
+ handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await m.depth(normalizeSymbol(symbol3), Number(limit4)))
485
+ },
486
+ {
487
+ name: "futures_recent_trades",
488
+ description: "Get the most recent executed trades for a symbol (public endpoint).",
489
+ inputSchema: z5.object({
490
+ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
491
+ limit: limitDefault.default(500)
492
+ }),
493
+ handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await m.trades(normalizeSymbol(symbol3), Number(limit4)))
494
+ },
495
+ {
496
+ name: "futures_historical_trades",
497
+ description: "Get older trades for a symbol by fromId (older than recent).",
498
+ inputSchema: z5.object({
499
+ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
500
+ limit: limitDefault.default(500),
501
+ fromId: z5.number().int().positive().optional()
502
+ }),
503
+ handler: async ({ symbol: symbol3, limit: limit4, fromId }) => textResult(await m.historicalTrades(normalizeSymbol(symbol3), { limit: Number(limit4), fromId }))
504
+ },
505
+ {
506
+ name: "futures_agg_trades",
507
+ description: "Get compressed/aggregate trades for a symbol within an optional time window. Each entry aggregates trades with the same price and side.",
508
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), limit: limitDefault.default(500), startTime: startTime2, endTime: endTime2 }),
509
+ handler: async ({ symbol: symbol3, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.aggTrades(normalizeSymbol(symbol3), { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
510
+ },
511
+ {
512
+ name: "futures_klines",
513
+ description: "Get candlestick (OHLCV) data for a symbol. Intervals: 1m,3m,5m,15m,30m,1h,2h,4h,6h,8h,12h,1d,3d,1w,1M. Max 1500 per request.",
514
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), interval: KlineIntervalSchema, limit: limitDefault.default(500), startTime: startTime2, endTime: endTime2 }),
515
+ handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.klines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
516
+ },
517
+ {
518
+ name: "futures_continuous_klines",
519
+ description: "Get klines for a continuous contract (perpetual, current_quarter, next_quarter) identified by base pair (e.g. BTCUSDT).",
520
+ inputSchema: z5.object({
521
+ symbol: z5.string().min(1).describe("Base pair, e.g. BTCUSDT"),
522
+ contractType,
523
+ interval: KlineIntervalSchema,
524
+ limit: limitDefault.default(500),
525
+ startTime: startTime2,
526
+ endTime: endTime2
527
+ }),
528
+ handler: async ({ symbol: symbol3, contractType: contractType2, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.continuousKlines(normalizeSymbol(symbol3), contractType2, interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
529
+ },
530
+ {
531
+ name: "futures_index_price_klines",
532
+ description: "Get index price candlesticks for a pair (e.g. BTCUSDT index).",
533
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("Base pair, e.g. BTCUSDT"), interval: KlineIntervalSchema, limit: limitDefault.default(500), startTime: startTime2, endTime: endTime2 }),
534
+ handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.indexPriceKlines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
535
+ },
536
+ {
537
+ name: "futures_mark_price_klines",
538
+ description: "Get mark price candlesticks for a symbol.",
539
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), interval: KlineIntervalSchema, limit: limitDefault.default(500), startTime: startTime2, endTime: endTime2 }),
540
+ handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.markPriceKlines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
541
+ },
542
+ {
543
+ name: "futures_trading_day_ticker",
544
+ description: "Get the trading-day ticker (v1: rolling window stats by symbol, including open, close, high, low, volume, closeTime).",
545
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
546
+ handler: async ({ symbol: symbol3 }) => textResult(await m.tradingDayTicker(normalizeSymbol(symbol3)))
547
+ },
548
+ {
549
+ name: "futures_mark_price",
550
+ description: "Get mark price, index price, estimated settle price, last funding rate, next funding time and interest rate for a symbol.",
551
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
552
+ handler: async ({ symbol: symbol3 }) => textResult(await d.premiumIndex(normalizeSymbol(symbol3)))
553
+ },
554
+ {
555
+ name: "futures_funding_rate_history",
556
+ description: "Get historical funding rates for a symbol.",
557
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), limit: limitDefault.default(100), startTime: startTime2, endTime: endTime2 }),
558
+ handler: async ({ symbol: symbol3, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await d.fundingRateHistory(normalizeSymbol(symbol3), { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
559
+ },
560
+ {
561
+ name: "futures_funding_info",
562
+ description: "Get funding rate configuration for all symbols with adjusted funding cap/floor or interval (e.g. under extreme volatility).",
563
+ inputSchema: z5.object({}),
564
+ handler: async () => textResult(await d.fundingInfo())
565
+ },
566
+ {
567
+ name: "futures_open_interest",
568
+ description: "Get the current total open interest for a symbol.",
569
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
570
+ handler: async ({ symbol: symbol3 }) => textResult(await d.openInterest(normalizeSymbol(symbol3)))
571
+ },
572
+ {
573
+ name: "futures_open_interest_hist",
574
+ description: "Get historical open interest statistics per period.",
575
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), period, limit: limitDefault.default(30) }),
576
+ handler: async ({ symbol: symbol3, period: period2, limit: limit4 }) => textResult(await d.openInterestHist(normalizeSymbol(symbol3), period2, Number(limit4)))
577
+ },
578
+ {
579
+ name: "futures_top_long_short_account_ratio",
580
+ description: "Get top trader long/short account ratio (number of accounts) for a symbol.",
581
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), period, limit: limitDefault.default(30) }),
582
+ handler: async ({ symbol: symbol3, period: period2, limit: limit4 }) => textResult(await d.topLongShortAccountRatio(normalizeSymbol(symbol3), period2, Number(limit4)))
583
+ },
584
+ {
585
+ name: "futures_top_long_short_position_ratio",
586
+ description: "Get top trader long/short position ratio (accounts with net positions) for a symbol.",
587
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), period, limit: limitDefault.default(30) }),
588
+ handler: async ({ symbol: symbol3, period: period2, limit: limit4 }) => textResult(await d.topLongShortPositionRatio(normalizeSymbol(symbol3), period2, Number(limit4)))
589
+ },
590
+ {
591
+ name: "futures_global_long_short_ratio",
592
+ description: "Get global long/short account ratio for a symbol (all accounts).",
593
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), period, limit: limitDefault.default(30) }),
594
+ handler: async ({ symbol: symbol3, period: period2, limit: limit4 }) => textResult(await d.globalLongShortAccountRatio(normalizeSymbol(symbol3), period2, Number(limit4)))
595
+ },
596
+ {
597
+ name: "futures_taker_long_short_ratio",
598
+ description: "Get taker buy/sell volume ratio for a symbol.",
599
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), period, limit: limitDefault.default(30) }),
600
+ handler: async ({ symbol: symbol3, period: period2, limit: limit4 }) => textResult(await d.takerLongShortRatio(normalizeSymbol(symbol3), period2, Number(limit4)))
601
+ },
602
+ {
603
+ name: "futures_basis",
604
+ description: "Get basis data (spot-futures spread, mark price - index price) for a pair and contract type.",
605
+ inputSchema: z5.object({
606
+ symbol: z5.string().min(1).describe("Base pair, e.g. BTCUSDT"),
607
+ period,
608
+ limit: limitDefault.default(30),
609
+ startTime: startTime2,
610
+ endTime: endTime2
611
+ }),
612
+ handler: async ({ symbol: symbol3, period: period2, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await d.basis(normalizeSymbol(symbol3), period2, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
613
+ },
614
+ {
615
+ name: "futures_asset_index",
616
+ description: "Get multi-assets mode asset index (collateral price) for one asset or all assets.",
617
+ inputSchema: z5.object({ symbol: optSymbol.describe("Asset index symbol, e.g. ADAUSD") }),
618
+ handler: async ({ symbol: symbol3 }) => textResult(await d.assetIndex(symbol3 ? normalizeSymbol(symbol3) : void 0))
619
+ },
620
+ {
621
+ name: "futures_composite_index_info",
622
+ description: "Get composite index symbol information (e.g. DEFIUSDT) with constituent weights.",
623
+ inputSchema: z5.object({ symbol: optSymbol }),
624
+ handler: async ({ symbol: symbol3 }) => textResult(await d.compositeIndexInfo(symbol3 ? normalizeSymbol(symbol3) : void 0))
625
+ },
626
+ {
627
+ name: "futures_insurance_balance",
628
+ description: "Get insurance fund balance snapshots for a symbol.",
629
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BNBUSDT"), limit: limitDefault.default(100), startTime: startTime2, endTime: endTime2 }),
630
+ handler: async ({ symbol: symbol3, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await d.insuranceFundBalance({ symbol: normalizeSymbol(symbol3), limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
631
+ },
632
+ {
633
+ name: "futures_index_price_constituents",
634
+ description: "Get the index price constituents (exchange weights) for a symbol.",
635
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT") }),
636
+ handler: async ({ symbol: symbol3 }) => textResult(await d.indexPriceConstituents(normalizeSymbol(symbol3)))
637
+ },
638
+ {
639
+ name: "futures_premium_index_klines",
640
+ description: "Get premium index candlesticks for a symbol (mark price premium over index price).",
641
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), interval: KlineIntervalSchema, limit: limitDefault.default(500), startTime: startTime2, endTime: endTime2 }),
642
+ handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.premiumIndexKlines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
643
+ },
644
+ {
645
+ name: "futures_rpi_depth",
646
+ description: "Get the RPI (Retail Price Improvement) order book depth for a symbol.",
647
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("USD-M pair, e.g. BTCUSDT"), limit: z5.number().int().positive().default(1e3) }),
648
+ handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await m.rpiDepth(normalizeSymbol(symbol3), Number(limit4)))
649
+ },
650
+ {
651
+ name: "futures_delivery_price",
652
+ description: "Get historical quarterly contract settlement/delivery prices for a pair.",
653
+ inputSchema: z5.object({ symbol: z5.string().min(1).describe("Base pair, e.g. BTCUSDT") }),
654
+ handler: async ({ symbol: symbol3 }) => textResult(await d.deliveryPrice(normalizeSymbol(symbol3)))
655
+ },
656
+ {
657
+ name: "futures_symbol_adl_risk",
658
+ description: "Get the auto-deleveraging (ADL) risk level for one symbol or all symbols on the account (signed).",
659
+ inputSchema: z5.object({ symbol: optSymbol }),
660
+ handler: async ({ symbol: symbol3 }) => textResult(await d.symbolAdlRisk(symbol3 ? normalizeSymbol(symbol3) : void 0))
661
+ },
662
+ {
663
+ name: "futures_adl_quantile",
664
+ description: "Get the position ADL (auto-deleveraging) quantile estimation for one symbol or all symbols (signed).",
665
+ inputSchema: z5.object({ symbol: optSymbol }),
666
+ handler: async ({ symbol: symbol3 }) => textResult(await d.adlQuantile(symbol3 ? normalizeSymbol(symbol3) : void 0))
667
+ },
668
+ {
669
+ name: "futures_force_orders",
670
+ description: "Get the user's force-liquidation orders (LIQUIDATION) and ADL orders for a symbol or all symbols (signed).",
671
+ inputSchema: z5.object({
672
+ symbol: optSymbol,
673
+ autoCloseType: z5.enum(["LIQUIDATION", "ADL"]).optional(),
674
+ startTime: startTime2,
675
+ endTime: endTime2,
676
+ limit: limitDefault.default(50)
677
+ }),
678
+ handler: async ({ symbol: symbol3, autoCloseType, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(
679
+ await d.forceOrders({
680
+ symbol: symbol3 ? normalizeSymbol(symbol3) : void 0,
681
+ autoCloseType,
682
+ startTime: startTime5,
683
+ endTime: endTime5,
684
+ limit: Number(limit4)
685
+ })
686
+ )
687
+ }
688
+ ];
689
+ return tools;
690
+ }
691
+
692
+ // src/tools/paper.tools.ts
693
+ import { z as z6 } from "zod";
694
+ function createPaperContext(client, initialState = {}) {
695
+ return {
696
+ client,
697
+ state: { balance: initialState.balance ?? 1e4, positions: initialState.positions ?? [], history: initialState.history ?? [] }
698
+ };
699
+ }
700
+ function pnl(position, price) {
701
+ const direction = position.side === "LONG" ? 1 : -1;
702
+ return (price - position.entryPrice) * position.quantity * direction;
703
+ }
704
+ function paperTools(ctx) {
705
+ const s = ctx.state;
706
+ const t = ctx.client.futures.market;
707
+ return [
708
+ {
709
+ name: "paper_init",
710
+ description: "Initialize paper-trading state (reset balances, positions, history). No API keys required.",
711
+ inputSchema: z6.object({ balance: z6.number().positive().default(1e4).describe("Starting USDT balance") }),
712
+ handler: async ({ balance }) => {
713
+ s.balance = balance;
714
+ s.positions = [];
715
+ s.history = [];
716
+ return textResult(s);
717
+ }
718
+ },
719
+ {
720
+ name: "paper_balance",
721
+ description: "Get current paper-trading balance and open-position equity (uses live market prices if an open position exists). No API keys required.",
722
+ inputSchema: z6.object({}),
723
+ handler: async () => textResult(s)
724
+ },
725
+ {
726
+ name: "paper_open_position",
727
+ description: "Open an in-memory paper position at the live ticker price (or a fixed price). No API keys required.",
728
+ inputSchema: z6.object({
729
+ symbol: z6.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
730
+ side: z6.enum(["LONG", "SHORT"]),
731
+ quantity: z6.number().positive(),
732
+ price: z6.number().positive().optional().describe("If omitted, uses live ticker price")
733
+ }),
734
+ handler: async ({ symbol: symbol3, side: side3, quantity, price }) => {
735
+ const sym = normalizeSymbol(symbol3);
736
+ const market = price ?? Number((await t.tickerPrice(sym)).price);
737
+ const position = { id: Date.now().toString(), symbol: sym, side: side3, quantity, entryPrice: market, openedAt: (/* @__PURE__ */ new Date()).toISOString() };
738
+ s.positions.push(position);
739
+ s.history.push({ type: "open", ...position });
740
+ return textResult(position);
741
+ }
742
+ },
743
+ {
744
+ name: "paper_close_position",
745
+ description: "Close a paper position by id (or symbol) and realize PnL at the live/last price.",
746
+ inputSchema: z6.object({
747
+ id: z6.string().optional().describe("Position id from paper_open_position"),
748
+ symbol: z6.string().min(1).optional().describe("Close the position for this symbol"),
749
+ price: z6.number().positive().optional().describe("If omitted, uses live ticker price")
750
+ }),
751
+ handler: async ({ id, symbol: symbol3, price }) => {
752
+ const idx = s.positions.findIndex((p) => id ? p.id === id : normalizeSymbol(p.symbol) === normalizeSymbol(symbol3 ?? ""));
753
+ if (idx === -1) throw new Error("paper position not found");
754
+ const position = s.positions[idx];
755
+ const market = price ?? Number((await t.tickerPrice(position.symbol)).price);
756
+ const realizedPnl = pnl(position, market);
757
+ s.balance += realizedPnl;
758
+ const closed = { type: "close", ...position, exitPrice: market, realizedPnl, closedAt: (/* @__PURE__ */ new Date()).toISOString() };
759
+ s.positions.splice(idx, 1);
760
+ s.history.push(closed);
761
+ return textResult(closed);
762
+ }
763
+ },
764
+ {
765
+ name: "paper_positions",
766
+ description: "List open paper positions with live unrealized PnL (marked to market).",
767
+ inputSchema: z6.object({}),
768
+ handler: async () => {
769
+ const out = await Promise.all(
770
+ s.positions.map(async (p) => {
771
+ const price = Number((await t.tickerPrice(p.symbol)).price);
772
+ return { ...p, markPrice: price, unrealizedPnl: pnl(p, price) };
773
+ })
774
+ );
775
+ return textResult(out);
776
+ }
777
+ },
778
+ {
779
+ name: "paper_history",
780
+ description: "List paper-trading history of open/close events with realized PnL.",
781
+ inputSchema: z6.object({}),
782
+ handler: async () => textResult(s.history)
783
+ },
784
+ {
785
+ name: "paper_summary",
786
+ description: "Summarize paper-trading state: balance, open positions, trade count.",
787
+ inputSchema: z6.object({}),
788
+ handler: async () => textResult({ balance: s.balance, openPositions: s.positions.length, trades: s.history.length })
789
+ }
790
+ ];
791
+ }
792
+
793
+ // src/tools/spot.tools.ts
794
+ import { z as z7 } from "zod";
795
+ var spotSymbol = z7.string().min(1).describe("Spot pair, e.g. BTCUSDT");
796
+ var optionalSymbol2 = z7.string().min(1).describe("Spot pair, e.g. BTCUSDT").optional();
797
+ var limit2 = z7.number().int().positive().max(1e3).default(100);
798
+ var startTime3 = z7.number().int().positive().optional();
799
+ var endTime3 = z7.number().int().positive().optional();
800
+ var side = z7.enum(["BUY", "SELL"]);
801
+ var spotOrderParamsSchema = z7.object({
802
+ symbol: spotSymbol,
803
+ side,
804
+ type: z7.enum(["LIMIT", "MARKET", "LIMIT_MAKER", "STOP_LOSS", "STOP_LOSS_LIMIT", "TAKE_PROFIT", "TAKE_PROFIT_LIMIT"]),
805
+ quantity: z7.union([z7.string(), z7.number()]).optional().describe("Base-asset quantity; omit if using quoteOrderQty"),
806
+ quoteOrderQty: z7.union([z7.string(), z7.number()]).optional().describe("Quote-asset quantity (e.g. spend 100 USDT on a MARKET order)"),
807
+ price: z7.union([z7.string(), z7.number()]).optional().describe("Required for LIMIT / STOP_LOSS_LIMIT / TAKE_PROFIT_LIMIT"),
808
+ stopPrice: z7.union([z7.string(), z7.number()]).optional().describe("Trigger price for STOP_LOSS / TAKE_PROFIT variants"),
809
+ timeInForce: z7.enum(["GTC", "IOC", "FOK"]).optional().describe("Required for LIMIT"),
810
+ newClientOrderId: z7.string().optional(),
811
+ newOrderRespType: z7.enum(["ACK", "RESULT", "FULL"]).optional(),
812
+ icebergQty: z7.union([z7.string(), z7.number()]).optional(),
813
+ selfTradePreventionMode: z7.enum(["NONE", "EXPIRE_TAKER", "EXPIRE_MAKER", "EXPIRE_BOTH"]).optional()
814
+ });
815
+ function spotTools(client) {
816
+ const m = client.spot.market;
817
+ const a = client.spot.account;
818
+ const t = client.spot.trading;
819
+ const tools = [
820
+ // ---- Market data (public) ----
821
+ {
822
+ name: "spot_ping",
823
+ description: "Test connectivity to the Binance Spot REST API.",
824
+ inputSchema: z7.object({}),
825
+ handler: async () => textResult(await m.ping())
826
+ },
827
+ {
828
+ name: "spot_server_time",
829
+ description: "Get the current Binance Spot server time in ms since epoch.",
830
+ inputSchema: z7.object({}),
831
+ handler: async () => textResult(await m.serverTime())
832
+ },
833
+ {
834
+ name: "spot_exchange_info",
835
+ description: "Get Spot exchange trading rules and symbol metadata (status, base/quote assets, filters, permissions).",
836
+ inputSchema: z7.object({}),
837
+ handler: async () => textResult(await m.exchangeInfo())
838
+ },
839
+ {
840
+ name: "spot_ticker_price",
841
+ description: "Get the latest price for a Spot symbol.",
842
+ inputSchema: z7.object({ symbol: spotSymbol }),
843
+ handler: async ({ symbol: symbol3 }) => textResult(await m.tickerPrice(normalizeSymbol(symbol3)))
844
+ },
845
+ {
846
+ name: "spot_ticker_24hr",
847
+ description: "Get 24-hour rolling price change statistics for a Spot symbol.",
848
+ inputSchema: z7.object({ symbol: spotSymbol }),
849
+ handler: async ({ symbol: symbol3 }) => textResult(await m.ticker24hr(normalizeSymbol(symbol3)))
850
+ },
851
+ {
852
+ name: "spot_book_ticker",
853
+ description: "Get the best bid/ask (top of book) for a Spot symbol.",
854
+ inputSchema: z7.object({ symbol: spotSymbol }),
855
+ handler: async ({ symbol: symbol3 }) => textResult(await m.bookTicker(normalizeSymbol(symbol3)))
856
+ },
857
+ {
858
+ name: "spot_order_book",
859
+ description: "Get the Spot order book depth for a symbol (limits 5/10/20/50/100/500/1000/5000).",
860
+ inputSchema: z7.object({
861
+ symbol: spotSymbol,
862
+ limit: z7.enum(["5", "10", "20", "50", "100", "500", "1000", "5000"]).default("100")
863
+ }),
864
+ handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await m.depth(normalizeSymbol(symbol3), Number(limit4)))
865
+ },
866
+ {
867
+ name: "spot_recent_trades",
868
+ description: "Get the most recent executed trades for a Spot symbol.",
869
+ inputSchema: z7.object({ symbol: spotSymbol, limit: limit2.default(500) }),
870
+ handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await m.trades(normalizeSymbol(symbol3), Number(limit4)))
871
+ },
872
+ {
873
+ name: "spot_historical_trades",
874
+ description: "Get older Spot trades for a symbol by fromId.",
875
+ inputSchema: z7.object({ symbol: spotSymbol, limit: limit2.default(500), fromId: z7.number().int().positive().optional() }),
876
+ handler: async ({ symbol: symbol3, limit: limit4, fromId }) => textResult(await m.historicalTrades(normalizeSymbol(symbol3), { limit: Number(limit4), fromId }))
877
+ },
878
+ {
879
+ name: "spot_agg_trades",
880
+ description: "Get compressed/aggregate Spot trades for a symbol within an optional time window.",
881
+ inputSchema: z7.object({ symbol: spotSymbol, limit: limit2.default(500), startTime: startTime3, endTime: endTime3 }),
882
+ handler: async ({ symbol: symbol3, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.aggTrades(normalizeSymbol(symbol3), { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
883
+ },
884
+ {
885
+ name: "spot_klines",
886
+ description: "Get Spot candlesticks (OHLCV). Intervals 1m\u20261M; max 1000 per request.",
887
+ inputSchema: z7.object({ symbol: spotSymbol, interval: KlineIntervalSchema, limit: limit2.default(500), startTime: startTime3, endTime: endTime3 }),
888
+ handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.klines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
889
+ },
890
+ {
891
+ name: "spot_ui_klines",
892
+ description: "Get Spot candlesticks via the optimized uiKlines endpoint (same shape as spot_klines).",
893
+ inputSchema: z7.object({ symbol: spotSymbol, interval: KlineIntervalSchema, limit: limit2.default(500), startTime: startTime3, endTime: endTime3 }),
894
+ handler: async ({ symbol: symbol3, interval, limit: limit4, startTime: startTime5, endTime: endTime5 }) => textResult(await m.uiKlines(normalizeSymbol(symbol3), interval, { limit: Number(limit4), startTime: startTime5, endTime: endTime5 }))
895
+ },
896
+ {
897
+ name: "spot_avg_price",
898
+ description: "Get the current average price (5-minute rolling average) for a Spot symbol.",
899
+ inputSchema: z7.object({ symbol: spotSymbol }),
900
+ handler: async ({ symbol: symbol3 }) => textResult(await m.avgPrice(normalizeSymbol(symbol3)))
901
+ },
902
+ {
903
+ name: "spot_rolling_window_ticker",
904
+ description: "Get rolling-window price change statistics (1d/7d/30d). Omit symbol for all symbols.",
905
+ inputSchema: z7.object({
906
+ symbol: optionalSymbol2,
907
+ windowSize: z7.enum(["1d", "7d", "30d"]).optional()
908
+ }),
909
+ handler: async ({ symbol: symbol3, windowSize }) => textResult(await m.rollingWindowTicker(symbol3 ? normalizeSymbol(symbol3) : void 0, windowSize))
910
+ },
911
+ {
912
+ name: "spot_trading_day_ticker",
913
+ description: "Get the Spot trading-day ticker (open/close/high/low/volume by UTC day). Omit symbol for all symbols.",
914
+ inputSchema: z7.object({ symbol: optionalSymbol2, timeZone: z7.string().optional(), type: z7.enum(["FULL", "MINI"]).optional() }),
915
+ handler: async ({ symbol: symbol3, timeZone, type }) => textResult(await m.tradingDayTicker(symbol3 ? normalizeSymbol(symbol3) : void 0, { timeZone, type }))
916
+ },
917
+ // ---- Account (signed) ----
918
+ {
919
+ name: "spot_account",
920
+ description: "Get the Spot account: balances (free/locked), commissions, permissions (signed).",
921
+ inputSchema: z7.object({}),
922
+ handler: async () => textResult(await a.account())
923
+ },
924
+ {
925
+ name: "spot_my_trades",
926
+ description: "Get the Spot account trade list (filled trades) for a symbol with optional time range (signed).",
927
+ inputSchema: z7.object({ symbol: spotSymbol, orderId: z7.number().int().positive().optional(), startTime: startTime3, endTime: endTime3, fromId: z7.number().int().positive().optional(), limit: limit2.default(500) }),
928
+ handler: async ({ symbol: symbol3, orderId, startTime: startTime5, endTime: endTime5, fromId, limit: limit4 }) => textResult(await a.myTrades(normalizeSymbol(symbol3), { orderId, startTime: startTime5, endTime: endTime5, fromId, limit: Number(limit4) }))
929
+ },
930
+ {
931
+ name: "spot_my_prevented_matches",
932
+ description: "Get Spot orders that were expired by the self-trade-prevention (STP) mechanism (signed).",
933
+ inputSchema: z7.object({ symbol: spotSymbol, preventedMatchId: z7.number().int().positive().optional(), orderId: z7.number().int().positive().optional(), limit: limit2.default(500) }),
934
+ handler: async ({ symbol: symbol3, preventedMatchId, orderId, limit: limit4 }) => textResult(await a.myPreventedMatches(normalizeSymbol(symbol3), { preventedMatchId, orderId, limit: Number(limit4) }))
935
+ },
936
+ {
937
+ name: "spot_account_commission",
938
+ description: "Get the Spot account commission rates for a symbol (signed).",
939
+ inputSchema: z7.object({ symbol: spotSymbol }),
940
+ handler: async ({ symbol: symbol3 }) => textResult(await a.accountCommission(normalizeSymbol(symbol3)))
941
+ },
942
+ {
943
+ name: "spot_rate_limit_order",
944
+ description: "Query the current Spot order rate limit usage (signed).",
945
+ inputSchema: z7.object({}),
946
+ handler: async () => textResult(await a.rateLimitOrder())
947
+ },
948
+ // ---- Trading (signed) ----
949
+ {
950
+ name: "spot_new_order",
951
+ description: "Place a new Spot order. Types: LIMIT, MARKET, LIMIT_MAKER, STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT. For MARKET orders use quantity OR quoteOrderQty. Signed.",
952
+ inputSchema: spotOrderParamsSchema,
953
+ handler: async (args) => textResult(await t.createOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
954
+ },
955
+ {
956
+ name: "spot_test_order",
957
+ description: "Validate a Spot order without submitting it. Signed.",
958
+ inputSchema: spotOrderParamsSchema,
959
+ handler: async (args) => textResult(await t.testOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
960
+ },
961
+ {
962
+ name: "spot_get_order",
963
+ description: "Query a specific Spot order by orderId or client order id. Signed.",
964
+ inputSchema: z7.object({ symbol: spotSymbol, orderId: z7.number().int().positive().optional(), origClientOrderId: z7.string().optional() }),
965
+ handler: async ({ symbol: symbol3, orderId, origClientOrderId }) => textResult(await t.getOrder(normalizeSymbol(symbol3), { orderId, origClientOrderId }))
966
+ },
967
+ {
968
+ name: "spot_cancel_order",
969
+ description: "Cancel a specific open Spot order by orderId or client order id. Signed.",
970
+ inputSchema: z7.object({ symbol: spotSymbol, orderId: z7.number().int().positive().optional(), origClientOrderId: z7.string().optional(), newClientOrderId: z7.string().optional() }),
971
+ handler: async ({ symbol: symbol3, orderId, origClientOrderId, newClientOrderId }) => textResult(await t.cancelOrder(normalizeSymbol(symbol3), { orderId, origClientOrderId, newClientOrderId }))
972
+ },
973
+ {
974
+ name: "spot_open_orders",
975
+ description: "Get all current open Spot orders, for one symbol or all symbols. Signed.",
976
+ inputSchema: z7.object({ symbol: optionalSymbol2 }),
977
+ handler: async ({ symbol: symbol3 }) => textResult(await t.getOpenOrders(symbol3 ? normalizeSymbol(symbol3) : void 0))
978
+ },
979
+ {
980
+ name: "spot_all_orders",
981
+ description: "Get historical Spot orders for a symbol with optional time range. Signed.",
982
+ inputSchema: z7.object({ symbol: spotSymbol, orderId: z7.number().int().positive().optional(), startTime: startTime3, endTime: endTime3, limit: limit2 }),
983
+ handler: async ({ symbol: symbol3, orderId, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await t.getAllOrders(normalizeSymbol(symbol3), { orderId, startTime: startTime5, endTime: endTime5, limit: limit4 }))
984
+ },
985
+ {
986
+ name: "spot_cancel_open_orders",
987
+ description: "Cancel all open Spot orders for a symbol. Signed.",
988
+ inputSchema: z7.object({ symbol: spotSymbol }),
989
+ handler: async ({ symbol: symbol3 }) => textResult(await t.cancelOpenOrders(normalizeSymbol(symbol3)))
990
+ },
991
+ {
992
+ name: "spot_cancel_replace_order",
993
+ description: "Cancel an existing Spot order and place a new one on the same symbol (cancel-replace). Signed.",
994
+ inputSchema: z7.object({
995
+ symbol: spotSymbol,
996
+ side,
997
+ type: z7.enum(["LIMIT", "MARKET", "STOP_LOSS", "STOP_LOSS_LIMIT", "TAKE_PROFIT", "TAKE_PROFIT_LIMIT"]),
998
+ cancelReplaceMode: z7.enum(["STOP_ON_FAILURE", "ALLOW_FAILURE"]).default("STOP_ON_FAILURE"),
999
+ cancelOrderId: z7.number().int().positive().optional(),
1000
+ cancelOrigClientOrderId: z7.string().optional(),
1001
+ cancelNewClientOrderId: z7.string().optional(),
1002
+ quantity: z7.union([z7.string(), z7.number()]).optional(),
1003
+ price: z7.union([z7.string(), z7.number()]).optional(),
1004
+ timeInForce: z7.enum(["GTC", "IOC", "FOK"]).optional(),
1005
+ newClientOrderId: z7.string().optional()
1006
+ }),
1007
+ handler: async (args) => textResult(await t.cancelReplaceOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
1008
+ },
1009
+ {
1010
+ name: "spot_new_oco_order",
1011
+ description: "Place a new Spot OCO (one-cancels-other) order: a stop-loss limit + a limit-maker take-profit. Signed.",
1012
+ inputSchema: z7.object({
1013
+ symbol: spotSymbol,
1014
+ side,
1015
+ quantity: z7.union([z7.string(), z7.number()]).describe("Total base-asset quantity for both legs"),
1016
+ price: z7.union([z7.string(), z7.number()]).describe("Limit (take-profit) price"),
1017
+ stopPrice: z7.union([z7.string(), z7.number()]).describe("Stop-loss trigger price"),
1018
+ stopLimitPrice: z7.union([z7.string(), z7.number()]).optional().describe("Stop-loss limit price (defaults to stopPrice)"),
1019
+ stopLimitTimeInForce: z7.enum(["GTC", "IOC", "FOK"]).optional(),
1020
+ listClientOrderId: z7.string().optional(),
1021
+ limitClientOrderId: z7.string().optional(),
1022
+ stopClientOrderId: z7.string().optional()
1023
+ }),
1024
+ handler: async (args) => textResult(await t.createOCOOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
1025
+ },
1026
+ {
1027
+ name: "spot_cancel_oco_order",
1028
+ description: "Cancel an entire Spot OCO order list by orderListId or listClientOrderId. Signed.",
1029
+ inputSchema: z7.object({ symbol: spotSymbol, orderListId: z7.number().int().positive().optional(), listClientOrderId: z7.string().optional(), newClientOrderId: z7.string().optional() }),
1030
+ handler: async ({ symbol: symbol3, orderListId, listClientOrderId, newClientOrderId }) => textResult(await t.cancelOCOOrder(normalizeSymbol(symbol3), { orderListId, listClientOrderId, newClientOrderId }))
1031
+ },
1032
+ {
1033
+ name: "spot_get_oco_order",
1034
+ description: "Query a Spot OCO order list by orderListId or listClientOrderId. Signed.",
1035
+ inputSchema: z7.object({ symbol: spotSymbol, orderListId: z7.number().int().positive().optional(), origClientOrderId: z7.string().optional() }),
1036
+ handler: async ({ symbol: symbol3, orderListId, origClientOrderId }) => textResult(await t.getOCOOrder(normalizeSymbol(symbol3), { orderListId, origClientOrderId }))
1037
+ },
1038
+ {
1039
+ name: "spot_open_oco_orders",
1040
+ description: "Get all current open Spot OCO order lists. Signed.",
1041
+ inputSchema: z7.object({}),
1042
+ handler: async () => textResult(await t.getOpenOCOOrders())
1043
+ },
1044
+ {
1045
+ name: "spot_all_oco_orders",
1046
+ description: "Get historical Spot OCO order lists for a symbol with optional time range. Signed.",
1047
+ inputSchema: z7.object({ symbol: spotSymbol, fromId: z7.number().int().positive().optional(), startTime: startTime3, endTime: endTime3, limit: limit2 }),
1048
+ handler: async ({ symbol: symbol3, fromId, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await t.getAllOCOOrders(normalizeSymbol(symbol3), { fromId, startTime: startTime5, endTime: endTime5, limit: limit4 }))
1049
+ },
1050
+ {
1051
+ name: "spot_cancel_open_oco_orders",
1052
+ description: "Cancel all open Spot OCO order lists for a symbol. Signed.",
1053
+ inputSchema: z7.object({ symbol: spotSymbol }),
1054
+ handler: async ({ symbol: symbol3 }) => textResult(await t.cancelOpenOCOOrders(normalizeSymbol(symbol3)))
1055
+ },
1056
+ // ---- User data stream (signed) ----
1057
+ {
1058
+ name: "spot_ws_start_user_stream",
1059
+ description: "Start the Spot user data stream: creates a listenKey, connects the private WebSocket, and begins keep-alive. Emits executionReport, outboundAccountPosition, balanceUpdate, listStatus.",
1060
+ inputSchema: z7.object({}),
1061
+ handler: async () => textResult({ listenKey: await client.startSpotUserStream() })
1062
+ },
1063
+ {
1064
+ name: "spot_ws_stop_user_stream",
1065
+ description: "Stop the Spot user data stream: closes the private WebSocket and invalidates the listenKey.",
1066
+ inputSchema: z7.object({}),
1067
+ handler: async () => {
1068
+ client.closeSpotUserStream();
1069
+ return textResult({ stopped: true });
1070
+ }
1071
+ }
1072
+ ];
1073
+ return tools;
1074
+ }
1075
+
1076
+ // src/tools/trading.tools.ts
1077
+ import { z as z8 } from "zod";
1078
+ var symbol2 = z8.string().min(1).describe("USD-M pair, e.g. BTCUSDT");
1079
+ var optionalSymbol3 = z8.string().min(1).describe("USD-M pair, e.g. BTCUSDT").optional();
1080
+ var limit3 = z8.number().int().positive().max(1e3).default(100);
1081
+ var startTime4 = z8.number().int().positive().optional();
1082
+ var endTime4 = z8.number().int().positive().optional();
1083
+ var side2 = z8.enum(["BUY", "SELL"]);
1084
+ var positionSide = z8.enum(["BOTH", "LONG", "SHORT"]).optional();
1085
+ var orderParamsSchema = z8.object({
1086
+ symbol: symbol2,
1087
+ side: side2,
1088
+ type: z8.enum(["LIMIT", "MARKET", "STOP", "STOP_MARKET", "TAKE_PROFIT", "TAKE_PROFIT_MARKET", "TRAILING_STOP_MARKET"]),
1089
+ quantity: z8.union([z8.string(), z8.number()]).describe("Order quantity in base asset"),
1090
+ price: z8.union([z8.string(), z8.number()]).optional().describe("Required for LIMIT and STOP/TAKE_PROFIT (limit-triggered) types"),
1091
+ timeInForce: z8.enum(["GTC", "IOC", "FOK", "GTX"]).optional(),
1092
+ stopPrice: z8.union([z8.string(), z8.number()]).optional().describe("Trigger price for STOP/STOP_MARKET/TAKE_PROFIT/TAKE_PROFIT_MARKET"),
1093
+ reduceOnly: z8.boolean().optional().describe("true = only reduces the position, never opens"),
1094
+ positionSide,
1095
+ newClientOrderId: z8.string().optional(),
1096
+ closePosition: z8.boolean().optional().describe("Close the full position on trigger (mutually exclusive with quantity)"),
1097
+ newOrderRespType: z8.enum(["ACK", "RESULT"]).optional(),
1098
+ priceProtect: z8.boolean().optional(),
1099
+ workingType: z8.enum(["MARK_PRICE", "CONTRACT_PRICE"]).optional().describe("Trigger price basis; default CONTRACT_PRICE"),
1100
+ callbackRate: z8.union([z8.string(), z8.number()]).optional().describe("Percent callback for TRAILING_STOP_MARKET, e.g. 0.5"),
1101
+ activationPrice: z8.union([z8.string(), z8.number()]).optional().describe("Activation price for TRAILING_STOP_MARKET"),
1102
+ selfTradePreventionMode: z8.enum(["NONE", "EXPIRE_TAKER", "EXPIRE_MAKER", "EXPIRE_BOTH"]).optional(),
1103
+ goodTillDate: z8.number().int().optional().describe("Timestamp when a GTD order expires")
1104
+ });
1105
+ function tradingTools(client) {
1106
+ const t = client.futures.trading;
1107
+ return [
1108
+ {
1109
+ name: "futures_new_order",
1110
+ description: "Place a new futures order. Types: LIMIT, MARKET, STOP, STOP_MARKET, TAKE_PROFIT, TAKE_PROFIT_MARKET, TRAILING_STOP_MARKET. Use STOP_MARKET as the take-profit/stop-loss trigger and LIMIT for the actual fill. Signed.",
1111
+ inputSchema: orderParamsSchema,
1112
+ handler: async (args) => textResult(await t.createOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
1113
+ },
1114
+ {
1115
+ name: "futures_test_order",
1116
+ description: "Validate a new order without submitting it. Returns 200 on success; use to validate fields and margin before real orders. Signed.",
1117
+ inputSchema: orderParamsSchema,
1118
+ handler: async (args) => textResult(await t.createTestOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
1119
+ },
1120
+ {
1121
+ name: "futures_get_order",
1122
+ description: "Query a specific order by orderId or client order id. Signed.",
1123
+ inputSchema: z8.object({ symbol: symbol2, orderId: z8.number().int().positive().optional(), origClientOrderId: z8.string().optional() }),
1124
+ handler: async ({ symbol: symbol3, orderId, origClientOrderId }) => textResult(await t.getOrder(normalizeSymbol(symbol3), { orderId, origClientOrderId }))
1125
+ },
1126
+ {
1127
+ name: "futures_cancel_order",
1128
+ description: "Cancel a specific open order by orderId or client order id. Signed.",
1129
+ inputSchema: z8.object({ symbol: symbol2, orderId: z8.number().int().positive().optional(), origClientOrderId: z8.string().optional() }),
1130
+ handler: async ({ symbol: symbol3, orderId, origClientOrderId }) => textResult(await t.cancelOrder(normalizeSymbol(symbol3), { orderId, origClientOrderId }))
1131
+ },
1132
+ {
1133
+ name: "futures_get_open_order",
1134
+ description: "Query a current open order (must exist in the open order book). Signed.",
1135
+ inputSchema: z8.object({ symbol: symbol2, orderId: z8.number().int().positive().optional(), origClientOrderId: z8.string().optional() }),
1136
+ handler: async ({ symbol: symbol3, orderId, origClientOrderId }) => textResult(await t.getCurrentOrder(normalizeSymbol(symbol3), { orderId, origClientOrderId }))
1137
+ },
1138
+ {
1139
+ name: "futures_open_orders",
1140
+ description: "Get all current open orders, for one symbol or all symbols. Signed.",
1141
+ inputSchema: z8.object({ symbol: optionalSymbol3 }),
1142
+ handler: async ({ symbol: symbol3 }) => textResult(await t.getOpenOrders(symbol3 ? normalizeSymbol(symbol3) : void 0))
1143
+ },
1144
+ {
1145
+ name: "futures_all_orders",
1146
+ description: "Get historical orders for a symbol with optional time range (last 7 days by default). Signed.",
1147
+ inputSchema: z8.object({ symbol: symbol2, orderId: z8.number().int().positive().optional(), startTime: startTime4, endTime: endTime4, limit: limit3 }),
1148
+ handler: async ({ symbol: symbol3, orderId, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await t.getAllOrders(normalizeSymbol(symbol3), { orderId, startTime: startTime5, endTime: endTime5, limit: limit4 }))
1149
+ },
1150
+ {
1151
+ name: "futures_cancel_all_orders",
1152
+ description: "Cancel all open orders for a symbol. Signed.",
1153
+ inputSchema: z8.object({ symbol: symbol2 }),
1154
+ handler: async ({ symbol: symbol3 }) => textResult(await t.cancelAllOpenOrders(normalizeSymbol(symbol3)))
1155
+ },
1156
+ {
1157
+ name: "futures_modify_order",
1158
+ description: "Modify an open order (price/quantity/stopPrice). Cannot modify when position side is BOTH and closePosition is true. Signed.",
1159
+ inputSchema: z8.object({
1160
+ symbol: symbol2,
1161
+ side: side2,
1162
+ quantity: z8.union([z8.string(), z8.number()]),
1163
+ price: z8.union([z8.string(), z8.number()]).optional(),
1164
+ orderId: z8.number().int().positive().optional(),
1165
+ origClientOrderId: z8.string().optional(),
1166
+ stopPrice: z8.union([z8.string(), z8.number()]).optional(),
1167
+ timeInForce: z8.enum(["GTC", "IOC", "FOK", "GTX"]).optional(),
1168
+ positionSide,
1169
+ newClientOrderId: z8.string().optional()
1170
+ }),
1171
+ handler: async (args) => textResult(await t.modifyOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
1172
+ },
1173
+ {
1174
+ name: "futures_order_modify_history",
1175
+ description: "Get order modification history for a symbol. Signed.",
1176
+ inputSchema: z8.object({ symbol: symbol2, startTime: startTime4, endTime: endTime4, limit: limit3 }),
1177
+ handler: async ({ symbol: symbol3, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await t.getOrderModifyHistory(normalizeSymbol(symbol3), { startTime: startTime5, endTime: endTime5, limit: limit4 }))
1178
+ },
1179
+ {
1180
+ name: "futures_batch_orders",
1181
+ description: "Place up to 5 orders in one request (array of order objects, max 30 per minute per symbol). Signed.",
1182
+ inputSchema: z8.object({ orders: z8.array(orderParamsSchema).min(1).max(5) }),
1183
+ handler: async (args) => {
1184
+ const mapped = args.orders.map((o) => ({ ...o, symbol: normalizeSymbol(o.symbol) }));
1185
+ return textResult(await t.createBatchOrders(mapped));
1186
+ }
1187
+ },
1188
+ {
1189
+ name: "futures_cancel_batch_orders",
1190
+ description: "Cancel multiple orders at once (up to 10 by orderId list or client order id list). Signed.",
1191
+ inputSchema: z8.object({
1192
+ symbol: symbol2,
1193
+ orderIdList: z8.array(z8.number().int().positive()).max(10).optional(),
1194
+ origClientOrderIdList: z8.array(z8.string()).max(10).optional()
1195
+ }),
1196
+ handler: async ({ symbol: symbol3, orderIdList, origClientOrderIdList }) => textResult(await t.cancelBatchOrders(normalizeSymbol(symbol3), { orderIdList, origClientOrderIdList }))
1197
+ },
1198
+ {
1199
+ name: "futures_set_leverage",
1200
+ description: "Change initial leverage for a symbol (1-125, within bracket). Signed.",
1201
+ inputSchema: z8.object({ symbol: symbol2, leverage: z8.number().int().min(1).max(125) }),
1202
+ handler: async ({ symbol: symbol3, leverage }) => textResult(await t.setLeverage(normalizeSymbol(symbol3), leverage))
1203
+ },
1204
+ {
1205
+ name: "futures_set_margin_type",
1206
+ description: "Change margin type for a symbol: isolated or cross. Only allowed when no open position for the symbol. Signed.",
1207
+ inputSchema: z8.object({ symbol: symbol2, marginType: z8.enum(["isolated", "cross"]) }),
1208
+ handler: async ({ symbol: symbol3, marginType }) => textResult(await t.setMarginType(normalizeSymbol(symbol3), marginType))
1209
+ },
1210
+ {
1211
+ name: "futures_modify_position_margin",
1212
+ description: "Add or reduce isolated position margin. marginType: 1 = add margin, 2 = reduce margin. Signed.",
1213
+ inputSchema: z8.object({ symbol: symbol2, amount: z8.number().positive(), marginType: z8.enum(["1", "2"]).describe("1 = add margin, 2 = reduce margin") }),
1214
+ handler: async ({ symbol: symbol3, amount, marginType }) => textResult(await t.modifyPositionMargin(normalizeSymbol(symbol3), amount, Number(marginType)))
1215
+ },
1216
+ {
1217
+ name: "futures_countdown_cancel_all",
1218
+ description: "Auto-cancel all open orders for a symbol after countdownTime ms (0 = cancel the countdown). Emergency circuit breaker. Signed.",
1219
+ inputSchema: z8.object({ symbol: symbol2, countdownTime: z8.number().int().min(100).max(6e4) }),
1220
+ handler: async ({ symbol: symbol3, countdownTime }) => textResult(await t.setCountdownCancelAll(normalizeSymbol(symbol3), countdownTime))
1221
+ },
1222
+ {
1223
+ name: "futures_new_algo_order",
1224
+ description: "Place a conditional algo order (CONDITIONAL or VP). CONDITIONAL supports STOP_MARKET/TAKE_PROFIT_MARKET types with triggerPrice; VP is a volume-participation order with urgency and quantity. Signed.",
1225
+ inputSchema: z8.object({
1226
+ algoType: z8.enum(["CONDITIONAL", "VP"]),
1227
+ symbol: symbol2,
1228
+ side: side2,
1229
+ positionSide,
1230
+ type: z8.enum(["STOP_MARKET", "TAKE_PROFIT_MARKET", "LIMIT"]).describe("For CONDITIONAL: STOP_MARKET/TAKE_PROFIT_MARKET. For VP: LIMIT"),
1231
+ quantity: z8.union([z8.string(), z8.number()]),
1232
+ triggerPrice: z8.union([z8.string(), z8.number()]).optional().describe("Required for CONDITIONAL"),
1233
+ price: z8.union([z8.string(), z8.number()]).optional(),
1234
+ timeInForce: z8.enum(["GTC", "IOC", "FOK", "GTX"]).optional(),
1235
+ workingType: z8.enum(["MARK_PRICE", "CONTRACT_PRICE"]).optional(),
1236
+ priceProtect: z8.boolean().optional(),
1237
+ reduceOnly: z8.boolean().optional(),
1238
+ closePosition: z8.boolean().optional(),
1239
+ urgency: z8.enum(["LOW", "MEDIUM", "HIGH"]).optional().describe("Required for VP"),
1240
+ clientAlgoId: z8.string().optional()
1241
+ }),
1242
+ handler: async (args) => textResult(await t.createAlgoOrder({ ...args, symbol: normalizeSymbol(args.symbol) }))
1243
+ },
1244
+ {
1245
+ name: "futures_cancel_algo_order",
1246
+ description: "Cancel an open algo order by algoId or clientAlgoId. Signed.",
1247
+ inputSchema: z8.object({ symbol: symbol2, algoId: z8.number().int().positive().optional(), clientAlgoId: z8.string().optional() }),
1248
+ handler: async ({ symbol: symbol3, algoId, clientAlgoId }) => textResult(await t.cancelAlgoOrder(normalizeSymbol(symbol3), { algoId, clientAlgoId }))
1249
+ },
1250
+ {
1251
+ name: "futures_cancel_all_algo_orders",
1252
+ description: "Cancel all open algo orders for a symbol. Signed.",
1253
+ inputSchema: z8.object({ symbol: symbol2 }),
1254
+ handler: async ({ symbol: symbol3 }) => textResult(await t.cancelAllOpenAlgoOrders(normalizeSymbol(symbol3)))
1255
+ },
1256
+ {
1257
+ name: "futures_get_algo_order",
1258
+ description: "Query an algo order by algoId or clientAlgoId. Signed.",
1259
+ inputSchema: z8.object({ symbol: symbol2, algoId: z8.number().int().positive().optional(), clientAlgoId: z8.string().optional() }),
1260
+ handler: async ({ symbol: symbol3, algoId, clientAlgoId }) => textResult(await t.getAlgoOrder(normalizeSymbol(symbol3), { algoId, clientAlgoId }))
1261
+ },
1262
+ {
1263
+ name: "futures_open_algo_orders",
1264
+ description: "Get all current open algo orders, optionally filtered by symbol. Signed.",
1265
+ inputSchema: z8.object({ symbol: optionalSymbol3 }),
1266
+ handler: async ({ symbol: symbol3 }) => textResult(await t.getOpenAlgoOrders(symbol3 ? normalizeSymbol(symbol3) : void 0))
1267
+ },
1268
+ {
1269
+ name: "futures_all_algo_orders",
1270
+ description: "Get historical algo orders for a symbol with optional time range. Signed.",
1271
+ inputSchema: z8.object({ symbol: symbol2, startTime: startTime4, endTime: endTime4, limit: limit3 }),
1272
+ handler: async ({ symbol: symbol3, startTime: startTime5, endTime: endTime5, limit: limit4 }) => textResult(await t.getAllAlgoOrders(normalizeSymbol(symbol3), { startTime: startTime5, endTime: endTime5, limit: limit4 }))
1273
+ },
1274
+ {
1275
+ name: "futures_convert_exchange_info",
1276
+ description: "List asset pairs eligible for futures Convert, optionally filtered by fromAsset/toAsset.",
1277
+ inputSchema: z8.object({ fromAsset: z8.string().optional(), toAsset: z8.string().optional() }),
1278
+ handler: async ({ fromAsset, toAsset }) => textResult(await t.convertExchangeInfo({ fromAsset, toAsset }))
1279
+ },
1280
+ {
1281
+ name: "futures_convert_get_quote",
1282
+ description: "Request a Convert quote between two assets (quote expires quickly; accept with futures_convert_accept_quote). Signed.",
1283
+ inputSchema: z8.object({
1284
+ fromAsset: z8.string().min(1),
1285
+ toAsset: z8.string().min(1),
1286
+ fromAmount: z8.number().positive().optional(),
1287
+ toAmount: z8.number().positive().optional(),
1288
+ validTime: z8.enum(["10s", "30s", "1m", "2m"]).optional()
1289
+ }),
1290
+ handler: async (args) => textResult(await t.convertGetQuote(args))
1291
+ },
1292
+ {
1293
+ name: "futures_convert_accept_quote",
1294
+ description: "Accept a previously requested Convert quote by quoteId. Signed.",
1295
+ inputSchema: z8.object({ quoteId: z8.string().min(1) }),
1296
+ handler: async ({ quoteId }) => textResult(await t.convertAcceptQuote(quoteId))
1297
+ },
1298
+ {
1299
+ name: "futures_convert_order_status",
1300
+ description: "Query the status of a Convert order by orderId or quoteId. Signed.",
1301
+ inputSchema: z8.object({ orderId: z8.string().optional(), quoteId: z8.string().optional() }),
1302
+ handler: async ({ orderId, quoteId }) => textResult(await t.convertOrderStatus({ orderId, quoteId }))
1303
+ }
1304
+ ];
1305
+ }
1306
+
1307
+ // src/tools/ws.tools.ts
1308
+ import { z as z9 } from "zod";
1309
+ var buffers = /* @__PURE__ */ new Map();
1310
+ var MAX_BUFFER = 500;
1311
+ function bufferFor(client) {
1312
+ let buffer = buffers.get(client);
1313
+ if (!buffer) {
1314
+ buffer = { subscriptions: /* @__PURE__ */ new Set(), events: [] };
1315
+ buffers.set(client, buffer);
1316
+ client.futures.ws.on("message", (stream, payload) => {
1317
+ buffer.events.push({ stream, payload, ts: Date.now() });
1318
+ if (buffer.events.length > MAX_BUFFER) buffer.events.splice(0, buffer.events.length - MAX_BUFFER);
1319
+ });
1320
+ }
1321
+ return buffer;
1322
+ }
1323
+ function getBufferedWsEvents(client, limit4 = 50) {
1324
+ return bufferFor(client).events.slice(-limit4);
1325
+ }
1326
+ function clearBufferedWsEvents(client) {
1327
+ bufferFor(client).events = [];
1328
+ }
1329
+ function wsTools(client) {
1330
+ const buffer = bufferFor(client);
1331
+ return [
1332
+ {
1333
+ name: "futures_ws_subscribe",
1334
+ description: "Subscribe to real-time market data streams. Topic format: <symbol>@<stream>, e.g. btcusdt@aggTrade, btcusdt@kline_1m, btcusdt@depth20, btcusdt@markPrice@1s, btcusdt@bookTicker, btcusdt@ticker, btcusdt@miniTicker, btcusdt@forceOrder, or all-market topics !ticker@arr, !bookTicker, !markPrice@arr, !forceOrder@arr, !miniTicker@arr. Multiple topics can be passed at once.",
1335
+ inputSchema: z9.object({
1336
+ topics: z9.array(z9.string().min(1)).min(1).describe('Stream topics, e.g. ["btcusdt@aggTrade", "btcusdt@kline_1m"]')
1337
+ }),
1338
+ handler: async ({ topics }) => {
1339
+ const normalized = topics.map((t) => t.trim().toLowerCase());
1340
+ client.futures.ws.subscribe(normalized);
1341
+ normalized.forEach((t) => buffer.subscriptions.add(t));
1342
+ return textResult({ subscribed: normalized, active: [...buffer.subscriptions] });
1343
+ }
1344
+ },
1345
+ {
1346
+ name: "futures_ws_unsubscribe",
1347
+ description: "Unsubscribe from previously subscribed market data streams.",
1348
+ inputSchema: z9.object({ topics: z9.array(z9.string().min(1)).min(1) }),
1349
+ handler: async ({ topics }) => {
1350
+ const normalized = topics.map((t) => t.trim().toLowerCase());
1351
+ client.futures.ws.unsubscribe(normalized);
1352
+ normalized.forEach((t) => buffer.subscriptions.delete(t));
1353
+ return textResult({ unsubscribed: normalized, active: [...buffer.subscriptions] });
1354
+ }
1355
+ },
1356
+ {
1357
+ name: "futures_ws_subscriptions",
1358
+ description: "List the currently subscribed WebSocket market streams for this client.",
1359
+ inputSchema: z9.object({}),
1360
+ handler: async () => textResult({ active: [...buffer.subscriptions] })
1361
+ },
1362
+ {
1363
+ name: "futures_ws_events",
1364
+ description: "Read the buffered real-time payloads received since the last read for the subscribed streams (aggregate trades, klines, depth deltas, mark price, book tickers, tickers, force orders). Payloads are parsed; depth deltas must be applied to a snapshot from futures_order_book.",
1365
+ inputSchema: z9.object({ limit: z9.number().int().min(1).max(200).default(50) }),
1366
+ handler: async ({ limit: limit4 }) => textResult(getBufferedWsEvents(client, limit4))
1367
+ },
1368
+ {
1369
+ name: "futures_ws_clear_events",
1370
+ description: "Clear the buffered WebSocket events so the next read only returns new payloads.",
1371
+ inputSchema: z9.object({}),
1372
+ handler: async () => {
1373
+ clearBufferedWsEvents(client);
1374
+ return textResult({ cleared: true });
1375
+ }
1376
+ },
1377
+ {
1378
+ name: "futures_ws_start_user_stream",
1379
+ description: "Start the user data stream: creates a listenKey, connects the private WebSocket, and begins a 30-minute keep-alive. Emits private events (ACCOUNT_UPDATE, ORDER_TRADE_UPDATE, MARGIN_CALL, ACCOUNT_CONFIG_UPDATE, listenKeyExpired) that the application can consume from the client.",
1380
+ inputSchema: z9.object({}),
1381
+ handler: async () => textResult({ listenKey: await client.startUserStream() })
1382
+ },
1383
+ {
1384
+ name: "futures_ws_stop_user_stream",
1385
+ description: "Stop the user data stream: closes the private WebSocket and invalidates the listenKey.",
1386
+ inputSchema: z9.object({}),
1387
+ handler: async () => {
1388
+ client.closeUserStream();
1389
+ return textResult({ stopped: true });
1390
+ }
1391
+ },
1392
+ {
1393
+ name: "futures_ws_api_order_status",
1394
+ description: "Query an order via the signed WebSocket API (order.status) \u2014 lower-latency alternative to futures_get_order.",
1395
+ inputSchema: z9.object({
1396
+ symbol: z9.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
1397
+ orderId: z9.number().int().positive().optional(),
1398
+ origClientOrderId: z9.string().optional()
1399
+ }),
1400
+ handler: async ({ symbol: symbol3, orderId, origClientOrderId }) => textResult(await client.futures.wsApi.orderStatus({ symbol: normalizeSymbol(symbol3), orderId, origClientOrderId }))
1401
+ },
1402
+ {
1403
+ name: "futures_ws_api_account_status",
1404
+ description: "Get account info via the signed WebSocket API (account.status).",
1405
+ inputSchema: z9.object({}),
1406
+ handler: async () => textResult(await client.futures.wsApi.accountStatus())
1407
+ },
1408
+ {
1409
+ name: "futures_ws_api_account_position",
1410
+ description: "Get current positions via the signed WebSocket API (account.position).",
1411
+ inputSchema: z9.object({ symbol: z9.string().min(1).describe("USD-M pair, e.g. BTCUSDT").optional() }),
1412
+ handler: async ({ symbol: symbol3 }) => textResult(await client.futures.wsApi.accountPosition(symbol3 ? { symbol: normalizeSymbol(symbol3) } : {}))
1413
+ },
1414
+ {
1415
+ name: "futures_ws_api_user_data_stream_start",
1416
+ description: "Create a listenKey via the signed WebSocket API (userDataStream.start) \u2014 no REST call required.",
1417
+ inputSchema: z9.object({}),
1418
+ handler: async () => textResult(await client.futures.wsApi.userDataStreamStart())
1419
+ },
1420
+ {
1421
+ name: "futures_ws_api_user_data_stream_stop",
1422
+ description: "Invalidate a listenKey via the signed WebSocket API (userDataStream.stop).",
1423
+ inputSchema: z9.object({ listenKey: z9.string().min(1) }),
1424
+ handler: async ({ listenKey }) => textResult(await client.futures.wsApi.userDataStreamStop(listenKey))
1425
+ },
1426
+ {
1427
+ name: "futures_ws_api_ticker_price",
1428
+ description: "Get latest price via the unsigned WebSocket API (ticker.price); omit symbol for all symbols.",
1429
+ inputSchema: z9.object({ symbol: z9.string().min(1).describe("USD-M pair, e.g. BTCUSDT").optional() }),
1430
+ handler: async ({ symbol: symbol3 }) => textResult(await client.futures.wsApi.tickerPrice(symbol3 ? { symbol: normalizeSymbol(symbol3) } : {}))
1431
+ },
1432
+ {
1433
+ name: "futures_ws_api_order_book",
1434
+ description: "Get order-book depth via the unsigned WebSocket API (depth).",
1435
+ inputSchema: z9.object({
1436
+ symbol: z9.string().min(1).describe("USD-M pair, e.g. BTCUSDT"),
1437
+ limit: z9.enum(["5", "10", "20", "50", "100", "500", "1000"]).optional()
1438
+ }),
1439
+ handler: async ({ symbol: symbol3, limit: limit4 }) => textResult(await client.futures.wsApi.depth({ symbol: normalizeSymbol(symbol3), limit: limit4 }))
1440
+ }
1441
+ ];
1442
+ }
1443
+
1444
+ // src/tools/index.ts
1445
+ function createFuturesToolkit(client) {
1446
+ const market = marketDataTools(client);
1447
+ const account = accountTools(client);
1448
+ const trading = tradingTools(client);
1449
+ const spot = spotTools(client);
1450
+ const ws = wsTools(client);
1451
+ const derived = derivedTools(client);
1452
+ const paperContext = createPaperContext(client);
1453
+ const paper = paperTools(paperContext);
1454
+ return {
1455
+ client,
1456
+ tools: [...market, ...account, ...trading, ...spot, ...ws, ...derived, ...paper],
1457
+ market,
1458
+ account,
1459
+ trading,
1460
+ spot,
1461
+ ws,
1462
+ derived,
1463
+ paper,
1464
+ paperContext
1465
+ };
1466
+ }
1467
+ function toolkitToFormats(toolkit) {
1468
+ return {
1469
+ openai: toToolList(toolkit.tools, "openai"),
1470
+ anthropic: toToolList(toolkit.tools, "anthropic"),
1471
+ mcp: toToolList(toolkit.tools, "mcp")
1472
+ };
1473
+ }
1474
+ export {
1475
+ accountTools,
1476
+ clearBufferedWsEvents,
1477
+ createFuturesToolkit,
1478
+ createPaperContext,
1479
+ derivedTools,
1480
+ getBufferedWsEvents,
1481
+ marketDataTools,
1482
+ paperTools,
1483
+ spotTools,
1484
+ textResult,
1485
+ toAnthropicTool,
1486
+ toJsonSchema,
1487
+ toMCPTool,
1488
+ toOpenAITool,
1489
+ toToolList,
1490
+ toolkitToFormats,
1491
+ tradingTools,
1492
+ wsTools
1493
+ };
1494
+ //# sourceMappingURL=index.js.map