Square Weighted Moving Average (SQWMA)

Parameters: period = 14

Overview

The Square Weighted Moving Average assigns weights proportional to the square of position within the window, dramatically emphasizing recent prices while still incorporating older data for smoothing. SQWMA calculates weights by squaring the position index, so the most recent bar receives a weight of period squared, the second most recent gets period minus one squared, continuing down to the oldest value which receives a weight of one. After multiplying each price by its squared weight, the sum gets normalized by dividing by the total of all squared weights to produce the final average. This quadratic weighting makes SQWMA significantly more responsive than linear weighted moving averages, as recent data carries exponentially more influence in the calculation. Traders use SQWMA when they need a moving average that reacts quickly to new information while maintaining enough smoothing to filter noise, making it particularly useful for short term trading and identifying trend changes with minimal lag.

Defaults: period = 14.

Implementation Examples

Get started with SQWMA in just a few lines:

use vectorta::indicators::sqwma::{sqwma, SqwmaInput, SqwmaParams};
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 = SqwmaParams { period: Some(14) }; // Default period is 14
let input = SqwmaInput::from_slice(&prices, params);
let result = sqwma(&input)?;

// Using with Candles data structure (default source = "close")
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = SqwmaInput::with_default_candles(&candles);
let result = sqwma(&input)?;

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

API Reference

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

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

// From candles with default params (close prices, period=14)
SqwmaInput::with_default_candles(&Candles) -> SqwmaInput
Parameters Structure
pub struct SqwmaParams {
    pub period: Option<usize>, // Default: 14
}
Output Structure
pub struct SqwmaOutput {
    pub values: Vec<f64>, // SQWMA values
}
Validation, Warmup & NaNs
  • period ≥ 2 and period ≤ data_len; otherwise SqwmaError::InvalidPeriod.
  • Requires at least period valid points after the first finite value; else SqwmaError::NotEnoughValidData.
  • Indices before first + period + 1 are NaN (warmup). The first finite output occurs at that index.
  • Leading all‑NaNs => SqwmaError::AllValuesNaN. Empty input => SqwmaError::EmptyInputData.
Error Handling
use vectorta::indicators::sqwma::SqwmaError;

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

Python Bindings

Basic Usage

Calculate SQWMA using NumPy arrays:

import numpy as np
from vectorta import sqwma

prices = np.array([100.0, 102.0, 101.5, 103.0, 105.0, 104.5])

# Default kernel is 'auto'; specify period explicitly
values = sqwma(prices, period=14, kernel="auto")
print(values)
Streaming Real-time Updates
from vectorta import SqwmaStream

stream = SqwmaStream(period=14)
for price in feed:
    value = stream.update(price)
    if value is not None:
        print("SQWMA:", value)
Batch Parameter Optimization
import numpy as np
from vectorta import sqwma_batch

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

results = sqwma_batch(
    prices,
    period_range=(5, 30, 5),
    kernel="auto",
)

# Results is a dict with 'values' (2D), 'periods', etc.
print(results["periods"])
CUDA Acceleration

CUDA-enabled Python APIs (when built with CUDA support):

from vectorta import (
    sqwma_cuda_batch_dev,
    sqwma_cuda_many_series_one_param_dev,
)
import numpy as np

prices_f32 = np.array([...], dtype=np.float32)
gpu_res = sqwma_cuda_batch_dev(
    data_f32=prices_f32,
    period_range=(5, 30, 1),
    device_id=0,
)

portfolio = np.array([...], dtype=np.float32)  # shape [T, N]
gpu_res2 = sqwma_cuda_many_series_one_param_dev(
    data_tm_f32=portfolio,
    period=14,
    device_id=0,
)

JavaScript/WASM Bindings

Basic Usage

Calculate SQWMA in JavaScript/TypeScript:

import { sqwma_js } from 'vectorta-wasm';

const prices = new Float64Array([100, 102, 101.5, 103, 105, 104.5]);
const result = sqwma_js(prices, 14);
console.log('SQWMA values:', result);
Memory-Efficient Operations

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

import { sqwma_alloc, sqwma_free, sqwma_into, memory } from 'vectorta-wasm';

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

const inPtr = sqwma_alloc(length);
const outPtr = sqwma_alloc(length);

// Copy input data into WASM memory
new Float64Array(memory.buffer, inPtr, length).set(prices);

// Calculate SQWMA directly into allocated memory
// Args: in_ptr, out_ptr, len, period
sqwma_into(inPtr, outPtr, length, 14);

// Read results from WASM memory
const values = new Float64Array(memory.buffer, outPtr, length).slice();

sqwma_free(inPtr, length);
sqwma_free(outPtr, length);

console.log('SQWMA values:', values);
Batch Processing

Test multiple period combinations efficiently:

import { sqwma_batch_js, sqwma_batch_metadata_js } from 'vectorta-wasm';

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

// Define parameter sweep
const start = 5, end = 30, step = 5;

// Get metadata (period list)
const periods = sqwma_batch_metadata_js(start, end, step);
const numCombos = periods.length;

// Calculate all combinations
const flat = sqwma_batch_js(prices, start, end, step);

// Reshape if needed
const matrix = [];
for (let i = 0; i < numCombos; i++) {
  const s = i * prices.length;
  matrix.push(flat.slice(s, s + prices.length));
}

Performance Analysis

Comparison:
View:
Loading chart...

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

Related Indicators