Module 12 · Statistical Computing and Reproducibility Module demo

Production-Grade Metrics Service

Same data, run twice.

6:26 clipUses lessons 111–120Watch on YouTube

Transcript

45 sentences · select one to jump there

Code lab

Run it yourself

The demo source in one language. Edit it, run TypeScript and Python right here, and compare with the expected output.

demo-production-metrics-service.ts
Start from GitHub
/**
 * Fintech Math Bootcamp · Module 12 demo · Production-Grade Metrics Service
 * The Module 11 risk report, rebuilt as a service that gives the same answer every time it runs.
 * A feed delivers twenty synthetic days of returns for two funds (60% A, 40% B) in a different order on
 * every run, with a few broken records. A naive report and the production service each run twice and
 * stamp their results with a checksum: the naive checksums drift, the production checksums match.
 * Lessons 111–120: floating point, compensated summation, Welford variance, batch/rolling/streaming
 * equivalence, input policies, seeded PRNGs, index alignment, leakage-free scaling, tolerance and property
 * tests, and an audit record with an FNV-1a checksum over canonical JSON.
 * Conventions: sample SD (n − 1), A = 252 trading days, loss = −return, type 7 loss quantiles.
 * Synthetic example; not investment advice.
 */

export type Rec = {day: number; id: string; r: unknown};
type Stats = {count: number; mean: number; m2: number};

// 111 · floating point is finite and rounded
export const floatFacts = () => ({
  sum: 0.1 + 0.2, exactlyPointThree: 0.1 + 0.2 === 0.3,
  overflow: String(Number.MAX_VALUE * 2), underflow: Number.MIN_VALUE / 2, epsilon: Number.EPSILON,
});

// 112 · Neumaier (improved Kahan) compensated summation
export function stableSum(values: number[]): number {
  let sum = 0, correction = 0;
  for (const x of values) {
    const next = sum + x;
    correction += Math.abs(sum) >= Math.abs(x) ? (sum - next) + x : (x - next) + sum;
    sum = next;
  }
  return sum + correction;
}
export const naiveSum = (values: number[]) => values.reduce((s, x) => s + x, 0);

// 113 · Welford: update count, mean and M2 one value at a time
export function welfordPush(s: Stats, x: number): Stats {
  const count = s.count + 1, delta = x - s.mean, mean = s.mean + delta / count;
  return {count, mean, m2: s.m2 + delta * (x - mean)};
}
export const welford = (values: number[]) => values.reduce(welfordPush, {count: 0, mean: 0, m2: 0});
export const welfordSD = (s: Stats) => Math.sqrt(s.m2 / (s.count - 1));
// the unstable textbook shortcut: (Σx² − n·mean²) / (n − 1)
export function textbookVariance(values: number[]): number {
  const n = values.length, sum = naiveSum(values), sumSq = naiveSum(values.map(x => x * x));
  return (sumSq - sum * sum / n) / (n - 1);
}
// two-pass batch SD with a stable mean
export function batchSD(values: number[]): number {
  const m = stableSum(values) / values.length;
  return Math.sqrt(stableSum(values.map(x => (x - m) ** 2)) / (values.length - 1));
}

// 114 · rolling window SD, recomputed per window from a queue of the last w observations
export function rollingSD(values: number[], w: number): (number | null)[] {
  const queue: number[] = [];
  return values.map(x => { queue.push(x); if (queue.length > w) queue.shift(); return queue.length === w ? welfordSD(welford(queue)) : null; });
}

// 115 · explicit input policy: missing ≠ zero ≠ invalid ≠ unsupported
export type Verdict = {day: number; id: string; raw: string; status: "accepted" | "missing" | "invalid" | "unsupported"; naive: string};
export function classify(rec: Rec): Verdict {
  const raw = rec.r === null ? "null" : typeof rec.r === "string" ? JSON.stringify(rec.r) : String(rec.r);
  const naive = String(Number(rec.r) || 0); // what a careless loader would store
  if (rec.r === null || rec.r === undefined) return {day: rec.day, id: rec.id, raw, status: "missing", naive};
  if (typeof rec.r !== "number") return {day: rec.day, id: rec.id, raw, status: "unsupported", naive};
  if (!Number.isFinite(rec.r)) return {day: rec.day, id: rec.id, raw, status: "invalid", naive};
  return {day: rec.day, id: rec.id, raw, status: "accepted", naive};
}

