Skip to content

Commit

Permalink
monte-carlo example
Browse files Browse the repository at this point in the history
  • Loading branch information
avhz authored and avhz committed Aug 11, 2024
1 parent f8b8253 commit af08845
Show file tree
Hide file tree
Showing 41 changed files with 550 additions and 414 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ keywords = [
categories = ["finance", "mathematics", "science", "algorithms", "simulation"]
license = "MIT OR Apache-2.0"


## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## COMPILATION PROFILES
## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -92,6 +93,7 @@ uuid = { version = "1.10.0", features = ["v4", "fast-rng"] }
[dev-dependencies]
finitediff = "0.1.4" # https://docs.rs/finitediff/latest/finitediff/


## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## PYTHON BINDINGS
## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
100 changes: 100 additions & 0 deletions examples/monte_carlo_pricing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// RustQuant: A Rust library for quantitative finance tools.
// Copyright (C) 2024 https://github.com/avhz
// Dual licensed under Apache 2.0 and MIT.
// See:
// - LICENSE-APACHE.md
// - LICENSE-MIT.md
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

use time::macros::date;
use RustQuant::instruments::option_flags::*;
use RustQuant::instruments::options::power::PowerOption;
use RustQuant::instruments::options::vanilla::VanillaOption;
use RustQuant::instruments::options::AsianOption;
use RustQuant::instruments::options::OptionContractBuilder;
use RustQuant::instruments::BarrierOption;
use RustQuant::models::geometric_brownian_motion::GeometricBrownianMotion;
use RustQuant::pricer::MonteCarloPricer;
use RustQuant::stochastics::StochasticProcessConfig;

fn main() {
// Set up the parameters.
let underlying = 100.0;
let strike = 100.0;
let rate = 0.05;
let time = 1.0;
let volatility = 0.2;

// Create the stochastic process.
let process = GeometricBrownianMotion::new(rate, volatility);
let config = StochasticProcessConfig::new(underlying, 0.0, time, 365, 100_000, true);

// Create the option contract.
let direction = TypeFlag::Call;

let exercise = ExerciseFlag::European {
expiry: date!(2025 - 01 - 01),
};

let contract = OptionContractBuilder::default()
.type_flag(direction)
.exercise_flag(exercise)
.strike_flag(Some(StrikeFlag::Fixed))
.build()
.unwrap();

// VANILLA
let vanilla = VanillaOption::new(contract.clone(), strike);
let asian = AsianOption::new(
contract.clone(),
AveragingMethod::ArithmeticDiscrete,
Some(strike),
);
let power = PowerOption::new(contract.clone(), strike, 2.0);

println!(
"Vanilla: {:?}",
vanilla.price_monte_carlo(&process, &config, rate)
);
println!(
"Asian: {:?}",
asian.price_monte_carlo(&process, &config, rate)
);
println!(
"Power: {:?}",
power.price_monte_carlo(&process, &config, rate)
);

// let start = Instant::now();
// let price = option.price_monte_carlo(process, &config, interest_rate);
// println!("Elapsed time: {:?}", start.elapsed());

// println!("Price: {}", price);

// let underlying = 100.0;
// let strike = 100.0;
// let interest_rate = 0.05;
// let time_to_maturity = 1.0;
// let volatility = 0.2;

// let contract = OptionContractBuilder::default()
// .type_flag(TypeFlag::Call)
// .exercise_flag(ExerciseFlag::European {
// expiry: date!(2025 - 01 - 01),
// })
// .strike_flag(Some(StrikeFlag::Fixed))
// .build()
// .unwrap();

// let option = AsianOption::new(contract, AveragingMethod::ArithmeticDiscrete, Some(strike));
// let process = GeometricBrownianMotion::new(interest_rate, volatility);

// let config = StochasticProcessConfig::new(underlying, 0.0, time_to_maturity, 1000, 1000, true);

// let start = Instant::now();
// let price = option.price_monte_carlo(process, &config, interest_rate);
// println!("Elapsed time: {:?}", start.elapsed());

// println!("Price: {}", price);
}
3 changes: 2 additions & 1 deletion src/instruments/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
//! | Compound |❌|❌|❌|❌|❌|
//! | Exchange |❌|❌|❌|❌|❌|
//! | Forward Start |❌|❌|❌|❌|❌|
//! | Lookback |❌|❌|❌|❌|❌|
//! | Log |❌|✅|❌|❌|❌|
//! | Lookback |❌|✅|❌|❌|❌|
//! | Power |❌|✅|❌|❌|❌|
//! | Quanto |❌|❌|❌|❌|❌|
//! | Spread |❌|❌|❌|❌|❌|
Expand Down
65 changes: 65 additions & 0 deletions src/instruments/options/log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// RustQuant: A Rust library for quantitative finance tools.
// Copyright (C) 2023 https://github.com/avhz
// Dual licensed under Apache 2.0 and MIT.
// See:
// - LICENSE-APACHE.md
// - LICENSE-MIT.md
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

use super::{OptionContract, TypeFlag};
use crate::instruments::Payoff;

/// Log Moneyness Contract.
#[derive(Debug, Clone)]
pub struct LogMoneynessContract {
/// The option contract.
pub contract: OptionContract,

/// Strike price of the option.
pub strike: f64,
}

/// Log Underlying Contract.
#[derive(Debug, Clone)]
pub struct LogUnderlyingContract {
/// The option contract.
pub contract: OptionContract,

/// Strike price of the option.
pub strike: f64,
}

/// Log Option.
#[derive(Debug, Clone)]
pub struct LogOption {
/// The option contract.
pub contract: OptionContract,

/// Strike price of the option.
pub strike: f64,
}

impl Payoff for LogMoneynessContract {
type Underlying = f64;

fn payoff(&self, underlying: Self::Underlying) -> f64 {
(underlying / self.strike).ln()
}
}

impl Payoff for LogUnderlyingContract {
type Underlying = f64;

fn payoff(&self, underlying: Self::Underlying) -> f64 {
underlying.ln()
}
}

impl Payoff for LogOption {
type Underlying = f64;

fn payoff(&self, underlying: Self::Underlying) -> f64 {
(underlying / self.strike).ln().max(0.0)
}
}
Loading

0 comments on commit af08845

Please sign in to comment.