pub mod adx;
pub mod alligator;
pub mod anchored_vwap;
pub mod atr;
pub mod bbtrend;
pub mod bollinger;
pub mod bop;
pub mod bos_choch;
pub mod buy_sell_pressure;
pub mod candle_story;
pub mod cci;
pub mod chaikin_osc;
pub mod chande_kroll;
pub mod chandelier_exit;
pub mod chandelier_flip_radar;
pub mod chart_patterns;
pub mod choppiness;
pub mod connors_rsi;
pub mod coppock;
pub mod cvd_intrabar;
pub mod divergence;
pub mod dpo;
pub mod efficiency;
pub mod elliott;
pub mod envelope;
pub mod eom;
pub mod fisher_transform;
pub mod force_index;
pub mod harmonics;
pub mod kst;
pub mod liquidity_fvg;
pub mod liquidity_sweeps;
pub mod lsma;
pub mod macd;
pub mod market_structure_breaks;
pub mod mass_index;
pub mod mcginley;
pub mod mfi;
pub mod midas;
pub mod momentum_indicators;
pub mod money_flow_profile;
pub mod moving_averages;
pub mod multi_factor;
pub mod nvi_pvi;
pub mod order_block;
pub mod params;
pub mod pivot_sets;
pub mod pivots_structure;
pub mod pmo;
pub mod price_levels;
pub mod pvt;
pub mod rci;
pub mod registry;
pub mod relative_strength;
pub mod relative_volatility;
pub mod rsi;
pub mod rvat;
pub mod rvi;
pub mod smart_money_structure;
pub mod smi;
pub mod smoothing;
pub mod source_mapped;
pub mod stoch_rsi;
pub mod swing_structure;
pub mod t3;
pub mod tema;
pub mod trend_quality;
pub mod trend_relationship;
pub mod trend_structural;
pub mod trix;
pub mod tsi;
pub mod twap;
pub mod ulcer;
pub mod vidya;
pub mod vix_fix;
pub mod volatility_indicators;
pub mod volatility_regime;
pub mod volume_flow;
pub mod volume_flow_hires;
pub mod volume_indicators;
pub mod volume_profile;
pub mod volume_profile_extended;
pub mod volume_profile_persistent;
pub mod vortex;
pub mod vwap;
pub mod wavetrend;
pub mod williams_r;
pub mod wyckoff;
pub mod zigzag;
pub mod zigzag_advanced;
pub mod zscore;
use std::collections::HashMap;
use std::fmt;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::artifact::Artifact;
use crate::model::{Bar, BarValidationError, SeriesCapabilities};
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct IndicatorOutput {
pub value: f64,
pub secondary: Option<f64>,
pub signal: Option<f64>,
pub extra: HashMap<String, f64>,
pub state: Option<String>,
pub reason: Option<String>,
pub artifacts: Vec<Artifact>,
pub series_capabilities: Option<SeriesCapabilities>,
}
impl IndicatorOutput {
pub fn new(value: f64) -> Self {
Self {
value,
secondary: None,
signal: None,
extra: HashMap::new(),
state: None,
reason: None,
artifacts: Vec::new(),
series_capabilities: None,
}
}
pub fn with_secondary(mut self, secondary: f64) -> Self {
self.secondary = Some(secondary);
self
}
pub fn with_signal(mut self, signal: f64) -> Self {
self.signal = Some(signal);
self
}
pub fn with_extra(value: f64, extra: HashMap<String, f64>) -> Self {
Self {
value,
secondary: None,
signal: None,
extra,
state: None,
reason: None,
artifacts: Vec::new(),
series_capabilities: None,
}
}
pub fn with_state(mut self, state: impl Into<String>) -> Self {
self.state = Some(state.into());
self
}
pub fn with_reason(mut self, reason: impl Into<String>) -> Self {
self.reason = Some(reason.into());
self
}
pub fn with_artifact(mut self, artifact: impl Into<Artifact>) -> Self {
self.artifacts.push(artifact.into());
self
}
pub fn with_capabilities(mut self, capabilities: SeriesCapabilities) -> Self {
self.series_capabilities = Some(capabilities);
self
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct IndicatorAlert {
pub kind: String,
pub note: String,
pub strength: f64,
}
impl IndicatorAlert {
pub fn new(kind: impl Into<String>, note: impl Into<String>, strength: f64) -> Self {
Self {
kind: kind.into(),
note: note.into(),
strength,
}
}
}
impl fmt::Display for IndicatorAlert {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} ({})", self.note, self.kind)
}
}
pub trait Indicator: Send + Sync {
fn name(&self) -> &str;
fn warmup_period(&self) -> usize {
0
}
fn reset(&mut self);
fn on_bar(&mut self, bar: &Bar) -> Option<IndicatorOutput>;
fn on_checked_bar(&mut self, bar: &Bar) -> Result<Option<IndicatorOutput>, BarValidationError> {
bar.validate()?;
Ok(self.on_bar(bar))
}
fn alerts(&self) -> Vec<IndicatorAlert> {
Vec::new()
}
}
impl<T: Indicator + ?Sized> Indicator for Box<T> {
fn name(&self) -> &str {
(**self).name()
}
fn warmup_period(&self) -> usize {
(**self).warmup_period()
}
fn reset(&mut self) {
(**self).reset()
}
fn on_bar(&mut self, bar: &Bar) -> Option<IndicatorOutput> {
(**self).on_bar(bar)
}
fn on_checked_bar(&mut self, bar: &Bar) -> Result<Option<IndicatorOutput>, BarValidationError> {
(**self).on_checked_bar(bar)
}
fn alerts(&self) -> Vec<IndicatorAlert> {
(**self).alerts()
}
}