// 116 · seeded linear congruential generator (reproducible, not cryptographic)
export function lcg(seed: number) {
  let state = seed >>> 0;
  return () => { state = (Math.imul(1664525, state) + 1013904223) >>> 0; return state / 4294967296; };
}

// 117 · align by identifier before a dot product; a missing ID throws instead of guessing
export function alignedDot(weights: {id: string; w: number}[], rets: {id: string; r: number}[]): number {
  const byId = new Map(rets.map(x => [x.id, x.r]));
  return weights.reduce((s, x) => { const r = byId.get(x.id); if (r === undefined) throw new Error("Missing asset " + x.id); return s + x.w * r; }, 0);
}
export const positionalDot = (weights: {id: string; w: number}[], rets: {id: string; r: number}[]) => weights.reduce((s, x, i) => s + x.w * rets[i].r, 0);

// 118 · fit a scaler on training data only, then freeze it
export function fitScaler(train: number[]) { const s = welford(train); return {mean: s.mean, sd: welfordSD(s)}; }
export const transform = (x: number[], p: {mean: number; sd: number}) => x.map(v => (v - p.mean) / p.sd);

// 119 · tolerance comparison: |a − b| ≤ absTol + relTol · max(|a|, |b|)
export const near = (a: number, b: number, absTol = 1e-12, relTol = 1e-10) => Math.abs(a - b) <= absTol + relTol * Math.max(Math.abs(a), Math.abs(b));

// 120 · canonical JSON (sorted keys, recursively) and FNV-1a over its UTF-16 code units
export function canonical(v: unknown): string {
  if (Array.isArray(v)) return "[" + v.map(canonical).join(",") + "]";
  if (v !== null && typeof v === "object") return "{" + Object.keys(v as object).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)).map(k => JSON.stringify(k) + ":" + canonical((v as Record<string, unknown>)[k])).join(",") + "}";
  return JSON.stringify(v);
}
export function fnv1a(text: string): string {
  let hash = 2166136261;
  for (let k = 0; k < text.length; k++) hash = Math.imul(hash ^ text.charCodeAt(k), 16777619) >>> 0;
  return hash.toString(16).padStart(8, "0");
}

/* ---------- the synthetic feed ---------- */
const A = 252, W = [{id: "A", w: 0.6}, {id: "B", w: 0.4}];
const PCT: Record<string, number[]> = {
  A: [0.6, -0.5, 0.8, -0.6, 0.5, -0.3, 0.7, -0.5, 0.6, -0.4, 0.4, -0.8, -0.6, 0.6, -0.9, 0.3, -0.7, 0.5, -0.6, 0.9],
  B: [-0.4, 0.7, -0.5, 0.8, -0.3, 0.6, -0.4, 0.7, -0.3, 0.7, 0.5, -0.7, -0.8, 0.5, -0.8, 0.4, -0.6, 0.6, -0.5, 0.8],
};
const LATE: Rec[] = [{day: 21, id: "A", r: null}, {day: 21, id: "B", r: NaN}, {day: 22, id: "A", r: Infinity}, {day: 22, id: "B", r: "0.003"}];
// the feed for run k: 40 good records plus 4 broken ones, shuffled by a seeded permutation (arrival order differs per run)
export function feed(run: number): Rec[] {
  const recs: Rec[] = [...["A", "B"].flatMap(id => PCT[id].map((p, i) => ({day: i + 1, id, r: p / 100}))), ...LATE];
  const rnd = lcg(1000 + run);
  for (let i = recs.length - 1; i > 0; i--) { const j = Math.floor(rnd() * (i + 1)); [recs[i], recs[j]] = [recs[j], recs[i]]; }
  return recs;
}

