Skip to content

Commit

Permalink
Add WeightedMovingAverage indicator in rust (nautechsystems#1305)
Browse files Browse the repository at this point in the history
  • Loading branch information
filipmacek authored and ghill2 committed Oct 26, 2023
1 parent 76da888 commit 9640394
Show file tree
Hide file tree
Showing 22 changed files with 1,000 additions and 348 deletions.
2 changes: 1 addition & 1 deletion nautilus_core/indicators/src/average/ama.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ pub struct AdaptiveMovingAverage {
pub value: f64,
/// The input count for the indicator.
pub count: usize,
pub is_initialized: bool,
_efficiency_ratio: EfficiencyRatio,
_prior_value: Option<f64>,
_alpha_fast: f64,
_alpha_slow: f64,
has_inputs: bool,
is_initialized: bool,
}

impl Display for AdaptiveMovingAverage {
Expand Down
77 changes: 1 addition & 76 deletions nautilus_core/indicators/src/average/dema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use std::fmt::{Display, Formatter};

use anyhow::Result;
use nautilus_core::python::to_pyvalue_err;
use nautilus_model::{
data::{bar::Bar, quote::QuoteTick, trade::TradeTick},
enums::PriceType,
Expand All @@ -42,8 +41,8 @@ pub struct DoubleExponentialMovingAverage {
pub value: f64,
/// The input count for the indicator.
pub count: usize,
pub is_initialized: bool,
has_inputs: bool,
is_initialized: bool,
_ema1: ExponentialMovingAverage,
_ema2: ExponentialMovingAverage,
}
Expand Down Expand Up @@ -126,80 +125,6 @@ impl MovingAverage for DoubleExponentialMovingAverage {
}
}

#[cfg(feature = "python")]
#[pymethods]
impl DoubleExponentialMovingAverage {
#[new]
fn py_new(period: usize, price_type: Option<PriceType>) -> PyResult<Self> {
Self::new(period, price_type).map_err(to_pyvalue_err)
}

#[getter]
#[pyo3(name = "name")]
fn py_name(&self) -> String {
self.name()
}

#[getter]
#[pyo3(name = "period")]
fn py_period(&self) -> usize {
self.period
}

#[getter]
#[pyo3(name = "count")]
fn py_count(&self) -> usize {
self.count
}

#[getter]
#[pyo3(name = "value")]
fn py_value(&self) -> f64 {
self.value
}

#[getter]
#[pyo3(name = "has_inputs")]
fn py_has_inputs(&self) -> bool {
self.has_inputs()
}

#[getter]
#[pyo3(name = "initialized")]
fn py_initialized(&self) -> bool {
self.is_initialized
}

#[pyo3(name = "handle_quote_tick")]
fn py_handle_quote_tick(&mut self, tick: &QuoteTick) {
self.py_update_raw(tick.extract_price(self.price_type).into());
}

#[pyo3(name = "handle_trade_tick")]
fn py_handle_trade_tick(&mut self, tick: &TradeTick) {
self.update_raw((&tick.price).into());
}

#[pyo3(name = "handle_bar")]
fn py_handle_bar(&mut self, bar: &Bar) {
self.update_raw((&bar.close).into());
}

#[pyo3(name = "reset")]
fn py_reset(&mut self) {
self.reset();
}

#[pyo3(name = "update_raw")]
fn py_update_raw(&mut self, value: f64) {
self.update_raw(value);
}

fn __repr__(&self) -> String {
format!("DoubleExponentialMovingAverage({})", self.period)
}
}

////////////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////////////
Expand Down
83 changes: 1 addition & 82 deletions nautilus_core/indicators/src/average/ema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use std::fmt::Display;

use anyhow::Result;
use nautilus_core::python::to_pyvalue_err;
use nautilus_model::{
data::{bar::Bar, quote::QuoteTick, trade::TradeTick},
enums::PriceType,
Expand All @@ -34,8 +33,8 @@ pub struct ExponentialMovingAverage {
pub alpha: f64,
pub value: f64,
pub count: usize,
pub is_initialized: bool,
has_inputs: bool,
is_initialized: bool,
}

impl Display for ExponentialMovingAverage {
Expand Down Expand Up @@ -117,86 +116,6 @@ impl MovingAverage for ExponentialMovingAverage {
}
}

#[cfg(feature = "python")]
#[pymethods]
impl ExponentialMovingAverage {
#[new]
fn py_new(period: usize, price_type: Option<PriceType>) -> PyResult<Self> {
Self::new(period, price_type).map_err(to_pyvalue_err)
}

#[getter]
#[pyo3(name = "name")]
fn py_name(&self) -> String {
self.name()
}

#[getter]
#[pyo3(name = "period")]
fn py_period(&self) -> usize {
self.period
}

#[getter]
#[pyo3(name = "alpha")]
fn py_alpha(&self) -> f64 {
self.alpha
}

#[getter]
#[pyo3(name = "count")]
fn py_count(&self) -> usize {
self.count
}

#[getter]
#[pyo3(name = "value")]
fn py_value(&self) -> f64 {
self.value
}

#[getter]
#[pyo3(name = "has_inputs")]
fn py_has_inputs(&self) -> bool {
self.has_inputs()
}

#[getter]
#[pyo3(name = "initialized")]
fn py_initialized(&self) -> bool {
self.is_initialized
}

#[pyo3(name = "handle_quote_tick")]
fn py_handle_quote_tick(&mut self, tick: &QuoteTick) {
self.py_update_raw(tick.extract_price(self.price_type).into());
}

#[pyo3(name = "handle_trade_tick")]
fn py_handle_trade_tick(&mut self, tick: &TradeTick) {
self.update_raw((&tick.price).into());
}

#[pyo3(name = "handle_bar")]
fn py_handle_bar(&mut self, bar: &Bar) {
self.update_raw((&bar.close).into());
}

#[pyo3(name = "reset")]
fn py_reset(&mut self) {
self.reset();
}

#[pyo3(name = "update_raw")]
fn py_update_raw(&mut self, value: f64) {
self.update_raw(value);
}

fn __repr__(&self) -> String {
format!("ExponentialMovingAverage({})", self.period)
}
}

////////////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////////////
Expand Down
1 change: 1 addition & 0 deletions nautilus_core/indicators/src/average/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,4 @@ pub mod ama;
pub mod dema;
pub mod ema;
pub mod sma;
pub mod wma;
58 changes: 2 additions & 56 deletions nautilus_core/indicators/src/average/sma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use std::fmt::Display;

use anyhow::Result;
use nautilus_core::python::to_pyvalue_err;
use nautilus_model::{
data::{bar::Bar, quote::QuoteTick, trade::TradeTick},
enums::PriceType,
Expand All @@ -34,7 +33,7 @@ pub struct SimpleMovingAverage {
pub value: f64,
pub count: usize,
pub inputs: Vec<f64>,
is_initialized: bool,
pub is_initialized: bool,
}

impl Display for SimpleMovingAverage {
Expand Down Expand Up @@ -85,7 +84,7 @@ impl SimpleMovingAverage {
price_type: price_type.unwrap_or(PriceType::Last),
value: 0.0,
count: 0,
inputs: Vec::new(),
inputs: Vec::with_capacity(period),
is_initialized: false,
})
}
Expand Down Expand Up @@ -115,59 +114,6 @@ impl MovingAverage for SimpleMovingAverage {
}
}

#[cfg(feature = "python")]
#[pymethods]
impl SimpleMovingAverage {
#[new]
fn py_new(period: usize, price_type: Option<PriceType>) -> PyResult<Self> {
Self::new(period, price_type).map_err(to_pyvalue_err)
}

#[getter]
#[pyo3(name = "name")]
fn py_name(&self) -> String {
self.name()
}

#[getter]
#[pyo3(name = "period")]
fn py_period(&self) -> usize {
self.period
}

#[getter]
#[pyo3(name = "count")]
fn py_count(&self) -> usize {
self.count
}

#[getter]
#[pyo3(name = "value")]
fn py_value(&self) -> f64 {
self.value
}

#[getter]
#[pyo3(name = "initialized")]
fn py_initialized(&self) -> bool {
self.is_initialized
}

#[pyo3(name = "has_inputs")]
fn py_has_inputs(&self) -> bool {
self.has_inputs()
}

#[pyo3(name = "update_raw")]
fn py_update_raw(&mut self, value: f64) {
self.update_raw(value);
}

fn __repr__(&self) -> String {
format!("SimpleMovingAverage({})", self.period)
}
}

////////////////////////////////////////////////////////////////////////////////
// Test
////////////////////////////////////////////////////////////////////////////////
Expand Down
Loading

0 comments on commit 9640394

Please sign in to comment.