nautilus_indicators/python/volatility/
kc.rs1use nautilus_core::python::to_pyvalue_err;
17use nautilus_model::data::Bar;
18use pyo3::prelude::*;
19
20use crate::{
21 average::MovingAverageType, indicator::Indicator, python::float_precision,
22 volatility::kc::KeltnerChannel,
23};
24
25#[pymethods]
26#[pyo3_stub_gen::derive::gen_stub_pymethods]
27impl KeltnerChannel {
28 #[new]
30 #[pyo3(signature = (period, k_multiplier, atr_period=None, ma_type=None, ma_type_atr=None, use_previous=None, atr_floor=None))]
31 pub fn py_new(
32 period: usize,
33 k_multiplier: f64,
34 atr_period: Option<usize>,
35 ma_type: Option<MovingAverageType>,
36 ma_type_atr: Option<MovingAverageType>,
37 use_previous: Option<bool>,
38 atr_floor: Option<f64>,
39 ) -> PyResult<Self> {
40 Self::new_checked(
41 period,
42 k_multiplier,
43 atr_period,
44 ma_type,
45 ma_type_atr,
46 use_previous,
47 atr_floor,
48 )
49 .map_err(to_pyvalue_err)
50 }
51
52 fn __repr__(&self) -> String {
53 format!("KeltnerChannel({})", self.period)
54 }
55
56 #[getter]
57 #[pyo3(name = "ma_type")]
58 const fn py_ma_type(&self) -> MovingAverageType {
59 self.ma_type
60 }
61
62 #[getter]
63 #[pyo3(name = "ma_type_atr")]
64 const fn py_ma_type_atr(&self) -> MovingAverageType {
65 self.ma_type_atr
66 }
67
68 #[getter]
69 #[pyo3(name = "atr_period")]
70 const fn py_atr_period(&self) -> usize {
71 self.atr_period
72 }
73
74 #[getter]
75 #[pyo3(name = "name")]
76 fn py_name(&self) -> String {
77 self.name()
78 }
79
80 #[getter]
81 #[pyo3(name = "period")]
82 const fn py_period(&self) -> usize {
83 self.period
84 }
85
86 #[getter]
87 #[pyo3(name = "k_multiplier")]
88 const fn py_k_multiplier(&self) -> f64 {
89 self.k_multiplier
90 }
91
92 #[getter]
93 #[pyo3(name = "use_previous")]
94 const fn py_use_previous(&self) -> bool {
95 self.use_previous
96 }
97
98 #[getter]
99 #[pyo3(name = "atr_floor")]
100 const fn py_atr_floor(&self) -> f64 {
101 self.atr_floor
102 }
103
104 #[getter]
105 #[pyo3(name = "has_inputs")]
106 fn py_has_inputs(&self) -> bool {
107 self.has_inputs()
108 }
109
110 #[getter]
111 #[pyo3(name = "upper")]
112 const fn py_upper(&self) -> f64 {
113 self.upper
114 }
115
116 #[getter]
117 #[pyo3(name = "middle")]
118 const fn py_middle(&self) -> f64 {
119 self.middle
120 }
121
122 #[getter]
123 #[pyo3(name = "lower")]
124 const fn py_lower(&self) -> f64 {
125 self.lower
126 }
127
128 #[getter]
129 #[pyo3(name = "initialized")]
130 const fn py_initialized(&self) -> bool {
131 self.initialized
132 }
133
134 #[pyo3(name = "update_raw")]
135 fn py_update_raw(&mut self, high: f64, low: f64, close: f64) {
136 self.update_raw(high, low, close);
137 }
138
139 #[pyo3(name = "handle_bar")]
140 fn py_handle_bar(&mut self, bar: &Bar) -> PyResult<()> {
141 float_precision::check_bar(bar)?;
142 self.handle_bar(bar);
143 Ok(())
144 }
145
146 #[pyo3(name = "reset")]
147 fn py_reset(&mut self) {
148 self.reset();
149 }
150}