Long the DEX. Short the perp.
Delta-neutral by construction.

Deltr is a CEX / DEX basis and funding agent on Binance Agent OS. Say “rebalance $5,000 into a delta-neutral BNB hedge”, and it prices the full round trip, sizes both legs to the lot step, and clears a deterministic 19-check risk gate before anything reaches Binance.

Runs in this browser · paper mode · real mainnet data · no keys needed

Deltr · scanningBNBUSDT · mainnet data
Binance perp (short)PancakeSwap V3 (long)basis + fundingRISK GATE · 19 CHECKS · 1.5 µsKILL SWITCHDRAWDOWNDELTA = 0LEV ≤ 3xRISK ≤ 2%SANITYEDGEreceiptsha256 d4e39509…c216fda5 · delta 0.00 BNB · paper

Rebalance $5,000 USDC into delta-neutral BNB arbitrage.

  • 19

    risk checks

  • 670

    tests passing

  • 22

    MCP tools

  • 500

    days of funding data

How it works

Four subsystems, one engine, one gate

Everything an agent can do goes through the same Engine facade: scan, explain, propose, evaluate, execute, unwind. Every order goes through the same gate. Two transports (MCP and REST) share one process, so what your agent does is what the dashboard shows.

agents/arbitrage_scout.py

Arbitrage Scout

Polls the three venues and prices the full round trip, not just the spread.

  • MarketDataHub polls CEX every 1 s and DEX every 3 s with per-feed ages and a Freshness verdict
  • Horizon-based edge: entry basis + funding over the horizon minus round-trip cost minus assumed exit basis
  • Marks each opportunity actionable or not, with the reason
trace · deltr_market
$ deltr_market symbol=BNBUSDT
dex 686.19 PancakeSwap V3 fee100 · bsc-mainnet-chain
perp 686.34 USDⓈ-M mark · binance-futures-mainnet
basis +2.2 bps · funding(72 h) ≈ 0.0 bps · 9 settlements
round trip −16.6 bps → net −14.4 bps
actionable: false · NEGATIVE_EDGE

The life of one hedge

  1. 01

    Tick

    The hub polls the venues, the Scout prices the edge, the Portfolio marks every position to close and feeds equity into the gate.

  2. 02

    Propose

    The Hedger sizes both legs and runs the gate as a pre-check. You get a single-use plan_id that expires in 60 s. Nothing executes.

  3. 03

    Execute

    execute(plan_id) re-quotes the DEX leg, re-runs the gate, places the DEX leg first and sizes the perp from the actual fill.

  4. 04

    Receipt

    Every price, rate and fill carries a DataSource tag and an age. The receipt embeds the ordered trace and a SHA-256 of it.

Architecture

One process, one engine, two transports

MCP hosts and the REST dashboard share one Engine. Every order crosses the same gate and the same router before it reaches a venue, and every number on screen carries the source it came from.
Deltr architectureMCP hosts talk to the Deltr MCP server and FastAPI, which share one Engine. The Engine drives the Scout, Hedger and Executor; every order passes the BinanceRiskGate, then a paper or testnet router, then the venues. A TypeScript bridge discovers the hosted Binance MCP server or a local shim.MCP HOSTSBINANCE AGENT OSClaude · Claude Code · Codex · Cursor · VS CodeMCP (streamable HTTP :8000/mcp or stdio)tools/callHosted Binance MCP serveragent.binance.com/mcp/agenticOAuth via the hostno withdrawal scopeDeltr MCP server22 tools · deltr/mcp/server.pyFastAPI /api + /ws/streamdeltr/api/ · serves ui/outdashboard/ and /app/Engine (facade)scan · explain · propose · evaluate · execute · unwindArbitrageScoutagents/arbitrage_scout.pyedge · historyHedgeragents/hedger.pysizing · plansExecutordeltr/executor.pyasyncio.Lock · builds gate inputBinanceRiskGate (risk_gate.py)19 ordered checks · stdlib only · zero LLMowns equity / drawdown / kill / registrymedian 1.5 to 2.5 µs, measured at startupAPPROVED onlyPaperRouter | TestnetRouter (LIMIT IOC, signed)fills labelled paper, or carry a testnet order idPancakeSwap V3 (BSC mainnet)slot0 + QuoterV2 via eth_callsource: bsc-mainnet-chainBinance USDⓈ-M Futures testnetpremiumIndex · bookTicker · orderssource: binance-futures-testnetSpot data mirrorbookTicker (reference only)source: binance-spot-mirrorAgent OS bridgeagents/agent_os_bridge.tsupstream: official > shim > noneinitialize / tools/list401 unless authorisedBinance MCP shim (local twin)deltr/mcp/binance_shim_server.pystdio · testnet-backedreads testnet RESTand the spot mirrorDeltr's executor never routesorders through the bridge orthe shim; the gate always sitsin front of the exchange.provenance:DEX (orange)perp (blue)Binance Agent OS / gateMCP surfaces

