1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
use super::{IndicatorInstance, IndicatorResult};
use crate::core::{Error, OHLCV};
/// Each indicator has it's own **Configuration** with parameters
///
/// Each that config should implement `IndicatorConfig` trait
///
/// See example with [`Example Indicator`](crate::indicators::example)
// Config cannot be Copy because it might consist ov Vec-s. F.e. if indicator using Conv method with custom weights.
pub trait IndicatorConfig: Clone {
/// Type of **State**
type Instance: IndicatorInstance<Config = Self>;
/// Name of an indicator
const NAME: &'static str;
/// Validates if **Configuration** is OK
fn validate(&self) -> bool;
/// Dynamically sets **Configuration** parameters
fn set(&mut self, name: &str, value: String) -> Result<(), Error>;
/// Returns an [`IndicatorResult`](crate::core::IndicatorResult) size processing by the indicator `(count of raw values, count of signals)`
fn size(&self) -> (u8, u8);
/// Initializes the **State** based on current **Configuration**
fn init<T: OHLCV>(self, initial_value: &T) -> Result<Self::Instance, Error>;
/// Returns a name of the indicator
fn name(&self) -> &'static str {
Self::NAME
}
/// Creates an `IndicatorInstance` function from this `IndicatorConfig`.
fn init_fn<'a, T: OHLCV>(
self,
initial_value: &'a T,
) -> Result<Box<dyn FnMut(&'a T) -> IndicatorResult>, Error>
where
Self: 'static,
{
let instance = self.init(initial_value)?;
Ok(instance.into_fn())
}
/// Evaluates indicator config over sequence of OHLC and returns sequence of `IndicatorResult`s
/// ```
/// use yata::prelude::*;
/// use yata::helpers::{RandomCandles};
/// use yata::indicators::Trix;
///
/// let candles: Vec<_> = RandomCandles::new().take(10).collect();
/// let trix = Trix::default();
/// let results = trix.over(&candles).unwrap();
/// println!("{:?}", results);
/// ```
fn over<T, S>(self, inputs: S) -> Result<Vec<IndicatorResult>, Error>
where
T: OHLCV,
S: AsRef<[T]>,
Self: Sized,
{
let inputs_ref = inputs.as_ref();
if inputs_ref.is_empty() {
return Ok(Vec::new());
}
let mut state = self.init(&inputs_ref[0])?;
Ok(IndicatorInstance::over(&mut state, inputs))
}
}