Skip to content

Commit a0f60ef

Browse files
Merge pull request #20 from carlobortolan/3-implement-black-scholes-model
Implement black scholes model
2 parents c529b99 + 4f024b9 commit a0f60ef

20 files changed

+1757
-865
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.lock.MSRV

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "quantrs"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
authors = ["Carlo Bortolan"]
55
description = " A tiny Rust library for quantitative finance"
66
license = "MIT"

README.md

Lines changed: 74 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,81 @@ Please check out the documentation [here][docs-url].
2323

2424
## Features
2525

26-
### Core Features
26+
## Features
27+
28+
### Options Pricing
29+
30+
For now quantrs only supports options pricing. The following features are available:
31+
32+
- [x] Option types: European, American, Binary Cash-or-Nothing, Binary Asset-or-Nothing
33+
- [x] Option pricing: Black-Scholes, Binomial Tree, Monte Carlo Simulation
34+
- [x] Greeks: Delta, Gamma, Theta, Vega, Rho
35+
- [x] Implied volatility
36+
37+
| Model | Black-Scholes | Binomial Tree | Monte Carlo Simulation |
38+
| ----------------------- | ------------------- | ------------- | ---------------------- |
39+
| European Options ||||
40+
| American Options | ❌ (not applicable) |||
41+
| Binary Cash-or-Nothing ||||
42+
| Binary Asset-or-Nothing ||||
43+
| Greeks ||||
44+
| Implied Volatility | ✅ (not tested yet) |||
45+
46+
(✅ = Supported, ⏳ = Planned / In progress, ❌ = Not supported)
47+
48+
## Usage
49+
50+
Add this to your `Cargo.toml`:
51+
52+
```toml
53+
[dependencies]
54+
quantrs = "0.1.2"
55+
```
56+
57+
Now if you want to e.g., model binary call options using the Black-Scholes model, you can:
58+
59+
```rust
60+
use quantrs::options::*;
61+
62+
fn main() {
63+
// Create a new instrument with a spot price of 100 and a dividend yield of 2%
64+
let mut instrument = Instrument::new(100.0);
65+
instrument.continuous_dividend_yield = 0.02;
66+
67+
68+
// Create a new Cash-or-Nothing binary call option with a strike price of 85
69+
let option = BinaryOption::new(instrument, 85.0, OptionType::Call);
70+
71+
// Create a new Black-Scholes model with:
72+
// - Time to maturity (T) = 0.78 years
73+
// - Risk-free interest rate (r) = 5%
74+
// - Volatility (σ) = 20%
75+
let model = BlackScholesModel::new(0.78, 0.05, 0.2);
76+
77+
// Calculate the price of the binary call option using the Black-Scholes model
78+
let price = model.price(option.clone());
79+
println!("Price: {}", price);
80+
81+
// Calculate the Greeks (Delta, Gamma, Theta, Vega, Rho) for the option
82+
let greeks = OptionGreeks::calculate(&model, option);
83+
println!("Greeks: {:?}\n", greeks);
84+
}
85+
```
86+
87+
This will output:
2788

28-
- [ ] Options pricing
29-
- [ ] Black-Scholes (work in progress)
30-
- [ ] Binomial tree (work in progress)
31-
- [ ] Monte Carlo simulation (work in progress)
32-
- [ ] Greeks (work in progress)
33-
- [ ] Implied volatility (work in progress)
89+
```text
90+
Price: 0.8006934914644723
91+
Greeks: OptionGreeks { delta: 0.013645840354947947, gamma: -0.0008813766475726433, theta: 0.17537248302290848, vega: -1.3749475702133236, rho: 0.4398346243436515 }
92+
```
93+
94+
See the [documentation][docs-url] for more information and examples.
95+
96+
## Minimum supported Rust version (MSRV)
97+
98+
This crate requires a Rust version of 1.65.0 or higher. Increases in MSRV will be considered a semver non-breaking API change and require a version increase (PATCH until 1.0.0, MINOR after 1.0.0).
99+
100+
## Outlook
34101

35102
### Planned Features
36103

@@ -62,38 +129,6 @@ Please check out the documentation [here][docs-url].
62129
- [ ] Minimum variance
63130
- [ ] Maximum diversification
64131

65-
## Usage
66-
67-
Add this to your `Cargo.toml`:
68-
69-
```toml
70-
[dependencies]
71-
quantrs = "0.1"
72-
```
73-
74-
Now you can use the library in your code:
75-
76-
```rust
77-
use quantrs::options::*;
78-
79-
fn main() {
80-
let option = BlackScholesOption {
81-
spot: 100.0,
82-
strike: 100.0,
83-
time_to_maturity: 1.0,
84-
risk_free_rate: 0.05,
85-
volatility: 0.2,
86-
};
87-
println!("Option price: {}", option.price(OptionType::Call));
88-
}
89-
```
90-
91-
See the [documentation][docs-url] and the [examples](examples) for more information.
92-
93-
## Minimum supported Rust version (MSRV)
94-
95-
This crate requires a Rust version of 1.65.0 or higher. Increases in MSRV will be considered a semver non-breaking API change and require a version increase (PATCH until 1.0.0, MINOR after 1.0.0).
96-
97132
## Contributing
98133

