diff --git a/Indicators/Variance.cs b/Indicators/Variance.cs
index 41352631672f..b158563145f3 100644
--- a/Indicators/Variance.cs
+++ b/Indicators/Variance.cs
@@ -57,8 +57,20 @@ public Variance(string name, int period)
/// A new value for this indicator
protected override decimal ComputeNextValue(IReadOnlyWindow window, IndicatorDataPoint input)
{
- _rollingSum += input.Value;
- _rollingSumOfSquares += input.Value * input.Value;
+ var previousRollingSum = _rollingSum;
+ var previousRollingSumOfSquares = _rollingSumOfSquares;
+ try
+ {
+ _rollingSum += input.Value;
+ _rollingSumOfSquares += input.Value * input.Value;
+ }
+ catch (OverflowException)
+ {
+ _rollingSum = previousRollingSum;
+ _rollingSumOfSquares = previousRollingSumOfSquares;
+ //Log.Error($"Variance.ComputeNextValue: Decimal overflow detected when adding value {input.Value}. The previous variance value will be returned.");
+ return Current.Value;
+ }
if (Samples < 2)
return 0m;
diff --git a/Tests/Indicators/VarianceTests.cs b/Tests/Indicators/VarianceTests.cs
index 5717f62a27c9..e5103ca07cea 100644
--- a/Tests/Indicators/VarianceTests.cs
+++ b/Tests/Indicators/VarianceTests.cs
@@ -13,6 +13,7 @@
* limitations under the License.
*/
+using System;
using NUnit.Framework;
using QuantConnect.Indicators;
@@ -29,5 +30,22 @@ protected override IndicatorBase CreateIndicator()
protected override string TestFileName => "spy_var.txt";
protected override string TestColumnName => "Var";
+
+ [Test]
+ public void DoesNotThrowOnDecimalOverflow()
+ {
+ var variance = new Variance(3);
+ var time = new DateTime(2020, 1, 1);
+
+ variance.Update(time, 100m);
+ variance.Update(time.AddSeconds(1), 200m);
+ variance.Update(time.AddSeconds(2), 150m);
+ var previousValue = variance.Current.Value;
+
+ var overflowValue = 300000000000000m; // 3e14 squared will exceed decimal.MaxValue
+
+ Assert.DoesNotThrow(() => variance.Update(time.AddSeconds(3), overflowValue));
+ Assert.AreEqual(previousValue, variance.Current.Value);
+ }
}
}
\ No newline at end of file