wickra_embed_core/ohlcv.rs
1//! The [`Candle`] OHLC bar — the `Copy` input type for candle indicators.
2
3use crate::math;
4
5/// One OHLCV bar.
6///
7/// Field order and semantics match `wickra_core::ohlcv::Candle`, so a candle
8/// built here feeds the parity oracle unchanged. `Copy` keeps the indicator
9/// update path allocation- and clone-free.
10#[derive(Debug, Clone, Copy, PartialEq)]
11pub struct Candle {
12 /// Bar open price.
13 pub open: f64,
14 /// Bar high price.
15 pub high: f64,
16 /// Bar low price.
17 pub low: f64,
18 /// Bar close price.
19 pub close: f64,
20 /// Bar volume.
21 pub volume: f64,
22 /// Bar timestamp (caller-defined epoch / resolution).
23 pub timestamp: i64,
24}
25
26impl Candle {
27 /// Construct a candle from its fields. Unlike the std `Candle::new`, this is
28 /// a plain `const` constructor with no validation: on bare metal the caller
29 /// (the C ABI, the firmware) is trusted to pass finite, ordered OHLC values,
30 /// and a validating constructor would add a panic path the core forbids.
31 #[must_use]
32 pub const fn new(
33 open: f64,
34 high: f64,
35 low: f64,
36 close: f64,
37 volume: f64,
38 timestamp: i64,
39 ) -> Self {
40 Self {
41 open,
42 high,
43 low,
44 close,
45 volume,
46 timestamp,
47 }
48 }
49
50 /// True range for this bar given the previous close, identical to
51 /// `wickra-core`: `max(high - low, |high - prev|, |low - prev|)`, or just
52 /// `high - low` for the first bar.
53 #[must_use]
54 pub fn true_range(&self, prev_close: Option<f64>) -> f64 {
55 let hl = self.high - self.low;
56 match prev_close {
57 Some(prev) => {
58 let hp = math::abs(self.high - prev);
59 let lp = math::abs(self.low - prev);
60 math::max(math::max(hl, hp), lp)
61 }
62 None => hl,
63 }
64 }
65}