/* ---------- shared risk math (module 11, compact) ---------- */
function drawdownOf(port: number[]) { let w = 1, peak = 1, mdd = 0; for (const r of port) { w *= 1 + r; peak = Math.max(peak, w); mdd = Math.min(mdd, w / peak - 1); } return mdd; }
function quantile7(sorted: number[], p: number) { const h = (sorted.length - 1) * p, i = Math.floor(h); return i + 1 < sorted.length ? sorted[i] + (h - i) * (sorted[i + 1] - sorted[i]) : sorted[i]; }
function tail(port: number[], p: number) { const losses = port.map(r => -r).sort((a, b) => a - b), v = quantile7(losses, p), t = losses.filter(l => l >= v); return {var: v, es: stableSum(t) / t.length}; }
function monteCarloVaR(port: number[], seed: number, paths: number, horizon: number, p: number) {
  const rnd = lcg(seed), losses: number[] = [];
  for (let k = 0; k < paths; k++) { let g = 1; for (let d = 0; d < horizon; d++) g *= 1 + port[Math.floor(rnd() * port.length)]; losses.push(1 - g); }
  losses.sort((a, b) => a - b);
  return quantile7(losses, p);
}
const MC = {paths: 2000, horizon: 10, confidence: 0.95, seed: 42};

// the production service: policy → canonical order → aligned dot → stable statistics → seeded simulation
export function productionReport(recs: Rec[]) {
  const verdicts = recs.map(classify), ok = recs.filter((_, i) => verdicts[i].status === "accepted") as {day: number; id: string; r: number}[];
  const days = [...new Set(ok.map(x => x.day))].sort((a, b) => a - b);
  const port = days.map(d => alignedDot(W, ok.filter(x => x.day === d).sort((a, b) => (a.id < b.id ? -1 : 1)).map(x => ({id: x.id, r: x.r}))));
  const s = welford(port), sd = welfordSD(s), t = tail(port, 0.9);
  return {
    rejected: verdicts.filter(v => v.status !== "accepted").length, days: port.length,
    meanDaily: stableSum(port) / port.length, sdDaily: sd, annualVol: sd * Math.sqrt(A), maxDrawdown: drawdownOf(port),
    var90: t.var, es90: t.es, mcVar95: monteCarloVaR(port, MC.seed, MC.paths, MC.horizon, MC.confidence),
  };
}
// the naive report: arrival order, coercion, positional dot product, one-pass variance, a seed that changes every run
export function naiveReport(recs: Rec[], run: number) {
  const byDay = new Map<number, {id: string; r: number}[]>();
  for (const x of recs) { const r = Number(x.r) || 0; if (!Number.isFinite(r)) continue; byDay.set(x.day, [...(byDay.get(x.day) ?? []), {id: x.id, r}]); }
  const port = [...byDay.values()].filter(v => v.length === 2).map(v => positionalDot(W, v));
  const sd = Math.sqrt(Math.max(0, textbookVariance(port))), t = tail(port, 0.9);
  return {
    rejected: 0, days: port.length, meanDaily: naiveSum(port) / port.length, sdDaily: sd, annualVol: sd * Math.sqrt(A),
    maxDrawdown: drawdownOf(port), var90: t.var, es90: t.es, mcVar95: monteCarloVaR(port, 7919 * run + 13, MC.paths, MC.horizon, MC.confidence),
  };
}
function audit(results: object) {
  const record = {dataset: "synthetic-two-fund-20d", version: "metrics-service-1.0", cutoff: "day-20", method: "sample-sd, type7-var90, es90, bootstrap-var95-10d",
    params: {annualization: A, confidence: 0.9, weights: {A: 0.6, B: 0.4}, mc: MC}, results};
  const text = canonical(record);
  return {text, checksum: fnv1a(text), bytes: text.length};
}

