diff --git a/Indicators/Beta.cs b/Indicators/Beta.cs index b475bf543b65..959fee63ad5b 100644 --- a/Indicators/Beta.cs +++ b/Indicators/Beta.cs @@ -58,10 +58,10 @@ public class Beta : DualSymbolIndicator public Beta(string name, Symbol targetSymbol, Symbol referenceSymbol, int period) : base(name, targetSymbol, referenceSymbol, 2) { - // Assert the period is greater than two, otherwise the beta can not be computed + // Assert the period is greater than one, otherwise the beta can not be computed if (period < 2) { - throw new ArgumentException($"Period parameter for Beta indicator must be greater than 2 but was {period}."); + throw new ArgumentException($"Period parameter for Beta indicator must be greater than 1 but was {period}."); } _targetReturns = new RollingWindow(period); diff --git a/Indicators/Correlation.cs b/Indicators/Correlation.cs index aab80112c13b..b2bdc9f09e2d 100644 --- a/Indicators/Correlation.cs +++ b/Indicators/Correlation.cs @@ -61,7 +61,7 @@ public Correlation(string name, Symbol targetSymbol, Symbol referenceSymbol, int : base(name, targetSymbol, referenceSymbol, period) { // Assert the period is greater than two, otherwise the correlation can not be computed - if (period < 2) + if (period < 3) { throw new ArgumentException($"Period parameter for Correlation indicator must be greater than 2 but was {period}"); } diff --git a/Indicators/Covariance.cs b/Indicators/Covariance.cs index ee3a85a003cf..2dfdaaf87549 100644 --- a/Indicators/Covariance.cs +++ b/Indicators/Covariance.cs @@ -51,10 +51,10 @@ public class Covariance : DualSymbolIndicator public Covariance(string name, Symbol targetSymbol, Symbol referenceSymbol, int period) : base(name, targetSymbol, referenceSymbol, 2) { - // Assert the period is greater than two, otherwise the covariance can not be computed + // Assert the period is greater than one, otherwise the covariance can not be computed if (period < 2) { - throw new ArgumentException($"Period parameter for Covariance indicator must be greater than 2 but was {period}."); + throw new ArgumentException($"Period parameter for Covariance indicator must be greater than 1 but was {period}."); } _targetReturns = new RollingWindow(period); diff --git a/Tests/Indicators/BetaIndicatorTests.cs b/Tests/Indicators/BetaIndicatorTests.cs index 0068e1a01ac0..84ccaa1bf742 100644 --- a/Tests/Indicators/BetaIndicatorTests.cs +++ b/Tests/Indicators/BetaIndicatorTests.cs @@ -312,5 +312,23 @@ public override void IndicatorShouldHaveSymbolAfterUpdates() Assert.AreEqual(Symbols.AAPL, indicator.Current.Symbol); } } + + [Test] + public void PeriodBelowMinimumThrows() + { + // One return is not a sample, so the smallest period this can accept is two + var period = 1; + + var exception = Assert.Throws(() => new Beta(Symbols.SPY, Symbols.AAPL, period)); + Assert.That(exception.Message, Is.EqualTo($"Period parameter for Beta indicator must be greater than 1 but was {period}.")); + } + + [Test] + public void PeriodOfTwoIsAccepted() + { + // Two returns give a finite, well defined beta, unlike the correlation + // of two points, which is 1 or -1 whatever the data says + Assert.DoesNotThrow(() => new Beta(Symbols.SPY, Symbols.AAPL, 2)); + } } } diff --git a/Tests/Indicators/CorrelationPearsonTests.cs b/Tests/Indicators/CorrelationPearsonTests.cs index a98c882126df..c65d90441474 100644 --- a/Tests/Indicators/CorrelationPearsonTests.cs +++ b/Tests/Indicators/CorrelationPearsonTests.cs @@ -223,5 +223,17 @@ public void CorrelationWithDifferentTimeZones() } Assert.AreEqual(1, (double)indicator.Current.Value); } + + [Test] + public void PeriodBelowMinimumThrows() + { + // A two point window leaves no spread to measure: the correlation of two + // points is 1 or -1 whatever the data says, so three is the smallest period + // that carries information + var period = 2; + + var exception = Assert.Throws(() => new Correlation(Symbols.SPY, Symbols.AAPL, period)); + Assert.That(exception.Message, Is.EqualTo($"Period parameter for Correlation indicator must be greater than 2 but was {period}")); + } } } diff --git a/Tests/Indicators/CovarianceTests.cs b/Tests/Indicators/CovarianceTests.cs index 32981af7f30a..902a077f708b 100644 --- a/Tests/Indicators/CovarianceTests.cs +++ b/Tests/Indicators/CovarianceTests.cs @@ -287,5 +287,23 @@ public override void IndicatorShouldHaveSymbolAfterUpdates() Assert.AreEqual(Symbols.AAPL, indicator.Current.Symbol); } } + + [Test] + public void PeriodBelowMinimumThrows() + { + // One return is not a sample, so the smallest period this can accept is two + var period = 1; + + var exception = Assert.Throws(() => new Covariance(Symbols.SPY, Symbols.AAPL, period)); + Assert.That(exception.Message, Is.EqualTo($"Period parameter for Covariance indicator must be greater than 1 but was {period}.")); + } + + [Test] + public void PeriodOfTwoIsAccepted() + { + // Two returns give a finite, well defined covariance, unlike the correlation + // of two points, which is 1 or -1 whatever the data says + Assert.DoesNotThrow(() => new Covariance(Symbols.SPY, Symbols.AAPL, 2)); + } } }