{
  "format": "siebly-integration-kit/v1",
  "id": "binance-position-manager",
  "title": "Binance Manual Position Manager Integration Kit",
  "lastReviewed": "2026-04-29",
  "package": {
    "ecosystem": "npm",
    "name": "binance",
    "install": "npm install binance",
    "docs": "https://siebly.io/sdk/binance/typescript",
    "repository": "https://github.com/tiagosiebler/binance"
  },
  "sourceVerificationChecklist": [
    "Record the installed binance package version before coding.",
    "Inspect SDK docs, endpoint map, examples, installed TypeScript declarations, and package source for the methods and types below.",
    "Verify the USD-M Algo Orders guide and recipe before coding futures TP/SL conditionals.",
    "Write a source-verification note in the generated README or docs with exact methods, types, and files checked."
  ],
  "minimalImplementationPath": [
    "Install the latest SDK, inspect installed declarations, and write a source-verification note before implementation.",
    "Scaffold config, dry-run store, SDK-prefixed ID helpers, filter parsing, planner, and structured logging with live trading disabled.",
    "Implement REST hydration, replacement-view snapshots, private stream buffering, and replay before any live submission path.",
    "Add explicit live submission gates, provisional accepted-order state, in-flight ID tracking, and rejection pause/reconcile behavior.",
    "Add conformance fixtures for manual cancel recovery, full close cleanup, hedge side coexistence, stale provisional orders, safe doctor/status commands, and redaction boundaries."
  ],
  "canonicalSources": [
    "https://siebly.io/ai/binance-position-manager",
    "https://siebly.io/.well-known/recipes/binance-position-manager.json",
    "https://siebly.io/ai/binance-usdm-algo-orders",
    "https://siebly.io/.well-known/recipes/binance-usdm-algo-orders.json",
    "https://siebly.io/sdk/binance/typescript",
    "https://siebly.io/llms-tasks.txt",
    "https://siebly.io/.well-known/siebly-sdk-catalog.json",
    "https://github.com/tiagosiebler/binance",
    "https://github.com/sieblyio/crypto-api-examples/tree/master/examples/Binance"
  ],
  "sdkSurface": {
    "restClients": [
      "MainClient",
      "USDMClient"
    ],
    "websocketClient": "WebsocketClient",
    "privateStreamHelpers": [
      "subscribeSpotUserDataStream",
      "subscribeUsdFuturesUserDataStream"
    ],
    "websocketEvents": [
      "open",
      "response",
      "formattedMessage",
      "formattedUserDataMessage",
      "reconnecting",
      "reconnected",
      "exception"
    ],
    "shutdown": "closeAll(true) or current documented closeAll variant",
    "spotRest": [
      "getExchangeInfo",
      "getAccountInformation",
      "getOpenOrders",
      "getAllOrders",
      "getAccountTradeList",
      "submitNewOrder",
      "cancelOrder",
      "testNewOrder"
    ],
    "usdmRest": [
      "getExchangeInfo",
      "getPositionsV3",
      "getAllOpenOrders",
      "getOpenAlgoOrders",
      "getAccountTrades",
      "getAllOrders",
      "getAccountInformationV3",
      "getCurrentPositionMode",
      "getMultiAssetsMode",
      "getFuturesSymbolConfig",
      "getNotionalAndLeverageBrackets",
      "submitNewOrder",
      "cancelOrder",
      "testOrder",
      "submitNewAlgoOrder",
      "cancelAlgoOrder"
    ],
    "customClientIdFields": {
      "spotAndUsdmRegular": "newClientOrderId",
      "usdmAlgoConditional": "clientAlgoId"
    }
  },
  "installedPackageLookupMap": [
    {
      "surface": "REST clients",
      "lookupTargets": [
        "MainClient",
        "USDMClient"
      ],
      "verify": "Find the public client declarations and confirm account, position, open-order, Algo, submit, cancel, and test-order methods before coding."
    },
    {
      "surface": "USD-M Algo request type",
      "lookupTargets": [
        "FuturesNewAlgoOrderParams",
        "FuturesAlgoConditionalOrderTypes",
        "FuturesAlgoOrderResponse"
      ],
      "verify": "Confirm current fields and valid type literals for TAKE_PROFIT, STOP_MARKET, closePosition, reduceOnly, positionSide, workingType, and priceProtect."
    },
    {
      "surface": "Private WebSocket lifecycle",
      "lookupTargets": [
        "WebsocketClient",
        "formattedUserDataMessage",
        "formattedMessage",
        "reconnected",
        "exception",
        "closeAll"
      ],
      "verify": "Confirm private stream helper names, event names, reconnect events, and shutdown method from installed declarations."
    },
    {
      "surface": "REST client options and order ID utilities",
      "lookupTargets": [
        "RestClientOptions",
        "filterUndefinedParams",
        "strictParamValidation",
        "beautifyResponses",
        "getOrderIdPrefix",
        "generateNewOrderId"
      ],
      "verify": "Confirm undefined-field filtering, strict validation, response beautification controls, and SDK-prefix order ID utilities."
    }
  ],
  "requestFieldMatrix": [
    {
      "mode": "USD-M one-way LONG",
      "hydratedPosition": "positionSide=BOTH and signed positionAmt > 0",
      "managedStrategySide": "LONG",
      "outboundPositionSide": "BOTH",
      "dcaAddSide": "BUY below entry",
      "takeProfitSide": "SELL above entry",
      "stopLossSide": "SELL below entry",
      "algoReduceOnly": "Allowed only for validated quantity-based reduce-only exits when configured; omit when closePosition=true."
    },
    {
      "mode": "USD-M one-way SHORT",
      "hydratedPosition": "positionSide=BOTH and signed positionAmt < 0",
      "managedStrategySide": "SHORT",
      "outboundPositionSide": "BOTH",
      "dcaAddSide": "SELL above entry",
      "takeProfitSide": "BUY below entry",
      "stopLossSide": "BUY above entry",
      "algoReduceOnly": "Allowed only for validated quantity-based reduce-only exits when configured; omit when closePosition=true."
    },
    {
      "mode": "USD-M hedge LONG",
      "hydratedPosition": "positionSide=LONG",
      "managedStrategySide": "LONG",
      "outboundPositionSide": "LONG",
      "dcaAddSide": "BUY below entry",
      "takeProfitSide": "SELL above entry",
      "stopLossSide": "SELL below entry",
      "algoReduceOnly": "Omit reduceOnly from Algo TP/SL conditionals."
    },
    {
      "mode": "USD-M hedge SHORT",
      "hydratedPosition": "positionSide=SHORT",
      "managedStrategySide": "SHORT",
      "outboundPositionSide": "SHORT",
      "dcaAddSide": "SELL above entry",
      "takeProfitSide": "BUY below entry",
      "stopLossSide": "BUY above entry",
      "algoReduceOnly": "Omit reduceOnly from Algo TP/SL conditionals."
    },
    {
      "mode": "close-position stop-market",
      "fields": "type=STOP_MARKET, closePosition=true, triggerPrice, workingType, priceProtect, clientAlgoId, side, positionSide",
      "forbiddenFields": [
        "quantity",
        "reduceOnly"
      ]
    },
    {
      "mode": "quantity-based take-profit",
      "fields": "type=TAKE_PROFIT, quantity, price, triggerPrice, timeInForce=GTC, workingType, priceProtect, clientAlgoId, side, positionSide",
      "oneWayReduceOnly": "May include reduceOnly=true in one-way BOTH only when configured and locally validated.",
      "hedgeReduceOnly": "Omit reduceOnly for hedge-mode LONG or SHORT Algo conditionals."
    }
  ],
  "eventReconciliationPolicy": {
    "sourceOfTruth": "REST startup, reconnect, and unknown-submission hydration are the recovery source of truth; private user-data events are the live update stream.",
    "replacementViews": [
      "positions",
      "regularOpenOrders",
      "algoOpenOrders"
    ],
    "workflowLock": "One per-product workflow lock covers REST reconciliation, buffered user-data replay, planning, and live submission.",
    "activeWorkflowUserData": "Buffer and coalesce user_data_* replans while the workflow lock is held; expected own-order NEW confirmations are info logs.",
    "idleUserData": "Run REST reconciliation before planning, but debounce ACCOUNT_UPDATE-only clusters by 750ms-1500ms per product with a 3000ms max delay to avoid one full hydration per event.",
    "immediateUserDataEvents": "ORDER_TRADE_UPDATE, ALGO_UPDATE, fills, cancels, and rejects reconcile immediately.",
    "skipAlreadyReplayed": "Skip only when bufferedEventCount === 0 and every deferred reason starts with user_data_.",
    "immediateReconciliationTriggers": [
      "startup",
      "reconnect or stale private stream",
      "live rejection",
      "unknown submission state",
      "conflicting REST/history/user-data state"
    ]
  },
  "hydrationRules": [
    "REST open positions, regular open orders, and open Algo orders replace the current product snapshot for the hydrated scope.",
    "Absent app-owned open orders are terminal or stale unless a newer user-data event proves otherwise.",
    "Accepted REST submissions are provisional local state until confirmed by user-data or current open-order hydration.",
    "If later REST open-order hydration still omits a provisional app-owned order after a short configured grace window, mark it stale so it cannot block replacement forever.",
    "Recent history is metadata and terminal evidence, not the active open-order view.",
    "Current open or provisional app-owned order state wins over older terminal history for the same client ID.",
    "If timestamps, statuses, or identifiers conflict and cannot be resolved deterministically, pause the product and reconcile instead of submitting."
  ],
  "lifecycleRules": [
    "Separate manual-position lifecycle epoch from DCA replacement generation.",
    "A fresh manual position on the same product, symbol, and strategy side receives a new lifecycle epoch.",
    "Restarting the same still-open position preserves its lifecycle epoch.",
    "App-owned order metadata stores product, symbol, exchange positionSide, managed strategy side, lifecycle epoch, role, and DCA generation.",
    "Cleanup stale wrong-side or stale-lifecycle app-owned DCA/TP/SL orders before placing new current-lifecycle orders.",
    "After manual full close or position flip, clean up app-owned DCA as well as TP/SL because DCA orders can reopen exposure.",
    "If the operator manually cancels app-owned DCA/TP/SL while the position remains open and the product is not paused, the next reconciliation should recreate the missing managed orders.",
    "In hedge mode, LONG and SHORT on the same symbol are independent managed lifecycles; closing or cleaning one side must preserve the other side."
  ],
  "commandSafety": [
    "doctor, inspect, status, readback, and similar commands must force public-only or read-only dry-run mode even when .env contains live-enabled settings.",
    "Safe inspection commands should strip credentials, disable order placement/cancel/amend endpoints, and refuse to inherit live acknowledgement flags.",
    "README command examples should make the safe mode visible so operators can run diagnostics without exchange-facing side effects."
  ],
  "redactionPolicy": {
    "redact": [
      "API keys",
      "signatures",
      "listen keys",
      "wsKey",
      "signed URLs",
      "private headers",
      "raw request bodies",
      "raw orderIntent payloads",
      "SDK debug messages that contain private request material"
    ],
    "preserveCounters": [
      "intentCount",
      "blockedCount",
      "activeOrders",
      "positions",
      "bufferedEventCount",
      "inFlightClientIds",
      "readiness"
    ],
    "rule": "Redaction should match explicit sensitive fields or paths, not broad substrings such as intent, order, or position that hide operational counters."
  },
  "rejectionCatalog": [
    {
      "code": "-1106",
      "cause": "reduceOnly was sent when the current USD-M Algo field mix does not require it.",
      "localAction": "Omit reduceOnly with closePosition=true and omit reduceOnly for hedge-mode Algo TP/SL conditionals unless current docs require it."
    },
    {
      "code": "-2011",
      "cause": "Cancel targeted an order the exchange no longer has open.",
      "localAction": "If current regular open-order or open-Algo hydration is absent for that app-owned ID, mark terminal/stale and stop retrying forever."
    },
    {
      "code": "-4116",
      "cause": "Duplicate deterministic client ID or replayed submission.",
      "localAction": "Track in-flight IDs, insert accepted responses into local state immediately, and reconcile before any retry."
    },
    {
      "code": "-1111",
      "cause": "Precision or filter validation missing, stale, or using the wrong product filters.",
      "localAction": "Re-read filters, normalize tick/step/notional rules, and block invalid rounded requests locally."
    },
    {
      "code": "-1116",
      "cause": "Invalid order type, such as strategy-language TAKE_PROFIT_LIMIT for current USD-M Algo TP.",
      "localAction": "Verify current package types and use valid Algo type literals such as TAKE_PROFIT."
    }
  ],
  "fixtures": [
    "Clean startup: startup reconcile -> submit DCA/TP/SL -> own-order user-data confirmations deferred -> one deferred reconcile replays all buffered events -> planner intentCount=0 -> already-drained deferrals skipped.",
    "Manual full close: position size is zero and app-owned DCA/TP/SL remain; cleanup app-owned orders only.",
    "Two separate manual positions on same symbol and side: second position gets a new lifecycle epoch and does not inherit stale orders/fills from the first.",
    "One-way short: positionSide=BOTH plus negative positionAmt becomes managed strategy side SHORT while outbound requests still send positionSide=BOTH.",
    "Stale wrong-side cleanup: old short-side app-owned DCA/TP/SL exist, hydration shows long position, cleanup emits before new long placement.",
    "Position flip stale unknown Algo cancel: app-owned close-position Algo is absent from open Algo hydration and -2011 does not retry forever.",
    "Hedge-mode TP/SL: positionSide=LONG or SHORT conditionals omit reduceOnly; one-way BOTH fixture covers configured quantity-based reduceOnly.",
    "Idle ACCOUNT_UPDATE storm: repeated account updates debounce by 750ms-1500ms per product with a 3000ms max delay, without skipping startup, reconnect, order/fill/algo, reject, cancel, or unknown-state hydration.",
    "Manual cancel recovery: app-owned DCA/TP/SL are manually cancelled while the position remains open; next reconciliation recreates the missing managed orders unless the product is explicitly paused.",
    "Provisional order staleness: accepted REST response inserted provisional app-owned state, but repeated open-order hydration omits it after the grace window; local state marks it stale and allows replacement.",
    "Safe doctor/status command: .env may be live-enabled, but the command forces public-only or read-only dry-run mode and cannot place, cancel, or amend orders.",
    "Hedge coexistence: opening LONG while SHORT remains open creates independent side-specific DCA/TP/SL sets and does not touch unowned orders.",
    "Redaction boundary: raw request/order intent fields are sanitized while intentCount, blockedCount, activeOrders, and positions remain visible.",
    "Filter precision failure: hydrated filters block or round locally before Binance returns -1111.",
    "Duplicate client ID: accepted response inserts provisional local state and clears in-flight ID before stream confirmation."
  ],
  "operatorConformanceScript": [
    "Open hedge LONG manually; expect app-owned LONG DCA, TP, and SL.",
    "Cancel all app-owned LONG orders manually while LONG remains open; expect reconciliation to recreate missing LONG DCA, TP, and SL.",
    "Close LONG manually; expect stale LONG app-owned orders to be cleaned without touching unowned orders.",
    "Open hedge SHORT manually; expect app-owned SHORT DCA, TP, and SL.",
    "Open hedge LONG while SHORT remains open; expect both side-specific order sets to coexist.",
    "Run doctor/status with live-enabled .env; expect forced safe mode and no exchange-facing order action."
  ],
  "debouncePolicy": {
    "immediateEvents": [
      "ORDER_TRADE_UPDATE",
      "ALGO_UPDATE",
      "fills",
      "cancels",
      "rejects",
      "startup",
      "reconnect",
      "unknown submission state",
      "conflicting state"
    ],
    "accountUpdateOnly": {
      "debounceMs": {
        "min": 750,
        "preferred": 1000,
        "max": 1500
      },
      "maxDelayMs": 3000,
      "coalesceBy": "product"
    },
    "rationale": "Binance can emit account-only clusters within 1-2 seconds; a 1s product-level debounce collapses idle reconciliations without delaying order/fill recovery materially."
  },
  "sourceReferenceNotes": {
    "localVerification": "Generated projects should verify these lookup targets against their installed node_modules before coding.",
    "sdkLookupTargets": [
      "FuturesNewAlgoOrderParams",
      "FuturesNewAlgoOrderParams.positionSide",
      "FuturesNewAlgoOrderParams.closePosition",
      "FuturesNewAlgoOrderParams.reduceOnly",
      "USDMClient.submitNewAlgoOrder(params: FuturesNewAlgoOrderParams)"
    ],
    "officialDocsRuntimeRules": [
      "USD-M New Algo Order docs: positionSide must be LONG or SHORT in Hedge Mode.",
      "USD-M New Algo Order docs: reduceOnly cannot be sent in Hedge Mode and cannot be sent with closePosition=true."
    ]
  },
  "expectedLogTimeline": [
    "source_verification_complete with package version and method/type list",
    "startup_reconciliation_started",
    "product_snapshot_replaced with compact counts",
    "position_classified with exchangePositionSide and managedStrategySide",
    "stale_app_owned_cleanup_planned before new placement when needed",
    "planner_finished with intentCount and blockedCount",
    "submission_batch_started under workflow lock",
    "live_submission_accepted with provisionalInserted=true and inFlightClientIds count",
    "replan_deferred_workflow_active level=info for expected user_data_* confirmations",
    "processing_deferred_replans with bufferedEventCount",
    "product_reconciled after replay",
    "planner_finished intentCount=0",
    "deferred_replan_already_replayed skipped=true when buffer is empty",
    "shutdown_summary with counts, readiness, bufferedEventCount, compact positions, compact active app-owned orders"
  ]
}
