{
  "np2_check": {
    "sha256": "51f1c1a9d4999ee460eb8bbc66880da8074b173399a4f5d71f96671482e18ac0",
    "seed_start": 0,
    "seed_end": 999,
    "n": 1000,
    "mean_edge_y": 526.1155722459862,
    "se": 2.7896004178197593,
    "expected": 526.1156,
    "absolute_error": 2.7754013785852294e-05,
    "pass": true
  },
  "ch_check": {
    "n": 1000,
    "mean_edge_y": 525.5258821780834,
    "expected": 525.525882178,
    "absolute_error": 8.344613888766617e-11,
    "pass": true
  },
  "seconds_per_sim": 0.12360931685939432,
  "timing": {
    "unmodified_np2_batch_seconds": 123.60931685939431,
    "instrumented_np2_seconds": 29.790882386267185,
    "instrumented_seconds_per_sim": 0.14895441193133593,
    "workers": 8,
    "compilation_included": false,
    "instrumented_np2_seconds_includes": "batch wall time plus Python aggregation and npz compression"
  },
  "paired": {
    "n": 0,
    "mean_diff": null,
    "se": null,
    "worst": null
  },
  "measurements": {
    "n": 200,
    "seeds": "0..199",
    "steps_per_run": 10000,
    "per_run": {
      "arb_edge": {
        "mean": -31.577664615900936,
        "se": 0.8900549296615307
      },
      "arb_prints_per_step": {
        "mean": 0.37471799999999994,
        "se": 0.0007279052895485537
      },
      "arb_volume_y": {
        "mean": 24288.51337591268,
        "se": 112.77720802648393
      },
      "arb_mean_fee_bps": {
        "mean": 74.48267652046326,
        "se": 0.37475863742849846
      },
      "arb_volume_weighted_fee_bps": {
        "mean": 105.83292466366682,
        "se": 0.9526678747435883
      },
      "retail_edge": {
        "mean": 565.6740710025074,
        "se": 6.815420730877146
      },
      "retail_prints_per_step": {
        "mean": 0.688446,
        "se": 0.006066399254879124
      },
      "retail_volume_y": {
        "mean": 78179.59693808384,
        "se": 706.405888137007
      },
      "retail_mean_fee_bps": {
        "mean": 36.68898762721902,
        "se": 0.15068931783278178
      },
      "retail_volume_weighted_fee_bps": {
        "mean": 37.78723648408073,
        "se": 0.16763161239983554
      },
      "arb_step_share": {
        "mean": 0.37471799999999994,
        "se": 0.0007279052895485537
      },
      "prints_per_step": {
        "mean": 1.0631639999999998,
        "se": 0.006393841809540421
      },
      "total_edge": {
        "mean": 534.0964063866064,
        "se": 6.357924141501572
      }
    },
    "pooled": {
      "arb": {
        "print_weighted_bps": 74.56212674959487,
        "volume_y_weighted_bps": 106.28990605064178,
        "prints": 749436,
        "total_volume_y": 4857702.675182536,
        "total_edge_y": -6315.532923180187
      },
      "retail": {
        "print_weighted_bps": 36.907560657327835,
        "volume_y_weighted_bps": 38.05714401709599,
        "prints": 1376892,
        "total_volume_y": 15635919.387616768,
        "total_edge_y": 113134.81420050148
      }
    },
    "arb_loss_bins": {
      "gap": {
        "1": {
          "loss_y_per_run": {
            "mean": 30.978618980688648,
            "se": 0.8916270553786124
          },
          "prints": 669117,
          "prints_per_run": {
            "mean": 3345.585,
            "se": 9.46292229529727
          },
          "loss_y_per_print": 0.009259552210058523,
          "share_of_total_arb_loss": 0.9810294509584905
        },
        "2": {
          "loss_y_per_run": {
            "mean": 0.4037895999320604,
            "se": 0.005164840497231394
          },
          "prints": 52498,
          "prints_per_run": {
            "mean": 262.49,
            "se": 1.971530920592997
          },
          "loss_y_per_print": 0.0015383046970629754,
          "share_of_total_arb_loss": 0.012787190086525022
        },
        "3-4": {
          "loss_y_per_run": {
            "mean": 0.16052035219105246,
            "se": 0.003150979264180565
          },
          "prints": 22698,
          "prints_per_run": {
            "mean": 113.49,
            "se": 1.6906480872061664
          },
          "loss_y_per_print": 0.0014144008475729356,
          "share_of_total_arb_loss": 0.005083350974290303
        },
        "5+": {
          "loss_y_per_run": {
            "mean": 0.033184433423286475,
            "se": 0.0012576977271916896
          },
          "prints": 4956,
          "prints_per_run": {
            "mean": 24.78,
            "se": 0.7448368341776196
          },
          "loss_y_per_print": 0.0013391619621988084,
          "share_of_total_arb_loss": 0.0010508830791298117
        }
      },
      "prev_close": {
        "<=20": {
          "loss_y_per_run": {
            "mean": 0.43209380693163285,
            "se": 0.00765351959921918
          },
          "prints": 49444,
          "prints_per_run": {
            "mean": 247.22,
            "se": 3.2428906393050725
          },
          "loss_y_per_print": 0.0017478108847651195,
          "share_of_total_arb_loss": 0.013683526384470242
        },
        "20-60": {
          "loss_y_per_run": {
            "mean": 3.749107863565149,
            "se": 0.03523395270384955
          },
          "prints": 259054,
          "prints_per_run": {
            "mean": 1295.27,
            "se": 9.239530840402763
          },
          "loss_y_per_print": 0.002894460509056142,
          "share_of_total_arb_loss": 0.1187265717451849
        },
        "60-200": {
          "loss_y_per_run": {
            "mean": 16.140768546073037,
            "se": 0.12995604323020538
          },
          "prints": 405936,
          "prints_per_run": {
            "mean": 2029.68,
            "se": 14.143853113791964
          },
          "loss_y_per_print": 0.007952371086118518,
          "share_of_total_arb_loss": 0.5111451002600537
        },
        ">200": {
          "loss_y_per_run": {
            "mean": 11.25569439933112,
            "se": 0.8846293550784563
          },
          "prints": 35002,
          "prints_per_run": {
            "mean": 175.01,
            "se": 2.8916531238972496
          },
          "loss_y_per_print": 0.06431457859168686,
          "share_of_total_arb_loss": 0.35644480161029113
        }
      },
      "last_retail": {
        "<=20": {
          "loss_y_per_run": {
            "mean": 0.4588978364392288,
            "se": 0.008250032383938842
          },
          "prints": 51694,
          "prints_per_run": {
            "mean": 258.47,
            "se": 3.3558013219740546
          },
          "loss_y_per_print": 0.0017754394569552707,
          "share_of_total_arb_loss": 0.014532355132055927
        },
        "20-60": {
          "loss_y_per_run": {
            "mean": 3.375682438071816,
            "se": 0.03057063616157137
          },
          "prints": 230813,
          "prints_per_run": {
            "mean": 1154.065,
            "se": 7.5006903451126625
          },
          "loss_y_per_print": 0.0029250366643748973,
          "share_of_total_arb_loss": 0.10690095290872115
        },
        "60-200": {
          "loss_y_per_run": {
            "mean": 15.543102457321503,
            "se": 0.12209053753706654
          },
          "prints": 414337,
          "prints_per_run": {
            "mean": 2071.685,
            "se": 12.375353560758125
          },
          "loss_y_per_print": 0.007502637928701275,
          "share_of_total_arb_loss": 0.49221823863107256
        },
        ">200": {
          "loss_y_per_run": {
            "mean": 12.198378445306712,
            "se": 0.8877894904041832
          },
          "prints": 52412,
          "prints_per_run": {
            "mean": 262.06,
            "se": 3.712620334580917
          },
          "loss_y_per_print": 0.04654803650044537,
          "share_of_total_arb_loss": 0.3862976757047517
        }
      },
      "gap_unknown": {
        "prints": 167,
        "loss_y_per_run": {
          "mean": 0.001551249665888588,
          "se": 0.0001858489314210111
        }
      },
      "retail_unknown": {
        "prints": 180,
        "loss_y_per_run": {
          "mean": 0.0016034387616757834,
          "se": 0.00019152556862368387
        }
      }
    }
  },
  "methodology": {
    "units": "Edge/loss/volume are Y units. Loss is positive arbitrageur profit. Fees are basis points of input. A print is a successful submission-side execution; split legs on the normalizer are excluded. SE uses sample standard deviation across 200 independent runs / sqrt(200).",
    "gap": "t minus timestamp of our immediately previous print, arb or retail. First-ever print is unknown, never put in gap=1.",
    "prev_close": "Absolute log(our closing spot at t-1 / fair at t-1)*10000, including prior steps without retail. Initial close displacement is 0.",
    "last_retail": "Absolute log(our spot immediately after most recent own retail print / fair at that print)*10000, carried until next own retail. No preceding retail is unknown. Bins (20,60], (60,200], (200,infinity), and [0,20]. Both displacement definitions supplied to make the ambiguous preceding-retail condition explicit.",
    "fee": "Pre-execution fee on actual trade side: ask when AMM sells X, bid when AMM buys X. per_run means average each run equally; pooled print and Y-volume weights supplied separately.",
    "baseline": "Pinned VanillaStrategy (30 bps); configs directly from MatchRunner._build_configs with canonical BASELINE_VARIANCE, seeds 0..999. Price seed=s, retail seed=s+1.",
    "instrumentation": "Replace route_orders wrapper with its identical ordered loop over route_order, snapshot fee before each order, and add result.decomposition rows [kind,t,edge,fee,volume_y,gap,previous_close_bps,last_retail_bps]. kind 0=arb, 1=retail. No trade execution or strategy changes.",
    "validation": "For every instrumented seed, edge matches the unmodified result within 1e-9; row edge sums match within 1e-8 and arb/retail Y volumes match engine totals within 1e-7."
  },
  "helper_usage": "After setup and the unmodified NP2 check, scratch/np2.bin and scratch/base.bin contain compiler creation bytecode; scratch/check.json contains edges in seed order. Run instrument.py once on pinned source; rebuild via maturin develop --release --uv --manifest-path amm_sim_rs/Cargo.toml; run measure.py. Always source scratch/env.sh first. measure.json holds per-seed sufficient statistics and trades.npz the raw print rows.",
  "blocked": null,
  "notes": "Measurements are local experiments, not leaderboard results. No strategy tuning or paired candidate comparison was performed (paired n=0). NP2 check rounds to the required value. All 200 instrumented seeds retain their unmodified edges. On these seeds, 98.10% of arb loss is in gap=1; long silent gaps contribute little. Previous-close displacement >200 bps accounts for 35.64% of arb loss from 4.67% of arb prints. These are associations, not causal attribution to retail: displacement also reflects stale quotes and past price moves. The preceding-own-retail definition gives 38.63% of loss above 200 bps. Most of the net edge comes from retail; reducing total arb loss alone by 9.6 would require eliminating about 30.4% of its measured mean. The 200-seed mean differs from the 1000-seed calibration because they are different sample sizes. seconds_per_sim is elapsed batch wall time divided by runs with 8 workers, not single-core CPU time; instrumented timing also includes Python aggregation and compressed trade-file output. Reproduction needs the pinned simulator and setup dependencies; the delivered JSON has no runtime dependencies.",
  "code": {
    "instrument.py": "from pathlib import Path\np=Path('amm_sim_rs/src/types/result.rs');s=p.read_text();needle='pub struct LightweightSimResult {';s=s.replace(needle,needle+'\\n    #[pyo3(get)]\\n    pub decomposition: Vec<Vec<f64>>,',1);p.write_text(s)\np=Path('amm_sim_rs/src/simulation/engine.rs');s=p.read_text()\ns=s.replace('        for t in 0..self.config.n_steps {','''        let mut decomposition = Vec::new();\n        let mut last_print: Option<u32> = None;\n        let mut previous_close_gap = 0.0_f64;\n        let mut last_retail_gap = -1.0_f64;\n        for t in 0..self.config.n_steps {''')\ns=s.replace('                if let Some(arb_result)', '''                let fee = if amm.spot_price() < fair_price {\n                    amm.fees().ask_fee.to_f64()\n                } else { amm.fees().bid_fee.to_f64() };\n                if let Some(arb_result)''')\ns=s.replace('                    *arb_volume_y.get_mut', '''                    if amm.name == \"submission\" {\n                        decomposition.push(vec![0.0, t as f64, -arb_result.profit, fee,\n                            arb_result.amount_y,\n                            last_print.map(|v| (t-v) as f64).unwrap_or(-1.0),\n                            previous_close_gap, last_retail_gap]);\n                        last_print = Some(t);\n                    }\n                    *arb_volume_y.get_mut''')\ns=s.replace('            let routed_trades = router.route_orders(&orders, &mut amms, fair_price, t as u64);\\n            for trade in routed_trades {','''            for order in &orders {\n                let f = amms[0].fees();\n                let fee = if order.side == \"buy\" { f.ask_fee.to_f64() } else { f.bid_fee.to_f64() };\n                let routed_trades = router.route_order(order, &mut amms, fair_price, t as u64);\n                for trade in routed_trades {''')\ns=s.replace('                let entry = edges.entry(trade.amm_name)', '''                if trade.amm_name == \"submission\" {\n                    last_retail_gap = (amms[0].spot_price()/fair_price).ln().abs()*10000.0;\n                    decomposition.push(vec![1.0, t as f64, trade_edge, fee, trade.amount_y,\n                        last_print.map(|v| (t-v) as f64).unwrap_or(-1.0),\n                        last_retail_gap, last_retail_gap]);\n                    last_print = Some(t);\n                }\n                let entry = edges.entry(trade.amm_name)''')\ns=s.replace('            // 4. Capture', '''            }\n            previous_close_gap = (amms[0].spot_price()/fair_price).ln().abs()*10000.0;\n\n            // 4. Capture''')\ns=s.replace('        Ok(LightweightSimResult {','        Ok(LightweightSimResult {\\n            decomposition,')\np.write_text(s)\n",
    "measure.py": "import json,time\nfrom pathlib import Path\nimport numpy as np, amm_sim_rs\nfrom amm_competition.competition.config import build_base_config, BASELINE_VARIANCE\nfrom amm_competition.competition.match import MatchRunner\np=Path('scratch');a=list((p/'np2.bin').read_bytes());b=list((p/'base.bin').read_bytes())\nr=MatchRunner(n_simulations=200,config=build_base_config(seed=0),n_workers=8,variance=BASELINE_VARIANCE)\nconfigs=r._build_configs(); rows=[];arrays=[];start=time.perf_counter();check=json.loads((p/'check.json').read_text())\nfor i in range(0,200,10):\n batch=amm_sim_rs.run_batch(a,b,configs[i:i+10],8)\n for z in batch.results:\n  d=np.array(z.decomposition); arrays.append(d)\n  assert abs(z.edges['submission']-check['edges'][z.seed])<1e-9\n  assert abs(d[:,2].sum()-z.edges['submission'])<1e-8\n  v={}\n  for k,name in enumerate(['arb','retail']):\n   x=d[d[:,0]==k];v[name+'_edge']=float(x[:,2].sum());v[name+'_prints_per_step']=len(x)/10000\n   v[name+'_volume_y']=float(x[:,4].sum());v[name+'_mean_fee_bps']=float(x[:,3].mean()*10000)\n   v[name+'_volume_weighted_fee_bps']=float(np.average(x[:,3],weights=x[:,4])*10000)\n   assert abs(x[:,4].sum()-getattr(z,name+'_volume_y')['submission'])<1e-7\n  v['arb_step_share']=len(set(d[d[:,0]==0,1]))/10000\n  v['prints_per_step']=len(d)/10000\n  x=d[d[:,0]==0]\n  for col,prefix,bins in [(5,'gap',[(1,1),(2,2),(3,4),(5,1e9)]),(6,'prev_close',[(0,20),(20,60),(60,200),(200,1e9)]),(7,'last_retail',[(0,20),(20,60),(60,200),(200,1e9)])]:\n   for j,(lo,hi) in enumerate(bins):\n    mask=(x[:,col]>=lo)&(x[:,col]<=hi) if col==5 else (x[:,col]>=0)&(x[:,col]<=hi)&((x[:,col]>lo) if j else True)\n    q=x[mask];v[f'{prefix}_{j}_loss']=float(-q[:,2].sum());v[f'{prefix}_{j}_count']=len(q)\n  v['gap_unknown_loss']=float(-x[x[:,5]<0,2].sum());v['gap_unknown_count']=int((x[:,5]<0).sum())\n  v['retail_unknown_loss']=float(-x[x[:,7]<0,2].sum());v['retail_unknown_count']=int((x[:,7]<0).sum())\n  rows.append(v)\n print(i+10,time.perf_counter()-start,flush=True)\nnp.savez_compressed(p/'trades.npz',**{str(i):a for i,a in enumerate(arrays)})\n(p/'measure.json').write_text(json.dumps({'seconds':time.perf_counter()-start,'rows':rows}))\n"
  },
  "validation": {
    "setup": "passed; supplied script run once, StarterStrategy validated",
    "np2_hash": "51f1c1a9d4999ee460eb8bbc66880da8074b173399a4f5d71f96671482e18ac0",
    "instrumented_runs_checked": 200,
    "per_seed_edge_tolerance": 1e-09,
    "trade_edge_sum_tolerance": 1e-08,
    "volume_sum_tolerance": 1e-07,
    "gap_bins_exhaustive": true,
    "displacement_bins_exhaustive_including_unknown": true
  }
}
