Skip to main content

EquityOptionBase

Struct EquityOptionBase 

Source
pub struct EquityOptionBase {
Show 21 fields pub symbol: String, pub currency: Option<String>, pub exchange: Option<String>, pub name: Option<String>, pub cusip: Option<String>, pub isin: Option<String>, pub settlement_type: Option<String>, pub underlying_price: Quote, pub current_price: Quote, pub strike_price: f64, pub dividend_yield: f64, pub borrow_cost: f64, pub futures_settlement: Option<FuturesSettlement>, pub cash_dividends: Vec<(NaiveDate, f64)>, pub vol_surface: VolSurface, pub maturity_date: NaiveDate, pub valuation_date: NaiveDate, pub discount_curve: YieldCurve, pub entry_price: f64, pub long_short: LongShort, pub multiplier: f64,
}

Fields§

§symbol: String§currency: Option<String>§exchange: Option<String>§name: Option<String>§cusip: Option<String>§isin: Option<String>§settlement_type: Option<String>§underlying_price: Quote§current_price: Quote§strike_price: f64§dividend_yield: f64§borrow_cost: f64

Continuous stock borrow (repo) cost; part of the carry alongside the dividend yield.

§futures_settlement: Option<FuturesSettlement>

When set, the underlying is a future priced with Black-76 (underlying_price is the futures price F), settled either with an up-front discounted premium or futures-style margined. European vanilla only, on the Analytical engine.

§cash_dividends: Vec<(NaiveDate, f64)>

Discrete cash dividends (ex-date, amount per share). Analytic, tree and terminal Monte Carlo engines use the escrowed model (spot minus PV of dividends); path-wise Monte Carlo and finite difference apply the jumps at the ex-dates.

§vol_surface: VolSurface

Volatility surface; a flat surface represents a single constant vol.

§maturity_date: NaiveDate§valuation_date: NaiveDate§discount_curve: YieldCurve

Discounting curve anchored at valuation_date; discount factors are the source of truth, rates are derived views.

§entry_price: f64§long_short: LongShort§multiplier: f64

Implementations§

Source§

impl EquityOptionBase

Source

pub fn time_to_maturity(&self) -> f64

Source

pub fn maturity_discount_factor(&self) -> f64

Discount factor from the valuation date to maturity, off the curve.

Source

pub fn risk_free_rate(&self) -> f64

Continuously compounded zero rate to maturity implied by the curve. This is the r that enters d1/d2; it is consistent with maturity_discount_factor by construction.

Source

pub fn carry_yield(&self) -> f64

Total continuous carry on the underlying: dividend yield plus borrow cost. This is the “q” every pricing formula uses.

