Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Sliding Features

Modular, chainable sliding window with various signal processing functions and technical indicators including normalization. Values in window are updated with each call to update. A View defines the function which processes the incoming values and provides an output value. Views can easily be added by implementing the View Trait which requires two functions:

  • update(&mut self, val: f64): Call whenever you have a new value with which to update the View
  • last(&self) -> f64: Retrieve the last value from the View

There are two ways of creating a new View:

  • new(view: Box, window_len: usize): Use if you want to chain another view to be calculated first
  • new_final(window_len: usize): Use if this View will be the last in the chain The last View which in each chain is always Echo, as this just echos the current value. Some Views have additional parameters such as ALMA. They can be created using the new_custom() function.

A SlidingWindow can be used to hold multiple chained views, which hast the following function:

  • new(): Create a new SlidingWindow
  • register_view(&mut self, view: Box): add a chainable View
  • update(&mut self, val: f64): Update all Views with a new value
  • last(&self) -> Vec: Get all the latest values from each View

This struct allows you to manage a bunch of Views at once and conveniently update them all.


In your Cargo.toml add the crate:

sliding_features = "0.6.0"

Basic single View example

/// Example showing how to use a single View
extern crate time_series_generator;

use sliding_features::*;
use time_series_generator::generate_standard_normal;

fn main() {
    let mut rsi = RSI::new_final(14);

    // generate dummy values
    let vals = generate_standard_normal(1024, 100.0);
    for r in &vals {
        rsi.update(*r); // update the rsi computation with the newest value
        let last = rsi.last(); // get the latest rsi value
        println!("last rsi value: {:?}", last);

See examples/ for the code Run the code using

cargo run --release --example basic_single_view

Basic Chainable Example

/// This Example provides a basic overview of chainable View definitions.
/// Assume you want to first transform your values with a Variance Stabilizing Centering Transform
//  and after that, smooth the values with an ALMA

// import the needed structs, and the View trait
use sliding_features::{View, ALMA, VSCT};

fn main() {
    // generate random value shifted up by 100.0 and scaled by 20.0,
    // a series which is neither centered around 0 nor variance stabilized
    let rands: Vec<f64> = (0..100)
        .map(|_| rand::random::<f64>() * 20.0 + 100.0)
    println!("rands: {:?}", rands);

    let window_len: usize = 20;
    let mut chain = ALMA::new(
        // first, define the last function which gets applied in the chain
        VSCT::new_final(window_len), // Make the first transformation in the chain a VSCT
    for v in &rands {
        // the chain will first call the inner most view, which is Echo.
        // after that it will apply the VSCT transform
        // and finally apply an Arnaux Legoux moving average
        let last_value = chain.last();
        println!("transformed value: {}", last_value);

See examples/ for the code Run the code using

cargo run --release --example basic_chainable_view

Multiple Sliding Features Example

/// Basic Example showing how to utilize a SlidingWindow to combine multiple chained views
use sliding_features::*;

fn main() {
    let mut sf = SlidingWindow::new();

    // lets register some of views, which will later be updated in a single step
    let window_len: usize = 16;
    // now a more complex view chain
        VSCT::new(SMA::new_final(window_len), window_len),

    // generate random dummy values
    let rands: Vec<f64> = (0..100)
        .map(|_| rand::random::<f64>() * 20.0 + 100.0)
    for r in &rands {
        sf.update(*r); // update all registered views with the newest value
        let last: Vec<f64> = sf.last(); // get the latest values from all views
        assert_eq!(last.len(), 3); // because there are 3 registered views we get three ordered values
        println!("last values: {:?}", last);

See examples/ for the code Run the code using

cargo run --release --example basic_multiple_views


A View defines the function which processes value updates. They currently include:

  • Echo
  • Technical Indicators
    • Center of Gravity
    • Cyber Cycle
    • Laguerre RSI
    • Laguerre Filter
    • ReFlex
    • TrendFlex
    • ROC
    • RSI
    • MyRSI (RSI in range [-1.0, 1.0])
    • NET (John Ehlers noise elimination technology using kendall correlation)
    • Correlation Trend Indicator (CTI)
    • Polarized Fractal Efficiency
    • Ehlers Fisher Transform
  • Normalization / variance / mean standardization
    • HLNormalizer, a sliding high-low normalizer
    • Variance Stabilizing Transform (VST)
    • Variance Stabilizing Centering Transform (VSCT)
  • Moving Averages
    • ALMA (Arnaux Legoux Moving Average)
    • SMA (Simple Moving Average)
    • EMA (Exponential Moving Average)
  • Standard deviation sliding window estimation using WelfordOnlineSliding
  • Multiplier
  • Entropy (acts on a bit stream, thus does not impl View trait)


Underlying data synthetically generated by MathisWellmann/time_series_generator-rs using a standard normal (gaussian) process. Note that each run uses common test data from for consistency.


Feel free to implement the following and create a PR for some easy open-source contributions:

  • Roofing Filter
  • MAMA
  • FAMA
  • Stochastic
  • Super Smoother
  • Zero Lag
  • gaussian filter
  • correlation cycle indicator
  • and so much more...


If you have a sliding window function or indicator which you would like to integrate, feel free to create a pull request. Any help is highly appreciated. Let's build the greatest sliding window library together 🤝

Donations 💰 💸

I you would like to support the development of this crate, feel free to send over a donation:

Monero (XMR) address:




Copyright (C) 2020 <MathisWellmann>

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see



Modular, chainable sliding windows wtih various signal processing functions such as normalization, RSI, ROC and other technical indicators.





No releases published


No packages published