diff --git a/Algorithm.CSharp/AddBetaIndicatorRegressionAlgorithm.cs b/Algorithm.CSharp/AddBetaIndicatorRegressionAlgorithm.cs
index bb9b00466855..60e8c67e4480 100644
--- a/Algorithm.CSharp/AddBetaIndicatorRegressionAlgorithm.cs
+++ b/Algorithm.CSharp/AddBetaIndicatorRegressionAlgorithm.cs
@@ -44,6 +44,11 @@ public override void Initialize()
_beta = B("IBM", "SPY", 3, Resolution.Daily);
_sma = SMA("SPY", 3, Resolution.Daily);
_lastSMAValue = 0;
+
+ if (!_beta.IsReady)
+ {
+ throw new RegressionTestException("Beta indicator was expected to be ready");
+ }
}
public override void OnData(Slice slice)
@@ -84,18 +89,6 @@ public override void OnOrderEvent(OrderEvent orderEvent)
}
}
- ///
- /// End of algorithm run event handler. This method is called at the end of a backtest or live trading operation. Intended for closing out logs.
- ///
- public override void OnEndOfAlgorithm()
- {
- if (!_beta.IsReady)
- {
- throw new RegressionTestException("Beta indicator was expected to be ready");
- }
- Log($"Beta between IBM and SPY is: {_beta.Current.Value}");
- }
-
///
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
///
@@ -114,7 +107,7 @@ public override void OnEndOfAlgorithm()
///
/// Data Points count of the algorithm history
///
- public int AlgorithmHistoryDataPoints => 9;
+ public int AlgorithmHistoryDataPoints => 15;
///
/// Final status of the algorithm
diff --git a/Algorithm/QCAlgorithm.Indicators.cs b/Algorithm/QCAlgorithm.Indicators.cs
index 9724762fd395..a55b412d3f97 100644
--- a/Algorithm/QCAlgorithm.Indicators.cs
+++ b/Algorithm/QCAlgorithm.Indicators.cs
@@ -390,9 +390,8 @@ public BollingerBands BB(Symbol symbol, int period, decimal k, MovingAverageType
[DocumentationAttribute(Indicators)]
public Beta B(Symbol target, Symbol reference, int period, Resolution? resolution = null, Func selector = null)
{
- var effectiveResolution = resolution ?? Resolution.Daily;
var name = CreateIndicatorName(QuantConnect.Symbol.None, $"B({period})", resolution);
- var beta = new Beta(name, target, reference, period, effectiveResolution);
+ var beta = new Beta(name, target, reference, period);
InitializeIndicator(beta, resolution, selector, target, reference);
return beta;
diff --git a/Indicators/Beta.cs b/Indicators/Beta.cs
index 4077bc0c610b..b90f9e8e6fbb 100644
--- a/Indicators/Beta.cs
+++ b/Indicators/Beta.cs
@@ -99,7 +99,7 @@ public class Beta : BarIndicator, IIndicatorWarmUpPeriodProvider
///
/// Gets a flag indicating when the indicator is ready and fully initialized
///
- public override bool IsReady => _targetReturns.Samples >= WarmUpPeriod && _referenceReturns.Samples >= WarmUpPeriod;
+ public override bool IsReady => (2 * _targetReturns.Samples >= WarmUpPeriod) && (2 * _referenceReturns.Samples >= WarmUpPeriod);
///
/// Creates a new Beta indicator with the specified name, target, reference,
@@ -109,8 +109,7 @@ public class Beta : BarIndicator, IIndicatorWarmUpPeriodProvider
/// The target symbol of this indicator
/// The period of this indicator
/// The reference symbol of this indicator
- /// The resolution
- public Beta(string name, Symbol targetSymbol, Symbol referenceSymbol, int period, Resolution resolution = Resolution.Daily)
+ public Beta(string name, Symbol targetSymbol, Symbol referenceSymbol, int period)
: base(name)
{
// Assert the period is greater than two, otherwise the beta can not be computed
@@ -119,12 +118,7 @@ public Beta(string name, Symbol targetSymbol, Symbol referenceSymbol, int period
throw new ArgumentException($"Period parameter for Beta indicator must be greater than 2 but was {period}.");
}
- if (resolution == Resolution.Tick)
- {
- throw new ArgumentException($"Resolution parameter for Beta indicator must be greater than Tick.");
- }
-
- WarmUpPeriod = period;
+ WarmUpPeriod = 2 * period;
_referenceSymbol = referenceSymbol;
_targetSymbol = targetSymbol;
@@ -140,7 +134,6 @@ public Beta(string name, Symbol targetSymbol, Symbol referenceSymbol, int period
_referenceTimeZone = MarketHoursDatabase.FromDataFolder()
.GetExchangeHours(_referenceSymbol.ID.Market, _referenceSymbol, _referenceSymbol.ID.SecurityType).TimeZone;
_isTimezoneDifferent = _targetTimeZone != _referenceTimeZone;
- _resolution = resolution;
}
///
@@ -150,9 +143,8 @@ public Beta(string name, Symbol targetSymbol, Symbol referenceSymbol, int period
/// The target symbol of this indicator
/// The period of this indicator
/// The reference symbol of this indicator
- /// The resolution
- public Beta(Symbol targetSymbol, Symbol referenceSymbol, int period, Resolution resolution = Resolution.Daily)
- : this($"B({period})", targetSymbol, referenceSymbol, period, resolution)
+ public Beta(Symbol targetSymbol, Symbol referenceSymbol, int period)
+ : this($"B({period})", targetSymbol, referenceSymbol, period)
{
}
@@ -191,6 +183,8 @@ protected override decimal ComputeNextValue(IBaseDataBar input)
if (_previousInput == null)
{
_previousInput = input;
+ var timeDifference = input.EndTime - input.Time;
+ _resolution = timeDifference.TotalHours > 1 ? Resolution.Daily : timeDifference.ToHigherResolutionEquivalent(false);
return decimal.Zero;
}
diff --git a/Tests/Indicators/BetaIndicatorTests.cs b/Tests/Indicators/BetaIndicatorTests.cs
index 437442868687..e7a5c81b58b4 100644
--- a/Tests/Indicators/BetaIndicatorTests.cs
+++ b/Tests/Indicators/BetaIndicatorTests.cs
@@ -205,18 +205,18 @@ public void ValidateBetaCalculation()
var values = new List()
{
- new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 10, Time = _reference.AddDays(1) },
- new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 35, Time = _reference.AddDays(1) },
- new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 2, Time = _reference.AddDays(2) },
- new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 2, Time = _reference.AddDays(2) },
- new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 15, Time = _reference.AddDays(3) },
- new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 80, Time = _reference.AddDays(3) },
- new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 4, Time = _reference.AddDays(4) },
- new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 4, Time = _reference.AddDays(4) },
- new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 37, Time = _reference.AddDays(5) },
- new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 90, Time = _reference.AddDays(5) },
- new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 105, Time = _reference.AddDays(6) },
- new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 302, Time = _reference.AddDays(6) },
+ new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 10, Time = _reference.AddDays(1), EndTime = _reference.AddDays(2) },
+ new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 35, Time = _reference.AddDays(1), EndTime = _reference.AddDays(2) },
+ new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 2, Time = _reference.AddDays(2),EndTime = _reference.AddDays(3) },
+ new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 2, Time = _reference.AddDays(2), EndTime = _reference.AddDays(3) },
+ new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 15, Time = _reference.AddDays(3), EndTime = _reference.AddDays(4) },
+ new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 80, Time = _reference.AddDays(3), EndTime = _reference.AddDays(4) },
+ new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 4, Time = _reference.AddDays(4), EndTime = _reference.AddDays(5) },
+ new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 4, Time = _reference.AddDays(4), EndTime = _reference.AddDays(5) },
+ new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 37, Time = _reference.AddDays(5), EndTime = _reference.AddDays(6) },
+ new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 90, Time = _reference.AddDays(5), EndTime = _reference.AddDays(6) },
+ new TradeBar() { Symbol = Symbols.AAPL, Low = 1, High = 2, Volume = 100, Close = 105, Time = _reference.AddDays(6), EndTime = _reference.AddDays(7) },
+ new TradeBar() { Symbol = Symbols.SPX, Low = 1, High = 2, Volume = 100, Close = 302, Time = _reference.AddDays(6), EndTime = _reference.AddDays(7) },
};
// Calculating beta manually using the formula: Beta = Covariance(AAPL, SPX) / Variance(SPX)
@@ -249,8 +249,10 @@ public void BetaWithDifferentTimeZones()
for (int i = 0; i < 10; i++)
{
- indicator.Update(new TradeBar() { Symbol = Symbols.SPY, Low = 1, High = 2, Volume = 100, Close = i + 1, Time = _reference.AddDays(1 + i) });
- indicator.Update(new TradeBar() { Symbol = Symbols.BTCUSD, Low = 1, High = 2, Volume = 100, Close = i + 1, Time = _reference.AddDays(1 + i) });
+ var startTime = _reference.AddDays(1 + i);
+ var endTime = startTime.AddDays(1);
+ indicator.Update(new TradeBar() { Symbol = Symbols.SPY, Low = 1, High = 2, Volume = 100, Close = i + 1, Time = startTime, EndTime = endTime });
+ indicator.Update(new TradeBar() { Symbol = Symbols.BTCUSD, Low = 1, High = 2, Volume = 100, Close = i + 1, Time = startTime, EndTime = endTime });
}
Assert.AreEqual(1, (double)indicator.Current.Value);
}