export function runDemo() {
  // 111 and 112
  const dimes = Array.from({length: 10}, () => 0.1);
  const ordered = PCT.A.map((a, i) => (0.6 * a + 0.4 * PCT.B[i]) / 100), reversed = [...ordered].reverse();
  const floats = {...floatFacts(), dimesNaive: naiveSum(dimes), dimesStable: stableSum(dimes),
    orderNaive: [naiveSum(ordered), naiveSum(reversed)], orderStable: [stableSum(ordered), stableSum(reversed)]};

  // 113 and 114
  const balances = [4, 7, 13, 16].map(c => 1e9 + c);
  const steps: Stats[] = []; balances.reduce((s, x) => { const n = welfordPush(s, x); steps.push(n); return n; }, {count: 0, mean: 0, m2: 0});
  const prod1 = productionReport(feed(1));
  const port = ordered;
  const roll = rollingSD(port, 5), stream = welford(port);
  const batch = batchSD(port), streaming = welfordSD(stream), rollLast = roll.at(-1)!, batchLast = batchSD(port.slice(-5));
  const variance = {balances, textbook: textbookVariance(balances), welford: welford(balances).m2 / 3, steps,
    batch, streaming, rolling: roll, rollingLast: rollLast, batchLast, maxGap: Math.max(Math.abs(batch - streaming), Math.abs(rollLast - batchLast))};

  // 115 and 117
  const policy = LATE.map(classify);
  const day1 = [{id: "B", r: PCT.B[0] / 100}, {id: "A", r: PCT.A[0] / 100}];
  const alignment = {weights: W, day1, positional: positionalDot(W, day1), aligned: alignedDot(W, day1),
    missing: (() => { try { alignedDot(W, [{id: "A", r: 0.01}]); return "no error"; } catch (e) { return (e as Error).message; } })()};

  // 116 · replay a simulation
  const draws = (() => { const r = lcg(MC.seed); return [r(), r(), r()]; })();
  const mc = {...MC, draws, replay: [monteCarloVaR(port, 42, MC.paths, MC.horizon, MC.confidence), monteCarloVaR(port, 42, MC.paths, MC.horizon, MC.confidence)],
    otherSeeds: [7919 + 13, 7919 * 2 + 13].map(sd => monteCarloVaR(port, sd, MC.paths, MC.horizon, MC.confidence))};

  // 118 · leakage-free scaling
  const train = port.slice(0, 15), test = port.slice(15), fit = fitScaler(train), leaky = fitScaler(port);
  const scaling = {train: train.length, test: test.length, fit, leaky, testScaled: transform(test, fit), testLeaky: transform(test, leaky)};

  // 119 · fixtures, tolerances and properties
  const x = [1, 2, 3, 4, 5], v = (a: number[]) => welford(a).m2 / (a.length - 1);
  const prod2 = productionReport(feed(2));
  const tests = [
    {name: "fixture: variance [1..5] = 2.5", pass: near(v(x), 2.5)},
    {name: "0.1 + 0.2 ≈ 0.3 within tolerance", pass: near(0.1 + 0.2, 0.3)},
    {name: "property: shift leaves variance unchanged", pass: near(v(x.map(q => q + 100)), v(x))},
    {name: "property: doubling multiplies variance by 4", pass: near(v(x.map(q => 2 * q)), 4 * v(x))},
    {name: "streaming SD ≈ batch SD", pass: near(streaming, batch)},
    {name: "rolling window ≈ batch on last 5 days", pass: near(rollLast, batchLast)},
    {name: "seed 42 replays the simulation exactly", pass: mc.replay[0] === mc.replay[1]},
    {name: "shuffled feed gives identical results", pass: canonical(prod1) === canonical(prod2)},
  ];

  // 120 · run twice, compare checksums
  const naive1 = naiveReport(feed(1), 1), naive2 = naiveReport(feed(2), 2);
  const a1 = audit(prod1), a2 = audit(prod2), n1 = audit(naive1), n2 = audit(naive2);
  const naiveSameSeed = [audit({...naive1, mcVar95: 0}).checksum, audit({...naive2, mcVar95: 0}).checksum];
  return {
    series: port, floats, variance, policy, alignment, mc, scaling, tests, passed: tests.filter(t => t.pass).length,
    report: prod1, naive: [naive1, naive2],
    audit: {production: [a1.checksum, a2.checksum], naive: [n1.checksum, n2.checksum], naiveWithoutSimulation: naiveSameSeed, bytes: a1.bytes, preview: a1.text.slice(0, 290)},
  };
}

