feat: add RRSI (Rocket RSI) — Ehlers TASC May 2018

Algorithm: SuperSmoother-filtered momentum → Ehlers RSI → Fisher Transform
- 2-pole Butterworth IIR pre-filter removes noise
- Ehlers RSI (raw summation, not Wilder) outputs [-1,1]
- arctanh produces Gaussian-distributed zero-mean oscillator

Files: Rrsi.cs, Rrsi.Quantower.cs, Rrsi.md, 31+7 tests
Integration: sidebar, indices, Python bridge (Exports, _bridge, oscillators, SPEC)
Build: 0 warnings, 0 errors | Tests: 15,963 passed, 0 failed
This commit is contained in:
Miha Kralj
2026-03-17 09:25:32 -07:00
parent 15f4bb90f3
commit eb9e41fc2e
12 changed files with 1028 additions and 0 deletions
@@ -0,0 +1,61 @@
using TradingPlatform.BusinessLayer;
using Xunit;
namespace QuanTAlib.Tests;
public sealed class RrsiIndicatorTests
{
[Fact]
public void Indicator_DefaultParams()
{
var indicator = new RrsiIndicator();
Assert.Equal(10, indicator.SmoothLength);
Assert.Equal(10, indicator.RsiLength);
Assert.True(indicator.ShowColdValues);
Assert.Contains("RRSI", indicator.Name, StringComparison.Ordinal);
Assert.True(indicator.SeparateWindow);
Assert.True(indicator.OnBackGround);
}
[Fact]
public void Indicator_CustomParams()
{
var indicator = new RrsiIndicator { SmoothLength = 8, RsiLength = 14 };
Assert.Equal(8, indicator.SmoothLength);
Assert.Equal(14, indicator.RsiLength);
}
[Fact]
public void Indicator_ShortName_Format()
{
var indicator = new RrsiIndicator { SmoothLength = 8, RsiLength = 14 };
Assert.Equal("RRSI (8,14)", indicator.ShortName);
}
[Fact]
public void Indicator_SourceCodeLink_Valid()
{
var indicator = new RrsiIndicator();
Assert.Contains("Rrsi.Quantower.cs", indicator.SourceCodeLink, StringComparison.Ordinal);
}
[Fact]
public void Indicator_HasLineSeries()
{
var indicator = new RrsiIndicator();
Assert.Single(indicator.LinesSeries);
}
[Fact]
public void Indicator_ImplementsIWatchlist()
{
var indicator = new RrsiIndicator();
Assert.IsAssignableFrom<IWatchlistIndicator>(indicator);
}
[Fact]
public void Indicator_MinHistoryDepths_IsZero()
{
Assert.Equal(0, RrsiIndicator.MinHistoryDepths);
}
}