Skip to content

Commit

Permalink
BSM Greeks: theta, rho, phi, zeta, strike-delta, strike-gamma.
Browse files Browse the repository at this point in the history
  • Loading branch information
avhz committed Sep 18, 2023
1 parent 43758ac commit 0019788
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## 17 September 2023

- @avhz: More Greeks for BSM model: theta, rho, phi, zeta, strike-delta, strike-gamma.

## 17 September 2023

- @avhz: More Greeks for BSM model: vega, vomma, ultima, vega bleed (adding more soon).

## 16 September 2023
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
name = "RustQuant"
authors = ["avhz <[email protected]>"]
description = "A Rust library for quantitative finance tools."
version = "0.0.30"
version = "0.0.31"
edition = "2021"
readme = "README.md"
repository = "https://github.com/avhz/RustQuant"
Expand Down
99 changes: 99 additions & 0 deletions src/instruments/options/black_scholes_merton.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
// - LICENSE-MIT.md
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//! The generalised Black-Scholes-Merton European Option pricing model.
//!
//! The differing cost of carry factor allows for the following models:
//! 1. b = r: Black-Scholes 1973 stock option model.
//! 2. b = r - q: Merton 1973 stock option model with continuous dividend yield.
//! 3. b = 0: Black 1976 futures option model.
//! 4. b = 0, r = 0: Asay 1982 margined futures option model.
//! 5. b = r_d - r_f: Garman and Kohlhagen 1983 currency option model.
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// IMPORTS
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -279,6 +288,96 @@ impl BlackScholesMerton {

self.vega() * (r - b + b * d1 / (v * T.sqrt()) - (d1 * d2 + 1.0) / (2.0 * T))
}

/// Theta of the generalised Black-Scholes European option.
/// Also known as Expected Bleed.
pub fn theta(&self) -> f64 {
let (S, K, v, r, b) = self.unpack();
let T = self.year_fraction();
let (d1, d2) = self.d1_d2();

let n = Gaussian::default();

match self.option_type {
TypeFlag::Call => {
-S * ((b - r) * T).exp() * n.pdf(d1) * v / (2.0 * T.sqrt())
- (b - r) * S * ((b - r) * T).exp() * n.cdf(d1)
- r * K * (-r * T).exp() * n.cdf(d2)
}
TypeFlag::Put => {
-S * ((b - r) * T).exp() * n.pdf(d1) * v / (2.0 * T.sqrt())
+ (b - r) * S * ((b - r) * T).exp() * n.cdf(-d1)
+ r * K * (-r * T).exp() * n.cdf(-d2)
}
}
}

/// Rho of the generalised Black-Scholes European option.
pub fn rho(&self) -> f64 {
let T = self.year_fraction();

match self.option_type {
TypeFlag::Call => {
self.strike_price
* T
* (-self.risk_free_rate * T).exp()
* Gaussian::default().cdf(self.d1_d2().1)
}
TypeFlag::Put => {
-self.strike_price
* T
* (-self.risk_free_rate * T).exp()
* Gaussian::default().cdf(-self.d1_d2().1)
}
}
}

/// Phi of the generalised Black-Scholes European option.
/// Also known as Rho-2.
pub fn phi(&self) -> f64 {
let (S, _, _, r, b) = self.unpack();
let T = self.year_fraction();

let (d1, _) = self.d1_d2();

match self.option_type {
TypeFlag::Call => -T * S * ((b - r) * T).exp() * Gaussian::default().cdf(d1),
TypeFlag::Put => T * S * ((b - r) * T).exp() * Gaussian::default().cdf(-d1),
}
}

/// Zeta of the generalised Black-Scholes European option.
/// Also known as the in-the-money probability.
pub fn zeta(&self) -> f64 {
let n = Gaussian::default();

match self.option_type {
TypeFlag::Call => n.cdf(self.d1_d2().1),
TypeFlag::Put => n.cdf(-self.d1_d2().1),
}
}

/// Strike Delta of the generalised Black-Scholes European option.
/// Also known as Dual Delta or Discounted Probability.
pub fn strike_delta(&self) -> f64 {
let n = Gaussian::default();

let T = self.year_fraction();

match self.option_type {
TypeFlag::Call => -(-self.risk_free_rate * T).exp() * n.cdf(self.d1_d2().1),
TypeFlag::Put => (-self.risk_free_rate * T).exp() * n.cdf(-self.d1_d2().1),
}
}

/// Strike Gamma of the generalised Black-Scholes European option.
pub fn strike_gamma(&self) -> f64 {
let n = Gaussian::default();
let T = self.year_fraction();

n.pdf(self.d1_d2().1) * (-self.risk_free_rate * T).exp()
/ (self.strike_price * self.volatility * T.sqrt())
}
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down

0 comments on commit 0019788

Please sign in to comment.