99134
If you find any bugs or have suggestions for improvement, please open a new issue or submit a pull request.

examples/options_pricing.rs

Lines changed: 58 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,56 @@
11
// Run: cargo run --release --example options_pricing
22

33
use quantrs::options::{
4-
BinomialTreeOption, BlackScholesOption, Greeks, MonteCarloOption, OptionGreeks, OptionPricing,
5-
OptionStyle, OptionType,
4+
BinaryOption, BinomialTreeModel, BlackScholesModel, EuropeanOption, Greeks, Instrument,
5+
MonteCarloModel, Option, OptionGreeks, OptionPricing, OptionType,
66
};
77

88
fn main() {
9+
example_from_readme();
910
example_black_scholes();
1011
example_binomial_tree();
1112
example_greeks();
1213
example_monte_carlo();
1314
}
1415

1516
fn example_black_scholes() {
16-
let bs_option = BlackScholesOption {
17-
spot: 100.0,
18-
strike: 100.0,
19-
time_to_maturity: 1.0,
20-
risk_free_rate: 0.05,
21-
volatility: 0.2,
22-
..Default::default()
23-
};
24-
25-
let call_price = bs_option.price(OptionType::Call);
17+
let instrument = Instrument::new(100.0);
18+
let option = EuropeanOption::new(instrument, 100.0, OptionType::Call);
19+
let model = BlackScholesModel::new(1.0, 0.05, 0.2);
20+
21+
let call_price = model.price(option.clone());
2622
println!("Black-Scholes Call Price: {}", call_price);
2723

28-
let put_price = bs_option.price(OptionType::Put);
24+
let put_price = model.price(option.clone().flip());
2925
println!("Black-Scholes Put Price: {}", put_price);
3026

3127
let market_price = 10.0; // Example market price
32-
let implied_volatility = bs_option.implied_volatility(market_price, OptionType::Call);
33-
println!("Implied Volatility: {}", implied_volatility);
28+
let implied_volatility = model.implied_volatility(option, market_price);
29+
println!("Implied Volatility: {}\n", implied_volatility);
3430
}
3531

3632
fn example_binomial_tree() {
37-
let bt_option = BinomialTreeOption {
38-
spot: 100.0,
39-
strike: 100.0,
40-
time_to_maturity: 1.0,
41-
risk_free_rate: 0.05,
42-
volatility: 0.2,
43-
steps: 100,
44-
style: OptionStyle::American,
45-
};
46-
47-
let bt_call_price = bt_option.price(OptionType::Call);
48-
println!("Binomial Tree Call Price: {}", bt_call_price);
49-
50-
let bt_put_price = bt_option.price(OptionType::Put);
51-
println!("Binomial Tree Put Price: {}", bt_put_price);
33+
let instrument = Instrument::new(100.0);
34+
let option = EuropeanOption::new(instrument, 100.0, OptionType::Call);
35+
let model = BinomialTreeModel::new(1.0, 0.05, 0.2, 100);
36+
37+
let call_price = model.price(option.clone());
38+
println!("Binomial Tree Call Price: {}", call_price);
39+
40+
let put_price = model.price(option.clone().flip());
41+
println!("Binomial Tree Put Price: {}", put_price);
5242

5343
let market_price = 10.0; // Example market price
54-
let implied_volatility = bt_option.implied_volatility(market_price, OptionType::Call);
55-
println!("Implied Volatility: {}", implied_volatility);
44+
let implied_volatility = model.implied_volatility(option, market_price);
45+
println!("Implied Volatility: {}\n", implied_volatility);
5646
}
5747

