indexes_rs/v2/cci/
types.rs

1use serde::{Deserialize, Serialize};
2use std::collections::VecDeque;
3
4/// Configuration for CCI calculation
5#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
6pub struct CCIConfig {
7    /// Period for CCI calculation (default: 20)
8    pub period: usize,
9    /// Overbought threshold (default: 100.0)
10    pub overbought: f64,
11    /// Oversold threshold (default: -100.0)
12    pub oversold: f64,
13    /// Extreme overbought threshold (default: 200.0)
14    pub extreme_overbought: f64,
15    /// Extreme oversold threshold (default: -200.0)
16    pub extreme_oversold: f64,
17}
18
19impl Default for CCIConfig {
20    fn default() -> Self {
21        Self {
22            period: 20,
23            overbought: 100.0,
24            oversold: -100.0,
25            extreme_overbought: 200.0,
26            extreme_oversold: -200.0,
27        }
28    }
29}
30
31/// Input data for CCI calculation
32#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
33pub struct CCIInput {
34    /// High price
35    pub high: f64,
36    /// Low price
37    pub low: f64,
38    /// Close price
39    pub close: f64,
40}
41
42/// Market condition based on CCI value
43#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
44pub enum CCIMarketCondition {
45    /// CCI above extreme overbought threshold
46    ExtremeOverbought,
47    /// CCI above overbought threshold
48    Overbought,
49    /// CCI in normal range
50    Normal,
51    /// CCI below oversold threshold
52    Oversold,
53    /// CCI below extreme oversold threshold
54    ExtremeOversold,
55    /// Not enough data yet
56    Insufficient,
57}
58
59/// Output from CCI calculation
60#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
61pub struct CCIOutput {
62    /// Commodity Channel Index value
63    pub cci: f64,
64    /// Current typical price ((H+L+C)/3)
65    pub typical_price: f64,
66    /// Simple moving average of typical price
67    pub sma_tp: f64,
68    /// Mean absolute deviation
69    pub mean_deviation: f64,
70    /// Market condition based on thresholds
71    pub market_condition: CCIMarketCondition,
72    /// Distance from zero (absolute CCI value)
73    pub distance_from_zero: f64,
74}
75
76/// CCI calculation state
77#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
78pub struct CCIState {
79    /// Configuration
80    pub config: CCIConfig,
81    /// History of typical prices
82    pub typical_prices: VecDeque<f64>,
83    /// Sum of typical prices (for SMA calculation)
84    pub tp_sum: f64,
85    /// Whether we have enough data for calculation
86    pub has_sufficient_data: bool,
87}
88
89impl CCIState {
90    pub fn new(config: CCIConfig) -> Self {
91        Self {
92            config,
93            typical_prices: VecDeque::with_capacity(config.period),
94            tp_sum: 0.0,
95            has_sufficient_data: false,
96        }
97    }
98}
99
100/// Error types for CCI calculation
101#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
102pub enum CCIError {
103    /// Invalid input data
104    InvalidInput(String),
105    /// Invalid HLC relationship (e.g., high < low)
106    InvalidHLC,
107    /// Invalid price (NaN or infinite)
108    InvalidPrice,
109    /// Invalid period (must be > 0)
110    InvalidPeriod,
111    /// Invalid threshold values
112    InvalidThresholds,
113    /// Division by zero in calculation
114    DivisionByZero,
115}