2026-03-23 23:34:28 +05:30
|
|
|
|
//! Streaming / Incremental Indicators — bar-by-bar stateful classes.
|
|
|
|
|
|
//!
|
2026-03-30 12:45:52 +05:30
|
|
|
|
//! Thin PyO3 wrappers that delegate to `ferro_ta_core::streaming`.
|
2026-03-23 23:34:28 +05:30
|
|
|
|
|
|
|
|
|
|
use pyo3::exceptions::PyValueError;
|
|
|
|
|
|
use pyo3::prelude::*;
|
|
|
|
|
|
|
2026-03-30 12:45:52 +05:30
|
|
|
|
use ferro_ta_core::streaming as core;
|
2026-03-23 23:34:28 +05:30
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
2026-03-30 12:45:52 +05:30
|
|
|
|
// Helper: convert core StreamingError to PyValueError
|
2026-03-23 23:34:28 +05:30
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
2026-03-30 12:45:52 +05:30
|
|
|
|
fn to_py_err(e: core::StreamingError) -> PyErr {
|
|
|
|
|
|
PyValueError::new_err(e.0)
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// StreamingSMA
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/// Simple Moving Average — O(1) per update via running sum.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// Returns NaN during the first `period - 1` bars.
|
|
|
|
|
|
#[pyclass(module = "ferro_ta._ferro_ta")]
|
|
|
|
|
|
pub struct StreamingSMA {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingSMA,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
|
|
impl StreamingSMA {
|
|
|
|
|
|
#[new]
|
|
|
|
|
|
#[pyo3(signature = (period))]
|
|
|
|
|
|
pub fn new(period: usize) -> PyResult<Self> {
|
|
|
|
|
|
Ok(Self {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingSMA::new(period).map_err(to_py_err)?,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a new bar and return the current SMA (NaN during warmup).
|
|
|
|
|
|
pub fn update(&mut self, value: f64) -> f64 {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.update(value)
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Reset state to initial condition.
|
|
|
|
|
|
pub fn reset(&mut self) {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.reset();
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[getter]
|
|
|
|
|
|
pub fn period(&self) -> usize {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.period()
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn __repr__(&self) -> String {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
format!("StreamingSMA(period={})", self.inner.period())
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// StreamingEMA
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/// Exponential Moving Average with SMA seeding.
|
|
|
|
|
|
#[pyclass(module = "ferro_ta._ferro_ta")]
|
|
|
|
|
|
pub struct StreamingEMA {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingEMA,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
|
|
impl StreamingEMA {
|
|
|
|
|
|
#[new]
|
|
|
|
|
|
#[pyo3(signature = (period))]
|
|
|
|
|
|
pub fn new(period: usize) -> PyResult<Self> {
|
|
|
|
|
|
Ok(Self {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingEMA::new(period).map_err(to_py_err)?,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a new bar and return the current EMA (NaN during warmup).
|
|
|
|
|
|
pub fn update(&mut self, value: f64) -> f64 {
|
|
|
|
|
|
self.inner.update(value)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn reset(&mut self) {
|
|
|
|
|
|
self.inner.reset();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[getter]
|
|
|
|
|
|
pub fn period(&self) -> usize {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.period()
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn __repr__(&self) -> String {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
format!("StreamingEMA(period={})", self.inner.period())
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// StreamingRSI
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/// Relative Strength Index with TA-Lib–compatible Wilder seeding.
|
|
|
|
|
|
#[pyclass(module = "ferro_ta._ferro_ta")]
|
|
|
|
|
|
pub struct StreamingRSI {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingRSI,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
|
|
impl StreamingRSI {
|
|
|
|
|
|
#[new]
|
|
|
|
|
|
#[pyo3(signature = (period = 14))]
|
|
|
|
|
|
pub fn new(period: usize) -> PyResult<Self> {
|
|
|
|
|
|
Ok(Self {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingRSI::new(period).map_err(to_py_err)?,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a new close and return RSI in [0, 100] (NaN during warmup).
|
|
|
|
|
|
pub fn update(&mut self, value: f64) -> f64 {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.update(value)
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn reset(&mut self) {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.reset();
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[getter]
|
|
|
|
|
|
pub fn period(&self) -> usize {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.period()
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn __repr__(&self) -> String {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
format!("StreamingRSI(period={})", self.inner.period())
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// StreamingATR
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/// Average True Range with TA-Lib–compatible Wilder seeding.
|
|
|
|
|
|
#[pyclass(module = "ferro_ta._ferro_ta")]
|
|
|
|
|
|
pub struct StreamingATR {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingATR,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
|
|
impl StreamingATR {
|
|
|
|
|
|
#[new]
|
|
|
|
|
|
#[pyo3(signature = (period = 14))]
|
|
|
|
|
|
pub fn new(period: usize) -> PyResult<Self> {
|
|
|
|
|
|
Ok(Self {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingATR::new(period).map_err(to_py_err)?,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a new bar (high, low, close) and return ATR (NaN during warmup).
|
|
|
|
|
|
pub fn update(&mut self, high: f64, low: f64, close: f64) -> f64 {
|
|
|
|
|
|
self.inner.update(high, low, close)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn reset(&mut self) {
|
|
|
|
|
|
self.inner.reset();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[getter]
|
|
|
|
|
|
pub fn period(&self) -> usize {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.period()
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn __repr__(&self) -> String {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
format!("StreamingATR(period={})", self.inner.period())
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// StreamingBBands
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
2026-03-30 12:45:52 +05:30
|
|
|
|
/// Bollinger Bands — streaming variant using Welford's online algorithm.
|
2026-03-23 23:34:28 +05:30
|
|
|
|
#[pyclass(module = "ferro_ta._ferro_ta")]
|
|
|
|
|
|
pub struct StreamingBBands {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingBBands,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
|
|
impl StreamingBBands {
|
|
|
|
|
|
#[new]
|
|
|
|
|
|
#[pyo3(signature = (period = 20, nbdevup = 2.0, nbdevdn = 2.0))]
|
|
|
|
|
|
pub fn new(period: usize, nbdevup: f64, nbdevdn: f64) -> PyResult<Self> {
|
|
|
|
|
|
Ok(Self {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingBBands::new(period, nbdevup, nbdevdn).map_err(to_py_err)?,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a new bar; return (upper, middle, lower). NaN tuple during warmup.
|
|
|
|
|
|
pub fn update(&mut self, value: f64) -> (f64, f64, f64) {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.update(value)
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn reset(&mut self) {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.reset();
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[getter]
|
|
|
|
|
|
pub fn period(&self) -> usize {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.period()
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn __repr__(&self) -> String {
|
|
|
|
|
|
format!(
|
2026-03-30 12:45:52 +05:30
|
|
|
|
"StreamingBBands(period={})",
|
|
|
|
|
|
self.inner.period()
|
2026-03-23 23:34:28 +05:30
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// StreamingMACD
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/// MACD — fast EMA, slow EMA, signal EMA.
|
|
|
|
|
|
#[pyclass(module = "ferro_ta._ferro_ta")]
|
|
|
|
|
|
pub struct StreamingMACD {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingMACD,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
|
|
impl StreamingMACD {
|
|
|
|
|
|
#[new]
|
|
|
|
|
|
#[pyo3(signature = (fastperiod = 12, slowperiod = 26, signalperiod = 9))]
|
|
|
|
|
|
pub fn new(fastperiod: usize, slowperiod: usize, signalperiod: usize) -> PyResult<Self> {
|
|
|
|
|
|
Ok(Self {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingMACD::new(fastperiod, slowperiod, signalperiod)
|
|
|
|
|
|
.map_err(to_py_err)?,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a new close; return (macd_line, signal_line, histogram).
|
|
|
|
|
|
pub fn update(&mut self, value: f64) -> (f64, f64, f64) {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.update(value)
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn reset(&mut self) {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.reset();
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn __repr__(&self) -> String {
|
|
|
|
|
|
format!(
|
|
|
|
|
|
"StreamingMACD(fastperiod={}, slowperiod={}, signalperiod={})",
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.fast_period(),
|
|
|
|
|
|
self.inner.slow_period(),
|
|
|
|
|
|
self.inner.signal_period()
|
2026-03-23 23:34:28 +05:30
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// StreamingStoch
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/// Slow Stochastic (SMA-smoothed).
|
|
|
|
|
|
#[pyclass(module = "ferro_ta._ferro_ta")]
|
|
|
|
|
|
pub struct StreamingStoch {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingStoch,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
|
|
impl StreamingStoch {
|
|
|
|
|
|
#[new]
|
|
|
|
|
|
#[pyo3(signature = (fastk_period = 5, slowk_period = 3, slowd_period = 3))]
|
|
|
|
|
|
pub fn new(fastk_period: usize, slowk_period: usize, slowd_period: usize) -> PyResult<Self> {
|
|
|
|
|
|
Ok(Self {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingStoch::new(fastk_period, slowk_period, slowd_period)
|
|
|
|
|
|
.map_err(to_py_err)?,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a new bar (high, low, close); return (slowk, slowd).
|
|
|
|
|
|
pub fn update(&mut self, high: f64, low: f64, close: f64) -> (f64, f64) {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.update(high, low, close)
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn reset(&mut self) {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.reset();
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn __repr__(&self) -> String {
|
|
|
|
|
|
format!(
|
2026-03-30 12:45:52 +05:30
|
|
|
|
"StreamingStoch(fastk_period={})",
|
|
|
|
|
|
self.inner.period()
|
2026-03-23 23:34:28 +05:30
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// StreamingVWAP
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/// Cumulative Volume Weighted Average Price.
|
|
|
|
|
|
#[pyclass(module = "ferro_ta._ferro_ta")]
|
|
|
|
|
|
pub struct StreamingVWAP {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingVWAP,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
|
|
impl StreamingVWAP {
|
|
|
|
|
|
#[new]
|
|
|
|
|
|
pub fn new() -> Self {
|
|
|
|
|
|
Self {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingVWAP::new(),
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a new bar (high, low, close, volume) and return cumulative VWAP.
|
|
|
|
|
|
pub fn update(&mut self, high: f64, low: f64, close: f64, volume: f64) -> f64 {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.update(high, low, close, volume)
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Reset for a new session.
|
|
|
|
|
|
pub fn reset(&mut self) {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.reset();
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn __repr__(&self) -> String {
|
|
|
|
|
|
"StreamingVWAP()".to_string()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// StreamingSupertrend
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/// ATR-based Supertrend — streaming variant.
|
|
|
|
|
|
#[pyclass(module = "ferro_ta._ferro_ta")]
|
|
|
|
|
|
pub struct StreamingSupertrend {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingSupertrend,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[pymethods]
|
|
|
|
|
|
impl StreamingSupertrend {
|
|
|
|
|
|
#[new]
|
|
|
|
|
|
#[pyo3(signature = (period = 7, multiplier = 3.0))]
|
|
|
|
|
|
pub fn new(period: usize, multiplier: f64) -> PyResult<Self> {
|
|
|
|
|
|
Ok(Self {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
inner: core::StreamingSupertrend::new(period, multiplier).map_err(to_py_err)?,
|
2026-03-23 23:34:28 +05:30
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Add a new bar (high, low, close); return (supertrend_line, direction).
|
|
|
|
|
|
pub fn update(&mut self, high: f64, low: f64, close: f64) -> (f64, i8) {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.update(high, low, close)
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn reset(&mut self) {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.reset();
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[getter]
|
|
|
|
|
|
pub fn period(&self) -> usize {
|
2026-03-30 12:45:52 +05:30
|
|
|
|
self.inner.period()
|
2026-03-23 23:34:28 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn __repr__(&self) -> String {
|
|
|
|
|
|
format!(
|
2026-03-30 12:45:52 +05:30
|
|
|
|
"StreamingSupertrend(period={})",
|
|
|
|
|
|
self.inner.period()
|
2026-03-23 23:34:28 +05:30
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// register
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
pub fn register(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
|
|
|
|
m.add_class::<StreamingSMA>()?;
|
|
|
|
|
|
m.add_class::<StreamingEMA>()?;
|
|
|
|
|
|
m.add_class::<StreamingRSI>()?;
|
|
|
|
|
|
m.add_class::<StreamingATR>()?;
|
|
|
|
|
|
m.add_class::<StreamingBBands>()?;
|
|
|
|
|
|
m.add_class::<StreamingMACD>()?;
|
|
|
|
|
|
m.add_class::<StreamingStoch>()?;
|
|
|
|
|
|
m.add_class::<StreamingVWAP>()?;
|
|
|
|
|
|
m.add_class::<StreamingSupertrend>()?;
|
|
|
|
|
|
Ok(())
|
|
|
|
|
|
}
|