"""Independent standard-library trade-ledger audit of the frozen BTC example. Reads the published candle file and implements the entry/exit accounting anew; does not import the production replay or indicator functions. """ import csv import gzip import json import math from pathlib import Path ROOT = Path(__file__).resolve().parents[1] LOCAL = Path(__file__).resolve().parent BASE = LOCAL if (LOCAL / "research.json").exists() else ROOT / "frontend/public/research-data/ai-strategy-validation/2026-09-25-v1" FEE, SLIP = .0005, .0002 def ema(values, period): series = [None] * len(values) seed = sum(values[:period]) / period series[period-1] = seed factor = 2 / (period + 1) previous = seed for index in range(period, len(values)): previous = factor * values[index] + (1-factor) * previous series[index] = previous return series def close(position, price, opened, reason, fee_rate, slip_rate): price *= 1-slip_rate fee = price * position["quantity"] * fee_rate gross = (price-position["entry"]) * position["quantity"] pnl = gross-position["entry_fee"]-fee return {"opened": position["opened"], "closed": opened, "entry": position["entry"], "exit": price, "fees": position["entry_fee"]+fee, "pnl": pnl, "reason": reason}, gross-fee def replay_independent(bars, start, fee_rate=FEE, slip_rate=SLIP): closes = [bar["c"] for bar in bars] short, long = ema(closes, 9), ema(closes, 21) cash, position, trades = 10000.0, None, [] for i in range(22, len(bars)): bar = bars[i] if bar["opened"] < start: continue prior, older = i-1, i-2 cross_up = short[prior] > long[prior] and short[older] <= long[older] cross_down = short[prior] < long[prior] and short[older] >= long[older] if position and (cross_down or bar["opened"]-position["opened"] >= 48*3600): trade, delta = close(position, bar["o"], bar["opened"], "Opposite signal" if cross_down else "Time exit", fee_rate, slip_rate) trades.append(trade) cash += delta position = None if position is None and cross_up and cash > 0: margin = min(500, max(0, cash*.1)) if margin >= 10: fill = bar["o"] * (1+slip_rate) quantity = margin/fill fee = quantity*fill*fee_rate cash -= fee position = {"opened": bar["opened"], "entry": fill, "quantity": quantity, "entry_fee": fee, "stop": fill*.98, "target": fill*1.04} if position: stop = bar["l"] <= position["stop"] target = bar["h"] >= position["target"] if stop or target: raw = min(bar["o"], position["stop"]) if stop else position["target"] reason = "Stop first (OHLC)" if stop else "Target (OHLC)" trade, delta = close(position, raw, bar["opened"], reason, fee_rate, slip_rate) trades.append(trade) cash += delta position = None if position: trade, delta = close(position, bars[-1]["c"], bars[-1]["opened"]+900, "End of sample", fee_rate, slip_rate) trades.append(trade) cash += delta return cash, trades def main(): with gzip.open(BASE / "candles.csv.gz", "rt") as handle: bars = [{k: (int(float(value)) if k == "opened" else float(value)) for k, value in row.items()} for row in csv.DictReader(handle)] research = json.loads((BASE / "research.json").read_text()) start = research["coverage"]["requested_start"] checks = 0 results = {} for label, fee_rate, slip_rate in (("result", FEE, SLIP), ("double_cost_result", 2*FEE, 2*SLIP)): cash, reproduced = replay_independent(bars, start, fee_rate, slip_rate) original = research[label].get("trades") expected_count = len(original) if original is not None else research[label]["trades_count"] if len(reproduced) != expected_count: raise AssertionError(f"{label} trade count mismatch: {len(reproduced)} != {expected_count}") checks += 1 if original is not None: for index, (actual, expected) in enumerate(zip(reproduced, original)): for key in ("opened", "closed", "entry", "exit", "fees", "pnl", "reason"): a, b = actual[key], expected[key] same = a == b if isinstance(a, str) else math.isclose(a, b, rel_tol=0, abs_tol=1e-7) if not same: raise AssertionError(f"{label} trade {index} {key}: {a} != {b}") checks += 1 if not math.isclose(cash, research[label]["final_balance"], rel_tol=0, abs_tol=1e-7): raise AssertionError(f"{label} final cash mismatch") checks += 1 if not math.isclose(sum(x["fees"] for x in reproduced), research[label]["fees"], rel_tol=0, abs_tol=1e-7): raise AssertionError(f"{label} fee total mismatch") checks += 1 results[label] = {"trades": len(reproduced), "final_cash": cash, "net_pct": (cash/10000-1)*100} print(json.dumps({"field_checks": checks, **results})) if __name__ == "__main__": main()