use crate::params::Inflation;
use crate::plan::{AssetClass, ClassReturns, Plan};
use super::{horizon_len, plan_inflation};
#[derive(Debug, Clone, PartialEq)]
pub struct MarketPath {
start_year: i16,
returns: Vec<ClassReturns>,
inflation: Inflation,
deflators: Vec<f64>,
}
impl MarketPath {
#[must_use]
pub fn expected(plan: &Plan) -> Self {
let market = plan.market();
let mut means = ClassReturns::default();
for &class in AssetClass::ALL {
means[class.index()] = market.mean(class);
}
let returns = vec![means; horizon_len(plan)];
Self::new(plan, returns, plan_inflation(plan))
}
pub(crate) fn new(plan: &Plan, returns: Vec<ClassReturns>, inflation: Inflation) -> Self {
let start_year = plan.plan.start_year;
let deflators = (start_year..)
.take(horizon_len(plan))
.map(|year| inflation.factor(start_year, year))
.collect();
Self {
start_year,
returns,
inflation,
deflators,
}
}
#[must_use]
pub fn returns(&self, year: i16) -> ClassReturns {
usize::try_from(year - self.start_year)
.ok()
.and_then(|at| self.returns.get(at))
.copied()
.unwrap_or_default()
}
#[must_use]
pub fn inflation(&self) -> &Inflation {
&self.inflation
}
#[must_use]
pub fn deflator(&self, year: i16) -> f64 {
usize::try_from(year - self.start_year)
.ok()
.and_then(|at| self.deflators.get(at))
.copied()
.unwrap_or_else(|| self.inflation.factor(self.start_year, year))
}
}