mod computed;
mod htf;
mod price;
pub use computed::*;
pub use htf::*;
pub use price::*;
use crate::indicators::Indicator;
use super::strategy::StrategyContext;
pub trait IndicatorRef: Clone + Send + Sync + 'static {
fn key(&self) -> &str;
fn required_indicators(&self) -> Vec<(String, Indicator)>;
fn value(&self, ctx: &StrategyContext) -> Option<f64>;
fn prev_value(&self, ctx: &StrategyContext) -> Option<f64>;
}
pub trait IndicatorRefExt: IndicatorRef + Sized {
fn above(self, threshold: f64) -> super::condition::Above<Self> {
super::condition::Above::new(self, threshold)
}
fn above_ref<R: IndicatorRef>(self, other: R) -> super::condition::AboveRef<Self, R> {
super::condition::AboveRef::new(self, other)
}
fn below(self, threshold: f64) -> super::condition::Below<Self> {
super::condition::Below::new(self, threshold)
}
fn below_ref<R: IndicatorRef>(self, other: R) -> super::condition::BelowRef<Self, R> {
super::condition::BelowRef::new(self, other)
}
fn crosses_above(self, threshold: f64) -> super::condition::CrossesAbove<Self> {
super::condition::CrossesAbove::new(self, threshold)
}
fn crosses_above_ref<R: IndicatorRef>(
self,
other: R,
) -> super::condition::CrossesAboveRef<Self, R> {
super::condition::CrossesAboveRef::new(self, other)
}
fn crosses_below(self, threshold: f64) -> super::condition::CrossesBelow<Self> {
super::condition::CrossesBelow::new(self, threshold)
}
fn crosses_below_ref<R: IndicatorRef>(
self,
other: R,
) -> super::condition::CrossesBelowRef<Self, R> {
super::condition::CrossesBelowRef::new(self, other)
}
fn between(self, low: f64, high: f64) -> super::condition::Between<Self> {
super::condition::Between::new(self, low, high)
}
fn equals(self, value: f64, tolerance: f64) -> super::condition::Equals<Self> {
super::condition::Equals::new(self, value, tolerance)
}
}
impl<T: IndicatorRef + Sized> IndicatorRefExt for T {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_indicator_ref_ext_methods_exist() {
let _sma = sma(20);
let _ema = ema(12);
let _rsi = rsi(14);
assert_eq!(_sma.key(), "sma_20");
assert_eq!(_ema.key(), "ema_12");
assert_eq!(_rsi.key(), "rsi_14");
}
}