Square Root Weighted Moving Average (SRWMA)

Parameters: period = 14

Overview

The Square Root Weighted Moving Average applies weights proportional to the square root of each position, creating a weighting scheme that falls between linear and squared emphasis on recent data. SRWMA calculates weights by taking the square root of position indices, so the most recent value receives the square root of the period as its weight, the second most recent gets the square root of period minus one, and so forth down to the oldest which receives a weight of one. These square root weights sum together for normalization before computing the weighted average, producing a smoothing curve that responds faster than simple or exponential moving averages while avoiding the extreme reactivity of squared weighted methods. The square root function creates a gradual decay in weights that gives recent prices meaningful influence without overwhelming the contribution of older data. Traders appreciate SRWMA for its balanced approach to trend following, as it adapts quickly enough to catch significant moves while maintaining sufficient smoothing to avoid whipsaw trades in choppy conditions.

Implementation Examples

Get started with SRWMA in just a few lines:

use vectorta::indicators::moving_averages::srwma::{srwma, SrwmaInput, SrwmaParams};
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 = SrwmaParams { period: Some(14) };
let input = SrwmaInput::from_slice(&prices, params);
let result = srwma(&input)?;

// Using with Candles data structure
// Quick and simple with default parameters (period=14; source="close")
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = SrwmaInput::with_default_candles(&candles);
let result = srwma(&input)?;

// Access the SRWMA values
for value in result.values {
    println!("SRWMA: {}", value);
}

API Reference

Input Methods
// From price slice
SrwmaInput::from_slice(&[f64], SrwmaParams) -> SrwmaInput

// From candles with custom source
SrwmaInput::from_candles(&Candles, &str, SrwmaParams) -> SrwmaInput

// From candles with default params (close prices, period=14)
SrwmaInput::with_default_candles(&Candles) -> SrwmaInput
Parameters Structure
#[derive(Debug, Clone)]
pub struct SrwmaParams {
    pub period: Option<usize>, // Default: 14
}
Output Structure
pub struct SrwmaOutput {
    pub values: Vec<f64>, // SRWMA values
}
Validation, Warmup & NaNs
  • period >= 2 recommended (Python + CUDA bindings enforce this); period == 0 is invalid.
  • There must be at least period + 1 valid points after the first finite value; otherwise SrwmaError::NotEnoughValidData.
  • Warmup: outputs are NaN through index first_valid + period + 1 (inclusive of prefix); first finite output appears after that.
  • Leading NaNs are skipped for warmup detection; subsequent NaNs propagate through the weighted sum.
Error Handling
use vectorta::indicators::moving_averages::srwma::SrwmaError;

match srwma(&input) {
    Ok(output) => process_results(output.values),
    Err(SrwmaError::EmptyInputData) =>
        println!("Input data is empty"),
    Err(SrwmaError::AllValuesNaN) =>
        println!("All input values are NaN"),
    Err(SrwmaError::InvalidPeriod { period, data_len }) =>
        println!("Invalid period {} for data length {}", period, data_len),
    Err(SrwmaError::NotEnoughValidData { needed, valid }) =>
        println!("Need {} valid points after first finite, got {}", needed, valid),
}

Python Bindings

Basic Usage

Calculate SRWMA using NumPy arrays (default period=14):

import numpy as np
from vectorta import srwma

# Prepare price data as NumPy array
prices = np.array([100.0, 102.0, 101.5, 103.0, 105.0, 104.5])

# Calculate SRWMA with defaults (period=14)
result = srwma(prices, period=14)

# Specify kernel for performance optimization: 'auto' | 'scalar' | 'avx2' | 'avx512'
result = srwma(prices, period=14, kernel="avx2")

print(f"SRWMA values: {result}")
Streaming Real-time Updates

Process real-time price updates efficiently:

from vectorta import SrwmaStream

# Initialize streaming SRWMA calculator
stream = SrwmaStream(period=14)

for price in price_feed:
    value = stream.update(price)
    if value is not None:
        print(f"Current SRWMA: {value}")
Batch Parameter Optimization

Test multiple period values in one pass:

import numpy as np
from vectorta import srwma_batch

prices = np.array([...])

# Define period range (start, end, step)
period_range = (5, 20, 5)

results = srwma_batch(prices, period_range=period_range, kernel="auto")

print(results['values'].shape)  # (num_periods, len(prices))
print(results['periods'])       # periods tested
CUDA Acceleration

Use development CUDA bindings when available:

# Requires vectorta built with Python + CUDA features
from vectorta import srwma_cuda_batch_dev, srwma_cuda_many_series_one_param_dev
import numpy as np

# One series, many parameters
prices_f32 = np.asarray([...], dtype=np.float32)
out_dev = srwma_cuda_batch_dev(prices_f32, period_range=(14, 50, 2), device_id=0)

# Many series (time-major), one parameter
tm = np.asarray([[...]], dtype=np.float32)  # shape: [T, N]
out_dev2 = srwma_cuda_many_series_one_param_dev(tm, period=14, device_id=0)

JavaScript/WASM Bindings

Basic Usage

Calculate SRWMA in JavaScript/TypeScript:

import { srwma_js } from 'vectorta-wasm';

const prices = new Float64Array([100.0, 102.0, 101.5, 103.0, 105.0, 104.5]);
const result = srwma_js(prices, 14);
console.log('SRWMA values:', result);
Memory-Efficient Operations

Use zero-copy operations for better performance with large datasets:

import { srwma_alloc, srwma_free, srwma_into, memory } from 'vectorta-wasm';

const prices = new Float64Array([/* your data */]);
const length = prices.length;

const inPtr = srwma_alloc(length);
const outPtr = srwma_alloc(length);
new Float64Array(memory.buffer, inPtr, length).set(prices);

// Args: in_ptr, out_ptr, len, period
srwma_into(inPtr, outPtr, length, 14);

const srwmaValues = new Float64Array(memory.buffer, outPtr, length).slice();
srwma_free(inPtr, length);
srwma_free(outPtr, length);
console.log('SRWMA values:', srwmaValues);
Batch Processing

Test multiple period values efficiently:

import { srwma_batch_js, srwma_batch_metadata_js } from 'vectorta-wasm';

const prices = new Float64Array([/* historical prices */]);

const start = 5, end = 20, step = 5; // 5, 10, 15, 20
const metadata = srwma_batch_metadata_js(start, end, step); // [period1, period2, ...]
const numCombos = metadata.length;

const flat = srwma_batch_js(prices, start, end, step);
const rows = numCombos, cols = prices.length;
const matrix: Float64Array[] = [];
for (let i = 0; i < rows; i++) {
  const s = i * cols;
  matrix.push(flat.slice(s, s + cols));
}

console.log('Periods:', metadata);
console.log('First combo SRWMA:', matrix[0]);

Performance Analysis

Comparison:
View:
Loading chart...

AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05

Related Indicators