# 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, 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, and GitHub Actions.

## License

MIT — see [`LICENSE`](LICENSE).
