#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum StopFill {
#[default]
Touched,
Close,
}
#[derive(Debug, Clone, Copy)]
pub struct StopConfig {
pub stop_loss: f64,
pub take_profit: f64,
pub trail_stop: f64,
pub trail_stop_activation: f64,
pub fill: StopFill,
}
impl Default for StopConfig {
fn default() -> Self {
StopConfig {
stop_loss: f64::NEG_INFINITY,
take_profit: f64::INFINITY,
trail_stop: f64::INFINITY,
trail_stop_activation: 0.0,
fill: StopFill::Touched,
}
}
}
impl StopConfig {
pub(crate) fn is_off(&self) -> bool {
self.stop_loss == f64::NEG_INFINITY
&& self.take_profit == f64::INFINITY
&& self.trail_stop == f64::INFINITY
}
pub fn is_active(&self) -> bool {
!self.is_off()
}
pub fn from_options(
stop_loss: Option<f64>,
take_profit: Option<f64>,
trail_stop: Option<f64>,
trail_stop_activation: f64,
fill: StopFill,
) -> Self {
StopConfig {
stop_loss: stop_loss.unwrap_or(f64::NEG_INFINITY),
take_profit: take_profit.unwrap_or(f64::INFINITY),
trail_stop: trail_stop.unwrap_or(f64::INFINITY),
trail_stop_activation,
fill,
}
}
}
#[derive(Debug, Clone)]
pub struct BacktestConfig {
pub fee_ratio: f64,
pub tax_ratio: f64,
pub position_limit: f64,
pub slippage_ratio: f64,
pub initial_capital: f64,
pub max_participation: f64,
pub impact_coef: f64,
pub delist_after: usize,
pub delist_haircut: f64,
pub benchmark_key: Option<String>,
pub bootstrap_samples: usize,
pub bootstrap_block: usize,
pub live_performance_start: Option<i32>,
pub stops: StopConfig,
}
impl Default for BacktestConfig {
fn default() -> Self {
BacktestConfig {
fee_ratio: 0.0,
tax_ratio: 0.0,
position_limit: 0.0,
slippage_ratio: 0.0,
initial_capital: 0.0,
max_participation: 0.0,
impact_coef: 0.0,
delist_after: 0,
delist_haircut: 0.0,
benchmark_key: None,
bootstrap_samples: 0,
bootstrap_block: 0,
live_performance_start: None,
stops: StopConfig::default(),
}
}
}