export const checkedResult = {"series":[0.0019999999999999996,-0.00020000000000000017,0.0027999999999999995,-0.00039999999999999926,0.0018,0.0006,0.0025999999999999994,-0.00020000000000000017,0.0024,0.0003999999999999998,0.0044,-0.0076,-0.0068000000000000005,0.005600000000000001,-0.008600000000000002,0.0034000000000000002,-0.006599999999999999,0.0054,-0.005600000000000001,0.008600000000000002],"floats":{"sum":0.30000000000000004,"exactlyPointThree":false,"overflow":"Infinity","underflow":0,"epsilon":2.220446049250313e-16,"dimesNaive":0.9999999999999999,"dimesStable":1,"orderNaive":[0.004000000000000001,0.003999999999999999],"orderStable":[0.004,0.004]},"variance":{"balances":[1000000004,1000000007,1000000013,1000000016],"textbook":-170.66666666666666,"welford":30,"steps":[{"count":1,"mean":1000000004,"m2":0},{"count":2,"mean":1000000005.5,"m2":4.5},{"count":3,"mean":1000000008,"m2":42},{"count":4,"mean":1000000010,"m2":90}],"batch":0.0048440957007365925,"streaming":0.0048440957007365925,"rolling":[null,null,null,null,0.0014212670403551892,0.0013608820668963198,0.0013608820668963195,0.0012930583900195689,0.0012033287165193057,0.001260158720161869,0.0018471599822430108,0.00455543631280254,0.005452338947644396,0.006157921727336261,0.0069799713466460606,0.006739436178197699,0.006574191965557441,0.006882441427284362,0.0063403469936589435,0.0067858676674394415],"rollingLast":0.0067858676674394415,"batchLast":0.0067858676674394415,"maxGap":0},"policy":[{"day":21,"id":"A","raw":"null","status":"missing","naive":"0"},{"day":21,"id":"B","raw":"NaN","status":"invalid","naive":"0"},{"day":22,"id":"A","raw":"Infinity","status":"invalid","naive":"Infinity"},{"day":22,"id":"B","raw":"\"0.003\"","status":"unsupported","naive":"0.003"}],"alignment":{"weights":[{"id":"A","w":0.6},{"id":"B","w":0.4}],"day1":[{"id":"B","r":-0.004},{"id":"A","r":0.006}],"positional":4.336808689942018e-19,"aligned":0.002,"missing":"Missing asset B"},"mc":{"paths":2000,"horizon":10,"confidence":0.95,"seed":42,"draws":[0.2523451747838408,0.08812504541128874,0.5772811982315034],"replay":[0.02288091697116998,0.02288091697116998],"otherSeeds":[0.0235096580423508,0.022490264485876904]},"scaling":{"train":15,"test":5,"fit":{"mean":-0.0000800000000000001,"sd":0.00428405682235225},"leaky":{"mean":0.0002000000000000001,"sd":0.0048440957007365925},"testScaled":[0.8123141555553024,-1.5219219236266006,1.2791613713916832,-1.2884983157084107,2.0261169167298925],"testLeaky":[0.6605980140965028,-1.403770779955068,1.073471772906817,-1.1973339005499115,1.73406978700332]},"tests":[{"name":"fixture: variance [1..5] = 2.5","pass":true},{"name":"0.1 + 0.2 ≈ 0.3 within tolerance","pass":true},{"name":"property: shift leaves variance unchanged","pass":true},{"name":"property: doubling multiplies variance by 4","pass":true},{"name":"streaming SD ≈ batch SD","pass":true},{"name":"rolling window ≈ batch on last 5 days","pass":true},{"name":"seed 42 replays the simulation exactly","pass":true},{"name":"shuffled feed gives identical results","pass":true}],"passed":8,"report":{"rejected":4,"days":20,"meanDaily":0.0002,"sdDaily":0.004844095700736592,"annualVol":0.07689763530687711,"maxDrawdown":-0.020744781492684217,"var90":0.0068800000000000016,"es90":0.0081,"mcVar95":0.02288091697116998},"naive":[{"rejected":0,"days":21,"meanDaily":0.00012380952380952365,"sdDaily":0.004665394384390752,"annualVol":0.07406083985481127,"maxDrawdown":-0.012361920000000026,"var90":0.0068000000000000005,"es90":0.0076,"mcVar95":0.02384626501528193},{"rejected":0,"days":21,"meanDaily":0.000019047619047619036,"sdDaily":0.00464667828105401,"annualVol":0.07376373092516404,"maxDrawdown":-0.021872247459054694,"var90":0.0068000000000000005,"es90":0.0076,"mcVar95":0.023645018842607172}],"audit":{"production":["e45c2a42","e45c2a42"],"naive":["fb4c38e3","bded2195"],"naiveWithoutSimulation":["a05d8d06","6b4b7085"],"bytes":511,"preview":"{\"cutoff\":\"day-20\",\"dataset\":\"synthetic-two-fund-20d\",\"method\":\"sample-sd, type7-var90, es90, bootstrap-var95-10d\",\"params\":{\"annualization\":252,\"confidence\":0.9,\"mc\":{\"confidence\":0.95,\"horizon\":10,\"paths\":2000,\"seed\":42},\"weights\":{\"A\":0.6,\"B\":0.4}},\"results\":{\"annualVol\":0.0768976353068"}};