Scroll sideways to see the whole diagram.

Modes

modedatafillssecrets
paperlivesimulated at quoted prices, labelled papernone
testnetlivereal USDⓈ-M testnet LIMIT IOC orders; DEX leg simulatedtestnet keys

There is no live/production mode by design.

Repository map

  • main.py one-command launcher
  • risk_gate.py deterministic gate
  • agents/ scout, hedger, agent_os_bridge.ts
  • deltr/edge.py edge / fee / funding / sizing math
  • deltr/executor.py the choke point: gate, legs, receipts
  • deltr/mcp/ Deltr MCP server + Binance shim
  • deltr/venues/ PancakeSwap V3, Futures testnet, spot mirror
  • ui/ this landing page and the dashboard
  • skills/deltr-binance/ SKILL.md, scripts/deltr.sh, references/ (MIT)
  • tests/ offline, deterministic; replay fixture recorded live

The edge, honestly

A naive bot sees a spread; Deltr prices the full round trip

The horizon-based edge is net(H) = basis_entry + funding(H) − roundtrip − basis_exit_assumed, with roundtrip = 2 · (dex_fee + dex_impact + perp_slip + cex_taker + gas_leg). Default horizon 72 h, nine funding settlements. This is why the gate often says no.

Worked example at the probe

BNBUSDT · mark 686.34 vs DEX exec 686.19
Round-trip cost waterfall in basis points at the 2026-09-02 probe40-4-8-12-16bpsbasispool fee ×2impact ×2gas ×2perp slip ×2−10.0taker ×2funding 72 h−14.4net edge

DEX costs in orange, perp costs in blue, funding in gold. Funding ≈ 0.0 bps at the probe (lastFundingRate 0.0, testnet, indicative). Values for the remaining bars are in the table.

basis

+2.2 bps

round trip

−16.6 bps

funding 72 h

≈ 0.0 bps

net

≈ −14 bps

Not actionable: NEGATIVE_EDGE vetoes at 0 bps. In PAPER mode the demo runs with a labelled --min-edge-bps -20 override so the mechanics are visible; the amber chip stays on screen the whole time.

Round-trip components

componentper leg×2
PancakeSwap pool fee (fee100)0.01 % tier1.002.00
DEX price impactQuoterV2 exec vs slot0 mid, net of fee0.300.60
Perp slippage vs marktestnet book is thin2.004.00
Binance taker fee0.05 %5.0010.00
Gas per swap≈ $0.0056 at 0.05 gwei on $3.3k0.020.03
round trip16.6 bps

Sizing: $5,000 at 2x

N = capital / (1 + 1/L), floored to the 0.01 lot step. The DEX leg is unlevered, so both legs must fit in the capital.

quantity
4.85 BNB
notional
$3,328
perp margin
$1,664
cash used
$4,992

At 686.19 per BNB. Positions are marked to close, net of the estimated exit round trip.

Safety by construction

19 ordered checks, every veto with a number

Checks run cheapest and most decisive first and short-circuit on the first failure. Every veto carries the observed value, the limit and the unit, so the dashboard renders leverage 10.0 > 3.0 x rather than a bare code. Two runs over the same replay fixture produce a byte-identical decision log: no model sits in the loop.