Examples found in repository?
examples/dividends_and_borrow.rs (line 148)
39fn main() {
40    common::title("DIVIDENDS AND BORROW COST — S=100 K=100 sigma=30% r=5% T=1y");
41
42    common::section("Continuous carry: dividend yield and borrow cost are interchangeable");
43    common::table_header();
44    common::row("no carry", &base().vanilla(PutOrCall::Call).build());
45    common::row("q = 4%", &base().dividend_yield(0.04).vanilla(PutOrCall::Call).build());
46    common::row("borrow = 4%", &base().borrow_cost(0.04).vanilla(PutOrCall::Call).build());
47    common::row(
48        "q = 1% + borrow = 3%",
49        &base().dividend_yield(0.01).borrow_cost(0.03).vanilla(PutOrCall::Call).build(),
50    );
51    common::note("carry_yield() = dividend_yield + borrow_cost enters every formula as 'q'");
52
53    let q_only = base().dividend_yield(0.04).vanilla(PutOrCall::Call).build();
54    let split = base().dividend_yield(0.01).borrow_cost(0.03).vanilla(PutOrCall::Call).build();
55    common::check("q=4% vs q=1%+b=3%", split.npv(), q_only.npv(), 1e-12);
56
57    common::section("Hard-to-borrow names: high borrow cost lowers the forward");
58    common::table_header();
59    for b in [0.0, 0.02, 0.05, 0.15] {
60        let option = base().borrow_cost(b).vanilla(PutOrCall::Call).build();
61        common::row(&format!("borrow = {:.0}%", b * 100.0), &option);
62    }
63    let hard = base().borrow_cost(0.15).vanilla(PutOrCall::Call).build();
64    println!(
65        "  forward with 15% borrow: {:.4} (vs spot {SPOT})",
66        hard.base.forward_price()
67    );
68
69    common::section("Discrete cash dividends: 2 x 1.50 over the year");
70    let with_divs = |b: EquityOptionBuilder| {
71        b.cash_dividend(NaiveDate::from_ymd_opt(2026, 4, 1).unwrap(), 1.5)
72            .cash_dividend(NaiveDate::from_ymd_opt(2026, 10, 1).unwrap(), 1.5)
73    };
74    let analytic = with_divs(base()).vanilla(PutOrCall::Call).build();
75    println!(
76        "  spot {SPOT} - PV(dividends) {:.6} = escrowed spot {:.6}",
77        analytic.base.pv_cash_dividends(),
78        analytic.base.effective_spot()
79    );
80    common::table_header();
81    common::row("Analytical (escrowed model)", &analytic);
82    common::row(
83        "Binomial (escrowed)",
84        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::Binomial).build(),
85    );
86    common::row(
87        "Finite difference (jump model)",
88        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::FiniteDifference).build(),
89    );
90    common::row(
91        "Monte Carlo terminal (escrowed)",
92        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::MonteCarlo).build(),
93    );
94    common::row(
95        "Monte Carlo path-wise (jump model)",
96        &with_divs(base())
97            .vanilla(PutOrCall::Call)
98            .engine(Engine::MonteCarlo)
99            .mc_time_steps(200)
100            .paths(50_000)
101            .build(),
102    );
103    common::note("escrowed: lognormal on S - PV(divs); jump: dividends subtracted at each ex-date");
104    common::note("the two models differ slightly by construction — that gap is expected, not a bug");
105
106    common::check(
107        "escrowed analytic == BS on the escrowed spot",
108        analytic.npv(),
109        bs_price(analytic.base.effective_spot(), STRIKE, RATE, 0.0, VOL, 1.0, PutOrCall::Call),
110        1e-10,
111    );
112
113    common::section("Where the jump model matters: American exercise and barriers");
114    common::table_header();
115    common::row(
116        "American put, FD (jumps)",
117        &with_divs(base())
118            .american()
119            .vanilla(PutOrCall::Put)
120            .engine(Engine::FiniteDifference)
121            .build(),
122    );
123    common::row(
124        "American put, no dividends",
125        &base().american().vanilla(PutOrCall::Put).engine(Engine::FiniteDifference).build(),
126    );
127    common::row(
128        "Down-and-out call H=85, MC (jumps)",
129        &with_divs(base())
130            .barrier(PutOrCall::Call, BarrierDirection::Down, KnockType::Out, 85.0)
131            .engine(Engine::MonteCarlo)
132            .paths(50_000)
133            .build(),
134    );
135    common::row(
136        "Down-and-out call H=85, no dividends",
137        &base()
138            .barrier(PutOrCall::Call, BarrierDirection::Down, KnockType::Out, 85.0)
139            .engine(Engine::MonteCarlo)
140            .paths(50_000)
141            .build(),
142    );
143    common::note("dividend drops push the path toward a down barrier and change exercise timing");
144
145    common::section("Put-call parity with full carry");
146    let call = with_divs(base()).borrow_cost(0.02).vanilla(PutOrCall::Call).build();
147    let put = with_divs(base()).borrow_cost(0.02).vanilla(PutOrCall::Put).build();
148    let parity = call.base.effective_spot() * (-call.base.carry_yield() * 1.0_f64).exp()
149        - STRIKE * (-RATE * 1.0_f64).exp();
150    common::check("C - P = S_eff e^{-(q+b)T} - K e^{-rT}", call.npv() - put.npv(), parity, 1e-10);
151    println!();
152}
Source

pub fn is_futures_option(&self) -> bool

True when the underlying is a future priced with Black-76.

Source

pub fn pv_cash_dividends(&self) -> f64

Escrow value of the cash dividends with ex-dates inside the option’s life: the amount to carve out of spot so the risky stub reproduces the jump-model forward.

Each dividend is discounted at the net carry rate r - carry, not the risk-free rate, so that the escrow accretes at the same rate the risky stub grows (effective_spot is grown at r - carry in [forward_price]). This makes the analytic forward match the well-defined jump model F = (S - D e^{-(r-carry)t}) e^{(r-carry)T} used by the FD and path-wise Monte Carlo engines. With no continuous carry this reduces to plain risk-free discounting.

