Files
Adaptive-Barrier-Monitor/README.md
T
2026-07-31 17:05:14 -04:00

196 lines
6.8 KiB
Markdown
Raw 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.
# Adaptive Barrier Monitor
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, BachelierLé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:** bidask 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, and GitHub Actions.
## License
MIT — see [`LICENSE`](LICENSE).