pub mod blackdiffusion;
use models::blackdiffusion::BlackDiffusionFactory;
use core::qm;
use instruments::RcInstrument;
use instruments::MonteCarloDependencies;
use instruments::MonteCarloContext;
use risk::Bumpable;
use risk::BumpablePricingContext;
use risk::marketdata::MarketData;
use dates::Date;
use dates::datetime::DateDayFraction;
use core::factories::{TypeId, Qrc, Registry};
use std::collections::HashMap;
use std::clone::Clone;
use erased_serde as esd;
use serde as sd;
use serde_tagged as sdt;
use serde_tagged::de::BoxFnSeed;
use std::fmt::Debug;
pub trait MonteCarloModelFactory : esd::Serialize + TypeId + Sync + Send + Debug {
fn factory(&self, timeline: &MonteCarloTimeline,
context: Box<BumpablePricingContext>)
-> Result<Box<MonteCarloModel>, qm::Error>;
}
pub type TypeRegistry = Registry<BoxFnSeed<Qrc<MonteCarloModelFactory>>>;
impl<'de> sd::Deserialize<'de> for Qrc<MonteCarloModelFactory> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: sd::Deserializer<'de>
{
sdt::de::external::deserialize(deserializer, get_registry())
}
}
pub fn get_registry() -> &'static TypeRegistry {
lazy_static! {
static ref REG: TypeRegistry = {
let mut reg = TypeRegistry::new();
reg.insert("BlackDiffusionFactory", BoxFnSeed::new(BlackDiffusionFactory::from_serial));
reg
};
}
®
}
pub type RcMonteCarloModelFactory = Qrc<MonteCarloModelFactory>;
pub trait MonteCarloModel : MonteCarloContext + Bumpable + MonteCarloModelClone {
fn as_mc_context(&self) -> &MonteCarloContext;
fn as_bumpable(&self) -> &Bumpable;
fn as_mut_bumpable(&mut self) -> &mut Bumpable;
fn raw_market_data(&self) -> &MarketData;
}
pub trait MonteCarloModelClone {
fn clone_box(&self) -> Box<MonteCarloModel>;
}
impl<T> MonteCarloModelClone for T
where T: 'static + MonteCarloModel + Clone,
{
fn clone_box(&self) -> Box<MonteCarloModel> {
Box::new(self.clone())
}
}
impl Clone for Box<MonteCarloModel> {
fn clone(&self) -> Box<MonteCarloModel> {
self.clone_box()
}
}
pub struct MonteCarloTimeline {
_spot_date: Date,
observations: HashMap<RcInstrument, Vec<DateDayFraction>>,
flows: Vec<RcInstrument>,
collated: bool
}
impl MonteCarloTimeline {
pub fn new(spot_date: Date) -> MonteCarloTimeline {
MonteCarloTimeline { _spot_date: spot_date,
observations: HashMap::new(), flows: Vec::new(),
collated: false }
}
pub fn collate(&mut self) -> Result<(), qm::Error> {
self.collated = true;
Ok(())
}
pub fn observations(&self) -> &HashMap<RcInstrument, Vec<DateDayFraction>> {
assert!(self.collated);
&self.observations
}
pub fn flows(&self) -> &[RcInstrument] {
assert!(self.collated);
&self.flows
}
}
impl MonteCarloDependencies for MonteCarloTimeline {
fn observation(&mut self, instrument: &RcInstrument,
date_time: DateDayFraction) {
self.observations.entry(instrument.clone())
.or_insert(Vec::<DateDayFraction>::new()).push(date_time);
}
fn flow(&mut self, instrument: &RcInstrument) {
self.flows.push(instrument.clone());
}
}