SPB Git

spb/wp7_uqo Public

UQO Working Paper No. 7 — Options-implied information for cross-asset return and volatility prediction: evidence from 3.8B option contracts.

Python 66.5% TeX 32.7% Makefile 0.8%
2.6 KB · 75 lines python
Raw Blame History
1# =============================================================================2# Author: Simon-Pierre Boucher3# Contact: contact@spboucher.ai4# =============================================================================5"""Compare regenerated result CSVs (_verify/results) against the originals6(results/). Numeric columns must match within rtol=1e-9 (and we report7whether they are byte-identical); non-numeric columns must match exactly."""89import sys10from pathlib import Path1112import numpy as np13import pandas as pd1415ROOT = Path(__file__).resolve().parents[1]16ORIG = ROOT / "results"17NEW = ROOT / "_verify" / "results"1819overall_ok = True20rows = []21for new_file in sorted(NEW.glob("*.csv")):22    name = new_file.name23    orig_file = ORIG / name24    if not orig_file.exists():25        rows.append((name, "NEW (no original to compare)"))26        continue2728    byte_identical = new_file.read_bytes() == orig_file.read_bytes()29    if byte_identical:30        rows.append((name, "IDENTICAL (byte-for-byte)"))31        continue3233    a = pd.read_csv(orig_file)34    b = pd.read_csv(new_file)35    if a.shape != b.shape:36        rows.append((name, f"MISMATCH shape {a.shape} vs {b.shape}"))37        overall_ok = False38        continue39    if list(a.columns) != list(b.columns):40        rows.append((name, f"MISMATCH columns"))41        overall_ok = False42        continue4344    bad_cols = []45    max_rel = 0.046    for col in a.columns:47        if pd.api.types.is_numeric_dtype(a[col]) and pd.api.types.is_numeric_dtype(b[col]):48            av, bv = a[col].values.astype(float), b[col].values.astype(float)49            both_nan = np.isnan(av) & np.isnan(bv)50            close = np.isclose(av, bv, rtol=1e-9, atol=1e-15, equal_nan=True)51            if not (close | both_nan).all():52                bad_cols.append(col)53            with np.errstate(all="ignore"):54                rel = np.abs(av - bv) / np.maximum(np.abs(av), 1e-300)55                rel = rel[~(both_nan | np.isnan(rel))]56                if len(rel):57                    max_rel = max(max_rel, np.nanmax(rel))58        else:59            if not a[col].fillna("§na§").astype(str).equals(60                    b[col].fillna("§na§").astype(str)):61                bad_cols.append(col)6263    if bad_cols:64        rows.append((name, f"MISMATCH in columns {bad_cols} (max rel diff {max_rel:.2e})"))65        overall_ok = False66    else:67        rows.append((name, f"EQUAL numerically (max rel diff {max_rel:.2e})"))6869width = max(len(r[0]) for r in rows) + 270for name, status in rows:71    print(f"{name:<{width}} {status}")7273print("\n" + ("ALL COMPARED FILES MATCH" if overall_ok else "DISCREPANCIES FOUND"))74sys.exit(0 if overall_ok else 1)75