Quantitative Volatility Models

Quantitative volatility models are crucial tools in financial engineering and quantitative finance. These models aim to forecast and understand the volatility of asset prices, which is a key factor in trading strategies, risk management, option pricing, and other financial activities. This comprehensive guide covers the different types of volatility models, their uses, and their implications.

Types of Volatility Models

  1. Historical Volatility Models:
    • These models calculate volatility based on historical price data. Common methods include calculating the standard deviation or variance of past returns over a given time period.
 [import](../i/import.html) numpy as np

 def historical_volatility(prices):
 returns = np.diff(np.log(prices))
 [return](../r/return.html) np.std(returns) * np.sqrt(252)
  1. Implied Volatility Models:
 from scipy.optimize [import](../i/import.html) brentq
 from scipy.stats [import](../i/import.html) norm
 [import](../i/import.html) numpy as np

 def black_scholes_call(S, K, T, r, sigma):
 d1 = (np.log(S / K) + (r + 0.5 * sigma ** 0.2) * T) / (sigma * np.sqrt(T))
 d2 = d1 - sigma * np.sqrt(T)
 call = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
 [return](../r/return.html) call

 def implied_volatility(S, K, T, r, market_price):
 objective_function = [lambda](../l/lambda.html) sigma: black_scholes_call(S, K, T, r, sigma) - market_price
 [return](../r/return.html) brentq(objective_function, 0.01, 2)
  1. ARCH and GARCH Models:
 from arch [import](../i/import.html) arch_model

 def arch_garch_model(returns):
 model = arch_model(returns, vol='Garch', p=1, q=1)
 model_fitted = model.fit(disp='off')
 [return](../r/return.html) model_fitted.forecast(horizon=1).variance[-1:]
  1. Stochastic Volatility Models:
    • These models assume that volatility follows a stochastic process. The Heston model is a well-known example, modeling volatility with a mean-reverting square-root process.
 [import](../i/import.html) numpy as np

 def heston_model(S, K, T, r, v0, [kappa](../k/kappa.html), [theta](../t/theta.html), sigma, [rho](../r/rho.html)):
 dt = T / 100
 V = v0
 S_t = S

 for _ in [range](../r/range.html)(100):
 S_t = S_t * (1 + r * dt + np.sqrt(V * dt) * np.random.normal())
 V = V + [kappa](../k/kappa.html) * ([theta](../t/theta.html) - V) * dt + sigma * np.sqrt(V * dt) * np.random.normal()

 [return](../r/return.html) np.maximum(S_t - K, 0)
  1. EGARCH Models:
    • The Exponential GARCH (EGARCH) model allows for asymmetric effects of positive and negative shocks on volatility, often capturing leverage effects better than symmetric models.
 from arch [import](../i/import.html) arch_model

 def egarch_model(returns):
 model = arch_model(returns, vol='EGARCH', p=1, o=1, q=1)
 model_fitted = model.fit(disp='off')
 [return](../r/return.html) model_fitted.forecast(horizon=1).variance[-1:]
  1. Stochastic Differential Equations (SDEs):
    • SDEs can model the dynamics of asset prices and volatilities. The Cox-Ingersoll-Ross (CIR) model is a famous example for interest rates, often adapted for volatility.
 [import](../i/import.html) numpy as np

 def cir_model(r0, [kappa](../k/kappa.html), [theta](../t/theta.html), sigma, T, dt=0.01):
 n = int(T / dt)
 rates = np.zeros(n)
 rates[0] = r0
 for i in [range](../r/range.html)(1, n):
 r = rates[i-1]
 dr = [kappa](../k/kappa.html) * ([theta](../t/theta.html) - r) * dt + sigma * np.sqrt(r * dt) * np.random.normal()
 rates[i] = r + dr
 [return](../r/return.html) rates

Applications of Volatility Models

  1. Risk Management:
 def value_at_risk(returns, confidence_level=0.95):
 [return](../r/return.html) np.percentile(returns, 100 * (1 - confidence_level))
  1. Option Pricing:
    • Volatility is a key input in pricing options. Models like Black-Scholes rely on either historical or implied volatility to determine theoretical option prices.
 def black_scholes_option(S, K, T, r, sigma, option_type='call'):
 d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
 d2 = d1 - sigma * np.sqrt(T)
 if option_type == 'call':
 option_price = S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)
 elif option_type == 'put':
 option_price = K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)
 [return](../r/return.html) option_price
  1. Portfolio Management:
 [import](../i/import.html) numpy as np
 from scipy.optimize [import](../i/import.html) minimize

 def portfolio_volatility(weights, cov_matrix):
 [return](../r/return.html) np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))

 def minimize_volatility(cov_matrix):
 n_assets = cov_matrix.shape[0]
 initial_weights = np.ones(n_assets) / n_assets
 bounds = [(0, 1) for _ in [range](../r/range.html)(n_assets)]
 constraints = ({'type': 'eq', 'fun': [lambda](../l/lambda.html) x: np.sum(x) - 1})
 result = minimize(portfolio_volatility, initial_weights, args=(cov_matrix,), bounds=bounds, constraints=constraints)
 [return](../r/return.html) result.x
  1. Algorithmic Trading:
 def trading_signal(hist_vol, threshold):
 if hist_vol > threshold:
 [return](../r/return.html) 'Sell'
 else:
 [return](../r/return.html) 'Buy'

Key Companies and Resources

Overall, quantitative volatility models form the backbone of modern financial engineering, providing actionable insights and enhancing decision-making across risk management, option pricing, portfolio management, and algorithmic trading.