Skip to content

Commit

Permalink
Handle resolution for beta indicator
Browse files Browse the repository at this point in the history
- Remove effectiveResolution and Beta constructor parameter for
  resolution.
- Streamlined resolution handling logic for Beta indicator.
- Fixed issues with regression test for Beta.
  • Loading branch information
JosueNina committed Dec 17, 2024
1 parent 630838f commit d17fd8d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 42 deletions.
19 changes: 6 additions & 13 deletions Algorithm.CSharp/AddBetaIndicatorRegressionAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -84,18 +89,6 @@ public override void OnOrderEvent(OrderEvent orderEvent)
}
}

/// <summary>
/// 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.
/// </summary>
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}");
}

/// <summary>
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
/// </summary>
Expand All @@ -114,7 +107,7 @@ public override void OnEndOfAlgorithm()
/// <summary>
/// Data Points count of the algorithm history
/// </summary>
public int AlgorithmHistoryDataPoints => 9;
public int AlgorithmHistoryDataPoints => 15;

/// <summary>
/// Final status of the algorithm
Expand Down
3 changes: 1 addition & 2 deletions Algorithm/QCAlgorithm.Indicators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<IBaseData, IBaseDataBar> 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;
Expand Down
20 changes: 7 additions & 13 deletions Indicators/Beta.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public class Beta : BarIndicator, IIndicatorWarmUpPeriodProvider
/// <summary>
/// Gets a flag indicating when the indicator is ready and fully initialized
/// </summary>
public override bool IsReady => _targetReturns.Samples >= WarmUpPeriod && _referenceReturns.Samples >= WarmUpPeriod;
public override bool IsReady => (2 * _targetReturns.Samples >= WarmUpPeriod) && (2 * _referenceReturns.Samples >= WarmUpPeriod);

/// <summary>
/// Creates a new Beta indicator with the specified name, target, reference,
Expand All @@ -109,8 +109,7 @@ public class Beta : BarIndicator, IIndicatorWarmUpPeriodProvider
/// <param name="targetSymbol">The target symbol of this indicator</param>
/// <param name="period">The period of this indicator</param>
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
/// <param name="resolution">The resolution</param>
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
Expand All @@ -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;

Expand All @@ -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;
}

/// <summary>
Expand All @@ -150,9 +143,8 @@ public Beta(string name, Symbol targetSymbol, Symbol referenceSymbol, int period
/// <param name="targetSymbol">The target symbol of this indicator</param>
/// <param name="period">The period of this indicator</param>
/// <param name="referenceSymbol">The reference symbol of this indicator</param>
/// <param name="resolution">The resolution</param>
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)
{
}

Expand Down Expand Up @@ -191,6 +183,8 @@ protected override decimal ComputeNextValue(IBaseDataBar input)
if (_previousInput == null)
{
_previousInput = input;
var timeDifference = input.EndTime - input.Time;
_resolution = timeDifference.ToHigherResolutionEquivalent(false);
return decimal.Zero;
}

Expand Down
30 changes: 16 additions & 14 deletions Tests/Indicators/BetaIndicatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,18 +205,18 @@ public void ValidateBetaCalculation()

var values = new List<TradeBar>()
{
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)
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit d17fd8d

Please sign in to comment.