Max futures leverage

3.0x

MAX_LEVERAGE

Max capital at risk per trade

2 % of equity

MAX_CAPITAL_RISK_PCT

Drawdown stop-loss (halt)

3 % from peak

MAX_DRAWDOWN_PCT

Drawdown warning

2 %

WARN_DRAWDOWN_PCT

RiskLimits clamps the three spec invariants so they can be tightened but never loosened. A drawdown of 2 % warns; 3 % halts and stays halted until the book recovers.

#codethreshold (default)input owner
1KILL_SWITCHoperator flag (verified unwinds pass)gate
2HALTED_DRAWDOWNdd ≥ 3 % (sticky)gate (update_equity)
3MALFORMEDfail-closed; a missing leverage is a vetoexecutor
4REDUCE_ONLY_UNVERIFIEDregistered position_id and qty ≤ open qtygate + executor
5NOT_DELTA_NEUTRALlegs must be DEX BUY / perp SELLexecutor (from plan legs)
6HEDGE_MISMATCH|dex_qty − perp_qty| ≤ max(1 lot step, 0.5 %)executor
7LEVERAGE≤ 3.0xcaller (validated)
8MIN_NOTIONAL≥ 5 USDTexecutor
9MAX_NOTIONALPAPER 50 000 / TESTNET 5 000config
10CAPITAL_RISK≤ 2 % of equity ($200 on $10 000)executor + gate floor
11AGGREGATE_RISKΣ open risk + new ≤ (3 % − dd) · equitygate registry
12CAPITAL_CAPACITYΣ notional · (1 + 1/L) ≤ 90 % · equitygate registry
13AGGREGATE_NOTIONALΣ notional ≤ 3 · equitygate registry
14SYMBOL_NOT_ALLOWEDDELTR_SYMBOLS whitelistconfig
15MAX_POSITIONSregistered positions < 3gate registry
16STALE_QUOTEoldest quote age ≤ 5 000 msexecutor (freshness)
17PRICE_SANITY|perp ref − DEX ref| ≤ 100 bpsexecutor (market state)
18PRICE_DRIFT|re-quote − plan price| ≤ 20 bpsexecutor (re-quote at execute)
19NEGATIVE_EDGEexpected edge ≥ 0 bps (PAPER may set a labelled override)scout via executor

Why check 10 has a floor: the proposer's own risk estimate is only a lower bound. The gate assumes the full round trip is paid and a 100 bps adverse basis move, so an optimistic caller cannot talk its way past the 2 % rule. Only the Executor assembles a gate input; an AST test checks that no other module constructs one.

What Deltr never does

Place a production order

Only paper and testnet modes exist; the frozen HOSTS table has no production trading host and BINANCE_API_ENV=prod is refused at startup.

Take a directional bet

Only a paired Long-DEX / Short-Perp is accepted, re-derived from the legs rather than trusted from a flag.

Let a caller loosen a limit

RiskLimits clamps 3x, 2 % and 3 %; equity, peak, drawdown and the open-position registry live inside the gate.

Trust "reduce only"

An unwind earns the kill-switch / halt bypass only for a registered position with qty at most the open quantity.

Let an LLM execute from free text

deltr_prompt is propose-only. Execution needs a plan_id; plans are single-use, expire after 60 s, and are re-priced and re-gated.

Withdraw or move funds

Deltr has no withdrawal or transfer code; the Binance MCP server itself has no withdrawal scope.

Hide a loss

Positions are marked to close, net of the estimated exit round trip.

Evade a halt by restarting

Gate and portfolio state persist per mode; a halt survives a restart and the peak is never silently re-based.

Connect your agent

Deltr is an MCP server. Point any host at it.

Start it once with python main.py. The same process serves this page, the dashboard, the REST API and the MCP endpoint at http://127.0.0.1:8000/mcp, so what your agent does is what the dashboard shows.
claude mcp add deltr --transport http http://127.0.0.1:8000/mcp

