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