use super::{IndicatorConfig, IndicatorInstance, IndicatorResult};
use crate::core::{Error, OHLCV};
pub trait IndicatorConfigDyn<T: OHLCV> {
fn init(&self, initial_value: &T) -> Result<Box<dyn IndicatorInstanceDyn<T>>, Error>;
fn over(&self, inputs: &dyn AsRef<[T]>) -> Result<Vec<IndicatorResult>, Error>;
fn name(&self) -> &'static str;
fn validate(&self) -> bool;
fn set(&mut self, name: &str, value: String) -> Result<(), Error>;
fn size(&self) -> (u8, u8);
}
impl<T, I, C> IndicatorConfigDyn<T> for C
where
T: OHLCV,
I: IndicatorInstanceDyn<T> + IndicatorInstance<Config = Self> + 'static,
C: IndicatorConfig<Instance = I> + Clone + 'static,
{
fn init(&self, initial_value: &T) -> Result<Box<dyn IndicatorInstanceDyn<T>>, Error> {
let instance = IndicatorConfig::init(self.clone(), initial_value)?;
Ok(Box::new(instance))
}
fn over(&self, inputs: &dyn AsRef<[T]>) -> Result<Vec<IndicatorResult>, Error> {
IndicatorConfig::over(self.clone(), inputs)
}
fn name(&self) -> &'static str {
<Self as IndicatorConfig>::NAME
}
fn validate(&self) -> bool {
IndicatorConfig::validate(self)
}
fn set(&mut self, name: &str, value: String) -> Result<(), Error> {
IndicatorConfig::set(self, name, value)
}
fn size(&self) -> (u8, u8) {
IndicatorConfig::size(self)
}
}
pub trait IndicatorInstanceDyn<T: OHLCV> {
fn next(&mut self, candle: &T) -> IndicatorResult;
fn over(&mut self, inputs: &dyn AsRef<[T]>) -> Vec<IndicatorResult>;
fn config(&self) -> &dyn IndicatorConfigDyn<T>;
fn size(&self) -> (u8, u8);
fn name(&self) -> &'static str;
}
impl<T, I> IndicatorInstanceDyn<T> for I
where
T: OHLCV,
I: IndicatorInstance + 'static,
{
fn next(&mut self, candle: &T) -> IndicatorResult {
IndicatorInstance::next(self, candle)
}
fn over(&mut self, inputs: &dyn AsRef<[T]>) -> Vec<IndicatorResult> {
IndicatorInstance::over(self, inputs)
}
fn config(&self) -> &dyn IndicatorConfigDyn<T> {
self.config()
}
fn size(&self) -> (u8, u8) {
IndicatorInstance::size(self)
}
fn name(&self) -> &'static str {
IndicatorInstance::name(self)
}
}