use super::OneFactorShortRateModel;
use super::common::build_one_factor_trinomial_tree;
use super::common::price_one_factor_zcb;
use crate::lattice::tree::TrinomialTree;
use crate::traits::FloatExt;
#[derive(Debug, Clone)]
pub struct HullWhiteTreeModel<T: FloatExt> {
pub initial_rate: T,
pub mean_reversion: T,
pub theta: T,
pub sigma: T,
}
impl<T: FloatExt> HullWhiteTreeModel<T> {
pub fn new(initial_rate: T, mean_reversion: T, theta: T, sigma: T) -> Self {
Self {
initial_rate,
mean_reversion,
theta,
sigma,
}
}
}
impl<T: FloatExt> OneFactorShortRateModel<T> for HullWhiteTreeModel<T> {
fn initial_state(&self) -> T {
self.initial_rate
}
fn drift(&self, _time: T, state: T) -> T {
self.mean_reversion * (self.theta - state)
}
fn diffusion(&self, _time: T, _state: T) -> T {
self.sigma
}
fn short_rate(&self, _time: T, state: T) -> T {
state
}
}
#[derive(Debug, Clone)]
pub struct HullWhiteTree<T: FloatExt> {
pub model: HullWhiteTreeModel<T>,
pub tree: TrinomialTree<T>,
pub horizon: T,
}
impl<T: FloatExt> HullWhiteTree<T> {
pub fn new(model: HullWhiteTreeModel<T>, horizon: T, steps: usize) -> Self {
let tree = build_one_factor_trinomial_tree(&model, horizon, steps);
Self {
model,
tree,
horizon,
}
}
pub fn zero_coupon_bond_price(&self) -> T {
price_one_factor_zcb(&self.tree, &self.model)
}
}