Examples found in repository?
examples/dividends_and_borrow.rs (line 77)
39fn main() {
40    common::title("DIVIDENDS AND BORROW COST — S=100 K=100 sigma=30% r=5% T=1y");
41
42    common::section("Continuous carry: dividend yield and borrow cost are interchangeable");
43    common::table_header();
44    common::row("no carry", &base().vanilla(PutOrCall::Call).build());
45    common::row("q = 4%", &base().dividend_yield(0.04).vanilla(PutOrCall::Call).build());
46    common::row("borrow = 4%", &base().borrow_cost(0.04).vanilla(PutOrCall::Call).build());
47    common::row(
48        "q = 1% + borrow = 3%",
49        &base().dividend_yield(0.01).borrow_cost(0.03).vanilla(PutOrCall::Call).build(),
50    );
51    common::note("carry_yield() = dividend_yield + borrow_cost enters every formula as 'q'");
52
53    let q_only = base().dividend_yield(0.04).vanilla(PutOrCall::Call).build();
54    let split = base().dividend_yield(0.01).borrow_cost(0.03).vanilla(PutOrCall::Call).build();
55    common::check("q=4% vs q=1%+b=3%", split.npv(), q_only.npv(), 1e-12);
56
57    common::section("Hard-to-borrow names: high borrow cost lowers the forward");
58    common::table_header();
59    for b in [0.0, 0.02, 0.05, 0.15] {
60        let option = base().borrow_cost(b).vanilla(PutOrCall::Call).build();
61        common::row(&format!("borrow = {:.0}%", b * 100.0), &option);
62    }
63    let hard = base().borrow_cost(0.15).vanilla(PutOrCall::Call).build();
64    println!(
65        "  forward with 15% borrow: {:.4} (vs spot {SPOT})",
66        hard.base.forward_price()
67    );
68
69    common::section("Discrete cash dividends: 2 x 1.50 over the year");
70    let with_divs = |b: EquityOptionBuilder| {
71        b.cash_dividend(NaiveDate::from_ymd_opt(2026, 4, 1).unwrap(), 1.5)
72            .cash_dividend(NaiveDate::from_ymd_opt(2026, 10, 1).unwrap(), 1.5)
73    };
74    let analytic = with_divs(base()).vanilla(PutOrCall::Call).build();
75    println!(
76        "  spot {SPOT} - PV(dividends) {:.6} = escrowed spot {:.6}",
77        analytic.base.pv_cash_dividends(),
78        analytic.base.effective_spot()
79    );
80    common::table_header();
81    common::row("Analytical (escrowed model)", &analytic);
82    common::row(
83        "Binomial (escrowed)",
84        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::Binomial).build(),
85    );
86    common::row(
87        "Finite difference (jump model)",
88        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::FiniteDifference).build(),
89    );
90    common::row(
91        "Monte Carlo terminal (escrowed)",
92        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::MonteCarlo).build(),
93    );
94    common::row(
95        "Monte Carlo path-wise (jump model)",
96        &with_divs(base())
97            .vanilla(PutOrCall::Call)
98            .engine(Engine::MonteCarlo)
99            .mc_time_steps(200)
100            .paths(50_000)
101            .build(),
102    );
103    common::note("escrowed: lognormal on S - PV(divs); jump: dividends subtracted at each ex-date");
104    common::note("the two models differ slightly by construction — that gap is expected, not a bug");
105
106    common::check(
107        "escrowed analytic == BS on the escrowed spot",
108        analytic.npv(),
109        bs_price(analytic.base.effective_spot(), STRIKE, RATE, 0.0, VOL, 1.0, PutOrCall::Call),
110        1e-10,
111    );
112
113    common::section("Where the jump model matters: American exercise and barriers");
114    common::table_header();
115    common::row(
116        "American put, FD (jumps)",
117        &with_divs(base())
118            .american()
119            .vanilla(PutOrCall::Put)
120            .engine(Engine::FiniteDifference)
121            .build(),
122    );
123    common::row(
124        "American put, no dividends",
125        &base().american().vanilla(PutOrCall::Put).engine(Engine::FiniteDifference).build(),
126    );
127    common::row(
128        "Down-and-out call H=85, MC (jumps)",
129        &with_divs(base())
130            .barrier(PutOrCall::Call, BarrierDirection::Down, KnockType::Out, 85.0)
131            .engine(Engine::MonteCarlo)
132            .paths(50_000)
133            .build(),
134    );
135    common::row(
136        "Down-and-out call H=85, no dividends",
137        &base()
138            .barrier(PutOrCall::Call, BarrierDirection::Down, KnockType::Out, 85.0)
139            .engine(Engine::MonteCarlo)
140            .paths(50_000)
141            .build(),
142    );
143    common::note("dividend drops push the path toward a down barrier and change exercise timing");
144
145    common::section("Put-call parity with full carry");
146    let call = with_divs(base()).borrow_cost(0.02).vanilla(PutOrCall::Call).build();
147    let put = with_divs(base()).borrow_cost(0.02).vanilla(PutOrCall::Put).build();
148    let parity = call.base.effective_spot() * (-call.base.carry_yield() * 1.0_f64).exp()
149        - STRIKE * (-RATE * 1.0_f64).exp();
150    common::check("C - P = S_eff e^{-(q+b)T} - K e^{-rT}", call.npv() - put.npv(), parity, 1e-10);
151    println!();
152}
Source

