"""Independently recompute the public CoinNudge spot trading-cost example. Run this downloaded file from its data directory with: python reproduce.py """ from __future__ import annotations import csv import hashlib import json import math from pathlib import Path def evidence_dir() -> Path: local = Path(__file__).resolve().parent if (local / "book-snapshots.json").exists(): return local return local.parent / "frontend/public/research-data/trading-cost/2026-09-25-v1" def acquire(asks: list[list[str]], amount: float) -> float: left, coins = amount, 0.0 for price_text, quantity_text in asks: price, quantity = float(price_text), float(quantity_text) fill_quote = min(left, price * quantity) coins += fill_quote / price left -= fill_quote if left < 1e-8: break if left >= 1e-8: raise AssertionError("Insufficient ask book") return coins def dispose(bids: list[list[str]], quantity: float) -> float: left, quote = quantity, 0.0 for price_text, quantity_text in bids: take = min(left, float(quantity_text)) quote += take * float(price_text) left -= take if left < 1e-10: break if left >= 1e-10: raise AssertionError("Insufficient bid book") return quote def close(actual: float, expected: float) -> None: if not math.isclose(actual, expected, rel_tol=1e-9, abs_tol=1e-8): raise AssertionError(f"Mismatch: actual={actual}, expected={expected}") def main() -> None: directory = evidence_dir() manifest = json.loads((directory / "manifest.json").read_text()) for name, expected in manifest["sha256"].items(): actual = hashlib.sha256((directory / name).read_bytes()).hexdigest() if actual != expected: raise AssertionError(f"Hash mismatch: {name}") books = json.loads((directory / "book-snapshots.json").read_text())["books"] rows = json.loads((directory / "research.json").read_text())["observations"] with (directory / "observations.csv").open(newline="") as stream: csv_rows = list(csv.DictReader(stream)) if len(rows) != 36 or len(csv_rows) != len(rows): raise AssertionError("Expected 36 observations") field_checks = 0 for row, csv_row in zip(rows, csv_rows): symbol, notional, fee_pct = row["symbol"], row["notional_usdt"], row["fee_per_side_pct"] if csv_row["symbol"] != symbol or float(csv_row["notional_usdt"]) != notional or float(csv_row["fee_per_side_pct"]) != fee_pct: raise AssertionError("CSV row mismatch") book = books[symbol] bid, ask = float(book["bids"][0][0]), float(book["asks"][0][0]) quantity = acquire(book["asks"], float(notional)) proceeds = dispose(book["bids"], quantity) fee = fee_pct / 100 net = proceeds * (1 - fee) - notional * (1 + fee) values = { "best_bid": bid, "best_ask": ask, "mid_price": (bid + ask) / 2, "spread_bps": (ask - bid) / ((bid + ask) / 2) * 10000, "buy_quantity": quantity, "buy_vwap": notional / quantity, "sell_vwap_same_book": proceeds / quantity, "immediate_round_trip_net_usdt": net, "immediate_round_trip_net_pct": net / notional * 100, "mid_move_to_breakeven_pct": (notional * (1 + fee) / (proceeds * (1 - fee)) - 1) * 100, } for name, value in values.items(): close(row[name], value) close(float(csv_row[name]), value) field_checks += 2 print(json.dumps({"status": "PASS", "rows": len(rows), "field_checks": field_checks, "source_files": len(manifest["sha256"])}, separators=(",", ":"))) if __name__ == "__main__": main()