Then /mcp and pick deltr. The repo also ships .mcp.json at project scope.

stdio alternative (hosts that only speak stdio)

python main.py --mcp adds a stdio transport to the same process; it still serves the dashboard on :8000. Do not run a second engine next to it, two engines would mean two books.

{
  "mcpServers": {
    "deltr": { "command": "/ABSOLUTE/PATH/Deltr/.venv/bin/python", "args": ["/ABSOLUTE/PATH/Deltr/main.py", "--mcp"] }
  }
}

The 22 tools

Coloured by phase; each one is described below. A VETO is final for the same inputs; change capital or leverage instead of retrying.

deltr_statusdeltr_marketdeltr_scandeltr_explain_edgedeltr_edge_reportdeltr_propose_hedgedeltr_evaluate_riskdeltr_execute_hedgedeltr_unwinddeltr_positionsdeltr_risk_logdeltr_receiptdeltr_activitydeltr_promptdeltr_kill_switchdeltr_reset_haltdeltr_set_min_edgedeltr_stressdeltr_funding_historydeltr_wallet_statusdeltr_onchain_swapdeltr_x402_pay

Resources: deltr://status, deltr://risk-limits, deltr://config

  • deltr_propose_hedge is phase 1: nothing executes, you get a plan_id.
  • deltr_execute_hedge is phase 2: re-priced, re-gated, single-use, 60 s TTL.
  • deltr_prompt turns free text into a plan and a pre-check. It never executes.

What each tool does

read12 tools
deltr_status
mode, venues, equity, drawdown state, kill/halt, measured gate latency
deltr_market
current DEX / perp / funding state and the edge breakdown
deltr_scan
the latest opportunity + spread history
deltr_explain_edge
dry sizing and the full cost/carry math for a capital + leverage
deltr_edge_report
the same decomposition rendered as a readable markdown report: waterfall, funding, breakeven verdict, source tags and feed ages
deltr_evaluate_risk
dry-run the gate (leverage 10 gives a LEVERAGE veto with observed/limit)
deltr_positions
open positions + portfolio (mark-to-close)
deltr_risk_log
recent gate decisions with every check's observed/limit
deltr_receipt
a receipt by id (trace steps + SHA-256)
deltr_activity
the inbound MCP call log (which client called what)
deltr_funding_history
real mainnet funding history for a perpetual and the share of windows that beat the round trip at taker and maker cost
deltr_wallet_status
read-only state of the on-chain leg through the Binance Agentic Wallet: installed, signed in, addresses, daily quota, arming state
propose2 tools
deltr_propose_hedge
phase 1: size a plan, run the gate pre-check, get a plan_id (nothing executes)
deltr_prompt
natural language to intent to plan to pre-check (propose-only)
execute4 tools
deltr_execute_hedge
phase 2: execute a plan_id (re-priced, re-gated, single-use; TESTNET needs confirm: true)
deltr_unwind
reduce-only unwind of a position or "all"
deltr_onchain_swap
request a swap through the Binance Agentic Wallet; the wallet holds the key, applies its own limits and broadcasts (LIVE, opt-in)
deltr_x402_pay
pay an HTTP 402 (x402 / B402) challenge on BNB Smart Chain through the wallet, inside Deltr's allow-list and per-payment ceiling
operator4 tools
deltr_kill_switch
operator kill switch on/off
deltr_reset_halt
clear a drawdown halt once the book has recovered
deltr_set_min_edge
runtime min-edge (PAPER may go negative, labelled on screen)
deltr_stress
labelled SIMULATED scenarios on the paper book; reset clears

Binance Agent OS

A bridge to the Binance MCP server, and a Skills Hub skill

Deltr discovers the hosted Binance MCP upstream, reports exactly which upstream it could reach, and ships as a Skills Hub skill. It never claims more than it exercised.

Connect the Binance MCP server next to Deltr

claude mcp add binance-mcp-server --transport http https://agent.binance.com/mcp/agentic

