Add TEMA (Triple Exponential Moving Average) implementation and validation tests

- Implemented TEMA calculation in QuanTAlib with O(1) update complexity.
- Added validation tests for TEMA against Skender, TA-Lib, and Tulip indicators.
- Updated documentation for TEMA, including its mathematical foundation and usage examples.
- Enhanced existing tests for other indicators (TRIMA, WMA) to generate more records.
- Adjusted benchmark tests to include DEMA and TEMA comparisons.
- Refactored code for better readability and performance, including zero-allocation Span API.
This commit is contained in:
Miha Kralj
2025-12-04 19:57:46 -08:00
parent ee358bfdd9
commit 9e152b9027
24 changed files with 2528 additions and 136 deletions
+2 -2
View File
@@ -19,9 +19,9 @@ public class SmaValidationTests
{
_output = output;
// 1. Generate 1000 records using GBM feed
// 1. Generate 5000 records using GBM feed
var gbm = new GBM(startPrice: 100.0, mu: 0.05, sigma: 0.2);
_bars = gbm.Fetch(1000, DateTime.UtcNow.Ticks, TimeSpan.FromMinutes(1));
_bars = gbm.Fetch(5000, DateTime.UtcNow.Ticks, TimeSpan.FromMinutes(1));
// 2. Extract Close TSeries
_data = _bars.Close;
+9 -18
View File
@@ -11,27 +11,18 @@ namespace QuanTAlib;
/// SMA: Simple Moving Average
/// </summary>
/// <remarks>
/// SMA calculates the arithmetic mean of the last N values.
/// Uses a RingBuffer for storage and manual running sum for O(1) operations.
/// SMA calculates the arithmetic mean of the last n values.
/// Uses a RingBuffer for storage and manual running sum for O(1) complexity per update.
///
/// Key characteristics:
/// - Equal weighting of all values in the period
/// - No lag bias - responds equally to all values in window
/// - Smooth output with good noise reduction
/// - O(1) time complexity for both update and bar correction
/// - O(1) space complexity for state save/restore (scalars only)
/// Calculation:
/// SMA = (P_n + P_(n-1) + ... + P_1) / n
///
/// Calculation method:
/// SMA = Sum(values in period) / period
/// O(1) update:
/// S_new = S_old - oldest + newest
/// SMA = S_new / n
///
/// Bar correction (isNew=false):
/// - Restores to state after last isNew=true
/// - Then replaces the last value with new correction value
/// - All O(1) using scalar state
///
/// Sources:
/// - https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages
/// - https://www.investopedia.com/terms/s/sma.asp
/// IsHot:
/// Becomes true when the buffer is full (period samples processed).
/// </remarks>
[SkipLocalsInit]
public sealed class Sma