mod comparison;
mod composite;
mod threshold;
pub use comparison::*;
pub use composite::*;
pub use threshold::*;
use crate::constants::Interval;
use crate::indicators::Indicator;
use super::strategy::StrategyContext;
#[derive(Clone, Debug)]
pub struct HtfIndicatorSpec {
pub interval: Interval,
pub htf_key: String,
pub base_key: String,
pub indicator: Indicator,
pub utc_offset_secs: i64,
}
pub trait Condition: Clone + Send + Sync + 'static {
fn evaluate(&self, ctx: &StrategyContext) -> bool;
fn required_indicators(&self) -> Vec<(String, Indicator)>;
fn htf_requirements(&self) -> Vec<HtfIndicatorSpec> {
vec![]
}
fn description(&self) -> String;
fn and<C: Condition>(self, other: C) -> And<Self, C>
where
Self: Sized,
{
And::new(self, other)
}
fn or<C: Condition>(self, other: C) -> Or<Self, C>
where
Self: Sized,
{
Or::new(self, other)
}
fn not(self) -> Not<Self>
where
Self: Sized,
{
Not::new(self)
}
}
#[derive(Debug, Clone, Copy)]
pub struct ConstantCondition(bool);
impl ConstantCondition {
pub fn always_true() -> Self {
Self(true)
}
pub fn always_false() -> Self {
Self(false)
}
}
impl Condition for ConstantCondition {
fn evaluate(&self, _ctx: &StrategyContext) -> bool {
self.0
}
fn required_indicators(&self) -> Vec<(String, Indicator)> {
vec![]
}
fn description(&self) -> String {
if self.0 {
"always true".to_string()
} else {
"always false".to_string()
}
}
}
#[inline]
pub fn always_true() -> ConstantCondition {
ConstantCondition::always_true()
}
#[inline]
pub fn always_false() -> ConstantCondition {
ConstantCondition::always_false()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_constant_conditions() {
assert_eq!(always_true().description(), "always true");
assert_eq!(always_false().description(), "always false");
}
}