Binance Agent OS publishes one hosted endpoint, https://agent.binance.com/mcp/agentic. It uses OAuth through a supported host, trades inside a dedicated Agentic sub-account, and has no withdrawal scope. Binance does not publish the tool names; discover them with tools/list after authorising.

Skills Hub packaging

packaged

skills/deltr-binance/: SKILL.md carries the Skills Hub frontmatter (name, description, version, license: MIT, metadata.version/author/openclaw), the command routing table and references/{tools,cli,risk-model}.md; scripts/deltr.sh wraps the REST API and the one-shot engine. The skill folder is MIT, the code Apache-2.0.

Install, then run one tick (nothing executes):

npx skills add https://github.com/mrnetwork0001/Deltr
bash scripts/deltr.sh once --json

The bridge CLI

agents/agent_os_bridge.ts, run with npx tsx.

  • npx tsx agents/agent_os_bridge.ts upstream-status

    official, then shim, then none

  • npx tsx agents/agent_os_bridge.ts list

    Deltr's 22 tools

  • npx tsx agents/agent_os_bridge.ts route '{"symbol":"BNBUSDT","capital_usd":2000}'

    JSON-RPC receipt with plan_id + precheck

  • npx tsx agents/agent_os_bridge.ts serve

    JSON-RPC 2.0 on :8788

Upstream, reported honestly

The official Binance MCP upstream is OAuth-gated. The bridge tries it first, falls back to the local testnet-backed shim, and reports the result on the dashboard status bar as one of three kinds. A 401 on the official endpoint is reported as authorized: false, never as a working connection.

  • upstream: official

    BINANCE_MCP_URL answered initialize (with BINANCE_MCP_TOKEN if you have a bearer). Unauthenticated calls get 401 + www-authenticate, reported as authorized: false.

  • upstream: shim

    The local deltr/mcp/binance_shim_server.py (stdio) mirroring the market / account / trade scopes against the Binance Futures testnet and the public spot data mirror.

  • upstream: none

    Neither upstream could be reached; the reason is reported.

Deltr's own executor never routes orders through the bridge or the shim; it signs testnet REST orders directly, so the deterministic gate always sits in front of the exchange.

FAQ

Questions judges ask

Is this live trading?

No. There are exactly two modes, paper (default, no secrets, simulated fills at live quoted prices) and testnet (real Binance USDⓈ-M Futures testnet LIMIT IOC orders, DEX leg simulated). There is no production mode by design, and BINANCE_API_ENV=prod is refused at startup.

Why does the gate say no so often?

Because the edge is priced honestly. At the probe the basis was about +2 bps while the full round trip cost about 16.6 bps, so the net was about −14 bps and NEGATIVE_EDGE vetoes. In PAPER mode a labelled min-edge override lets you watch the mechanics anyway.

What does the SIMULATED badge mean?

A stress scenario (basis_shock, equity_shock, dex_leg_fail, funding_flip, feed_stale) mutated the paper portfolio or leg state. The market feed is never touched. The badge stays on the status bar, the affected positions and receipts until reset, and stress is refused in TESTNET while real orders are open.

The prompt says USDC but the perp is USDT-margined. What happens?

USDC is accepted and treated as USDT-equivalent for sizing, with no conversion leg in this version. The intent records a stablecoin note and the prompt result says so.

Can Deltr withdraw or move funds?

No. Deltr has no withdrawal or transfer code, and the Binance MCP server itself has no withdrawal scope. Testnet mode trades inside the testnet account with LIMIT IOC orders only.

How is the gate latency measured?

risk_gate.benchmark() runs 10,000 evaluations at startup. The banner, the status bar and the README quote that measured median, never a target: across repeated runs on an Apple M-series laptop it lands between 1.5 and 2.5 µs. The test suite fails above 5 µs so slower CI machines stay green.

Can an LLM talk its way past a limit?

No. Callers may supply only capital_usd, leverage, symbol, plan_id, confirm, position_id and reason. Only the Executor assembles the gate input, equity and the position registry live inside the gate, and an AST test checks that no other module constructs a proposal.