pub fn effective_spot(&self) -> f64

Escrowed-model spot: the quoted spot minus the PV of cash dividends paid over the option’s life. This is the lognormal driver for the analytic and terminal-simulation engines.

Examples found in repository?
examples/dividends_and_borrow.rs (line 78)
39fn main() {
40    common::title("DIVIDENDS AND BORROW COST — S=100 K=100 sigma=30% r=5% T=1y");
41
42    common::section("Continuous carry: dividend yield and borrow cost are interchangeable");
43    common::table_header();
44    common::row("no carry", &base().vanilla(PutOrCall::Call).build());
45    common::row("q = 4%", &base().dividend_yield(0.04).vanilla(PutOrCall::Call).build());
46    common::row("borrow = 4%", &base().borrow_cost(0.04).vanilla(PutOrCall::Call).build());
47    common::row(
48        "q = 1% + borrow = 3%",
49        &base().dividend_yield(0.01).borrow_cost(0.03).vanilla(PutOrCall::Call).build(),
50    );
51    common::note("carry_yield() = dividend_yield + borrow_cost enters every formula as 'q'");
52
53    let q_only = base().dividend_yield(0.04).vanilla(PutOrCall::Call).build();
54    let split = base().dividend_yield(0.01).borrow_cost(0.03).vanilla(PutOrCall::Call).build();
55    common::check("q=4% vs q=1%+b=3%", split.npv(), q_only.npv(), 1e-12);
56
57    common::section("Hard-to-borrow names: high borrow cost lowers the forward");
58    common::table_header();
59    for b in [0.0, 0.02, 0.05, 0.15] {
60        let option = base().borrow_cost(b).vanilla(PutOrCall::Call).build();
61        common::row(&format!("borrow = {:.0}%", b * 100.0), &option);
62    }
63    let hard = base().borrow_cost(0.15).vanilla(PutOrCall::Call).build();
64    println!(
65        "  forward with 15% borrow: {:.4} (vs spot {SPOT})",
66        hard.base.forward_price()
67    );
68
69    common::section("Discrete cash dividends: 2 x 1.50 over the year");
70    let with_divs = |b: EquityOptionBuilder| {
71        b.cash_dividend(NaiveDate::from_ymd_opt(2026, 4, 1).unwrap(), 1.5)
72            .cash_dividend(NaiveDate::from_ymd_opt(2026, 10, 1).unwrap(), 1.5)
73    };
74    let analytic = with_divs(base()).vanilla(PutOrCall::Call).build();
75    println!(
76        "  spot {SPOT} - PV(dividends) {:.6} = escrowed spot {:.6}",
77        analytic.base.pv_cash_dividends(),
78        analytic.base.effective_spot()
79    );
80    common::table_header();
81    common::row("Analytical (escrowed model)", &analytic);
82    common::row(
83        "Binomial (escrowed)",
84        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::Binomial).build(),
85    );
86    common::row(
87        "Finite difference (jump model)",
88        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::FiniteDifference).build(),
89    );
90    common::row(
91        "Monte Carlo terminal (escrowed)",
92        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::MonteCarlo).build(),
93    );
94    common::row(
95        "Monte Carlo path-wise (jump model)",
96        &with_divs(base())
97            .vanilla(PutOrCall::Call)
98            .engine(Engine::MonteCarlo)
99            .mc_time_steps(200)
100            .paths(50_000)
101            .build(),
102    );
103    common::note("escrowed: lognormal on S - PV(divs); jump: dividends subtracted at each ex-date");
104    common::note("the two models differ slightly by construction — that gap is expected, not a bug");
105
106    common::check(
107        "escrowed analytic == BS on the escrowed spot",
108        analytic.npv(),
109        bs_price(analytic.base.effective_spot(), STRIKE, RATE, 0.0, VOL, 1.0, PutOrCall::Call),
110        1e-10,
111    );
112
113    common::section("Where the jump model matters: American exercise and barriers");
114    common::table_header();
115    common::row(
116        "American put, FD (jumps)",
117        &with_divs(base())
118            .american()
119            .vanilla(PutOrCall::Put)
120            .engine(Engine::FiniteDifference)
121            .build(),
122    );
123    common::row(
124        "American put, no dividends",
125        &base().american().vanilla(PutOrCall::Put).engine(Engine::FiniteDifference).build(),
126    );
127    common::row(
128        "Down-and-out call H=85, MC (jumps)",
129        &with_divs(base())
130            .barrier(PutOrCall::Call, BarrierDirection::Down, KnockType::Out, 85.0)
131            .engine(Engine::MonteCarlo)
132            .paths(50_000)
133            .build(),
134    );
135    common::row(
136        "Down-and-out call H=85, no dividends",
137        &base()
138            .barrier(PutOrCall::Call, BarrierDirection::Down, KnockType::Out, 85.0)
139            .engine(Engine::MonteCarlo)
140            .paths(50_000)
141            .build(),
142    );
143    common::note("dividend drops push the path toward a down barrier and change exercise timing");
144
145    common::section("Put-call parity with full carry");
146    let call = with_divs(base()).borrow_cost(0.02).vanilla(PutOrCall::Call).build();
147    let put = with_divs(base()).borrow_cost(0.02).vanilla(PutOrCall::Put).build();
148    let parity = call.base.effective_spot() * (-call.base.carry_yield() * 1.0_f64).exp()
149        - STRIKE * (-RATE * 1.0_f64).exp();
150    common::check("C - P = S_eff e^{-(q+b)T} - K e^{-rT}", call.npv() - put.npv(), parity, 1e-10);
151    println!();
152}
Source

