Fibonacci Weighted Moving Average (FWMA)
period = 5 Overview
The Fibonacci Weighted Moving Average applies nature's golden ratio sequence as weights to create a unique smoothing that naturally emphasizes recent price action while maintaining mathematical harmony across the lookback window. Each price point receives a weight based on Fibonacci numbers (1, 1, 2, 3, 5, 8...), with the most recent data assigned the highest Fibonacci value, creating an organic progression that many traders believe aligns with natural market cycles. After multiplying prices by their Fibonacci weights, the sum gets normalized to produce an average that responds faster to new developments than simple averages yet smoother than aggressive exponential weighting. Traders find FWMA particularly effective during trending markets where the Fibonacci weighting captures momentum shifts earlier while the normalized calculation prevents overshooting during volatile swings. The indicator serves dual purposes as both a dynamic support and resistance level during trends and an early warning system for potential reversals when price diverges significantly from the FWMA line. Moreover, the mathematical elegance of Fibonacci relationships appeals to traders who view markets through the lens of natural patterns and sacred geometry, making FWMA a bridge between technical analysis and mathematical philosophy. Because Fibonacci weights concentrate most influence into the most recent ~7–10 bars, increasing the period beyond roughly 10–12 only changes the curve very slightly. In practice that “plateau” is expected behavior, not a bug in the period handling.
Implementation Examples
Get started with FWMA in just a few lines:
use vectorta::indicators::moving_averages::fwma::{fwma, FwmaInput, FwmaParams};
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 = FwmaParams { period: Some(5) };
let input = FwmaInput::from_slice(&prices, params);
let result = fwma(&input)?;
// Using with Candles data structure (default: period=5, source="close")
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = FwmaInput::with_default_candles(&candles);
let result = fwma(&input)?;
// Access the FWMA values
for value in result.values {
println!("FWMA: {}", value);
} API Reference
Input Methods ▼
// From price slice
FwmaInput::from_slice(&[f64], FwmaParams) -> FwmaInput
// From candles with custom source
FwmaInput::from_candles(&Candles, &str, FwmaParams) -> FwmaInput
// From candles with default params (close prices, period=5)
FwmaInput::with_default_candles(&Candles) -> FwmaInput Parameters Structure ▼
pub struct FwmaParams {
pub period: Option<usize>, // Default: 5
} Output Structure ▼
pub struct FwmaOutput {
pub values: Vec<f64>, // FWMA values (normalized Fibonacci-weighted mean)
} Validation, Warmup & NaNs ▼
period > 0andperiod ≤ data_len; otherwiseFwmaError::InvalidPeriod.- Requires at least
periodvalid points after the first finite value; elseFwmaError::NotEnoughValidData. - Empty slice:
FwmaError::EmptyInputData. All-NaN slice:FwmaError::AllValuesNaN. - Warmup: indices before
first_finite + period − 1are initialized toNaN. - NaNs in any window propagate to the corresponding output index.
- Streaming: returns
Noneuntilperiodinputs have been observed; then emits a value each update.
Error Handling ▼
use vectorta::indicators::moving_averages::fwma::{fwma, FwmaInput, FwmaParams, FwmaError};
let input = FwmaInput::from_slice(&prices, FwmaParams { period: Some(5) });
match fwma(&input) {
Ok(out) => println!("first value: {:?}", out.values.iter().find(|v| v.is_finite())),
Err(FwmaError::EmptyInputData) => eprintln!("fwma: input slice is empty"),
Err(FwmaError::AllValuesNaN) => eprintln!("fwma: all input values are NaN"),
Err(FwmaError::InvalidPeriod { period, data_len }) => {
eprintln!("fwma: invalid period {period} for length {data_len}")
}
Err(FwmaError::NotEnoughValidData { needed, valid }) => {
eprintln!("fwma: need {needed} valid points, only {valid}")
}
Err(FwmaError::ZeroFibonacciSum) => eprintln!("fwma: zero Fibonacci sum (normalization failed)"),
} Python Bindings
Basic Usage ▼
Calculate FWMA using NumPy arrays (default period=5):
import numpy as np
from vectorta import fwma
# Prepare price data as NumPy array
prices = np.array([100.0, 102.0, 101.5, 103.0, 105.0, 104.5])
# Calculate FWMA with default (period=5)
result = fwma(prices, period=5)
# Specify kernel for performance optimization
result = fwma(prices, period=5, kernel="avx2")
print(f"FWMA values: {result}") Streaming Real-time Updates ▼
Process real-time price updates efficiently:
from vectorta import FwmaStream
# Initialize streaming FWMA calculator
stream = FwmaStream(period=5)
# Process real-time price updates
for price in price_feed:
value = stream.update(price)
if value is not None:
print(f"Current FWMA: {value}") Batch Parameter Optimization ▼
Test multiple period values for optimization:
import numpy as np
from vectorta import fwma_batch
prices = np.array([...])
# Define period sweep (start, end, step)
period_range = (3, 20, 1)
results = fwma_batch(prices, period_range=period_range, kernel="auto")
print(results["values"].shape) # (num_periods, len(prices))
print(results["periods"]) # array of periods tested CUDA Acceleration ▼
CUDA-enabled APIs are available when built with Python + CUDA features:
# Requires vectorta built with CUDA support
from vectorta import fwma_cuda_batch_dev, fwma_cuda_many_series_one_param_dev
import numpy as np
# One series, many periods on GPU
prices = np.array([...], dtype=np.float64)
out_dev = fwma_cuda_batch_dev(prices, period_range=(3, 20, 1), device_id=0)
# Many series (time-major), one period on GPU
data_tm = np.array([...], dtype=np.float32) # shape [T, N]
out_dev2 = fwma_cuda_many_series_one_param_dev(data_tm, period=5, device_id=0) JavaScript/WASM Bindings
Basic Usage ▼
Calculate FWMA in JavaScript/TypeScript:
import { fwma_js } from 'vectorta-wasm';
const prices = new Float64Array([100.0, 102.0, 101.5, 103.0, 105.0, 104.5]);
// Calculate FWMA for a given period
const values = fwma_js(prices, 5);
console.log('FWMA values:', values); Memory-Efficient Operations ▼
Use zero-copy operations for large datasets:
import { fwma_alloc, fwma_free, fwma_into, memory } from 'vectorta-wasm';
const prices = new Float64Array([/* your data */]);
const len = prices.length;
const inPtr = fwma_alloc(len);
const outPtr = fwma_alloc(len);
new Float64Array(memory.buffer, inPtr, len).set(prices);
// Args: in_ptr, out_ptr, len, period
fwma_into(inPtr, outPtr, len, 5);
const out = new Float64Array(memory.buffer, outPtr, len).slice();
fwma_free(inPtr, len);
fwma_free(outPtr, len);
console.log('FWMA values:', out); Batch Processing ▼
Test multiple period values efficiently:
import { fwma_batch_js, fwma_batch_metadata_js } from 'vectorta-wasm';
const prices = new Float64Array([/* historical prices */]);
// Define period sweep range
const start = 3, end = 20, step = 1; // 3, 4, 5, ..., 20
// Get metadata about periods tested
const periods = fwma_batch_metadata_js(start, end, step);
const numCombos = periods.length;
// Calculate all combinations
const results = fwma_batch_js(prices, start, end, step);
// Reshape into matrix [numCombos x len]
const matrix = [];
for (let i = 0; i < numCombos; i++) {
const s = i * prices.length;
matrix.push(results.slice(s, s + prices.length));
}
// Access results for a specific period
const p = periods[0];
const fwmaValues = matrix[0]; 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