- WRMSE extends the classic RMSE by incorporating weights for each observation, enabling analysts to emphasize critical data points such as recent ob...
WRMSE extends the classic RMSE by incorporating weights for each observation, enabling analysts to emphasize critical data points such as recent observations, high-volume periods, or specific market regimes. When all weights are equal, WRMSE reduces exactly to RMSE, making it a strict generalization. This implementation uses dual RingBuffers for O(1) streaming updates with periodic resync to manage floating-point drift.
## Historical Context
Root Mean Squared Error has been a foundational metric in statistics and signal processing since Gauss's work on least squares in the early 19th century. The weighted variant emerged naturally from generalized least squares theory, where heteroscedasticity (non-constant variance) necessitates giving different importance to different observations.
In financial contexts, weighting becomes essential because market conditions vary significantly: a 1% error during a flash crash carries different implications than the same error during low-volatility consolidation. Volume-weighted errors, recency-weighted errors, and regime-adaptive weighting schemes all build on this foundation.
The implementation here maintains exact mathematical equivalence to RMSE when weights are uniform, verified through comparison tests against our standard RMSE indicator.
## Architecture & Physics
The indicator maintains two parallel RingBuffers tracking weighted squared errors and weights separately, enabling proper normalization as the window slides.
### 1. Dual Buffer State Management
The state tracks running sums for both numerator and denominator:
The `isNew=false` pattern enables bar correction for live trading scenarios where the current bar's values may update multiple times before close. State rollback uses `_p_state` (previous valid state) to restore buffers to the pre-correction position.
### 4. Floating-Point Drift Mitigation
Running sums accumulate floating-point errors over time. Periodic resync (every 1000 ticks by default) recalculates sums from buffer contents to bound drift.
The denominator $\sum w_i$ ensures the metric remains scale-invariant with respect to weight magnitude. Doubling all weights produces identical results.
### NaN/Invalid Value Handling
Invalid inputs (NaN, Infinity, negative weights) substitute the last valid value:
$$
v_t = \begin{cases}
v_t & \text{if } v_t \text{ is finite and valid} \\
v_{\text{last valid}} & \text{otherwise}
\end{cases}
$$
## Performance Profile
### Operation Count (Streaming Mode, Scalar)
| Operation | Count | Cost (cycles) | Subtotal |
| :--- | :---: | :---: | :---: |
| Validation/NaN checks | 3 | 1 | 3 |
| SUB (diff) | 1 | 1 | 1 |
| MUL (diff², weight×diff²) | 2 | 3 | 6 |
| ADD/SUB (running sums) | 4 | 1 | 4 |
| DIV | 1 | 15 | 15 |
| SQRT | 1 | 15 | 15 |
| CMP (weight threshold) | 1 | 1 | 1 |
| **Total** | **~13** | — | **~45 cycles** |
The dominant costs are DIV and SQRT (67% combined), consistent with other RMSE-family indicators.
### Batch Mode (SIMD/FMA)
For uniform weights, the batch path delegates to the same SIMD infrastructure as RMSE:
For weighted batch computation, an additional weight multiplication occurs in the SIMD loop, but the rolling aggregation remains sequential due to the cumulative nature of the window.
4. Streaming/batch parity tests for both uniform and custom weights
## Common Pitfalls
1.**Weight Interpretation**: Weights are multiplied by squared errors, not linear errors. A weight of 2.0 gives that observation twice the influence in the squared error sum, which may not align with intuitive expectations.
2.**Zero Weight Sum**: If all weights in the window sum to effectively zero (< 1e-10), the result is 0.0 to avoid division by zero. This edge case should be rare in practice.
3.**Negative Weights**: Negative weights are rejected and replaced with the last valid weight. Consider using absolute values or clamping in upstream processing if your weight source may produce negatives.
4.**Memory Footprint**: Each instance allocates two RingBuffers of size `period`, doubling memory compared to unweighted RMSE. For a period of 100:
5.**Warmup Period**: The indicator requires `period` observations before `IsHot` becomes true. During warmup, results use the available data but may not represent the full window statistics.
6.**Bar Correction**: When using `isNew=false`, ensure you're correcting the most recent observation. Multiple corrections without intervening new bars work correctly, but the pattern assumes temporal locality.
## References
- Aitken, A.C. (1936). "On Least Squares and Linear Combinations of Observations." *Proceedings of the Royal Society of Edinburgh*.
- Gauss, C.F. (1809). *Theoria Motus Corporum Coelestium*. (Foundation of least squares theory)