use optionstratlib_core::error::{DecimalError, OptionsError};
use optionstratlib_pricing::error::PricingError;
use optionstratlib_simulation::error::SimulationError;
use optionstratlib_strategies::error::StrategyError;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum BacktestError {
#[error(transparent)]
Strategy(Box<StrategyError>),
#[error(transparent)]
Simulation(Box<SimulationError>),
#[error(transparent)]
Pricing(Box<PricingError>),
#[error(transparent)]
Options(Box<OptionsError>),
#[error(transparent)]
Decimal(Box<DecimalError>),
#[error(transparent)]
Positive(#[from] optionstratlib_core::model::PositiveError),
#[error("backtest counter `{counter}` overflowed")]
CounterOverflow {
counter: &'static str,
},
}
impl BacktestError {
#[cold]
#[inline(never)]
#[must_use]
pub fn counter_overflow(counter: &'static str) -> Self {
BacktestError::CounterOverflow { counter }
}
}
impl From<PricingError> for BacktestError {
#[inline]
fn from(error: PricingError) -> Self {
BacktestError::Pricing(Box::new(error))
}
}
impl From<OptionsError> for BacktestError {
#[inline]
fn from(error: OptionsError) -> Self {
BacktestError::Options(Box::new(error))
}
}
impl From<DecimalError> for BacktestError {
#[inline]
fn from(error: DecimalError) -> Self {
BacktestError::Decimal(Box::new(error))
}
}
impl From<StrategyError> for BacktestError {
#[inline]
fn from(error: StrategyError) -> Self {
BacktestError::Strategy(Box::new(error))
}
}
impl From<SimulationError> for BacktestError {
#[inline]
fn from(error: SimulationError) -> Self {
BacktestError::Simulation(Box::new(error))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_counter_overflow_names_the_counter() {
let error = BacktestError::counter_overflow("total_simulations");
assert!(matches!(
error,
BacktestError::CounterOverflow {
counter: "total_simulations"
}
));
assert_eq!(
error.to_string(),
"backtest counter `total_simulations` overflowed"
);
}
}