Remove multiple Pine Script indicators: SSFDSP, STARCHANNEL, STBANDS, STC, UBANDS, UCHANNEL, VWAPBANDS, and VWAPSD. These indicators were deleted to streamline the library and remove unused or redundant code.

This commit is contained in:
Miha Kralj
2026-02-20 18:44:56 -08:00
parent 3dd05f23e4
commit cbeefc9d64
283 changed files with 23963 additions and 3838 deletions
+13 -16
View File
@@ -12,7 +12,6 @@ public class JbandsIndicatorTests
Assert.Equal(7, ind.Period);
Assert.Equal(0, ind.Phase);
Assert.Equal(0.45, ind.Power);
Assert.True(ind.ShowColdValues);
Assert.Equal("Jbands - Jurik Adaptive Envelope Bands", ind.Name);
Assert.False(ind.SeparateWindow);
@@ -171,32 +170,30 @@ public class JbandsIndicatorTests
}
[Fact]
public void Power_Parameter_Stored_Correctly()
public void Phase_Parameter_Stored_Correctly()
{
// Power parameter is accepted and stored but not currently used in Jbands calculation.
// This test verifies the parameter is properly stored and accessible.
var indLow = new JbandsIndicator { Period = 7, Power = 0.3 };
var indHigh = new JbandsIndicator { Period = 7, Power = 0.8 };
var indPos = new JbandsIndicator { Period = 7, Phase = 50 };
var indNeg = new JbandsIndicator { Period = 7, Phase = -50 };
Assert.Equal(0.3, indLow.Power);
Assert.Equal(0.8, indHigh.Power);
Assert.Equal(50, indPos.Phase);
Assert.Equal(-50, indNeg.Phase);
// Verify both indicators produce valid output
indLow.Initialize();
indHigh.Initialize();
indPos.Initialize();
indNeg.Initialize();
var now = DateTime.UtcNow;
for (int i = 0; i < 30; i++)
{
double price = 100 + Math.Sin(i * 0.3) * 10;
indLow.HistoricalData.AddBar(now.AddMinutes(i), price - 1, price + 2, price - 2, price);
indHigh.HistoricalData.AddBar(now.AddMinutes(i), price - 1, price + 2, price - 2, price);
indLow.ProcessUpdate(new UpdateArgs(i == 0 ? UpdateReason.HistoricalBar : UpdateReason.NewBar));
indHigh.ProcessUpdate(new UpdateArgs(i == 0 ? UpdateReason.HistoricalBar : UpdateReason.NewBar));
indPos.HistoricalData.AddBar(now.AddMinutes(i), price - 1, price + 2, price - 2, price);
indNeg.HistoricalData.AddBar(now.AddMinutes(i), price - 1, price + 2, price - 2, price);
indPos.ProcessUpdate(new UpdateArgs(i == 0 ? UpdateReason.HistoricalBar : UpdateReason.NewBar));
indNeg.ProcessUpdate(new UpdateArgs(i == 0 ? UpdateReason.HistoricalBar : UpdateReason.NewBar));
}
// Both should produce finite values
Assert.True(double.IsFinite(indLow.LinesSeries[0].GetValue(0)));
Assert.True(double.IsFinite(indHigh.LinesSeries[0].GetValue(0)));
Assert.True(double.IsFinite(indPos.LinesSeries[0].GetValue(0)));
Assert.True(double.IsFinite(indNeg.LinesSeries[0].GetValue(0)));
}
}
+1 -4
View File
@@ -18,9 +18,6 @@ public sealed class JbandsIndicator : Indicator, IWatchlistIndicator
[InputParameter("Phase", sortIndex: 20, minimum: -100, maximum: 100, increment: 1, decimalPlaces: 0)]
public int Phase { get; set; } = 0;
[InputParameter("Power", sortIndex: 30, minimum: 0.01, maximum: 5.0, increment: 0.01, decimalPlaces: 2)]
public double Power { get; set; } = 0.45;
[InputParameter("Show Cold Values", sortIndex: 100)]
public bool ShowColdValues { get; set; } = true;
@@ -39,7 +36,7 @@ public sealed class JbandsIndicator : Indicator, IWatchlistIndicator
protected override void OnInit()
{
_indicator = new Jbands(Period, Phase, Power);
_indicator = new Jbands(Period, Phase);
AddLineSeries(new LineSeries("Middle", Color.DodgerBlue, 2, LineStyle.Solid));
AddLineSeries(new LineSeries("Upper", Color.FromArgb(255, 180, 180), 1, LineStyle.Dash));
+11 -11
View File
@@ -11,7 +11,7 @@ public class JbandsTests
{
Assert.Throws<ArgumentOutOfRangeException>(() => new Jbands(0));
Assert.Throws<ArgumentOutOfRangeException>(() => new Jbands(-5));
Assert.Throws<ArgumentException>(() => new Jbands(14, 0, double.NaN));
// power parameter removed - no longer applicable
var j = new Jbands(14);
Assert.Contains("Jbands", j.Name, StringComparison.OrdinalIgnoreCase);
@@ -19,10 +19,10 @@ public class JbandsTests
}
[Fact]
public void Jbands_Constructor_InfinityPower_Throws()
public void Jbands_Constructor_Period1_IsValid()
{
Assert.Throws<ArgumentException>(() => new Jbands(14, 0, double.PositiveInfinity));
Assert.Throws<ArgumentException>(() => new Jbands(14, 0, double.NegativeInfinity));
var j = new Jbands(1);
Assert.True(j.WarmupPeriod > 0);
}
[Fact]
@@ -276,7 +276,7 @@ public class JbandsTests
[Fact]
public void Jbands_Reset_ThenReuse_ProducesSameResults()
{
var j = new Jbands(14, 0, 0.45);
var j = new Jbands(14, 0);
var gbm = new GBM(startPrice: 100, mu: 0.02, sigma: 0.1, seed: 88);
double[] prices = new double[100];
for (int i = 0; i < prices.Length; i++)
@@ -424,8 +424,8 @@ public class JbandsTests
[Fact]
public void Jbands_Prime_MatchesStreamingResults()
{
var jPrime = new Jbands(14, 0, 0.45);
var jStream = new Jbands(14, 0, 0.45);
var jPrime = new Jbands(14, 0);
var jStream = new Jbands(14, 0);
var gbm = new GBM(startPrice: 100, mu: 0.01, sigma: 0.1, seed: 42);
var series = new TSeries();
@@ -459,7 +459,7 @@ public class JbandsTests
series.Add(bar.Time, bar.Close);
}
var (results, indicator) = Jbands.Calculate(series, 14, 0, 0.45);
var (results, indicator) = Jbands.Calculate(series, 14, 0);
Assert.True(indicator.IsHot);
Assert.Equal(300, results.Middle.Count);
@@ -513,7 +513,7 @@ public class JbandsTests
[Fact]
public void Jbands_BatchVsStreaming_Match()
{
var jStream = new Jbands(14, 0, 0.45);
var jStream = new Jbands(14, 0);
var gbm = new GBM(startPrice: 100, mu: 0.02, sigma: 0.1, seed: 42);
var series = new TSeries();
@@ -528,7 +528,7 @@ public class JbandsTests
double expectedUp = jStream.Upper.Value;
double expectedLo = jStream.Lower.Value;
var (midBatch, upBatch, loBatch) = Jbands.Batch(series, 14, 0, 0.45);
var (midBatch, upBatch, loBatch) = Jbands.Batch(series, 14, 0);
Assert.Equal(expectedMid, midBatch.Last.Value, 1e-10);
Assert.Equal(expectedUp, upBatch.Last.Value, 1e-10);
@@ -634,7 +634,7 @@ public class JbandsTests
public void Jbands_MiddleBand_MatchesJma()
{
// Verify that middle band matches standalone JMA
var jbands = new Jbands(14, 0, 0.45);
var jbands = new Jbands(14, 0);
var jma = new Jma(14, 0, 0.45);
var gbm = new GBM(startPrice: 100, mu: 0.01, sigma: 0.1, seed: 999);
+17 -17
View File
@@ -16,34 +16,34 @@ public class JbandsValidationTests
[Fact]
public void Jbands_MiddleBand_MatchesJma_Period7()
{
ValidateMiddleBandMatchesJma(7, 0, 0.45, 42);
ValidateMiddleBandMatchesJma(7, 0, 42);
}
[Fact]
public void Jbands_MiddleBand_MatchesJma_Period14()
{
ValidateMiddleBandMatchesJma(14, 0, 0.45, 123);
ValidateMiddleBandMatchesJma(14, 0, 123);
}
[Fact]
public void Jbands_MiddleBand_MatchesJma_Period20()
{
ValidateMiddleBandMatchesJma(20, 0, 0.45, 456);
ValidateMiddleBandMatchesJma(20, 0, 456);
}
[Fact]
public void Jbands_MiddleBand_MatchesJma_WithPhase()
{
ValidateMiddleBandMatchesJma(14, 50, 0.45, 789);
ValidateMiddleBandMatchesJma(14, -50, 0.45, 321);
ValidateMiddleBandMatchesJma(14, 100, 0.45, 654);
ValidateMiddleBandMatchesJma(14, -100, 0.45, 987);
ValidateMiddleBandMatchesJma(14, 50, 789);
ValidateMiddleBandMatchesJma(14, -50, 321);
ValidateMiddleBandMatchesJma(14, 100, 654);
ValidateMiddleBandMatchesJma(14, -100, 987);
}
private static void ValidateMiddleBandMatchesJma(int period, int phase, double power, int seed)
private static void ValidateMiddleBandMatchesJma(int period, int phase, int seed)
{
var jbands = new Jbands(period, phase, power);
var jma = new Jma(period, phase, power);
var jbands = new Jbands(period, phase);
var jma = new Jma(period, phase);
var gbm = new GBM(startPrice: 100, mu: 0.01, sigma: 0.1, seed: seed);
for (int i = 0; i < 500; i++)
@@ -60,7 +60,7 @@ public class JbandsValidationTests
[Fact]
public void Jbands_StreamingVsBatch_Match()
{
var jStream = new Jbands(14, 0, 0.45);
var jStream = new Jbands(14, 0);
var gbm = new GBM(startPrice: 100, mu: 0.02, sigma: 0.1, seed: 42);
var series = new TSeries();
@@ -71,13 +71,13 @@ public class JbandsValidationTests
jStream.Update(new TValue(bar.Time, bar.Close), isNew: true);
}
var (midBatch, upBatch, loBatch) = Jbands.Batch(series, 14, 0, 0.45);
var (midBatch, upBatch, loBatch) = Jbands.Batch(series, 14, 0);
// Compare last 100 values
for (int i = series.Count - 100; i < series.Count; i++)
{
// Rebuild streaming to get value at index i
var jCheck = new Jbands(14, 0, 0.45);
var jCheck = new Jbands(14, 0);
for (int j = 0; j <= i; j++)
{
jCheck.Update(new TValue(new DateTime(series.Times[j], DateTimeKind.Utc), series.Values[j]), isNew: true);
@@ -131,23 +131,23 @@ public class JbandsValidationTests
}
// Mode 1: Streaming
var jStream = new Jbands(14, 25, 0.45);
var jStream = new Jbands(14, 25);
for (int i = 0; i < rawValues.Length; i++)
{
jStream.Update(new TValue(DateTime.UtcNow, rawValues[i]), isNew: true);
}
// Mode 2: Batch (TSeries)
var (midBatch, upBatch, loBatch) = Jbands.Batch(series, 14, 25, 0.45);
var (midBatch, upBatch, loBatch) = Jbands.Batch(series, 14, 25);
// Mode 3: Span Calculate
double[] middleSpan = new double[150];
double[] upperSpan = new double[150];
double[] lowerSpan = new double[150];
Jbands.Batch(rawValues.AsSpan(), middleSpan.AsSpan(), upperSpan.AsSpan(), lowerSpan.AsSpan(), 14, 25, 0.45);
Jbands.Batch(rawValues.AsSpan(), middleSpan.AsSpan(), upperSpan.AsSpan(), lowerSpan.AsSpan(), 14, 25);
// Mode 4: Event-based
var jEvent = new Jbands(14, 25, 0.45);
var jEvent = new Jbands(14, 25);
double lastEventMid = 0, lastEventUp = 0, lastEventLo = 0;
jEvent.Pub += (object? sender, in TValueEventArgs args) =>
{
+10 -16
View File
@@ -60,18 +60,13 @@ public sealed class Jbands : ITValuePublisher, IDisposable
public event TValuePublishedHandler? Pub;
public Jbands(int period, int phase = 0, double power = 0.45)
public Jbands(int period, int phase = 0)
{
if (period < 1)
{
throw new ArgumentOutOfRangeException(nameof(period), "Period must be >= 1.");
}
if (!double.IsFinite(power))
{
throw new ArgumentException("Power must be finite.", nameof(power));
}
// Phase parameter: maps -100..100 -> 0.5..2.5
if (phase < -100)
{
@@ -107,7 +102,7 @@ public sealed class Jbands : ITValuePublisher, IDisposable
WarmupPeriod = (int)Math.Ceiling(20.0 + 80.0 * Math.Pow(period, 0.36));
_handler = Handle;
Name = $"Jbands({period},{phase},{power})";
Name = $"Jbands({period},{phase})";
_devBuffer = new RingBuffer(DevWindowSize);
_volBuffer = new RingBuffer(VolWindowSize);
@@ -115,8 +110,8 @@ public sealed class Jbands : ITValuePublisher, IDisposable
Reset();
}
public Jbands(ITValuePublisher source, int period, int phase = 0, double power = 0.45)
: this(period, phase, power)
public Jbands(ITValuePublisher source, int period, int phase = 0)
: this(period, phase)
{
_source = source;
source.Pub += _handler;
@@ -380,9 +375,9 @@ public sealed class Jbands : ITValuePublisher, IDisposable
}
}
public static (TSeries Middle, TSeries Upper, TSeries Lower) Batch(TSeries source, int period, int phase = 0, double power = 0.45)
public static (TSeries Middle, TSeries Upper, TSeries Lower) Batch(TSeries source, int period, int phase = 0)
{
var jbands = new Jbands(period, phase, power);
var jbands = new Jbands(period, phase);
return jbands.Update(source);
}
@@ -392,8 +387,7 @@ public sealed class Jbands : ITValuePublisher, IDisposable
Span<double> upper,
Span<double> lower,
int period,
int phase = 0,
double power = 0.45)
int phase = 0)
{
if (middle.Length != source.Length)
{
@@ -415,7 +409,7 @@ public sealed class Jbands : ITValuePublisher, IDisposable
return;
}
var jbands = new Jbands(period, phase, power);
var jbands = new Jbands(period, phase);
for (int i = 0; i < source.Length; i++)
{
var (jma, u, l) = jbands.Step(source[i], isNew: true);
@@ -428,9 +422,9 @@ public sealed class Jbands : ITValuePublisher, IDisposable
/// <summary>
/// Calculates Jbands and returns both the results and the indicator instance.
/// </summary>
public static ((TSeries Middle, TSeries Upper, TSeries Lower) Results, Jbands Indicator) Calculate(TSeries source, int period, int phase = 0, double power = 0.45)
public static ((TSeries Middle, TSeries Upper, TSeries Lower) Results, Jbands Indicator) Calculate(TSeries source, int period, int phase = 0)
{
var indicator = new Jbands(period, phase, power);
var indicator = new Jbands(period, phase);
var results = indicator.Update(source);
return (results, indicator);
}