Files
Miha Kralj eb9e41fc2e 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
2026-03-17 09:25:32 -07:00

71 lines
2.3 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Drawing;
using System.Runtime.CompilerServices;
using TradingPlatform.BusinessLayer;
namespace QuanTAlib;
[SkipLocalsInit]
public sealed class RrsiIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Smooth Length", sortIndex: 1, 1, 500, 1, 0)]
public int SmoothLength { get; set; } = 10;
[InputParameter("RSI Length", sortIndex: 2, 1, 500, 1, 0)]
public int RsiLength { get; set; } = 10;
[IndicatorExtensions.DataSourceInput(sortIndex: 3)]
public SourceType Source { get; set; } = SourceType.Close;
[InputParameter("Show cold values", sortIndex: 21)]
public bool ShowColdValues { get; set; } = true;
private Rrsi _rrsi = null!;
private readonly LineSeries _rrsiLine;
public static int MinHistoryDepths => 0;
int IWatchlistIndicator.MinHistoryDepths => MinHistoryDepths;
public override string ShortName => $"RRSI ({SmoothLength},{RsiLength})";
public override string SourceCodeLink => "https://github.com/mihakralj/QuanTAlib/blob/main/lib/oscillators/rrsi/Rrsi.Quantower.cs";
public RrsiIndicator()
{
OnBackGround = true;
SeparateWindow = true;
Name = "RRSI - Rocket RSI (Ehlers)";
Description = "Fisher Transform of Super Smootherfiltered RSI for cyclic reversal signals";
_rrsiLine = new LineSeries("RocketRSI", Color.DodgerBlue, 2, LineStyle.Solid);
AddLineSeries(_rrsiLine);
AddLineLevel(0, "Zero", Color.Gray, 1, LineStyle.Dash);
AddLineLevel(2, "Overbought", Color.Red, 1, LineStyle.Dash);
AddLineLevel(-2, "Oversold", Color.Green, 1, LineStyle.Dash);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override void OnInit()
{
_rrsi = new Rrsi(SmoothLength, RsiLength);
base.OnInit();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override void OnUpdate(UpdateArgs args)
{
var priceSelector = Source.GetPriceSelector();
var item = HistoricalData[0, SeekOriginHistory.End];
double price = priceSelector(item);
TValue input = new(item.TimeLeft, price);
TValue result = _rrsi.Update(input, args.IsNewBar());
if (!_rrsi.IsHot && !ShowColdValues)
{
return;
}
_rrsiLine.SetValue(result.Value);
}
}