This project implements a dynamic option replication strategy based on delta-hedging.
The goal is to synthesize the payoff of a European call by building a self-financing portfolio of the risky asset and a risk-free cash account, rebalanced daily according to the Black-Scholes sensitivities.
Methodological note: in this educational setting, some curves use the realized volatility as input. This isolates the hedging error due to time discretization by neutralizing the noise coming from volatility estimation.
-
Demonstrate replication: show that a portfolio
$\Delta S + B$ tracks the option price. - Cash management: visualize the funding flows (leverage) required to hold the position.
- Volatility analysis: compare the impact of different estimators on the hedge.
The call price and its delta (
where:
$d_1 = \frac{\ln(S_t/K) + (r + \sigma^2/2)\tau}{\sigma\sqrt{\tau}}$ $d_2 = d_1 - \sigma\sqrt{\tau}$
The same self-financing rule is applied at every step, including the last one:
- Accrue interest on the cash account:
$B_i \leftarrow B_{i-1} e^{r,dt}$ - Rebalance to the new delta, funded from cash:
$B_i \leftarrow B_i - (\Delta_i - \Delta_{i-1}) S_i$ - Mark the portfolio:
$V_i = \Delta_i S_i + B_i$
There is no special-cased liquidation at maturity. As
-
Fixed volatility: chosen manually (
$\sigma = 18%$ ) - Log-returns volatility: annualized standard deviation of historical log returns
- Garman-Klass volatility: OHLC-based estimator
- Call price by volatility
- Delta by volatility
- Cash account evolution
- Replicating portfolio vs theoretical call price (one figure per volatility)
numpy
scipy
yfinance
matplotlib
pip install numpy scipy yfinance matplotlibThe script pulls real NVIDIA (NVDA) daily data over the last three months. If the download fails (no network or yfinance not installed), it falls back to a simulated geometric Brownian path so the script stays runnable offline.
python plot_hedging.pySet at the top of plot_hedging.py:
TICKER: ticker symbol (default"NVDA")PERIOD: history window (default"3mo")RATE: annual risk-free rate (default0.04)SIGMA_FIXED: chosen annual volatility (default0.18)
The strike defaults to the initial price
black_scholes.py # closed-form call price and delta (pure functions)
volatility.py # realized log-returns and Garman-Klass estimators
hedging.py # DeltaHedger class + HedgingResult dataclass
plot_hedging.py # data loading, replication run, plots
tests/
test_hedging.py
pip install pytest ruff
pytest -q
ruff check .The suite covers the closed-form Black-Scholes value, the delta bounds and monotonicity, the volatility estimators (zero on flat prices, recovery of a known GBM sigma), and the core replication property: with fine rebalancing and the true volatility, the terminal portfolio value tracks the option payoff.
Educational project illustrating hedging mechanics, the Black-Scholes theory in practice, and the impact of volatility on replication. Not investment advice.
Alexandre R. - Université Paris Cité