Smoothed Moving Average (SMMA)
period = 7 Overview
The Smoothed Moving Average employs recursive smoothing that begins with a simple average of the first period values and then updates each subsequent point by blending the previous SMMA with new data. SMMA calculates its first value as the arithmetic mean of the initial window, then for each following bar it removes a fraction of the old average and adds a fraction of the new price according to the period length. This recursive formula produces smoother curves than simple moving averages while responding more slowly to price changes, making SMMA particularly effective at filtering out market noise. The indicator closely resembles an exponential moving average with an equivalent period, though SMMA uses a slightly different weighting scheme derived from its recursive initialization. Traders favor SMMA for identifying longer term trends and dynamic support resistance zones, as the smoothing reduces false signals during choppy periods while still tracking major price movements.
Defaults: period = 7 (close as default source).
Implementation Examples
Get started with SMMA in just a few lines:
use vectorta::indicators::smma::{smma, SmmaInput, SmmaParams};
use vectorta::utilities::data_loader::{Candles, read_candles_from_csv};
// Using with price data slice
let prices = vec![100.0, 102.0, 101.5, 103.0, 105.0, 104.5];
let params = SmmaParams { period: Some(7) }; // default period = 7
let input = SmmaInput::from_slice(&prices, params);
let result = smma(&input)?;
// Using with Candles data structure
// Quick and simple with default parameters (period=7; source="close")
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = SmmaInput::with_default_candles(&candles);
let result = smma(&input)?;
// Access the SMMA values
for value in result.values {
println!("SMMA: {}", value);
} API Reference
Input Methods ▼
// From price slice
SmmaInput::from_slice(&[f64], SmmaParams) -> SmmaInput
// From candles with custom source
SmmaInput::from_candles(&Candles, &str, SmmaParams) -> SmmaInput
// From candles with default params (close price, period=7)
SmmaInput::with_default_candles(&Candles) -> SmmaInput Parameters Structure ▼
#[derive(Debug, Clone)]
pub struct SmmaParams {
pub period: Option<usize>,
}
impl Default for SmmaParams {
fn default() -> Self { Self { period: Some(7) } }
} Output Structure ▼
pub struct SmmaOutput {
pub values: Vec<f64>, // SMMA values (same length as input)
} Validation, Warmup & NaNs ▼
- Input must be non-empty; otherwise
SmmaError::EmptyInputData. All-NaN input:SmmaError::AllValuesNaN. period > 0andperiod ≤ len; otherwiseSmmaError::InvalidPeriod.- Requires at least
periodvalid points after the first finite value; otherwiseSmmaError::NotEnoughValidData. - Warmup: indices
[0 .. first + period - 1)areNaN; first computable index isfirst + period - 1(seeded by SMA). - Streaming returns
Noneuntil the buffer fills, then yields each update. SubsequentNaNs in data propagate.
Error Handling ▼
use vectorta::indicators::smma::{smma, SmmaError};
match smma(&input) {
Ok(output) => process_results(output.values),
Err(SmmaError::EmptyInputData) => eprintln!("input is empty"),
Err(SmmaError::AllValuesNaN) => eprintln!("all values are NaN"),
Err(SmmaError::InvalidPeriod { period, data_len }) => {
eprintln!("invalid period: {} for len {}", period, data_len)
}
Err(SmmaError::NotEnoughValidData { needed, valid }) => {
eprintln!("not enough valid data: needed {}, got {}", needed, valid)
}
Err(SmmaError::InvalidKernel { kernel }) => {
eprintln!("invalid kernel for batch: {:?}", kernel)
}
Err(SmmaError::OutputLenMismatch { expected, actual }) => {
eprintln!("preallocated output mismatch: expected {}, got {}", expected, actual)
}
} Python Bindings
Basic Usage ▼
Calculate SMMA using NumPy arrays (default period=7):
import numpy as np
from vectorta import smma
# Prepare price data as NumPy array
prices = np.array([100.0, 101.0, 102.5, 101.8, 103.2, 104.0])
# Calculate SMMA (defaults from library: period=7)
result = smma(prices, period=7)
# Or specify kernel explicitly: 'auto' | 'scalar' | 'avx2' | 'avx512'
result = smma(prices, period=10, kernel="avx2")
print(f"SMMA values: {result}") Streaming Real-time Updates ▼
Process real-time price updates efficiently:
from vectorta import SmmaStream
# Initialize streaming SMMA calculator
stream = SmmaStream(period=7)
# Process real-time price updates
for price in price_feed:
smma_value = stream.update(price)
if smma_value is not None:
print(f"Current SMMA: {smma_value}") Batch Processing ▼
Sweep period values in one pass:
import numpy as np
from vectorta import smma_batch
prices = np.array([/* your data */], dtype=np.float64)
results = smma_batch(prices, period_range=(5, 20, 5))
# Access 2D values [rows x cols] and period list
values = results['values']
periods = results['periods']
print(periods, values.shape) CUDA Acceleration ▼
CUDA helpers are available when built with CUDA + Python features.
import numpy as np
from vectorta import smma_cuda_batch_dev, smma_cuda_many_series_one_param_dev
# Option 1: One series, many parameters (parameter optimization)
prices = np.array([/* your data */], dtype=np.float64)
gpu_out = smma_cuda_batch_dev(prices, period_range=(5, 20, 1), device_id=0)
# Option 2: Many series, one parameter (portfolio/time-major: [T, N])
data_tm = np.array([/* time-major data */], dtype=np.float32)
gpu_out = smma_cuda_many_series_one_param_dev(data_tm, period=7, device_id=0) JavaScript/WASM Bindings
Basic Usage ▼
Calculate SMMA in JavaScript/TypeScript:
import { smma } from 'vectorta-wasm';
// Price data as Float64Array or regular array
const prices = new Float64Array([100.0, 102.0, 101.5, 103.0, 105.0, 104.5]);
// Calculate SMMA with specified period
const result = smma(prices, 7);
console.log('SMMA values:', result); Memory-Efficient Operations ▼
Use zero-copy operations for large datasets:
import { smma_alloc, smma_free, smma_into, memory } from 'vectorta-wasm';
const prices = new Float64Array([/* your data */]);
const length = prices.length;
// Allocate WASM memory for input and output
const inPtr = smma_alloc(length);
const outPtr = smma_alloc(length);
// Copy input data into WASM memory
new Float64Array(memory.buffer, inPtr, length).set(prices);
// Compute directly into output buffer (in_ptr, out_ptr, len, period)
smma_into(inPtr, outPtr, length, 7);
// Read results from WASM memory
const smmaValues = new Float64Array(memory.buffer, outPtr, length).slice();
// Free allocated memory
smma_free(inPtr, length);
smma_free(outPtr, length); Batch Processing ▼
Test multiple period values efficiently:
import { smma_batch, smma_batch_metadata, smma_batch_rows_cols } from 'vectorta-wasm';
const prices = new Float64Array([/* historical prices */]);
// Define period sweep range
const start = 5, end = 20, step = 5; // 5, 10, 15, 20
// Optional metadata
const periods = smma_batch_metadata(start, end, step); // [5,10,15,20]
const [rows, cols] = smma_batch_rows_cols(start, end, step, prices.length);
// Unified batch API with config object
const results = smma_batch(prices, { period_range: [start, end, step] });
// Results: { values: Float64Array(rows*cols), combos: SmmaParams[], rows, cols }
console.log(rows, cols, results); Performance Analysis
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05
Related Indicators
Arnaud Legoux Moving Average
Moving average indicator
Compound Ratio Moving Average (CoRa Wave)
Moving average indicator
Centered Weighted Moving Average
Moving average indicator
Double Exponential Moving Average
Moving average indicator
Ehlers Distance Coefficient Filter
Moving average indicator
Ehlers Error-Correcting EMA (ECEMA)
Moving average indicator