# Adaptive Barrier Monitor [![Live Demo](https://img.shields.io/badge/demo-webapp-teal)](https://abm.pawelsarkowicz.xyz) A five-notebook quantitative-finance project connecting random walks, Brownian motion, geometric Brownian motion, first-passage times, Brownian bridges, and state-dependent monitoring. The motivating question is: > A stock is monitored for a large move over a short window. Continuous polling > is expensive. What probability model describes a hidden barrier crossing, and > how can that model inform a sampling schedule? The project is written for a mathematically mature reader who wants to see how Gaussian processes, conditioning, stochastic calculus, and Monte Carlo methods appear in a practical monitoring problem. ## Core results and scope Under geometric Brownian motion, $$ \frac{dS_t}{S_t}=\mu dt+\sigma dW_t, $$ the relative log-price $X_t=\log(S_t/S_0)$ is arithmetic Brownian motion. A 10% drop corresponds to the lower log barrier $B=\log(0.9)$. For zero drift, the probability of touching the barrier by time $T$ is $$ P(\tau_B\leq T)=2\Phi\left(\frac{B}{\sigma\sqrt{T}}\right). $$ At 30% annualised volatility, a 10% move in five trading minutes is roughly a 49-standard-deviation diffusion event. Pure GBM therefore assigns it probability below ordinary floating-point resolution; jumps and market microstructure are essential for realistic extreme-move modelling. Conditional on two observations $x_0,x_T>B$, the Brownian-bridge probability that the hidden path crossed the barrier is $$ P_{\mathrm{cross}} =\exp\left( -\frac{2(x_0-B)(x_T-B)}{\sigma^2\Delta t} \right). $$ If both endpoint distances are set equal to $D$, inversion gives $$ \Delta t_{\mathrm{sym}} =\frac{2D^2}{\sigma^2\log(1/\varepsilon)}. $$ This inversion is exact **conditional on both endpoints being known**. In a live scheduler, the future endpoint is unknown; the implementation substitutes the current distance for both endpoints. Thus $\varepsilon$ is a local diffusion-design parameter, not an unconditional miss guarantee, and it does not control jumps. A hard maximum polling interval remains necessary. ## Notebooks | # | Notebook | Main topics | |---|---|---| | 01 | [Random walks to Brownian motion](notebooks/01_random_walks_to_brownian_motion.ipynb) | Log returns, the $\min(s,t)$ covariance kernel, Cholesky sampling, Brownian scaling | | 02 | [GBM and Itô's lemma](notebooks/02_geometric_brownian_motion_and_ito.ipynb) | Multiplicative prices, exact GBM simulation, Itô correction | | 03 | [First passage and reflection](notebooks/03_first_passage_and_reflection_principle.ipynb) | Reflection principle, Bachelier–Lévy formula, hitting-time diagnostics | | 04 | [Brownian bridges and hidden crossings](notebooks/04_brownian_bridges_and_miss_probability.ipynb) | Gaussian conditioning, Schur complements, bridge crossing probabilities | | 05 | [Adaptive barrier monitoring](notebooks/05_adaptive_barrier_monitor.ipynb) | Unit-consistent scheduler, practical polling cap, controlled jump stress test, model-risk discussion | The analytical formulae are checked against Monte Carlo simulation in the notebooks. ## Interactive web application The FastAPI/Plotly demo compares two sampling schedules on the **same simulated paths**. The adaptive schedule uses the local symmetric-endpoint bridge proxy, while the fixed baseline can run in either of two modes: - **Equal budget:** the fixed schedule receives exactly the adaptive schedule's sample count on each path, isolating where observations are placed. - **Fixed cadence:** the fixed schedule samples at a user-selected interval, so detection quality, lag, and total observation cost can be compared directly. A barrier event counts as detected only if a sampled point remains beyond the barrier within a configurable number of simulation steps. The comparison is therefore explicit and reproducible rather than based on an unrestricted "eventually detected" definition. The demo supports GBM and an optional Merton jump-diffusion stress mode. When jumps are enabled, the interface explicitly warns that the Brownian diffusion parameter $\varepsilon$ does not bound jump-event misses. ### Run locally ```bash python -m venv .venv source .venv/bin/activate python -m pip install -e ".[webapp]" python -m uvicorn webapp.app:app --host 127.0.0.1 --port 8055 ``` Open `http://127.0.0.1:8055`. ### Docker ```bash docker compose -f docker-compose.webapp.yml up --build ``` For an existing Caddy Docker network: ```bash docker compose -f docker-compose.webapp.proxy.yml up --build -d ``` The container runs as a non-root user and includes an HTTP health check. ## Run the notebooks ```bash python -m venv .venv source .venv/bin/activate pip install -e ".[notebooks]" jupyter lab notebooks/ ``` Notebooks that request market data cache successful downloads under `data/cache/`. Their analytical and simulation sections remain usable when the network fetch is unavailable. ## Tests ```bash pip install -e ".[dev,webapp]" pytest ``` The test suite covers: - inversion of the Brownian-bridge formula; - vectorised interval calculations and input validation; - consistent time/volatility units in the adaptive schedule; - enforcement of the detection deadline; - exact per-path sample-budget equality; - equivalence of zero-intensity jump diffusion and GBM; - aggregate simulation invariants. ## Project structure ```text adaptive-barrier-monitor/ ├── notebooks/ # five executed research notebooks ├── src/adaptive_barrier/ │ ├── __init__.py │ └── engine.py # samplers, closed forms, scheduler, evaluation ├── tests/ │ └── test_engine.py ├── webapp/ │ ├── app.py # FastAPI API │ ├── Dockerfile │ └── static/ # vanilla JS, Plotly, CSS ├── .github/workflows/tests.yml ├── pyproject.toml ├── requirements.txt ├── requirements-webapp.txt ├── requirements-dev.txt ├── bibliography.md ├── LICENSE └── webapp.md ``` ## Model limitations - **Online endpoint uncertainty:** the bridge crossing formula is conditional on both endpoints; the scheduler uses a local approximation before the next endpoint exists. - **Jump risk:** diffusion-derived polling cannot guarantee detection of sudden jump-and-recovery events. - **No market microstructure model:** bid–ask bounce, asynchronous feeds, exchange halts, queueing, and packet latency are not represented. - **Simulation-grid dependence:** the web demo's detection deadline is measured in simulated grid steps; changing `n_steps` changes its physical duration. - **Educational calibration:** jump parameters in the sandbox are user-controlled stress parameters, not production estimates. ## Tech stack Python, NumPy, SciPy, pandas, SymPy, Matplotlib, FastAPI, Pydantic, Uvicorn, Plotly.js, Docker, pytest. ## License MIT — see [`LICENSE`](LICENSE).