# Gauss: Gaussian Filter

> "SMA smears data like cheap paint. Gaussian filtering respects the signal's soul."

Gauss (Gaussian Filter) is a smoothing filter that applies a Gaussian kernel to time series data. Unlike Simple Moving Average (SMA), which weights all points in the window equally (boxcar function), the Gaussian filter applies weights that follow a bell curve distribution. This minimizes lag while providing superior noise reduction and significantly better preservation of signal edges.

## Historical Context

The Gaussian filter is a cornerstone of signal processing, derived from the probability density function of the normal distribution formalized by Carl Friedrich Gauss in 1809. In modern trading, it is favored by quantitative analysts for its properties of minimum group delay and lack of overshoot (step response monotonicity). It serves as an optimal time-domain filter for smoothing price data where noise reduction is critical but trend reversal signals must remain timely.

## Architecture & Physics

The implementation uses a Finite Impulse Response (FIR) architecture with a truncated Gaussian kernel.

* **Kernel Construction:** The weights are derived from the Gaussian function $G(x) = e^{-(x^2)/(2\sigma^2)}$.
* **Truncation:** The kernel extends primarily to $\pm3\sigma$, capturing >99.7% of the area. The effective window size is calculated as $2 \cdot \lceil 3\sigma \rceil + 1$.
* **Normalization:** Weights are normalized so that $\sum w_i = 1$, ensuring the filter has unity gain at DC (zero frequency) and does not bias the price level.
* **Boundary Handling:** During the startup period (warmup) or when initialized, the filter performs normalized partial convolution to provide valid outputs immediately, avoiding the common "zero-start" ramp-up artifact seen in simpler FIR implementations.

### Warmup and Lag

* **Warmup:** The filter is considered "hot" only when the full kernel window is populated.
* **Lag:** Proportional to $\sigma$. Larger $\sigma$ smooths more but introduces more lag. However, the lag is generally less obtrusive than an equivalent-length SMA due to the rapid decay of weights away from the center.

## Mathematical Foundation

### 1. Window Size Determination

The kernel width $N$ is determined by the standard deviation $\sigma$:

$$ N = 2 \cdot \lceil 3\sigma \rceil + 1 $$

### 2. Weight Calculation

For each point $x$ in the window centered at 0 (where $x \in [-\lfloor N/2 \rfloor, \lfloor N/2 \rfloor]$):

$$ w(x) = e^{-\frac{x^2}{2\sigma^2}} $$

### 3. Normalization

$$ W(x) = \frac{w(x)}{\sum_{i} w(i)} $$

### 4. Convolution

The filtered value $y_t$ at time $t$ is the convolution of input $x$ and normalized weights $W$:

$$ y_t = \sum_{i=0}^{N-1} x_{t-i} \cdot W(i) $$

## Performance Profile

| Metric | Score | Notes |
| :--- | :--- | :--- |
| **Throughput** | 10 ns/bar | SIMD-optimized static calculation; RingBuffer-optimized streaming. |
| **Allocations** | 0 | Core update loop is allocation-free. |
| **Complexity** | O(N) | Linear with respect to kernel size (depends on $\sigma$). |
| **Accuracy** | 10/10 | Exact FIR implementation. |
| **Timeliness** | 8/10 | Better than SMA/EMA for equivalent smoothing power. |
| **Overshoot** | 0 | Gaussian filters have no overshoot in step response. |
| **Smoothness** | 10/10 | Ideally smooth due to infinite differentiability of the underlying function. |

## Validation

The implementation is validated against a reference convolution algorithm to ensure mathematical correctness.

| Library | Status | Notes |
| :--- | :--- | :--- |
| **Reference** | ✅ | Matches manual convolution with $10^{-9}$ precision. |
| **Quantower** | ✅ | Verified visual alignment with platform primitives. |

### Common Pitfalls

* **Sigma vs Period:** Users often confuse $\sigma$ with period. $\sigma$ controls width. Period/Length is a derived property ($ \approx 6\sigma$).
* **Input NaNs:** Gaussian weights will propagate a single NaN to the entire window. This implementation handles NaNs by ignoring them and renomalizing expected weights, ensuring robustness.

## C# Usage

```csharp
// Initialize with sigma=1.0 (approx window size 7)
var gauss = new Gauss(sigma: 1.0);

// Update with a new value
var result = gauss.Update(new TValue(DateTime.UtcNow, 100.0));

// Static calculation on a span
Gauss.Calculate(inputSpan, outputSpan, sigma: 2.0);

// Use with a higher sigma for stronger smoothing
var smoothGauss = new Gauss(sigma: 3.0); // Window ~19