5848
fn example_greeks() {
59-
let bt_option = BinomialTreeOption {
60-
spot: 100.0,
61-
strike: 100.0,
62-
time_to_maturity: 1.0,
63-
risk_free_rate: 0.05,
64-
volatility: 0.2,
65-
steps: 100,
66-
..Default::default()
67-
};
68-
69-
let greeks = OptionGreeks::calculate(&bt_option, OptionType::Call);
49+
let instrument = Instrument::new(100.0);
50+
let option = EuropeanOption::new(instrument, 100.0, OptionType::Call);
51+
let model = BlackScholesModel::new(1.0, 0.05, 0.2);
52+
53+
let greeks = OptionGreeks::calculate(&model, option.clone());
7054

7155
println!("Delta: {}", greeks.delta);
7256
println!("Gamma: {}", greeks.gamma);
@@ -75,31 +59,38 @@ fn example_greeks() {
7559
println!("Rho: {}", greeks.rho);
7660

7761
// Greeks via function calls
78-
println!("Delta: {}", bt_option.delta(OptionType::Call));
79-
println!("Gamma: {}", bt_option.gamma(OptionType::Call));
80-
println!("Theta: {}", bt_option.theta(OptionType::Call));
81-
println!("Vega: {}", bt_option.vega(OptionType::Call));
82-
println!("Rho: {}", bt_option.rho(OptionType::Call));
62+
println!("Delta: {}", model.delta(option.clone()));
63+
println!("Gamma: {}", model.gamma(option.clone()));
64+
println!("Theta: {}", model.theta(option.clone()));
65+
println!("Vega: {}", model.vega(option.clone()));
66+
println!("Rho: {}\n", model.rho(option.clone()));
8367
}
8468

8569
fn example_monte_carlo() {
86-
let mc_option = MonteCarloOption {
87-
spot: 100.0,
88-
strike: 100.0,
89-
time_to_maturity: 1.0,
90-
risk_free_rate: 0.05,
91-
volatility: 0.2,
92-
simulations: 10_000,
93-
..Default::default()
94-
};
95-
96-
let mc_call_price = mc_option.price(OptionType::Call);
97-
println!("Monte Carlo Call Price: {}", mc_call_price);
98-
99-
let mc_put_price = mc_option.price(OptionType::Put);
100-
println!("Monte Carlo Put Price: {}", mc_put_price);
101-
102-
let market_price = mc_call_price; // Example market price
103-
let implied_volatility = mc_option.implied_volatility(market_price, OptionType::Call);
104-
println!("Implied Volatility: {}", implied_volatility);
70+
let instrument = Instrument::new(100.0);
71+
let option = EuropeanOption::new(instrument, 100.0, OptionType::Call);
72+
let model = MonteCarloModel::new(1.0, 0.05, 0.2, 10_000);
73+
74+
let call_price = model.price(option.clone());
75+
println!("Monte Carlo Call Price: {}", call_price);
76+
77+
let put_price = model.price(option.clone().flip());
78+
println!("Monte Carlo Put Price: {}", put_price);
79+
80+
let market_price = call_price; // Example market price
81+
let implied_volatility = model.implied_volatility(option, market_price);
82+
println!("Implied Volatility: {}\n", implied_volatility);
83+
}
84+
85+
fn example_from_readme() {
86+
let mut instrument = Instrument::new(100.0);
87+
instrument.continuous_dividend_yield = 0.02;
88+
let option = BinaryOption::new(instrument, 85.0, OptionType::Call);
89+
let model = BlackScholesModel::new(0.78, 0.05, 0.2);
90+
91+
let price = model.price(option.clone());
92+
println!("Price: {}", price);
93+
94+
let greeks = OptionGreeks::calculate(&model, option);
95+
println!("Greeks: {:?}\n", greeks);
10596
}

src/lib.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
1-
//! # quantrs
21
//!
3-
//! A tiny Rust library for options pricing, portfolio optimization, and risk analysis.
2+
//! This crate is designed to be simple and easy to use library for options pricing, portfolio optimization, and risk analysis. It is not intended to be a full-fledged quantitative finance library.
3+
//! The goal is to provide library for pricing options, calculating greeks, and performing basic risk analysis without the need to write complex code or have a PhD in reading quantlib documentation.
4+
//! The library is still in the early stages of development, and many features are not yet implemented.
5+
//!
6+
//! There are no benchmarks yet, but it is expected to be faster than FinancePy, optlib, QuantScale and easier to use than RustQuant or QuantLib.
7+
//!
8+
//! ## Options Pricing
9+
//!
10+
//! For now quantrs only supports options pricing. The following features are available:
11+
//!
12+
//! - Option types: European, American, Binary Cash-or-Nothing, Binary Asset-or-Nothing
13+
//! - Option pricing: Black-Scholes, Binomial Tree, Monte Carlo Simulation
14+
//! - Greeks: Delta, Gamma, Theta, Vega, Rho
15+
//! - Implied volatility
16+
//!
17+
//! ```rust
18+
//! use quantrs::options::*;
19+
//!
20+
//! let mut instrument = Instrument::new(100.0);
21+
//! let option = BinaryOption::new(instrument, 85.0, OptionType::Call);
22+
//! let model = BlackScholesModel::new(0.78, 0.05, 0.2);
23+
//! let price = model.price(option.clone());
24+
//! let greeks = OptionGreeks::calculate(&model, option);
25+
//! ```
426
527
#![allow(unused_variables)]
628

0 commit comments

Comments
 (0)