@nemesis-oss/binance-sdk 2.0.0 → 3.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.
- package/LICENSE +21 -0
- package/README.md +280 -9
- package/dist/{index-BO27qOb5.d.cts → index-C06A22Dz.d.cts} +5506 -3153
- package/dist/{index-BO27qOb5.d.ts → index-C06A22Dz.d.ts} +5506 -3153
- package/dist/index.cjs +10761 -3849
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1908 -302
- package/dist/index.d.ts +1908 -302
- package/dist/index.js +10675 -3850
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.cjs +8583 -3842
- package/dist/mcp/index.cjs.map +1 -1
- package/dist/mcp/index.js +8583 -3842
- package/dist/mcp/index.js.map +1 -1
- package/dist/tools/index.cjs +578 -481
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.d.cts +2 -1
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.js +577 -481
- package/dist/tools/index.js.map +1 -1
- package/package.json +6 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shubham Taywade
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -26,6 +26,11 @@ const client = new BinanceClient({
|
|
|
26
26
|
testnet: true, // or demo: true; defaults to live
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
// v3: lazy product namespaces over one shared CoreContext — nothing is built
|
|
30
|
+
// until first access, and `client.core` exposes the shared runtime.
|
|
31
|
+
client.core.credentials.canSign; // true
|
|
32
|
+
client.core.http('fapi'); // cached per-host transport
|
|
33
|
+
|
|
29
34
|
// Public market data (no keys needed)
|
|
30
35
|
const klines = await client.spot.market.klines('SOLUSDT', '15m', { limit: 500 });
|
|
31
36
|
const funding = await client.futures.data.fundingRateHistory('ETHUSDT', { limit: 100 });
|
|
@@ -211,8 +216,13 @@ creation, futures/margin enablement, deposit address/history.
|
|
|
211
216
|
`apiKey`, `apiSecret`, `privateKey` + `signatureAlgorithm` (Ed25519/RSA, instead of HMAC),
|
|
212
217
|
`testnet`, `demo`, `recvWindow`, `apiBase`, `wsBase`, `wsUserBase`, `wsApiBase`, `dapiBase`,
|
|
213
218
|
`wsSpotApiBase`, `wsDapiBase`, `timeoutMs`, `maxRetries`, `retryBaseDelayMs`, `retryMaxDelayMs`,
|
|
214
|
-
`
|
|
215
|
-
|
|
219
|
+
`retryPolicy` (`strict` default / `legacy`), `idempotentPaths`, `rateLimitWeightPerMinute`,
|
|
220
|
+
`rateLimitSafetyMargin`, `httpsAgent`, `proxy`, `events` (observability bus),
|
|
221
|
+
`safety` (see [Agent safety](#agent-safety)).
|
|
222
|
+
|
|
223
|
+
Product aliases: `client.futures.usdm` and `client.futures.coinm` point at the USDⓈ-M and
|
|
224
|
+
COIN-M surfaces; `client.products` gives the product-oriented view
|
|
225
|
+
(`spot` / `usdm` / `coinm` / `margin` / `wallet` / `subaccount`).
|
|
216
226
|
|
|
217
227
|
### Reliability
|
|
218
228
|
|
|
@@ -223,14 +233,118 @@ creation, futures/margin enablement, deposit address/history.
|
|
|
223
233
|
`client.getRateLimitUsage()`.
|
|
224
234
|
- **Server time sync**: `client.syncTime()` fetches each REST host's server time and applies the
|
|
225
235
|
offset to every signed request's `timestamp`, mitigating `-1021` errors from local clock drift.
|
|
226
|
-
- **
|
|
227
|
-
`
|
|
236
|
+
- **Endpoint-aware retries (strict by default)**: exponential backoff with jitter on `429`/`418`
|
|
237
|
+
(rejected before processing — safe for any method) and `5xx`/network errors on idempotent
|
|
238
|
+
methods (GET/DELETE, whitelisted paths such as `order/test`). A `POST` order placement that
|
|
239
|
+
times out is **not** blindly retried — the request may already be live on the exchange.
|
|
240
|
+
Retried signed requests are re-signed with a fresh timestamp. Set `retryPolicy: 'legacy'` to
|
|
241
|
+
restore retry-everything behavior.
|
|
242
|
+
- **WebSocket lifecycle**: every WS client is an explicit state machine
|
|
243
|
+
(`IDLE → CONNECTING → OPEN → RECONNECTING → CLOSING → CLOSED`, via `ws.getState()` and
|
|
244
|
+
`ws.state` events) with race-free reconnection (a retired socket can never trigger a duplicate
|
|
245
|
+
connection) and **proactive 24-hour rotation**: Binance kills stream connections at 24h, so the
|
|
246
|
+
SDK opens a replacement at T-23h and swaps traffic with no data gap.
|
|
247
|
+
- **Subscription acknowledgement**: `await ws.subscribe([...])` resolves only after the server
|
|
248
|
+
confirms the subscription, and every (re)connect verifies the live subscription set with
|
|
249
|
+
`LIST_SUBSCRIPTIONS` and repairs drift automatically.
|
|
250
|
+
- **Exact numbers**: all WS frames are parsed with large-integer preservation (identifiers above
|
|
251
|
+
2^53 surface as decimal strings instead of silently-corrupted floats — also available as
|
|
252
|
+
`parseJsonLossless` for your own payloads), and money math in the execution/risk/state layers
|
|
253
|
+
runs on a BigInt-backed `Decimal` (`0.1 + 0.2 === 0.3`, exactly).
|
|
254
|
+
|
|
255
|
+
### Execution (idempotent placement + reconciliation)
|
|
256
|
+
|
|
257
|
+
`client.futures.execution` and `client.spot.execution` are the safe way to place orders — one
|
|
258
|
+
execution semantics across USDⓈ-M, spot and the paper simulator (see
|
|
259
|
+
[Multi-backend execution](#multi-backend-execution-live--paper) below):
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
const execution = await client.futures.execution.placeOrder({
|
|
263
|
+
symbol: 'BTCUSDT',
|
|
264
|
+
side: 'BUY',
|
|
265
|
+
type: 'MARKET',
|
|
266
|
+
quantity: 0.001,
|
|
267
|
+
intentId: 'my-strategy-signal-42', // idempotency key: replays return the original execution
|
|
268
|
+
});
|
|
269
|
+
// {
|
|
270
|
+
// intentId, clientOrderId, exchangeOrderId, status, executedQuantity: '0.001',
|
|
271
|
+
// averagePrice: '…', fills: [...], reconciliationState: 'acked' | 'reconciled' | …
|
|
272
|
+
// }
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
- Every order carries a deterministic `newClientOrderId` derived from the intent — the exchange
|
|
276
|
+
itself becomes the idempotency guard; duplicate intents return the recorded execution.
|
|
277
|
+
- On a transport failure the outcome is **reconciled** by polling
|
|
278
|
+
`GET /fapi/v1/order?origClientOrderId=…`: found → the execution is recovered and returned;
|
|
279
|
+
`-2013` (order does not exist) → one safe resubmission with the same clientOrderId; still
|
|
280
|
+
ambiguous → `ExecutionUnknownError` carrying the intent for manual follow-up — never a guess.
|
|
281
|
+
- With a user-data stream attached (`execution.setUserStream(wsUser)`), execution reports
|
|
282
|
+
(`ORDER_TRADE_UPDATE` on futures, `executionReport` on spot) stream live fills into the ledger.
|
|
283
|
+
- `cancelOrder` reconciles the same way, and `execution.reconcile(intentId)` forces a refresh.
|
|
284
|
+
|
|
285
|
+
### Multi-backend execution (live + paper)
|
|
286
|
+
|
|
287
|
+
Product specifics live behind `ExecutionAdapter` implementations
|
|
288
|
+
(`FuturesExecutionAdapter`, `SpotExecutionAdapter`, `PaperExecutionAdapter`), so paper trading
|
|
289
|
+
is a first-class execution backend — the same envelope, idempotency and reconciliation
|
|
290
|
+
semantics, zero exchange traffic:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
// Paper manager: identical API to client.futures.execution
|
|
294
|
+
const paper = client.createPaperExecutionManager({ initialBalance: 50_000 });
|
|
295
|
+
const fill = await paper.placeOrder({
|
|
296
|
+
symbol: 'BTCUSDT', side: 'BUY', type: 'MARKET', quantity: 0.01, intentId: 'strategy-1',
|
|
297
|
+
});
|
|
298
|
+
// fill.status === 'FILLED', fill.fills[0].price — exact decimal strings
|
|
299
|
+
|
|
300
|
+
// Gateway: route live/paper through one interface, independent ledgers
|
|
301
|
+
const gateway = client.createExecutionGateway({ defaultBackend: 'paper' });
|
|
302
|
+
await gateway.placeOrder({ ... }); // paper (default)
|
|
303
|
+
await gateway.placeOrder({ ...order }, { backend: 'live' }); // one live order
|
|
304
|
+
gateway.paperEngine.getAccountInfo(); // simulation state
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Standalone single-product clients for focused integrations. v2 factories
|
|
308
|
+
still ship for back-compat; the v3 first-class `ProductClient` classes
|
|
309
|
+
(`SpotClient`, `USDMClient`, `CoinMClient`) own their own `CoreContext`,
|
|
310
|
+
the v3 execution platform (Spot / USDⓈ-M) and the v3 state engine
|
|
311
|
+
(Spot / USDⓈ-M):
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
import { createSpotClient, createUSDMClient } from '@nemesis-oss/binance-sdk';
|
|
315
|
+
const spot = createSpotClient({ apiKey, apiSecret }); // v2 factory
|
|
316
|
+
await spot.syncTime();
|
|
317
|
+
await spot.market.depth('BTCUSDT', 20);
|
|
318
|
+
spot.close();
|
|
319
|
+
|
|
320
|
+
// v3 first-class product client — owns CoreContext, owns the platform
|
|
321
|
+
import { CoreContext, SpotClient, USDMClient, CoinMClient } from '@nemesis-oss/binance-sdk';
|
|
322
|
+
const core = new CoreContext({ apiKey, apiSecret });
|
|
323
|
+
const usdm = new USDMClient(core);
|
|
324
|
+
await usdm.executionPlatform.startUserSession(); // managed listen-key + 30-min keep-alive
|
|
325
|
+
const book = await usdm.books.watch('BTCUSDT'); // local L2 book, synced
|
|
326
|
+
usdm.close();
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Local order books
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
const books = client.createFuturesOrderBookEngine();
|
|
333
|
+
const btc = await books.subscribe('BTCUSDT');
|
|
334
|
+
btc.metrics(); // bestBid / bestAsk / midPrice / spread / spreadBps / microprice /
|
|
335
|
+
// imbalance / bidDepth / askDepth / lastUpdateId / synced
|
|
336
|
+
btc.vwap('bids', 5); // size-weighted VWAP of the top 5 levels (exact decimal string)
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
The engine seeds each book from a REST snapshot, applies `@depth@100ms` diffs in sequence,
|
|
340
|
+
detects gaps (`pu` / sequence discontinuity) and self-heals with a fresh snapshot.
|
|
228
341
|
|
|
229
342
|
### Agent safety
|
|
230
343
|
|
|
231
|
-
`BinanceClientOptions.safety` configures a `
|
|
232
|
-
before it leaves the process — for
|
|
233
|
-
shouldn't be able to spend the account.
|
|
344
|
+
`BinanceClientOptions.safety` configures a `RiskGateway` (a superset of the v2.0
|
|
345
|
+
`TradingPolicy`), evaluated on every mutating request before it leaves the process — for
|
|
346
|
+
autonomous/LLM-driven callers where a misread prompt shouldn't be able to spend the account.
|
|
347
|
+
Shared across every product namespace, and fed live state by `client.futures.execution`.
|
|
234
348
|
|
|
235
349
|
```typescript
|
|
236
350
|
const client = new BinanceClient({
|
|
@@ -239,9 +353,14 @@ const client = new BinanceClient({
|
|
|
239
353
|
dryRun: true, // throws DryRunError instead of sending the request
|
|
240
354
|
allowedSymbols: ['BTCUSDT', 'ETHUSDT'],
|
|
241
355
|
maxNotionalPerOrder: 100, // an order whose notional can't be verified is refused
|
|
356
|
+
maxLeverage: 20, // leverage changes above this are refused
|
|
357
|
+
maxOpenNotional: 5_000, // aggregate tracked open-order notional budget
|
|
358
|
+
maxDailyLoss: 1_000, // realized-loss kill switch (UTC day window)
|
|
359
|
+
maxConsecutiveFailures: 5, // exchange-rejection streak circuit breaker
|
|
242
360
|
allowWithdrawals: false, // default once `safety` is set at all
|
|
243
361
|
},
|
|
244
362
|
});
|
|
363
|
+
client.getRiskStatus(); // { circuitBreaker, openNotional: '500', dailyPnl: '-12.5', ... }
|
|
245
364
|
```
|
|
246
365
|
|
|
247
366
|
- `dryRun` — intercepts `POST`/`PUT`/`DELETE` and throws `DryRunError` (carrying the request that
|
|
@@ -252,6 +371,10 @@ const client = new BinanceClient({
|
|
|
252
371
|
- `maxNotionalPerOrder` — caps a single order's notional (from `price*quantity` or
|
|
253
372
|
`quoteOrderQty`); an order whose notional can't be determined (e.g. a MARKET order with no
|
|
254
373
|
price) is refused rather than waved through.
|
|
374
|
+
- `maxLeverage` / `maxOpenNotional` / `maxDailyLoss` / `maxConsecutiveFailures` — layered
|
|
375
|
+
account-state limits. The circuit breaker trips on the daily loss limit or a rejection streak,
|
|
376
|
+
refuses every mutating request while tripped, and rolls over at the UTC day boundary (or via
|
|
377
|
+
`resetBreaker()` after human review).
|
|
255
378
|
- `allowWithdrawals` / `allowTransfers` / `blockedPaths` — withdrawals are denied by default the
|
|
256
379
|
moment any `safety` config is set; transfers and arbitrary endpoints can be pinned off too.
|
|
257
380
|
|
|
@@ -271,13 +394,141 @@ Simulates fills against live public prices — nothing is sent to the exchange.
|
|
|
271
394
|
at the requested leverage and released pro-rata as a position is reduced.
|
|
272
395
|
|
|
273
396
|
```typescript
|
|
274
|
-
import { PaperTradingEngine } from '@nemesis-oss/binance-sdk';
|
|
397
|
+
import { PaperTradingEngine, SlippageModel, BinanceUsdmFeeModel } from '@nemesis-oss/binance-sdk';
|
|
275
398
|
|
|
399
|
+
// Legacy behaviour (instant fills, zero fees) is the default:
|
|
276
400
|
const engine = new PaperTradingEngine({ initialBalance: 10_000 });
|
|
277
401
|
await engine.placeOrder({ symbol: 'BTCUSDT', side: 'BUY', type: 'MARKET', quantity: 0.05, leverage: 5 });
|
|
278
402
|
await engine.updatePositions(); // re-mark against live prices
|
|
279
403
|
const close = await engine.placeOrder({ symbol: 'BTCUSDT', side: 'SELL', type: 'MARKET', quantity: 0.05 });
|
|
280
404
|
console.log(close.realizedPnl, engine.getAccountInfo().balance);
|
|
405
|
+
|
|
406
|
+
// Or approximate reality in layers:
|
|
407
|
+
const realistic = new PaperTradingEngine({
|
|
408
|
+
initialBalance: 10_000,
|
|
409
|
+
executionModel: new SlippageModel(10), // 10 bps market impact
|
|
410
|
+
feeModel: new BinanceUsdmFeeModel(), // 5 bps taker / 2 bps maker
|
|
411
|
+
});
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Execution models compose: `SlippageModel`, `PartialFillModel`, `OrderBookModel` (VWAP walks
|
|
415
|
+
against a real/injected book), `LatencyModel`, `CompositeModel`. Fee models implement
|
|
416
|
+
`FeeModel` (`TakerMakerFeeModel` / `BinanceUsdmFeeModel`).
|
|
417
|
+
|
|
418
|
+
### Observability
|
|
419
|
+
|
|
420
|
+
`client.events` is a structured, JSON-serializable event bus wired through every subsystem:
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
client.events.on('execution.', (event) => console.log(event.scope, event.name, event.payload));
|
|
424
|
+
client.events.on('risk.denied', (event) => audit(event.payload));
|
|
425
|
+
client.events.on('ws.', (event) => console.log(event.name, event.payload));
|
|
426
|
+
// http.request.start / http.request.end / http.request.retry / http.request.error
|
|
427
|
+
// — each carrying contract metadata: product, operation, security, declaredWeight
|
|
428
|
+
// ws.connecting / ws.open / ws.state / ws.reconnecting / ws.rotated / ws.resynced / ws.stale
|
|
429
|
+
// execution.submitted / execution.acked / execution.reconciled / execution.retry / risk.*
|
|
430
|
+
// orderBook.synced / orderBook.desync
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Events carry `ts`/`seq`/`scope`/`name`/`payload`; subscribe with exact names, trailing-dot
|
|
434
|
+
prefixes (`'ws.'`) or `'*'`. Pass your own bus via `new BinanceClient({ events })`, or forward
|
|
435
|
+
everything to a logger with `forwardEventsToLogger(bus, logger)`.
|
|
436
|
+
|
|
437
|
+
### Endpoint maps & agent-native docs
|
|
438
|
+
|
|
439
|
+
- `llms.txt` / `llms-full.txt` — machine-oriented SDK index and flattened endpoint list
|
|
440
|
+
(Binance Agent-Native convention).
|
|
441
|
+
- `docs/endpoint-map/*.md` — per-product tables of every implemented endpoint
|
|
442
|
+
(operation → method → path → auth → SDK surface).
|
|
443
|
+
- **`contracts/` (v3)** — machine-readable inventory of the SDK surface:
|
|
444
|
+
`endpoint-catalog.json` (every REST operation: product, method, path, security, weight,
|
|
445
|
+
implementer), `security-catalog.json` (auth matrix per product),
|
|
446
|
+
`websocket-catalog.json` (WS families, stream ceilings, renewal/liveness policy),
|
|
447
|
+
`catalog.json` (index).
|
|
448
|
+
Generated with `npm run contracts:generate` and CI-validated against the registry —
|
|
449
|
+
the input layer for generated bindings, tool metadata and coverage accounting.
|
|
450
|
+
- `ENDPOINT_REGISTRY` / `listEndpoints({ product, method, authentication })` in code.
|
|
451
|
+
- **Contract layer**: `getContract(product, operation)` / `findContract(path, method)` /
|
|
452
|
+
`contractFor(baseURL, method, path)` — registry entries with normalized security schemes
|
|
453
|
+
(`none`/`apiKey`/`signature`) and declared request weights; `describeContract()` renders a
|
|
454
|
+
one-line description for logs and agents.
|
|
455
|
+
- Regenerate everything from the registry with `npm run docs:generate` (the generator
|
|
456
|
+
cross-checks the registry against the actual `http.<verb>()` calls in `src/resources`)
|
|
457
|
+
and `npm run contracts:generate`.
|
|
458
|
+
- `docs/architecture/v3-foundation.md` — the v3 platform architecture and migration plan.
|
|
459
|
+
- `docs/architecture/v3-websocket.md` — the v3 WebSocket platform design (milestone 2).
|
|
460
|
+
- `docs/architecture/v3-execution.md` — the v3 execution platform design (milestone 3).
|
|
461
|
+
- `docs/architecture/v3-state.md` — the v3 state engine + paper backend design (milestone 4).
|
|
462
|
+
|
|
463
|
+
## v3 Platform (stable since 3.0.0)
|
|
464
|
+
|
|
465
|
+
`3.0.0` ships the platform rewrite: the foundation (see
|
|
466
|
+
`docs/architecture/v3-foundation.md`), the WebSocket platform (see
|
|
467
|
+
`docs/architecture/v3-websocket.md`), the execution platform (see
|
|
468
|
+
`docs/architecture/v3-execution.md`), the state engine + paper execution
|
|
469
|
+
backend (see `docs/architecture/v3-state.md`), the first-class
|
|
470
|
+
Spot / USDⓈ-M / COIN-M product clients, and the execution audit sink;
|
|
471
|
+
every v2.x surface keeps
|
|
472
|
+
working unchanged.
|
|
473
|
+
|
|
474
|
+
```typescript
|
|
475
|
+
import { BinanceClient, CoreContext, USDMClient, Credentials } from '@nemesis-oss/binance-sdk';
|
|
476
|
+
|
|
477
|
+
// Standalone product client over a caller-owned shared runtime
|
|
478
|
+
const core = new CoreContext({ apiKey, apiSecret });
|
|
479
|
+
const usdm = new USDMClient(core);
|
|
480
|
+
await core.syncTime(); // one clock sync, every host
|
|
481
|
+
const fill = await usdm.execution.placeOrder({
|
|
482
|
+
symbol: 'BTCUSDT', side: 'BUY', type: 'MARKET', quantity: '0.01',
|
|
483
|
+
});
|
|
484
|
+
usdm.close(); // product-scoped cleanup
|
|
485
|
+
|
|
486
|
+
// Two products, one runtime: shared transports, shared event bus
|
|
487
|
+
const other = new USDMClient(core); // same weight budget, same events
|
|
488
|
+
|
|
489
|
+
// The multi-product facade is lazy now — namespaces build on first access
|
|
490
|
+
// (stable identity) and share client.core:
|
|
491
|
+
const client = new BinanceClient({ apiKey, apiSecret });
|
|
492
|
+
client.core.credentials.describe(); // 'hmac key ****xxxx'
|
|
493
|
+
client.futures.execution === client.futures.execution; // true — cached
|
|
494
|
+
|
|
495
|
+
// --- WebSocket platform (milestone 2): client.ws ---
|
|
496
|
+
const sub = await client.ws.usdm.subscribe('btcusdt@aggTrade');
|
|
497
|
+
sub.on('message', (tick) => console.log(tick.p)); // parsed payload
|
|
498
|
+
await sub.waitForReady();
|
|
499
|
+
client.ws.stats(); // pools, renewal deadlines, WS API state
|
|
500
|
+
await client.ws.api.usdm.accountStatus(); // persistent multiplexed WS API
|
|
501
|
+
sub.close(); // refcounted UNSUBSCRIBE
|
|
502
|
+
|
|
503
|
+
// --- Execution platform (milestone 3): usdm.executionPlatform ---
|
|
504
|
+
const session = await usdm.executionPlatform.startUserSession();
|
|
505
|
+
// listen key created + WS connected + 30-min keep-alive + auto key rotation;
|
|
506
|
+
// the product's execution manager now tracks live fills from the stream:
|
|
507
|
+
|
|
508
|
+
const execution = await usdm.execution.placeOrder({
|
|
509
|
+
symbol: 'BTCUSDT', side: 'BUY', type: 'MARKET', quantity: '0.001',
|
|
510
|
+
});
|
|
511
|
+
const record = usdm.executionPlatform.orders.get(execution.clientOrderId);
|
|
512
|
+
// → live OrderRecord: status, exact decimal quantities, per-trade fills
|
|
513
|
+
await usdm.executionPlatform.orders.waitForTerminal(execution.clientOrderId);
|
|
514
|
+
usdm.executionPlatform.positions.get('BTCUSDT'); // from ACCOUNT_UPDATE
|
|
515
|
+
usdm.executionPlatform.classify(err).safety;
|
|
516
|
+
// → 'safe' | 'idempotent' | 'reconciliation-required' | 'never-retry'
|
|
517
|
+
|
|
518
|
+
// --- State engine + paper backend (milestone 4) ---
|
|
519
|
+
const book = await usdm.books.watch('BTCUSDT'); // local L2 book, synced
|
|
520
|
+
book.bestBid; // exact decimal strings
|
|
521
|
+
book.metrics(); // spread, microprice, imbalance
|
|
522
|
+
await usdm.executionPlatform.reconcile(); // REST fold: startup gap-fill
|
|
523
|
+
|
|
524
|
+
import { createPaperExecutionPlatform } from '@nemesis-oss/binance-sdk';
|
|
525
|
+
const paper = createPaperExecutionPlatform(client.core, { initialBalance: 25_000 });
|
|
526
|
+
await paper.platform.startUserSession(); // local session, zero network
|
|
527
|
+
const fill = await paper.execution.placeOrder({
|
|
528
|
+
symbol: 'BTCUSDT', side: 'BUY', type: 'MARKET', quantity: '0.01',
|
|
529
|
+
});
|
|
530
|
+
paper.platform.orders.get(fill.clientOrderId); // same OrderRecord as live
|
|
531
|
+
paper.platform.positions.get('BTCUSDT'); // same PositionRecord as live
|
|
281
532
|
```
|
|
282
533
|
|
|
283
534
|
## LLM Tools & MCP
|
|
@@ -292,11 +543,31 @@ const { openai, anthropic, mcp } = toolkitToFormats(tk); // tool schemas per for
|
|
|
292
543
|
```
|
|
293
544
|
|
|
294
545
|
- **Tool groups**: `market`, `account`, `trading` (USD-M futures), `spot` (Spot), `ws`
|
|
295
|
-
(streams + WS API), `derived` (composites like size/close/bracket), `paper
|
|
546
|
+
(streams + WS API), `derived` (composites like size/close/bracket), `paper`, and
|
|
547
|
+
`execution` (v2.3).
|
|
548
|
+
- **Execution tools (v2.3)** — order tools routed through the `ExecutionGateway`, so agents
|
|
549
|
+
get idempotency, reconciliation and backend routing for free:
|
|
550
|
+
|
|
551
|
+
```ts
|
|
552
|
+
// Run the whole toolkit against the simulator — no API-key trading risk
|
|
553
|
+
const tk = createFuturesToolkit(client, { executionBackend: 'paper', paper: { initialBalance: 50_000 } });
|
|
554
|
+
|
|
555
|
+
// Same schema, one extra param per call: backend: 'live' | 'paper' (optional)
|
|
556
|
+
const fill = await call('execution_place_order', {
|
|
557
|
+
symbol: 'BTCUSDT', side: 'BUY', type: 'MARKET', quantity: 0.01,
|
|
558
|
+
intentId: 'strategy-1', // idempotency: retries return the original execution
|
|
559
|
+
});
|
|
560
|
+
// execution_get_order finds intents across both ledgers; execution_status returns
|
|
561
|
+
// default backend + risk-gateway state + paper account; execution_cancel_order
|
|
562
|
+
// resolves already-gone orders to a terminal CANCELED execution (never a thrown -2011).
|
|
563
|
+
```
|
|
564
|
+
|
|
296
565
|
- **MCP server**: `npx binance-sdk-mcp` (stdio) auto-registers every tool plus reference
|
|
297
566
|
resources (`binance://futures/symbols`, `binance://futures/premium-index`, `binance://spot/symbols`).
|
|
298
567
|
For local development against source instead of the published package, point your MCP host at
|
|
299
568
|
`mcp-config/local-dev.json` (runs `npx tsx src/mcp/index.ts` directly).
|
|
569
|
+
`createBinanceMcpServer(client, { executionBackend: 'paper' })` builds a paper-mode server —
|
|
570
|
+
every order tool routes through the simulator, safe to expose to untrusted hosts.
|
|
300
571
|
- **Agent skills**: Markdown skills under `skills/` — futures trading / market-data / algo /
|
|
301
572
|
portfolio-margin, plus spot trading / market-data — for Skills-Hub-style agents.
|
|
302
573
|
|