Files
ps e5d785f511 Polish web demo tests and refresh notebooks
- add README live-demo badge
- tighten engine validation for jump grids and detector indices
- replace flaky FastAPI TestClient web tests with direct handler tests
- remove unused httpx dev dependency
- clean stale frontend comments
- re-execute notebooks with clean sequential outputs
2026-08-03 08:15:22 -04:00

207 lines
11 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Adaptive Barrier Monitor</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap">
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
<script src="https://cdn.plot.ly/plotly-3.0.1.min.js"></script>
<link rel="stylesheet" href="/static/app.css?v=1" />
</head>
<body>
<header class="site-header">
<div>
<p class="eyebrow">Adaptive Barrier Monitor</p>
<h1>State-dependent sampling near price barriers</h1>
<p>Monte Carlo demo comparing adaptive sampling with equal-budget and fixed-cadence baselines.</p>
</div>
<div id="health" class="health">Loading…</div>
</header>
<main class="layout">
<!-- Left column, row 1: interactive controls. -->
<section class="controls" id="col-top">
<div class="card collapsible" id="card-simulation">
<h2>Simulation parameters</h2>
<label>Comparison mode
<select id="mc-comparison-mode">
<option value="equal_budget">Equal budget</option>
<option value="fixed_cadence">Fixed cadence</option>
</select>
<span class="field-help">Equal budget isolates sample placement. Fixed cadence compares detection and observation cost against an independently chosen interval.</span>
</label>
<label id="mc-fixed-cadence-row" hidden>Fixed cadence (minutes)
<input id="mc-fixed-cadence" type="number" min="0.1" max="39000" step="0.1" value="60" />
<span class="field-help">The fixed monitor samples at this interval, plus the start and end of the window. Smaller values use more observations.</span>
</label>
<label>Annual volatility (σ)
<div class="range-row">
<input id="mc-sigma" type="range" min="0.05" max="1.0" step="0.01" value="0.30" />
<input id="mc-sigma-val" type="number" min="0.05" max="1.0" step="0.01" value="0.30" />
</div>
<span class="field-help">Annualised volatility. Higher values produce wider price swings and more barrier events.</span>
</label>
<label>Annual drift (μ)
<input id="mc-mu" type="number" min="-0.5" max="0.5" step="0.01" value="0.07" />
<span class="field-help">Average annual return. Positive values tilt paths upward; negative values push them toward the lower barrier.</span>
</label>
<label>Window (minutes)
<input id="mc-window" type="number" min="5" max="39000" step="5" value="1950" />
<span class="field-help">1950 minutes is about five trading days. Longer windows tend to produce more events.</span>
</label>
<label>Number of paths
<input id="mc-paths" type="number" min="1" max="100" step="1" value="20" />
<span class="field-help">More paths give steadier aggregate results but take longer to render.</span>
</label>
<label>Steps per path
<input id="mc-steps" type="number" min="50" max="2000" step="10" value="500" />
<span class="field-help">The fine simulation grid used as the reference history. More steps resolve shorter-lived crossings.</span>
</label>
<label>Drop threshold (%)
<input id="mc-threshold" type="number" min="0.1" max="50" step="0.1" value="5" />
<span class="field-help">Percentage decline from the initial price that defines a lower-barrier event.</span>
</label>
<label>Rise threshold (%)
<input id="mc-rise-threshold" type="number" min="0.1" max="50" step="0.1" value="10" />
<span class="field-help">Percentage increase from the initial price that defines an upper-barrier event.</span>
</label>
<label>Miss budget (ε)
<div class="range-row">
<input id="mc-eps" type="range" min="1e-6" max="0.1" step="1e-6" value="0.001" />
<input id="mc-eps-val" type="number" min="1e-6" max="0.1" step="0.0001" value="0.001" />
</div>
<span class="field-help">Local diffusion-model design parameter. Lower ε produces denser adaptive sampling; it is not a global guarantee and does not cover jumps.</span>
</label>
<label>Max interval cap (minutes)
<input id="mc-dtcap" type="number" min="1" max="1440" step="1" placeholder="auto" />
<span class="field-help">Leave empty for an automatic cap of window/15. Lower values force denser sampling everywhere.</span>
</label>
<label>Detection deadline (grid steps)
<input id="mc-max-lag" type="number" min="0" max="100" step="1" value="3" />
<span class="field-help">An event counts as detected only if a sample still lies beyond the barrier within this many reference-grid steps.</span>
</label>
<label>RNG seed
<input id="mc-seed" type="number" min="0" max="100000" step="1" placeholder="random" />
<span class="field-help">Leave empty for a new run, or enter a seed to reproduce and share the same paths.</span>
</label>
<label>
<span class="checkbox-label">
<input id="mc-jumps" type="checkbox" /> Include jumps (Merton jump-diffusion)
</span>
<span class="field-help">Adds sudden moves that the diffusion-derived schedule cannot anticipate. Treat this as a model-risk stress test.</span>
</label>
<button id="mc-run-btn">Run simulation</button>
</div>
</section>
<!-- Right column: results and simulated paths. -->
<section class="viewer" id="col-viewer">
<div class="result-card">
<div class="result-header">
<h2 id="result-title">Monte Carlo Sandbox</h2>
<p id="result-subtitle">Running…</p>
</div>
<div class="headline">
<div class="tile">
<span class="tile-num" id="hl-adaptive"></span>
<span class="tile-lab">events detected — adaptive</span>
<span class="tile-sub" id="hl-adaptive-sub">↓ lower · ↑ upper</span>
</div>
<div class="tile">
<span class="tile-num" id="hl-fixed"></span>
<span class="tile-lab">events detected — fixed</span>
<span class="tile-sub" id="hl-fixed-sub">↓ lower · ↑ upper</span>
</div>
<div class="tile">
<span class="tile-num" id="hl-samples"></span>
<span class="tile-lab">total samples</span>
<span class="tile-sub" id="hl-samples-sub">matched path by path</span>
</div>
<div class="tile">
<span class="tile-num" id="hl-lag"></span>
<span class="tile-lab">mean detection lag</span>
<span class="tile-sub">adaptive vs fixed · detected events only</span>
</div>
</div>
<p class="result-note" id="comparison-note">
The adaptive and fixed monitors receive the <strong>same number of samples on every path</strong>.
The experiment therefore compares sample placement—not computational cost.
</p>
<div id="warning-box" class="warning-box" hidden></div>
<div id="chart-stage" class="chart-stage">
<div style="padding:3rem; text-align:center; color:var(--muted)">Running simulation…</div>
</div>
<details class="advanced-opts method-note" open>
<summary>How the Monte Carlo comparison works</summary>
<ol>
<li><strong>Simulate:</strong> generate independent GBM or Merton jump-diffusion price paths on a fine grid.</li>
<li><strong>Mark events:</strong> record each path's first lower- and upper-barrier crossing.</li>
<li id="allocation-method"><strong>Allocate samples:</strong> adaptive intervals shrink near the closest barrier; the fixed monitor receives the same sample count, spaced uniformly.</li>
<li><strong>Score:</strong> an event is detected when a sampled price remains beyond the barrier within the selected deadline.</li>
</ol>
<p>
<span id="method-conclusion">The headline compares detections and mean lag under an equal sample budget.</span>
The miss budget <strong>ε</strong> is a local diffusion-model design parameter, not a global guarantee.
</p>
</details>
<details class="json-block">
<summary>Raw result JSON</summary>
<pre id="stats-json">{}</pre>
</details>
</div>
</section>
<!-- Left column, row 2: supporting information. -->
<section class="controls" id="col-info">
<div class="card explain">
<h2>How to read it</h2>
<dl>
<dt>Open cyan circles</dt>
<dd>Adaptive observations. The interval shrinks quadratically as the log-price approaches the nearer barrier.</dd>
<dt>Grey dots</dt>
<dd id="fixed-explanation">An equal-budget fixed sampler with the same number of observations on each path, spaced uniformly.</dd>
<dt>Red × and green ▲</dt>
<dd>The first lower- and upper-barrier events on the fine reference grid.</dd>
<dt>Headline</dt>
<dd id="headline-explanation">Same paths and the same sample budget. Compare how many events each schedule confirms before the deadline.</dd>
</dl>
</div>
<div class="card note">
<h2>Research demo caveat</h2>
<p>The adaptive law is derived from a continuous diffusion model. Discrete grids, estimated volatility, latency, and jumps weaken any literal miss-probability guarantee.</p>
</div>
<div class="card explain">
<h2>How this works</h2>
<p>The app simulates price paths, marks first barrier crossings, and compares two observation schedules on exactly the same paths.</p>
<p>Adaptive intervals use a Brownian-bridge proxy and shrink with squared distance to the nearest barrier. Fixed observations are either equal-budget or independently spaced at a chosen cadence.</p>
</div>
<div class="card note">
<h2>Links</h2>
<ul class="link-list">
<li><a href="https://pawelsarkowicz.xyz" target="_blank" rel="noreferrer">pawelsarkowicz.xyz</a></li>
<li><a href="https://github.com/psark007/adaptive-barrier-monitor" target="_blank" rel="noreferrer">Adaptive Barrier Monitor repo</a></li>
<li><a href="https://github.com/psark007/adaptive-barrier-monitor/blob/main/LICENSE" target="_blank" rel="noreferrer">License</a></li>
</ul>
</div>
</section>
</main>
<footer class="site-footer">
<span>© Pawel Sarkowicz</span>
</footer>
<script src="/static/app.js?v=1"></script>
</body>
</html>