Table of Contents

Class MovingAverage

Namespace
SignalSharp.Smoothing.MovingAverage
Assembly
SignalSharp.dll

Provides methods to calculate various types of moving averages on a signal.

public static class MovingAverage
Inheritance
MovingAverage
Inherited Members

Methods

ExponentialMovingAverage(double[], double)

Calculates the Exponential Moving Average (EMA) of a given signal.

public static double[] ExponentialMovingAverage(double[] signal, double alpha)

Parameters

signal double[]

The input signal array.

alpha double

The smoothing factor. Must be in the range (0, 1]. A higher alpha gives more weight to recent points.

Returns

double[]

A new array containing the exponential moving averages, having the same length as the input signal.

Examples

double[] signal = {1, 2, 3, 4, 5};
double alpha = 0.5; // Smoothing factor
double[] ema = MovingAverage.ExponentialMovingAverage(signal, alpha);
// ema will be {1, 1.5, 2.25, 3.125, 4.0625}

Remarks

The EMA is calculated recursively using a smoothing factor, alpha, which gives more weight to recent data points. The formula is: EMA[t] = alpha * signal[t] + (1 - alpha) * EMA[t-1]. The first value EMA[0] is initialized as signal[0].

This method calculates the EMA directly on the input signal; padding is not applicable to the standard EMA calculation. The output array will have the same length as the input signal.

Exceptions

ArgumentNullException

Thrown when the signal is null.

ArgumentOutOfRangeException

Thrown when alpha is not strictly greater than 0 and less than or equal to 1.

SimpleMovingAverage(double[], int, Padding, double)

Calculates the Simple Moving Average (SMA) of a given signal using an efficient sliding window approach.

public static double[] SimpleMovingAverage(double[] signal, int windowSize, Padding padding = Padding.None, double paddedValue = 0)

Parameters

signal double[]

The input signal array.

windowSize int

The number of points to include in each average calculation. Must be positive.

padding Padding

The padding mode to use. Default is None.

paddedValue double

The value used for padding if Constant is selected. Default is 0.

Returns

double[]

A new array containing the simple moving averages.

Examples

double[] signal = {1, 2, 3, 4, 5};
int windowSize = 3;

double[] smaValid = MovingAverage.SimpleMovingAverage(signal, windowSize, Padding.None);
// smaValid will be {2, 3, 4}

Remarks

The SMA is calculated by taking the average of a fixed number of points (window size) in the signal. This implementation uses a sliding window for O(N) efficiency.

Behavior with Padding:

  • NoneThe output signal will be shorter than the input signal, with a length of `signal.Length - windowSize + 1`. It contains only the averages where the window fits entirely within the original signal (similar to 'valid' convolution mode).
  • Other Padding Modes (Constant, Mirror, etc.)The output signal will have the same length as the input signal. Padding is applied internally to compute the average values near the signal boundaries.

Exceptions

ArgumentNullException

Thrown when the signal is null.

ArgumentOutOfRangeException

Thrown when the window size is less than or equal to zero.

ArgumentOutOfRangeException

Thrown if padding is None and windowSize is greater than the signal length.

WeightedMovingAverage(double[], double[], Padding, double)

Calculates the Weighted Moving Average (WMA) of a given signal.

public static double[] WeightedMovingAverage(double[] signal, double[] weights, Padding padding = Padding.None, double paddedValue = 0)

Parameters

signal double[]

The input signal array.

weights double[]

The weights to apply. The length of this array determines the window size. Must not be empty.

padding Padding

The padding mode to use. Default is None.

paddedValue double

The value used for padding if Constant is selected. Default is 0.

Returns

double[]

A new array containing the weighted moving averages.

Examples

double[] signal = {1, 2, 3, 4, 5};
double[] weights = {0.1, 0.3, 0.6}; // Window size = 3, Sum = 1.0

// No padding ('valid' mode)
double[] wmaValid = MovingAverage.WeightedMovingAverage(signal, weights, Padding.None);
// WMA[0] = (1*0.1 + 2*0.3 + 3*0.6) / 1.0 = 2.5
// WMA[1] = (2*0.1 + 3*0.3 + 4*0.6) / 1.0 = 3.5
// WMA[2] = (3*0.1 + 4*0.3 + 5*0.6) / 1.0 = 4.5
// wmaValid will be {2.5, 3.5, 4.5} (Length = 5 - 3 + 1 = 3)

// Constant padding ('same' mode output length)
// Assuming ApplyPadding({1,2,3,4,5}, 3, Constant, 0) -> {0, 1, 2, 3, 4, 5, 0}
// WMA[0] = (0*0.1 + 1*0.3 + 2*0.6) / 1.0 = 1.5
// WMA[1] = (1*0.1 + 2*0.3 + 3*0.6) / 1.0 = 2.5
// WMA[2] = (2*0.1 + 3*0.3 + 4*0.6) / 1.0 = 3.5
// WMA[3] = (3*0.1 + 4*0.3 + 5*0.6) / 1.0 = 4.5
// WMA[4] = (4*0.1 + 5*0.3 + 0*0.6) / 1.0 = 1.9
double[] wmaPadded = MovingAverage.WeightedMovingAverage(signal, weights, Padding.Constant, 0);
// wmaPadded will be {1.5, 2.5, 3.5, 4.5, 1.9} (Length = 5)

Remarks

The WMA is calculated by applying a specified set of weights to the signal points within a sliding window. The length of the `weights` array determines the window size (`W`). The calculation for the output at index `i` (in 'valid' mode) is: `Sum(signal[i+j] * weights[j] for j=0 to W-1) / Sum(weights)`.

The time complexity is O(N*W) where N is the signal length and W is the window size (weights length), as the weighted sum is recalculated for each output point.

Behavior with Padding (consistent with SMA):

  • NoneThe output signal will be shorter than the input signal, with a length of `signal.Length - W + 1`. It contains only the averages where the window fits entirely within the original signal ('valid' mode).
  • Other Padding Modes (Constant, Mirror, etc.)The output signal will have the same length as the input signal. Padding is applied internally to compute the average values near the signal boundaries ('same' mode equivalent length).

Exceptions

ArgumentNullException

Thrown when the signal or weights are null.

ArgumentException

Thrown when the weights array is empty or the sum of weights is zero.

ArgumentOutOfRangeException

Thrown if padding is None and the weights length (window size) is greater than the signal length.