pub fn forward_price(&self) -> f64

Forward price of the underlying at maturity: escrowed spot grown at the carry-adjusted rate, (S - PV(divs)) * exp((r - q - b) * T).

Examples found in repository?
examples/dividends_and_borrow.rs (line 66)
39fn main() {
40    common::title("DIVIDENDS AND BORROW COST — S=100 K=100 sigma=30% r=5% T=1y");
41
42    common::section("Continuous carry: dividend yield and borrow cost are interchangeable");
43    common::table_header();
44    common::row("no carry", &base().vanilla(PutOrCall::Call).build());
45    common::row("q = 4%", &base().dividend_yield(0.04).vanilla(PutOrCall::Call).build());
46    common::row("borrow = 4%", &base().borrow_cost(0.04).vanilla(PutOrCall::Call).build());
47    common::row(
48        "q = 1% + borrow = 3%",
49        &base().dividend_yield(0.01).borrow_cost(0.03).vanilla(PutOrCall::Call).build(),
50    );
51    common::note("carry_yield() = dividend_yield + borrow_cost enters every formula as 'q'");
52
53    let q_only = base().dividend_yield(0.04).vanilla(PutOrCall::Call).build();
54    let split = base().dividend_yield(0.01).borrow_cost(0.03).vanilla(PutOrCall::Call).build();
55    common::check("q=4% vs q=1%+b=3%", split.npv(), q_only.npv(), 1e-12);
56
57    common::section("Hard-to-borrow names: high borrow cost lowers the forward");
58    common::table_header();
59    for b in [0.0, 0.02, 0.05, 0.15] {
60        let option = base().borrow_cost(b).vanilla(PutOrCall::Call).build();
61        common::row(&format!("borrow = {:.0}%", b * 100.0), &option);
62    }
63    let hard = base().borrow_cost(0.15).vanilla(PutOrCall::Call).build();
64    println!(
65        "  forward with 15% borrow: {:.4} (vs spot {SPOT})",
66        hard.base.forward_price()
67    );
68
69    common::section("Discrete cash dividends: 2 x 1.50 over the year");
70    let with_divs = |b: EquityOptionBuilder| {
71        b.cash_dividend(NaiveDate::from_ymd_opt(2026, 4, 1).unwrap(), 1.5)
72            .cash_dividend(NaiveDate::from_ymd_opt(2026, 10, 1).unwrap(), 1.5)
73    };
74    let analytic = with_divs(base()).vanilla(PutOrCall::Call).build();
75    println!(
76        "  spot {SPOT} - PV(dividends) {:.6} = escrowed spot {:.6}",
77        analytic.base.pv_cash_dividends(),
78        analytic.base.effective_spot()
79    );
80    common::table_header();
81    common::row("Analytical (escrowed model)", &analytic);
82    common::row(
83        "Binomial (escrowed)",
84        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::Binomial).build(),
85    );
86    common::row(
87        "Finite difference (jump model)",
88        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::FiniteDifference).build(),
89    );
90    common::row(
91        "Monte Carlo terminal (escrowed)",
92        &with_divs(base()).vanilla(PutOrCall::Call).engine(Engine::MonteCarlo).build(),
93    );
94    common::row(
95        "Monte Carlo path-wise (jump model)",
96        &with_divs(base())
97            .vanilla(PutOrCall::Call)
98            .engine(Engine::MonteCarlo)
99            .mc_time_steps(200)
100            .paths(50_000)
101            .build(),
102    );
103    common::note("escrowed: lognormal on S - PV(divs); jump: dividends subtracted at each ex-date");
104    common::note("the two models differ slightly by construction — that gap is expected, not a bug");
105
106    common::check(
107        "escrowed analytic == BS on the escrowed spot",
108        analytic.npv(),
109        bs_price(analytic.base.effective_spot(), STRIKE, RATE, 0.0, VOL, 1.0, PutOrCall::Call),
110        1e-10,
111    );
112
113    common::section("Where the jump model matters: American exercise and barriers");
114    common::table_header();
115    common::row(
116        "American put, FD (jumps)",
117        &with_divs(base())
118            .american()
119            .vanilla(PutOrCall::Put)
120            .engine(Engine::FiniteDifference)
121            .build(),
122    );
123    common::row(
124        "American put, no dividends",
125        &base().american().vanilla(PutOrCall::Put).engine(Engine::FiniteDifference).build(),
126    );
127    common::row(
128        "Down-and-out call H=85, MC (jumps)",
129        &with_divs(base())
130            .barrier(PutOrCall::Call, BarrierDirection::Down, KnockType::Out, 85.0)
131            .engine(Engine::MonteCarlo)
132            .paths(50_000)
133            .build(),
134    );
135    common::row(
136        "Down-and-out call H=85, no dividends",
137        &base()
138            .barrier(PutOrCall::Call, BarrierDirection::Down, KnockType::Out, 85.0)
139            .engine(Engine::MonteCarlo)
140            .paths(50_000)
141            .build(),
142    );
143    common::note("dividend drops push the path toward a down barrier and change exercise timing");
144
145    common::section("Put-call parity with full carry");
146    let call = with_divs(base()).borrow_cost(0.02).vanilla(PutOrCall::Call).build();
147    let put = with_divs(base()).borrow_cost(0.02).vanilla(PutOrCall::Put).build();
148    let parity = call.base.effective_spot() * (-call.base.carry_yield() * 1.0_f64).exp()
149        - STRIKE * (-RATE * 1.0_f64).exp();
150    common::check("C - P = S_eff e^{-(q+b)T} - K e^{-rT}", call.npv() - put.npv(), parity, 1e-10);
151    println!();
152}
Source

pub fn volatility(&self) -> f64

Black volatility for this option’s strike and expiry, read off the surface (a flat surface returns its single vol).

Source

pub fn d1(&self) -> f64

Source

pub fn d2(&self) -> f64

Trait Implementations§

Source§

impl Debug for EquityOptionBase

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V