// Run this file directly: npx tsx lessons/12-statistical-computing-and-reproducibility/demo-production-metrics-service.ts
if (process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/\\/g, "/").split("/").pop()!)) {
  console.log(JSON.stringify(runDemo(), null, 2));
}

Your output

Press Run to execute the code in your browser.

Expected output

{
  "series": [
    0.0019999999999999996,
    -0.00020000000000000017,
    0.0027999999999999995,
    -0.00039999999999999926,
    0.0018,
    0.0006,
    0.0025999999999999994,
    -0.00020000000000000017,
    0.0024,
    0.0003999999999999998,
    0.0044,
    -0.0076,
    -0.0068000000000000005,
    0.005600000000000001,
    -0.008600000000000002,
    0.0034000000000000002,
    -0.006599999999999999,
    0.0054,
    -0.005600000000000001,
    0.008600000000000002
  ],
  "floats": {
    "sum": 0.30000000000000004,
    "exactlyPointThree": false,
    "overflow": "Infinity",
    "underflow": 0,
    "epsilon": 2.220446049250313e-16,
    "dimesNaive": 0.9999999999999999,
    "dimesStable": 1,
    "orderNaive": [
      0.004000000000000001,
      0.003999999999999999
    ],
    "orderStable": [
      0.004,
      0.004
    ]
  },
  "variance": {
    "balances": [
      1000000004,
      1000000007,
      1000000013,
      1000000016
    ],
    "textbook": -170.66666666666666,
    "welford": 30,
    "steps": [
      {
        "count": 1,
        "mean": 1000000004,
        "m2": 0
      },
      {
        "count": 2,
        "mean": 1000000005.5,
        "m2": 4.5
      },
      {
        "count": 3,
        "mean": 1000000008,
        "m2": 42
      },
      {
        "count": 4,
        "mean": 1000000010,
        "m2": 90
      }
    ],
    "batch": 0.0048440957007365925,
    "streaming": 0.0048440957007365925,
    "rolling": [
      null,
      null,
      null,
      null,
      0.0014212670403551892,
      0.0013608820668963198,
      0.0013608820668963195,
      0.0012930583900195689,
      0.0012033287165193057,
      0.001260158720161869,
      0.0018471599822430108,
      0.00455543631280254,
      0.005452338947644396,
      0.006157921727336261,
      0.0069799713466460606,
      0.006739436178197699,
      0.006574191965557441,
      0.006882441427284362,
      0.0063403469936589435,
      0.0067858676674394415
    ],
    "rollingLast": 0.0067858676674394415,
    "batchLast": 0.0067858676674394415,
    "maxGap": 0
  },
  "policy": [
    {
      "day": 21,
      "id": "A",
      "raw": "null",
      "status": "missing",
      "naive": "0"
    },
    {
      "day": 21,
      "id": "B",
      "raw": "NaN",
      "status": "invalid",
      "naive": "0"
    },
    {
      "day": 22,
      "id": "A",
      "raw": "Infinity",
      "status": "invalid",
      "naive": "Infinity"
    },
    {
      "day": 22,
      "id": "B",
      "raw": "\"0.003\"",
      "status": "unsupported",
      "naive": "0.003"
    }
  ],
  "alignment": {
    "weights": [
      {
        "id": "A",
        "w": 0.6
      },
      {
        "id": "B",
        "w": 0.4
      }
    ],
    "day1": [
      {
        "id": "B",
        "r": -0.004
      },
      {
        "id": "A",
        "r": 0.006
      }
    ],
    "positional": 4.336808689942018e-19,
    "aligned": 0.002,
    "missing": "Missing asset B"
  },
  "mc": {
    "paths": 2000,
    "horizon": 10,
    "confidence": 0.95,
    "seed": 42,
    "draws": [
      0.2523451747838408,
      0.08812504541128874,
      0.5772811982315034
    ],
    "replay": [
      0.02288091697116998,
      0.02288091697116998
    ],
    "otherSeeds": [
      0.0235096580423508,
      0.022490264485876904
    ]
  },
  "scaling": {
    "train": 15,
    "test": 5,
    "fit": {
      "mean": -0.0000800000000000001,
      "sd": 0.00428405682235225
    },
    "leaky": {
      "mean": 0.0002000000000000001,
      "sd": 0.0048440957007365925
    },
    "testScaled": [
      0.8123141555553024,
      -1.5219219236266006,
      1.2791613713916832,
      -1.2884983157084107,
      2.0261169167298925
    ],
    "testLeaky": [
      0.6605980140965028,
      -1.403770779955068,
      1.073471772906817,
      -1.1973339005499115,
      1.73406978700332
    ]
  },
  "tests": [
    {
      "name": "fixture: variance [1..5] = 2.5",
      "pass": true
    },
    {
      "name": "0.1 + 0.2 ≈ 0.3 within tolerance",
      "pass": true
    },
    {
      "name": "property: shift leaves variance unchanged",
      "pass": true
    },
    {
      "name": "property: doubling multiplies variance by 4",
      "pass": true
    },
    {
      "name": "streaming SD ≈ batch SD",
      "pass": true
    },
    {
      "name": "rolling window ≈ batch on last 5 days",
      "pass": true
    },
    {
      "name": "seed 42 replays the simulation exactly",
      "pass": true
    },
    {
      "name": "shuffled feed gives identical results",
      "pass": true
    }
  ],
  "passed": 8,
  "report": {
    "rejected": 4,
    "days": 20,
    "meanDaily": 0.0002,
    "sdDaily": 0.004844095700736592,
    "annualVol": 0.07689763530687711,
    "maxDrawdown": -0.020744781492684217,
    "var90": 0.0068800000000000016,
    "es90": 0.0081,
    "mcVar95": 0.02288091697116998
  },
  "naive": [
    {
      "rejected": 0,
      "days": 21,
      "meanDaily": 0.00012380952380952365,
      "sdDaily": 0.004665394384390752,
      "annualVol": 0.07406083985481127,
      "maxDrawdown": -0.012361920000000026,
      "var90": 0.0068000000000000005,
      "es90": 0.0076,
      "mcVar95": 0.02384626501528193
    },
    {
      "rejected": 0,
      "days": 21,
      "meanDaily": 0.000019047619047619036,
      "sdDaily": 0.00464667828105401,
      "annualVol": 0.07376373092516404,
      "maxDrawdown": -0.021872247459054694,
      "var90": 0.0068000000000000005,
      "es90": 0.0076,
      "mcVar95": 0.023645018842607172
    }
  ],
  "audit": {
    "production": [
      "e45c2a42",
      "e45c2a42"
    ],
    "naive": [
      "fb4c38e3",
      "bded2195"
    ],
    "naiveWithoutSimulation": [
      "a05d8d06",
      "6b4b7085"
    ],
    "bytes": 511,
    "preview": "{\"cutoff\":\"day-20\",\"dataset\":\"synthetic-two-fund-20d\",\"method\":\"sample-sd, type7-var90, es90, bootstrap-var95-10d\",\"params\":{\"annualization\":252,\"confidence\":0.9,\"mc\":{\"confidence\":0.95,\"horizon\":10,\"paths\":2000,\"seed\":42},\"weights\":{\"A\":0.6,\"B\":0.4}},\"results\":{\"annualVol\":0.0768976353068"
  }
}

Prefer your own machine? Every file is in the course repository · open it in Codespaces.

What the demo does

The Module 11 risk report rebuilt as a service that gives the same answer every run: stable sums, Welford variance, an explicit input policy, ID alignment, a seeded Monte Carlo, a leakage-free scaler, tolerance and property tests, and an audit record whose FNV-1a checksum matches across runs while a naive version drifts.