nautilus_indicators/python/ratio/
efficiency_ratio.rs1use nautilus_core::python::to_pyvalue_err;
17use nautilus_model::{
18 data::Bar,
19 enums::PriceType,
20 types::{Money, Price, Quantity},
21};
22use pyo3::prelude::*;
23
24use crate::{
25 indicator::Indicator, python::float_precision, ratio::efficiency_ratio::EfficiencyRatio,
26};
27
28#[pymethods]
29#[pyo3_stub_gen::derive::gen_stub_pymethods]
30impl EfficiencyRatio {
31 #[new]
51 #[pyo3(signature = (period, price_type=None))]
52 fn py_new(period: usize, price_type: Option<PriceType>) -> PyResult<Self> {
53 Self::new_checked(period, price_type).map_err(to_pyvalue_err)
54 }
55
56 fn __repr__(&self) -> String {
57 format!("EfficiencyRatio({})", self.period)
58 }
59
60 #[getter]
61 #[pyo3(name = "name")]
62 fn py_name(&self) -> String {
63 self.name()
64 }
65
66 #[getter]
67 #[pyo3(name = "period")]
68 const fn py_period(&self) -> usize {
69 self.period
70 }
71
72 #[getter]
73 #[pyo3(name = "value")]
74 const fn py_value(&self) -> f64 {
75 self.value
76 }
77
78 #[getter]
79 #[pyo3(name = "initialized")]
80 const fn py_initialized(&self) -> bool {
81 self.initialized
82 }
83
84 #[getter]
85 #[pyo3(name = "has_inputs")]
86 fn py_has_inputs(&self) -> bool {
87 self.has_inputs()
88 }
89
90 #[pyo3(name = "update_raw")]
91 fn py_update_raw(
92 &mut self,
93 #[gen_stub(override_type(type_repr = "float"))] value: &Bound<'_, PyAny>,
94 ) -> PyResult<()> {
95 let value = extract_update_value(value)?;
96 self.update_raw(value);
97 Ok(())
98 }
99
100 #[pyo3(name = "handle_bar")]
101 fn py_handle_bar(&mut self, bar: &Bar) -> PyResult<()> {
102 float_precision::check_bar(bar)?;
103
104 self.handle_bar(bar);
105 Ok(())
106 }
107
108 #[pyo3(name = "reset")]
109 fn py_reset(&mut self) {
110 self.reset();
111 }
112}
113
114fn extract_update_value(value: &Bound<'_, PyAny>) -> PyResult<f64> {
115 if value.is_instance_of::<Price>() {
116 let price = value.extract::<Price>()?;
117 float_precision::check(price.precision)?;
118 return Ok(price.as_f64());
119 }
120
121 if value.is_instance_of::<Quantity>() {
122 let quantity = value.extract::<Quantity>()?;
123 float_precision::check(quantity.precision)?;
124 return Ok(quantity.as_f64());
125 }
126
127 if value.is_instance_of::<Money>() {
128 let money = value.extract::<Money>()?;
129 float_precision::check(money.currency.precision)?;
130 return Ok(money.as_f64());
131 }
132
133 value.extract()
134}