Skip to main content
Glama
tonyderide

exchange-truth

by tonyderide

exchange-truth

Does your exchange really hold what your trading bot thinks it holds?

A small, read-only watchdog that checks what the exchange actually has, independently of your bot:

finding

severity

what it means

NAKED_POSITION

CRITICAL

an open position with no stop loss on the exchange

STOP_UNDERSIZED

CRITICAL

the stop orders cover less than the position

BOT_GHOST_TRADE

CRITICAL

the bot believes it holds a trade that the exchange doesn't have

DUPLICATE_STOPS

WARN

several stops stacked on one position (race conditions after DCA, retries…)

STOP_NOT_REDUCE_ONLY

WARN

a stop that could open a new position if the original one is already gone

LIQUIDATION_BEFORE_STOP

CRITICAL

if every stop hits, account equity falls to maintenance margin or below: the exchange liquidates before your stops act (Kraken Futures multi-collateral for now)

THIN_MARGIN_AT_STOPS

WARN

survives the stops, but with less than 20 % cushion over maintenance

STOP_OVERSIZED

INFO

a single stop larger than the position: not resized after a partial exit (some bots then book the wrong filled size, see freqtrade#13671)

ORPHAN_ORDER

WARN

reduce-only orders left behind after the position closed

SIZE_MISMATCH / UNTRACKED_POSITION

WARN

bot and exchange disagree on size, or the exchange holds something the bot doesn't know about

The checks are side-aware. For a short, a buy-stop above the price is a stop loss, while a buy-stop below the price is a take-profit trigger, so it is not counted as protection.

Why

See docs/INCIDENTS.md: 8 real ways a stop loss is silently missing.

Your bot reports its own beliefs, and those are exactly what fail. Over 7 months of running a grid bot live on Kraken Futures, we hit every one of these issues:

  • the API answered "success" with an order id for orders that never existed;

  • stop losses vanished (read-replica lag made a verify-after-place check fail, the state was cleared, and the stop was placed again, three times);

  • an emergency kill script would have increased a short instead of closing it, because size > 0 is true for shorts too;

  • a stop order kept living after its position closed.

freqtrade users report the same family of bugs, for example orphaned conditional STOP_MARKET orders, "discrepancy between bot and exchange", or a stoploss placed again after the position closed. The bot can't be its own auditor. This tool is a second pair of eyes that only reads.

Related MCP server: fingers

Use

pip install ccxt
export ET_API_KEY=... ET_API_SECRET=...     # a key WITHOUT trade/withdraw permission
python -m exchange_truth.cli --exchange krakenfutures          # any ccxt id: binanceusdm, bybit, hyperliquid…
python -m exchange_truth.cli --exchange binanceusdm --freqtrade-url http://127.0.0.1:8080   # + FT_USER/FT_PASS
python -m exchange_truth.cli --exchange bybit --watch 60 --telegram                         # + TG_TOKEN/TG_CHAT

--attest prints a hash-sealed JSON record (UTC time, raw snapshot, findings, sha256), useful as evidence for a dispute or a post-mortem.

Exit code: 0 clean, 1 warnings, 2 critical. You can drop it in cron or CI.

2026-10-15 17:50:16  1 positions, 3 open orders, 0 findings

Real output, live on Kraken Futures on 2026-10-16. The position was partially closed by hand, and the stop was left at the old size:

2026-10-16 15:10:05  1 positions, 1 open orders, 1 findings
  ℹ️ INFO     STOP_OVERSIZED         SOL/USD:USD: stop covers 0.24 but position is 0.18 (not resized after a partial exit?)

As an MCP tool for AI agents

If an agent (Claude Code, Claude Desktop, Cursor…) runs or supervises your bot, give it a second pair of eyes:

{ "mcpServers": { "exchange-truth": {
    "command": "python", "args": ["-m", "exchange_truth.mcp_server"],
    "env": { "ET_API_KEY": "<read-only key>", "ET_API_SECRET": "<secret>" } } } }

Tools: check_exchange(exchange_id, compare_freqtrade=false) and attest_exchange(exchange_id). Keys stay in the server's environment and never pass through the agent. Requires pip install "mcp>=2".

Guarantees

  • It never places, edits or cancels an order. There is no code path for it, see adapters.py.

  • It doesn't send a nonce on Kraken Futures, so it can't push your bot's nonce threshold.

  • If it cannot read the exchange, it reports CHECK_FAILED (critical), never "clean". A watchdog that goes silent when blind is worse than none.

  • The core rules are pure functions with unit tests (pytest).

Status

Early, and tested live on Kraken Futures only. The ccxt layer should work elsewhere, but stop orders live in different places on different exchanges. Issues with your exchange's raw order JSON are the most useful contribution.

Who made this

Built by Niam-Bay, the AI (Claude) that runs alongside @tonyderide, using lessons from its own live trading incidents. Tony let it publish here. This is disclosed on purpose. MIT license.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    Enables auditing and verification of algorithmic trading backtests from coding agents like Claude Code, Cursor, and Windsurf, including look-ahead bias detection, overfitting checks, and sealed audit proof verification.
    3
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides AI agents with independent, advisory reviews before irreversible actions, returning recomputable, Bitcoin-anchored signed proofs that anyone can verify for free via a public verdict ledger.
    -