indexes_rs/v2/obv/
types.rs

1use serde::{Deserialize, Serialize};
2
3/// Configuration for OBV calculation
4#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
5pub struct OBVConfig {
6    /// Whether to use cumulative calculation (default: true)
7    pub cumulative: bool,
8}
9
10impl Default for OBVConfig {
11    fn default() -> Self {
12        Self { cumulative: true }
13    }
14}
15
16/// Input data for OBV calculation
17#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
18pub struct OBVInput {
19    /// Current closing price
20    pub close: f64,
21    /// Current volume
22    pub volume: f64,
23}
24
25/// Output from OBV calculation
26#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
27pub struct OBVOutput {
28    /// On Balance Volume value
29    pub obv: f64,
30    /// Optional: Volume flow direction (1.0 = up, -1.0 = down, 0.0 = unchanged)
31    pub flow_direction: f64,
32}
33
34/// OBV calculation state
35#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
36pub struct OBVState {
37    /// Previous closing price
38    pub previous_close: Option<f64>,
39    /// Current cumulative OBV value
40    pub cumulative_obv: f64,
41    /// Configuration
42    pub config: OBVConfig,
43    /// Whether this is the first calculation
44    pub is_first: bool,
45}
46
47impl OBVState {
48    pub fn new(config: OBVConfig) -> Self {
49        Self {
50            previous_close: None,
51            cumulative_obv: 0.0,
52            config,
53            is_first: true,
54        }
55    }
56}
57
58/// Error types for OBV calculation
59#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
60pub enum OBVError {
61    /// Invalid input data
62    InvalidInput(String),
63    /// Negative volume provided
64    NegativeVolume,
65    /// Invalid price (NaN or infinite)
66    InvalidPrice,
67}