Operations & Indicators
Streaming operations chained on Comp — moving averages, statistics, derivatives, signal conditioning — plus financial technical-analysis indicators in the optional tflo-fintech plugin.
Two crates, one API surface.
Generic temporal event processing operations (SMA, EMA, RSI, std, correlation, derivatives, deviation bands,
z-score, …) live in tflo-ops — add it alongside tflo-core and import with use tflo_ops::prelude::*;.
Financial indicators (MACD, ADX, ATR, KAMA, Stochastic, CCI, OBV, VWAP, …) live in the
tflo-fintech plugin. Add the crate and bring it into scope with
use tflo_fintech::prelude::*; to get the FintechIndicators trait.
Its FintechAliases trait also re-exposes finance names for renamed core ops
(bollinger_bands, drawdown, roc_n, mom_n).
Usage Examples
SMA
//! Full runnable example: tflo-examples/examples/docs-indicators
// use tflo_core::prelude::*; use tflo_ops::prelude::*;
let sma = value.sma(20_u64.secs()); // 20-second SMA (time-based)
let sma = value.sma(20usize); // 20-tick SMA (count-based) SMA(20) Demo
A 20-period Simple Moving Average on a sine wave feed.
RSI
//! Full runnable example: tflo-examples/examples/docs-indicators
// use tflo_core::prelude::*; use tflo_ops::prelude::*;
let rsi = value.rsi(14usize); // 14-period RSI (count-based)
let rsi = value.rsi(14_u64.secs()); // 14-second RSI (time-based) MACD
// MACD lives in the tflo-fintech plugin.
use tflo_fintech::prelude::*;
let (macd_line, signal_line, histogram) = price.macd_n(
12, // fast period
26, // slow period
9, // signal period
); RSI(14) Demo
A 14-period RSI on a noisy sine wave feed.
Deviation Band (Bollinger Bands)
//! Full runnable example: tflo-examples/examples/docs-indicators
// use tflo_core::prelude::*; use tflo_ops::prelude::*;
// deviation_band is provided by the Composites trait from tflo-ops.
let (middle, upper, lower) = value.deviation_band(
20usize, // window (also accepts Duration via .secs())
2.0, // multiplier (k)
);
// tflo-fintech's FintechAliases trait also exposes the finance name:
// use tflo_fintech::prelude::*;
// let (middle, upper, lower) = price.bollinger_bands(20usize, 2.0); Combining Multiple Operations
//! Full runnable example: tflo-examples/examples/docs-indicators
use tflo_core::prelude::*;
use tflo_ops::prelude::*;
let results = events.into_iter()
.tflo(|t| {
t.timestamp(|x| x.ts);
let value = t.prop(|x| x.value);
let weight = t.prop(|x| x.weight);
// Bundle everything into a tuple
let sma = value.sma(20_u64.secs());
let ema = value.ema(20_u64.secs());
let rsi = value.rsi(14usize);
let weight_sma = weight.sma(100usize);
(sma, ema, rsi, weight_sma)
})
.collect();
// Catalog ops come from tflo-ops (WindowOps, StatefulOps, CrossOps, etc.) Bollinger Bands(20, 2) Demo
Bollinger Bands with period 20 and multiplier 2.0 on a sine wave feed.
Cross Detection Demo
A cross detection demo showing price crossing a threshold of 70 on a step feed.
All operations are chainable methods on Comp<R,f64>. The catalog ops (sma, ema, rsi, detectors, etc.) are defined as extension traits in
tflo-ops/src/ops/;
financial indicators come from the FintechIndicators trait in tflo-fintech.
Bring in the catalog with use tflo_ops::prelude::*; alongside use tflo_core::prelude::*;.
Windowed ops accept impl Into<Window> — pass a Duration (.sma(5_u64.secs()))
for time-based windows, or a usize (.sma(20usize)) for count-based windows.
Core node = dedicated Comp variant; Composite = composed from other primitives via scan_f64 / scan2_f64.
The Crate column shows whether an op ships in tflo-ops or the tflo-fintech plugin.
Operation Inventory
Moving Averages (7)
| Indicator | Method | Kind | Crate | Description |
|---|---|---|---|---|
| SMA | .sma(window) | Core node | tflo-ops | Simple Moving Average |
| EMA | .ema(window) | Core node | tflo-ops | Exponential Moving Average (time- or count-based decay) |
| WMA | .wma(window) | Core node | tflo-ops | Weighted Moving Average with linearly increasing weights |
| TRIMA | .trima(n) | Composite | tflo-fintech | Triangular MA — SMA of SMA |
| DEMA | .dema_n(n) | Composite | tflo-fintech | Double Exponential MA: 2*EMA(x) - EMA(EMA(x)) |
| TEMA | .tema_n(n) | Composite | tflo-fintech | Triple Exponential MA: 3*EMA1 - 3*EMA2 + EMA3 |
| KAMA | .kama_n(n) | Composite | tflo-fintech | Kaufman Adaptive MA with efficiency ratio |
Momentum Oscillators (14)
| Indicator | Method | Kind | Crate | Description |
|---|---|---|---|---|
| RSI | .rsi(window) | Core node | tflo-ops | Relative Strength Index (0–100) |
| RSI Wilder | .rsi_wilder_n(n) | Core node | tflo-ops | Wilder's smoothed RSI — matches TradingView / TA-Lib |
| Momentum | .momentum(n) | Composite | tflo-ops | value - value(n ago) (finance alias: mom_n) |
| Rate of Change | .rate_of_change(n) | Composite | tflo-ops | Rate of Change percentage (finance alias: roc_n) |
| MACD | .macd_n(fast, slow, signal) | Composite | tflo-fintech | Returns (line, signal, histogram) |
| Stochastic | .stochastic_n(k, d) | Composite | tflo-fintech | Returns (%K, %D) |
| Stochastic OHLC | .stochastic_ohlc_n(high, low, k, d) | Composite | tflo-fintech | Stochastic with explicit high/low inputs |
| Williams %R | .williams_r_n(n) | Composite | tflo-fintech | Range –100 to 0 |
| Williams %R OHLC | .williams_r_ohlc_n(high, low, n) | Composite | tflo-fintech | Williams %R with explicit high/low |
| CCI | .cci_n(n) | Composite | tflo-fintech | Commodity Channel Index |
| CMO | .cmo_n(n) | Composite | tflo-fintech | Chande Momentum Oscillator (–100 to +100) |
| PPO | .ppo_n(fast, slow) | Composite | tflo-fintech | Percentage Price Oscillator |
| TRIX | .trix_n(n) | Composite | tflo-fintech | Rate of change of triple-smoothed EMA |
| StochRSI | .stochrsi_n(rsi_period, fastk, fastd) | Composite | tflo-fintech | Returns (fast_k, fast_d) |
For output identical to TradingView and TA-Lib, use the Wilder's smoothed RSI variant via .rsi_wilder_n(n).
Golden vector tests validating the financial indicators against these platforms live at tflo-fintech/tests/golden/:
// Wilder's RSI (TradingView compatible) — via tflo-ops:
// use tflo_core::prelude::*; use tflo_ops::prelude::*;
let rsi = value.rsi_wilder_n(14);
// See tflo-fintech/tests/golden/ for validation against TA-Lib/TradingView Volatility (6)
| Indicator | Method | Kind | Crate | Description |
|---|---|---|---|---|
| Std Dev | .std(window) | Core node | tflo-ops | Rolling standard deviation |
| Variance | .variance(window) | Core node | tflo-ops | Rolling variance |
| Deviation Band | .deviation_band(window, k) | Composite | tflo-ops | Returns (middle, upper, lower) (finance alias: bollinger_bands) |
| ATR | .atr_n(high, low, n) | Composite | tflo-fintech | Average True Range (Wilder variant) |
| ATR (EMA) | .atr_wilder_n(high, low, period) | Composite | tflo-fintech | ATR with Wilder's EMA smoothing |
| True Range | .true_range(high, low) | Composite | tflo-fintech | max(high-low, |high-prev_close|, |low-prev_close|) |
Volume-Based (3)
| Indicator | Method | Kind | Crate | Description |
|---|---|---|---|---|
| OBV | .obv(volume) | Composite | tflo-fintech | On-Balance Volume (TA-Lib compatible) |
| MFI | .mfi_n(volume, n) | Composite | tflo-fintech | Money Flow Index |
| VWAP | .vwap(volume) | Composite | tflo-fintech | Volume-Weighted Average Price (cumulative sum) |
Trend / Directional (4)
| Indicator | Method | Kind | Crate | Description |
|---|---|---|---|---|
| ADX | .adx_n(high, low, n) | Composite | tflo-fintech | Average Directional Index (0–100) |
| +DI | .plus_di_n(high, low, n) | Composite | tflo-fintech | Plus Directional Indicator |
| -DI | .minus_di_n(high, low, n) | Composite | tflo-fintech | Minus Directional Indicator |
| LinearReg Slope | .linearreg_slope_n(n) | Composite | tflo-fintech | Linear regression slope |
Statistical (8)
| Operation | Method | Kind | Crate | Description |
|---|---|---|---|---|
| Z-Score | .zscore(window) | Composite | tflo-ops | (value - mean) / std |
| Median | .median(window) | Core node | tflo-ops | Rolling median |
| Quantile | .quantile(window, q) | Core node | tflo-ops | Rolling quantile (0.0–1.0) |
| Correlation | .correlation(&other, window) | Core node | tflo-ops | Rolling Pearson correlation |
| Covariance | .covariance(&other, window) | Core node | tflo-ops | Rolling covariance |
| Skewness | .skewness(window) | Core node | tflo-ops | Rolling skewness |
| Kurtosis | .kurtosis(window) | Core node | tflo-ops | Rolling excess kurtosis |
| Rank | .rank(window) | Core node | tflo-ops | Current percentile rank (0.0–1.0) |
Stateful / Transform (13)
| Indicator | Method | Kind | Crate | Description |
|---|---|---|---|---|
| Prev | .prev() | Core node | tflo-ops | Previous value |
| PrevBy | .prev_by(key_fn) | Core node | tflo-ops | Previous value by key |
| Lag | .lag(duration) | Core node | tflo-ops | Value from N seconds ago |
| Delta | .delta(duration) | Core node | tflo-ops | current - lag(duration) |
| CumSum | .cumsum() | Core node | tflo-ops | Cumulative sum |
| CumMax | .cummax() | Core node | tflo-ops | Cumulative max |
| CumMin | .cummin() | Core node | tflo-ops | Cumulative min |
| CumProd | .cumprod() | Core node | tflo-ops | Cumulative product |
| PctChange | .pct_change() | Core node | tflo-ops | (cur - prev) / prev * 100 |
| LogReturn | .log_return() | Core node | tflo-ops | ln(cur / prev) |
| Rate | .rate(window) | Core node | tflo-ops | Rate of change per unit time |
| Velocity | .velocity(window) | Core node | tflo-ops | First derivative |
| Acceleration | .acceleration(window) | Core node | tflo-ops | Second derivative |
Math & Comparison (16)
| Operation | Method / Operator | Kind | Crate | Description |
|---|---|---|---|---|
| Add | + | Core node | tflo-ops | Arithmetic addition via std::ops::Add |
| Sub | - | Core node | tflo-ops | Arithmetic subtraction via std::ops::Sub |
| Mul | * | Core node | tflo-ops | Arithmetic multiplication via std::ops::Mul |
| Div | / | Core node | tflo-ops | Arithmetic division via std::ops::Div |
| Neg | - (unary) | Core node | tflo-ops | Unary negation via std::ops::Neg |
| Greater Than | .gt(&other) | Core node | tflo-ops | Returns 1.0 if true, 0.0 otherwise |
| Greater Than or Equal | .gte(&other) | Core node | tflo-ops | Returns 1.0 if true, 0.0 otherwise |
| Less Than | .lt(&other) | Core node | tflo-ops | Returns 1.0 if true, 0.0 otherwise |
| Less Than or Equal | .lte(&other) | Core node | tflo-ops | Returns 1.0 if true, 0.0 otherwise |
| Abs | .abs() | Core node | tflo-ops | Absolute value |
| Sqrt | .sqrt() | Core node | tflo-ops | Square root |
| Ln | .ln() | Core node | tflo-ops | Natural logarithm |
| Exp | .exp() | Core node | tflo-ops | Exponential function |
| Pow | .pow(n) | Core node | tflo-ops | Raising to a power |
| Floor / Ceil / Round | .floor(), .ceil(), .round() | Core node | tflo-ops | Rounding operations |
| Clamp | .clamp(min, max) | Core node | tflo-ops | Constrain value to [min, max] range |
Signal Conditioning (5)
| Indicator | Method | Kind | Crate | Description |
|---|---|---|---|---|
| DC Remove | .dc_remove(window) | Composite | tflo-ops | signal - SMA(signal) — AC coupling |
| Baseline Correct | .baseline_correct(window, percentile) | Composite | tflo-ops | Subtract rolling percentile baseline |
| Normalize Range | .normalize_range(window) | Composite | tflo-ops | Normalize signal to [0, 1] |
| Calibrate | .calibrate(gain, offset) | Composite | tflo-ops | output = input * gain + offset |
| Peak Decline | .peak_decline() | Composite | tflo-ops | (current - cummax) / cummax — always ≤ 0 (finance alias: drawdown) |
Functional Primitives (6)
| Primitive | Method | Kind | Crate | Description |
|---|---|---|---|---|
| map_f64 | .map_f64(|x| ...) | Core node | tflo-ops | Stateless unary transform (optional .named("...")) |
| map2_f64 | .map2_f64(&other, |x, y| ...) | Core node | tflo-ops | Stateless binary transform |
| filter_f64 | .filter_f64(|x| ...) | Core node | tflo-ops | Suppress values where predicate returns false |
| filter_map_f64 | .filter_map_f64(|x| ...) | Core node | tflo-ops | Transform + optionally suppress |
| scan_f64 | .scan_f64(|| init, |state, x| ...) | Core node | tflo-ops | Stateful unary scan |
| scan2_f64 | .scan2_f64(&other, || init, |state, x, y| ...) | Core node | tflo-ops | Stateful binary scan |
Next: Learn how to detect signals with Signal Detection.