Skip to main content

nautilus_indicators/python/average/
ama.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16use nautilus_core::python::to_pyvalue_err;
17use nautilus_model::{
18    data::{Bar, QuoteTick, TradeTick},
19    enums::PriceType,
20};
21use pyo3::prelude::*;
22
23use crate::{
24    average::ama::AdaptiveMovingAverage,
25    indicator::{Indicator, MovingAverage},
26};
27
28#[pyo3_stub_gen::derive::gen_stub_pymethods]
29#[pymethods]
30impl AdaptiveMovingAverage {
31    /// An indicator which calculates an adaptive moving average (AMA) across a
32    /// rolling window. Developed by Perry Kaufman, the AMA is a moving average
33    /// designed to account for market noise and volatility. The AMA will closely
34    /// follow prices when the price swings are relatively small and the noise is
35    /// low. The AMA will increase lag when the price swings increase.
36    #[new]
37    #[pyo3(signature = (period_efficiency_ratio, period_fast, period_slow, price_type=None))]
38    pub fn py_new(
39        period_efficiency_ratio: usize,
40        period_fast: usize,
41        period_slow: usize,
42        price_type: Option<PriceType>,
43    ) -> PyResult<Self> {
44        Self::new_checked(
45            period_efficiency_ratio,
46            period_fast,
47            period_slow,
48            price_type,
49        )
50        .map_err(to_pyvalue_err)
51    }
52
53    fn __repr__(&self) -> String {
54        format!(
55            "WeightedMovingAverage({}({},{},{})",
56            self.name(),
57            self.period_efficiency_ratio,
58            self.period_fast,
59            self.period_slow
60        )
61    }
62
63    #[getter]
64    #[pyo3(name = "name")]
65    fn py_name(&self) -> String {
66        self.name()
67    }
68
69    #[getter]
70    #[pyo3(name = "period_efficiency_ratio")]
71    const fn py_period_efficiency_ratio(&self) -> usize {
72        self.period_efficiency_ratio
73    }
74
75    #[getter]
76    #[pyo3(name = "period_fast")]
77    const fn py_period_fast(&self) -> usize {
78        self.period_fast
79    }
80
81    #[getter]
82    #[pyo3(name = "period_slow")]
83    const fn py_period_slow(&self) -> usize {
84        self.period_slow
85    }
86
87    #[getter]
88    #[pyo3(name = "alpha_fast")]
89    const fn py_alpha_fast(&self) -> f64 {
90        self.alpha_fast()
91    }
92
93    #[getter]
94    #[pyo3(name = "alpha_slow")]
95    const fn py_alpha_slow(&self) -> f64 {
96        self.alpha_slow()
97    }
98
99    #[getter]
100    #[pyo3(name = "alpha_diff")]
101    fn py_alpha_diff(&self) -> f64 {
102        self.alpha_diff()
103    }
104
105    #[getter]
106    #[pyo3(name = "price_type")]
107    const fn py_price_type(&self) -> PriceType {
108        self.price_type
109    }
110
111    #[getter]
112    #[pyo3(name = "value")]
113    const fn py_value(&self) -> f64 {
114        self.value
115    }
116
117    #[getter]
118    #[pyo3(name = "count")]
119    const fn py_count(&self) -> usize {
120        self.count
121    }
122
123    #[getter]
124    #[pyo3(name = "has_inputs")]
125    fn py_has_inputs(&self) -> bool {
126        self.has_inputs()
127    }
128
129    #[getter]
130    #[pyo3(name = "initialized")]
131    const fn py_initialized(&self) -> bool {
132        self.initialized
133    }
134
135    #[pyo3(name = "handle_quote_tick")]
136    fn py_handle_quote_tick(&mut self, quote: &QuoteTick) -> PyResult<()> {
137        self.handle_quote(quote).map_err(to_pyvalue_err)
138    }
139
140    #[pyo3(name = "handle_trade_tick")]
141    fn py_handle_trade_tick(&mut self, trade: &TradeTick) {
142        self.handle_trade(trade);
143    }
144
145    #[pyo3(name = "handle_bar")]
146    fn py_handle_bar(&mut self, bar: &Bar) {
147        self.handle_bar(bar);
148    }
149
150    #[pyo3(name = "reset")]
151    fn py_reset(&mut self) {
152        self.reset();
153    }
154
155    #[pyo3(name = "update_raw")]
156    fn py_update_raw(&mut self, value: f64) {
157        self.update_raw(value);
158    }
159}