Weekend Gap Guard

BNB Hack · Tokenized Stocks Edition

Tokenized stocks trade all weekend.
Their reference price doesn't.

From Friday 16:00 ET to Monday 09:30 ET the stock market prints nothing, but Ondo, xStocks and bStocks tokens keep trading on BNB Chain. A stop-loss cannot fill at a price the market never prints, so an agent that sizes weekend trades like weekday trades is taking a risk it cannot see. Weekend Gap Guard is the pre-trade gate in front of the wallet: every order comes back ALLOW REDUCE or BLOCK, with the reason.

Replay a real weekend

Hourly on-chain prices of every issuer of one ticker on BSC, and what the guard said about a $2,000 buy at each hour. No look-ahead: each decision sees only data available at that moment.

Live board — 30 stock tokens on BSC

Recorded from the public Binance Wallet endpoints by gapguard record.

Per-share price = token price ÷ shares multiplier. Δ median = distance from the cross-issuer median for the same stock. A quote counts as stale when it is older than 15 min or the endpoint reports a 24 h change of exactly 0 (nothing traded for a day).

Does the gap model hold?

Out-of-sample: for every weekend, the model is fitted on data before Friday's close and compared with what Monday did.

How it works

  1. Data integrityNo price, a quote older than 15 min, a pool that has not traded for 24 h, or no reference while the market is shut → BLOCK. Fail closed.
  2. Venue statusASSET_PAUSED / MARKET_PAUSED / maintenance → BLOCK. Earnings-limited → gap ×2.5, size ×0.5.
  3. Session phaseopen · pre-close (last hour) · closed · pre-open (last 2 h). Holiday weekends cut deeper.
  4. Risk per dollarWhile the stock trades: the stop. While it is shut: the 99 % weekend-gap quantile, stretched by any upward drift you buy into. ×1.43 for the worst fill we have seen.
  5. Stale referenceWeekend drift vs Friday close (in σ of a weekend move); distance from the cross-issuer median; premium to a live stock print.
  6. CapsPosition cap by phase, gross-exposure ("leverage") cap, issuer notional limit, and account guards: static floor, daily loss limit, 40 % consistency rule.
  7. Verdictallowed = min(request, caps). Exits are never sized down.

From a terminal

pip install -e .
gapguard check TSLAB --usd 2000 --wallet-plan     # live, public endpoints
gapguard check MSTRon --usd 2000 --at 2026-09-20T16:00Z   # replay
gapguard scenario MSTR --friday 2026-09-18
gapguard gaps                                      # out-of-sample calibration
gapguard portfolio 0xYourAddress                   # watch-only, BSC RPC

From an agent (Agent Skill)

skills/weekend-gap-guard/SKILL.md
1. gapguard check <SYMBOL> --usd <N> --json --wallet-plan --exit-code
2. BLOCK  → do not call baw; show the reason
   REDUCE → use allowed_usd, not the request
3. baw market-order quote ... (from agentic_wallet.quote_cmd)
4. user confirms → baw market-order swap ...

What is real and what is not

  • Prices, candles, statuses and issuer limits come from the public Binance Wallet Skills endpoints (no key). Balances come from public BSC JSON-RPC. All replays use recorded hourly candles; the live board uses our own recordings.
  • The guard does not trade. The Agentic Wallet hand-off prints the baw commands; we could not run them because the Agentic Wallet requires a Binance account and the Binance app.
  • Historical venue status (pauses, earnings) is not available from the endpoints, so replays mark it "unknown"; the live path reads it.
  • The reference close is the Ondo token's 16:00 ET hourly close (Ondo tracks the stock within ~0.1 % in regular hours), not an exchange feed.