diff --git a/Algorithm/QCAlgorithm.Indicators.cs b/Algorithm/QCAlgorithm.Indicators.cs index cb822fede225..a00526d5bf45 100644 --- a/Algorithm/QCAlgorithm.Indicators.cs +++ b/Algorithm/QCAlgorithm.Indicators.cs @@ -1691,6 +1691,50 @@ public NormalizedAverageTrueRange NATR(Symbol symbol, int period, Resolution? re return normalizedAverageTrueRange; } + /// + /// Creates a new New Highs - New Lows indicator + /// + /// The symbols whose NHNL we want + /// The period over which to compute the NHNL + /// The resolution + /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a IBaseDataBar + /// The NewHighsNewLows indicator for the requested symbols over the specified period + [DocumentationAttribute(Indicators)] + public NewHighsNewLows NHNL(IEnumerable symbols, int period, Resolution? resolution = null, Func selector = null) + { + var name = CreateIndicatorName(QuantConnect.Symbol.None, $"NH/NL({period})", resolution ?? GetSubscription(symbols.First()).Resolution); + var nhnlDifference = new NewHighsNewLows(name, period); + foreach (var symbol in symbols) + { + nhnlDifference.Add(symbol); + } + InitializeIndicator(nhnlDifference, resolution, selector, symbols.ToArray()); + + return nhnlDifference; + } + + /// + /// Creates a new New Highs - New Lows Volume indicator + /// + /// The symbols whose NHNLV we want + /// The period over which to compute the NHNLV + /// The resolution + /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar + /// The NewHighsNewLowsVolume indicator for the requested symbols over the specified period + [DocumentationAttribute(Indicators)] + public NewHighsNewLowsVolume NHNLV(IEnumerable symbols, int period, Resolution? resolution = null, Func selector = null) + { + var name = CreateIndicatorName(QuantConnect.Symbol.None, $"NH/NL Volume({period})", resolution ?? GetSubscription(symbols.First()).Resolution); + var nhnlVolume = new NewHighsNewLowsVolume(name, period); + foreach (var symbol in symbols) + { + nhnlVolume.Add(symbol); + } + InitializeIndicator(nhnlVolume, resolution, selector, symbols.ToArray()); + + return nhnlVolume; + } + /// /// Creates a new On Balance Volume indicator. This will compute the cumulative total volume /// based on whether the close price being higher or lower than the previous period. @@ -2215,7 +2259,7 @@ public TargetDownsideDeviation TDD(Symbol symbol, int period, double minimumAcce return targetDownsideDeviation; } - + /// /// Creates a new TomDemark Sequential candlestick indicator for the symbol. The indicator will be automatically /// updated on the symbol's subscription resolution. diff --git a/Indicators/NewHighsNewLows.cs b/Indicators/NewHighsNewLows.cs new file mode 100644 index 000000000000..fa53bf4d08cc --- /dev/null +++ b/Indicators/NewHighsNewLows.cs @@ -0,0 +1,340 @@ +/* + * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. + * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +using QuantConnect.Data.Market; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace QuantConnect.Indicators +{ + /// + /// The NewHighsNewLows is a New Highs / New Lows indicator that accepts IBaseDataBar data as its input. + /// + /// This type is more of a shim/typedef to reduce the need to refer to things as NewHighsNewLows<IBaseDataBar> + /// + public class NewHighsNewLows : NewHighsNewLows + { + /// + /// Initializes a new instance of the class + /// + public NewHighsNewLows(string name, int period) : base(name, period) + { + } + } + + /// + /// The New Highs - New Lows indicator displays the daily difference or ratio between + /// the number of assets reaching new highs and the number of stocks reaching new lows + /// in defined time period. + /// + public abstract class NewHighsNewLows : IndicatorBase, IIndicatorWarmUpPeriodProvider + where T : class, IBaseDataBar + { + private readonly TrackedAssets _trackedAssets; + private readonly int _period; + + private DateTime? _currentPeriodTime; + + /// + /// Difference between the number of assets reaching new highs and the number of assets + /// reaching new lows in defined time period. + /// + public IndicatorBase Difference { get; } + + /// + /// Ratio between the number of assets reaching new highs and the number of assets + /// reaching new lows in defined time period. + /// + public IndicatorBase Ratio { get; } + + /// + /// List of assets that reached new high + /// + protected ICollection NewHighs { get; private set; } = []; + + /// + /// List of assets that reached new high + /// + protected ICollection NewLows { get; private set; } = []; + + /// + /// Initializes a new instance of the class + /// + protected NewHighsNewLows(string name, int period) : base(name) + { + _period = period; + _trackedAssets = new TrackedAssets(period); + + Difference = new FunctionalIndicator( + $"{name}_Difference", + (input) => + { + return NewHighs.Count - NewLows.Count; + }, + _ => IsReady); + + Ratio = new FunctionalIndicator( + $"{name}_Ratio", + (input) => + { + return NewLows.Count == 0m ? NewHighs.Count : (decimal)NewHighs.Count / NewLows.Count; + }, + _ => IsReady); + } + + /// + /// Add tracking asset issue + /// + /// tracking asset issue + public virtual void Add(Symbol asset) + { + _trackedAssets.Add(asset); + } + + /// + /// Remove tracking asset issue + /// + /// tracking asset issue + public virtual void Remove(Symbol asset) + { + _trackedAssets.Remove(asset); + } + + /// + /// Gets a flag indicating when this indicator is ready and fully initialized + /// + public override bool IsReady => HasSufficientPreviousDataForComputation(); + + /// + /// Resets this indicator to its initial state + /// + public override void Reset() + { + _trackedAssets.Reset(); + + _currentPeriodTime = null; + + Difference.Reset(); + Ratio.Reset(); + + base.Reset(); + } + + /// + /// Required period, in data points, for the indicator to be ready and fully initialized. + /// + public int WarmUpPeriod => _period + 1; + + /// + /// Computes the next value of this indicator from the given state + /// + /// The input given to the indicator + /// A new value for this indicator + protected override decimal ComputeNextValue(T input) + { + NewHighs.Clear(); + NewLows.Clear(); + + foreach (TrackedAsset asset in _trackedAssets) + { + if (asset.CurrentPeriodValue.High > asset.RollingPreviousHigh.Current.Value) + { + NewHighs.Add(asset.CurrentPeriodValue); + } + + if (asset.CurrentPeriodValue.Low < asset.RollingPreviousLow.Current.Value) + { + NewLows.Add(asset.CurrentPeriodValue); + } + } + + Difference.Update(input); + Ratio.Update(input); + + return Difference.Current.Value; + } + + /// + /// Computes the next value of this indicator from the given state + /// + /// The input given to the indicator + /// A new value for this indicator + protected override IndicatorResult ValidateAndComputeNextValue(T input) + { + Enqueue(input); + + if (HasMissingCurrentPeriodValue() || !HasSufficientPreviousDataForComputation()) + { + return new IndicatorResult(0, IndicatorStatus.ValueNotReady); + } + + decimal vNext = ComputeNextValue(input); + return new IndicatorResult(vNext); + } + + private void Enqueue(T input) + { + TrackedAsset trackedAsset; + + // In case of unordered input + if (input.EndTime == _currentPeriodTime) + { + // Update the previous values in rolling window + if (_trackedAssets.TryGetAsset(input.Symbol, out trackedAsset)) + { + UpdatePreviousValues(trackedAsset, input); + } + return; + } + + // In case of new period + if (input.Time > _currentPeriodTime) + { + foreach (TrackedAsset asset in _trackedAssets) + { + // We got new period and therefore we need to update + // the previous value in rolling window so we can use them for calculation + UpdatePreviousValues(asset, asset.CurrentPeriodValue); + asset.CurrentPeriodValue = default; + } + _currentPeriodTime = input.Time; + } + + if (_trackedAssets.TryGetAsset(input.Symbol, out trackedAsset) + && (!_currentPeriodTime.HasValue || input.Time == _currentPeriodTime)) + { + trackedAsset.CurrentPeriodValue = input; + + if (!_currentPeriodTime.HasValue) + { + _currentPeriodTime = input.Time; + } + } + } + + private bool HasMissingCurrentPeriodValue() + { + return _trackedAssets.Any(x => x.CurrentPeriodValue == null); + } + + private bool HasSufficientPreviousDataForComputation() + { + return _trackedAssets.All(asset => + asset.RollingPreviousHigh.IsReady + && asset.RollingPreviousLow.IsReady); + } + + private void UpdatePreviousValues(TrackedAsset asset, IBaseDataBar bar) + { + if (bar == null) + { + return; + } + + asset.RollingPreviousHigh.Update(_currentPeriodTime.Value, bar.High); + asset.RollingPreviousLow.Update(_currentPeriodTime.Value, bar.Low); + } + + /// + /// Assets tracked by NewHighsNewLows indicator + /// + private class TrackedAssets : IEnumerable + { + private readonly int _period; + + private readonly IDictionary _assets = new Dictionary(); + + public TrackedAssets(int period) + { + _period = period; + } + + /// + /// Add tracking asset issue + /// + /// tracking asset issue + public void Add(Symbol asset) + { + if (!_assets.ContainsKey(asset.ID)) + { + _assets.Add(asset.ID, new TrackedAsset(_period)); + } + } + + /// + /// Remove tracking asset issue + /// + /// tracking asset issue + public void Remove(Symbol asset) + { + _assets.Remove(asset.ID); + } + + /// + /// Resets tracked assets to its initial state + /// + public void Reset() + { + foreach (TrackedAsset asset in this) + { + asset.Reset(); + } + } + + public bool TryGetAsset(Symbol asset, out TrackedAsset trackedAsset) + { + return _assets.TryGetValue(asset.ID, out trackedAsset); + } + + public IEnumerator GetEnumerator() + { + return _assets.Values.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + /// + /// Asset tracked by NewHighsNewLows indicator + /// + private class TrackedAsset + { + public T CurrentPeriodValue { get; set; } + public Maximum RollingPreviousHigh { get; init; } + public Minimum RollingPreviousLow { get; init; } + + public TrackedAsset(int period) + { + CurrentPeriodValue = default; + RollingPreviousHigh = new Maximum(period); + RollingPreviousLow = new Minimum(period); + } + /// + /// Resets tracked asset to its initial state + /// + public void Reset() + { + CurrentPeriodValue = default; + RollingPreviousHigh.Reset(); + RollingPreviousLow.Reset(); + } + } + } +} diff --git a/Indicators/NewHighsNewLowsVolume.cs b/Indicators/NewHighsNewLowsVolume.cs new file mode 100644 index 000000000000..64f2f336dd6b --- /dev/null +++ b/Indicators/NewHighsNewLowsVolume.cs @@ -0,0 +1,76 @@ +/* + * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. + * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +using QuantConnect.Data.Market; +using System.Linq; + +namespace QuantConnect.Indicators +{ + /// + /// The New Highs - New Lows Volume Ratio is a Breadth indicator calculated as ratio of + /// summary volume of stocks reaching new high to summary volume of stocks reaching new + /// low compared to high and low values in defined time period. + /// + public class NewHighsNewLowsVolume : NewHighsNewLows + { + /// + /// Volume ratio between the number of assets reaching new highs and the number of assets + /// reaching new lows in defined time period. + /// + public IndicatorBase VolumeRatio { get; } + + /// + /// Initializes a new instance of the class + /// + public NewHighsNewLowsVolume(string name, int period) + : base(name, period) + { + VolumeRatio = new FunctionalIndicator( + $"{name}_VolumeRatio", + (input) => + { + decimal newHighsVolume = NewHighs.Sum(x => x.Volume); + decimal newLowsVolume = NewLows.Sum(x => x.Volume); + + return newLowsVolume == 0m ? newHighsVolume : newHighsVolume / newLowsVolume; + }, + _ => IsReady); + } + + /// + /// Computes the next value of this indicator from the given state + /// + /// The input given to the indicator + /// A new value for this indicator + protected override decimal ComputeNextValue(TradeBar input) + { + decimal nextValue = base.ComputeNextValue(input); + + VolumeRatio.Update(input); + + return VolumeRatio.Current.Value; + } + + /// + /// Resets tracked assets to its initial state + /// + public override void Reset() + { + VolumeRatio.Reset(); + + base.Reset(); + } + } +} diff --git a/Tests/Indicators/NewHighsNewLowsDifferenceTests.cs b/Tests/Indicators/NewHighsNewLowsDifferenceTests.cs new file mode 100644 index 000000000000..e20bdc59b708 --- /dev/null +++ b/Tests/Indicators/NewHighsNewLowsDifferenceTests.cs @@ -0,0 +1,269 @@ +/* + * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. + * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +using NUnit.Framework; +using QuantConnect.Data.Market; +using QuantConnect.Indicators; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QuantConnect.Tests.Indicators +{ + [TestFixture] + public class NewHighsNewLowsDifferenceTests : NewHighsNewLowsTestsBase + { + protected override IndicatorBase CreateIndicator() + { + // For test purposes we use period of two + NewHighsNewLows nhnlDifference = new("test_name", 2); + if (SymbolList.Count > 2) + { + SymbolList.Take(3).ToList().ForEach(nhnlDifference.Add); + } + else + { + nhnlDifference.Add(Symbols.AAPL); + nhnlDifference.Add(Symbols.IBM); + nhnlDifference.Add(Symbols.GOOG); + RenkoBarSize = 5000000; + } + + // Even if the indicator is ready, there may be zero values + ValueCanBeZero = true; + + return nhnlDifference; + } + + protected override List GetSymbols() + { + return [Symbols.SPY, Symbols.AAPL, Symbols.IBM]; + } + + protected override Action, double> Assertion => (indicator, expected) => + { + // we need to use the Difference sub-indicator + base.Assertion((indicator as NewHighsNewLows).Difference, expected); + }; + + [Test] + public virtual void ShouldIgnoreRemovedStocks() + { + NewHighsNewLows indicator = CreateIndicator() as NewHighsNewLows; + DateTime reference = DateTime.Today; + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + + // value is not ready yet + Assert.AreEqual(0m, indicator.Difference.Current.Value); + + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 0.5m, Time = reference.AddMinutes(3) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.3m, Time = reference.AddMinutes(3) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.2m, Time = reference.AddMinutes(3) }); + + Assert.AreEqual(-3m, indicator.Difference.Current.Value); + + indicator.Reset(); + indicator.Remove(Symbols.GOOG); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + + // value is not ready yet + Assert.AreEqual(0m, indicator.Difference.Current.Value); + + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 0.5m, Time = reference.AddMinutes(3) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.3m, Time = reference.AddMinutes(3) }); + // new low (ignored) + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.2m, Time = reference.AddMinutes(3) }); + + Assert.AreEqual(-2m, indicator.Difference.Current.Value); + } + + [Test] + public virtual void IgnorePeriodIfAnyStockMissed() + { + NewHighsNewLows indicator = CreateIndicator() as NewHighsNewLows; + indicator.Add(Symbols.MSFT); + DateTime reference = DateTime.Today; + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + + // value is not ready yet + Assert.AreEqual(0m, indicator.Difference.Current.Value); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 0.5m, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, Close = 3, Low = 1, Time = reference.AddMinutes(3) }); + + Assert.AreEqual(0m, indicator.Difference.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 4, Low = 1, Time = reference.AddMinutes(4) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 0.3m, Time = reference.AddMinutes(4) }); + // no change + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Time = reference.AddMinutes(4) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 4, Low = 1, Time = reference.AddMinutes(4) }); + + Assert.AreEqual(1m, indicator.Difference.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 5, Low = 1, Time = reference.AddMinutes(5) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 0.2m, Time = reference.AddMinutes(5) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 4, Low = 1, Time = reference.AddMinutes(5) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 5, Low = 1, Time = reference.AddMinutes(5) }); + + Assert.AreEqual(2m, indicator.Difference.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 6, Low = 1, Time = reference.AddMinutes(6) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 3, Low = 1, Time = reference.AddMinutes(6) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 6, Low = 1, Time = reference.AddMinutes(6) }); + + Assert.AreEqual(2m, indicator.Difference.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 7, Low = 1, Time = reference.AddMinutes(7) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 5, Low = 1, Time = reference.AddMinutes(7) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 7, Low = 1, Time = reference.AddMinutes(7) }); + + Assert.AreEqual(2m, indicator.Difference.Current.Value); + } + + [Test] + public override void WarmsUpProperly() + { + NewHighsNewLows indicator = CreateIndicator() as NewHighsNewLows; + DateTime reference = DateTime.Today; + + // setup period (unordered) + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 0.5m, Low = 0.2m, Time = reference.AddMinutes(2) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Time = reference.AddMinutes(2) }); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Time = reference.AddMinutes(3) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 0.75m, Low = 0.1m, Time = reference.AddMinutes(3) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 5, Low = 2, Time = reference.AddMinutes(3) }); + + Assert.IsTrue(indicator.IsReady); + Assert.AreEqual(1m, indicator.Difference.Current.Value); + Assert.AreEqual(9, indicator.Samples); + Assert.AreEqual(1, indicator.Difference.Samples); + } + + [Test] + public virtual void WarmsUpOrdered() + { + NewHighsNewLows indicator = CreateIndicator() as NewHighsNewLows; + DateTime reference = DateTime.Today; + + // setup period (ordered) + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 0.5m, Low = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Time = reference.AddMinutes(2) }); + + // indicator is not ready yet + Assert.IsFalse(indicator.IsReady); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Time = reference.AddMinutes(3) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 4, Low = 1, Time = reference.AddMinutes(3) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 5, Low = 1, Time = reference.AddMinutes(3) }); + + Assert.IsTrue(indicator.IsReady); + Assert.AreEqual(3m, indicator.Difference.Current.Value); + } + + [Test] + public override void IndicatorShouldHaveSymbolAfterUpdates() + { + NewHighsNewLows indicator = CreateIndicator() as NewHighsNewLows; + DateTime reference = DateTime.Today; + + for (int i = 0; i < 10; i++) + { + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Volume = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Volume = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Volume = 1, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Volume = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.5m, Volume = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Volume = 1, Time = reference.AddMinutes(2) }); + + // indicator is not ready yet + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Volume = 1, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.3m, Volume = 1, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 4, Low = 1, Volume = 1, Time = reference.AddMinutes(3) }); + + // indicator is ready + + // The last update used Symbol.GOOG, so the indicator's current Symbol should be GOOG + Assert.AreEqual(Symbols.GOOG, indicator.Difference.Current.Symbol); + } + } + + protected override string TestFileName => "nhnl_data.csv"; + + protected override string TestColumnName => "NH/NL Difference"; + } +} diff --git a/Tests/Indicators/NewHighsNewLowsRatioTests.cs b/Tests/Indicators/NewHighsNewLowsRatioTests.cs new file mode 100644 index 000000000000..831172040579 --- /dev/null +++ b/Tests/Indicators/NewHighsNewLowsRatioTests.cs @@ -0,0 +1,269 @@ +/* + * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. + * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +using NUnit.Framework; +using QuantConnect.Data.Market; +using QuantConnect.Indicators; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QuantConnect.Tests.Indicators +{ + [TestFixture] + public class NewHighsNewLowsRatioTests : NewHighsNewLowsTestsBase + { + protected override IndicatorBase CreateIndicator() + { + // For test purposes we use period of two + NewHighsNewLows nhnlRatio = new("test_name", 2); + if (SymbolList.Count > 2) + { + SymbolList.Take(3).ToList().ForEach(nhnlRatio.Add); + } + else + { + nhnlRatio.Add(Symbols.AAPL); + nhnlRatio.Add(Symbols.IBM); + nhnlRatio.Add(Symbols.GOOG); + RenkoBarSize = 5000000; + } + + // Even if the indicator is ready, there may be zero values + ValueCanBeZero = true; + + return nhnlRatio; + } + + protected override List GetSymbols() + { + return [Symbols.SPY, Symbols.AAPL, Symbols.IBM]; + } + + protected override Action, double> Assertion => (indicator, expected) => + { + // we need to use the Ratio sub-indicator + base.Assertion(((NewHighsNewLows)indicator).Ratio, expected); + }; + + [Test] + public void ShouldIgnoreRemovedStocks() + { + NewHighsNewLows indicator = (NewHighsNewLows)CreateIndicator(); + DateTime reference = DateTime.Today; + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + + // value is not ready yet + Assert.AreEqual(0m, indicator.Ratio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 0.9m, Time = reference.AddMinutes(3) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.3m, Time = reference.AddMinutes(3) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.2m, Time = reference.AddMinutes(3) }); + + Assert.AreEqual(0.5m, indicator.Ratio.Current.Value); + + indicator.Reset(); + indicator.Remove(Symbols.GOOG); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.9m, Time = reference.AddMinutes(2) }); + + // value is not ready yet + Assert.AreEqual(0m, indicator.Ratio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 0.9m, Time = reference.AddMinutes(3) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 0.9m, Time = reference.AddMinutes(3) }); + // new low (ignored) + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.2m, Time = reference.AddMinutes(3) }); + + Assert.AreEqual(2m, indicator.Ratio.Current.Value); + } + + [Test] + public void IgnorePeriodIfAnyStockMissed() + { + NewHighsNewLows indicator = (NewHighsNewLows)CreateIndicator(); + indicator.Add(Symbols.MSFT); + DateTime reference = DateTime.Today; + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + + // value is not ready yet + Assert.AreEqual(0m, indicator.Ratio.Current.Value); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 0.5m, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, Close = 3, Low = 1, Time = reference.AddMinutes(3) }); + + Assert.AreEqual(0m, indicator.Ratio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 4, Low = 1, Time = reference.AddMinutes(4) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 0.3m, Time = reference.AddMinutes(4) }); + // no change + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Time = reference.AddMinutes(4) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 4, Low = 1, Time = reference.AddMinutes(4) }); + + Assert.AreEqual(2m, indicator.Ratio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 5, Low = 1, Time = reference.AddMinutes(5) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 0.2m, Time = reference.AddMinutes(5) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 4, Low = 1, Time = reference.AddMinutes(5) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 5, Low = 1, Time = reference.AddMinutes(5) }); + + Assert.AreEqual(3m, indicator.Ratio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 6, Low = 1, Time = reference.AddMinutes(6) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 3, Low = 1, Time = reference.AddMinutes(6) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 6, Low = 1, Time = reference.AddMinutes(6) }); + + Assert.AreEqual(3m, indicator.Ratio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 7, Low = 1, Time = reference.AddMinutes(7) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 5, Low = 1, Time = reference.AddMinutes(7) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 7, Low = 1, Time = reference.AddMinutes(7) }); + + Assert.AreEqual(3m, indicator.Ratio.Current.Value); + } + + [Test] + public override void WarmsUpProperly() + { + NewHighsNewLows indicator = (NewHighsNewLows)CreateIndicator(); + DateTime reference = DateTime.Today; + + // setup period (unordered) + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 0.5m, Low = 0.2m, Time = reference.AddMinutes(2) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Time = reference.AddMinutes(2) }); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Time = reference.AddMinutes(3) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 0.75m, Low = 0.1m, Time = reference.AddMinutes(3) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 5, Low = 2, Time = reference.AddMinutes(3) }); + + Assert.IsTrue(indicator.Ratio.IsReady); + Assert.AreEqual(2m, indicator.Ratio.Current.Value); + Assert.AreEqual(9, indicator.Samples); + Assert.AreEqual(1, indicator.Ratio.Samples); + } + + [Test] + public void WarmsUpOrdered() + { + NewHighsNewLows indicator = (NewHighsNewLows)CreateIndicator(); + DateTime reference = DateTime.Today; + + // setup period (ordered) + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 0.5m, Low = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Time = reference.AddMinutes(2) }); + + // indicator is not ready yet + Assert.IsFalse(indicator.Ratio.IsReady); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Time = reference.AddMinutes(3) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 4, Low = 1, Time = reference.AddMinutes(3) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 5, Low = 1, Time = reference.AddMinutes(3) }); + + Assert.IsTrue(indicator.Ratio.IsReady); + Assert.AreEqual(3m, indicator.Ratio.Current.Value); + } + + [Test] + public override void IndicatorShouldHaveSymbolAfterUpdates() + { + NewHighsNewLows indicator = CreateIndicator() as NewHighsNewLows; + DateTime reference = DateTime.Today; + + for (int i = 0; i < 10; i++) + { + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Volume = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Volume = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Volume = 1, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Volume = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.5m, Volume = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Volume = 1, Time = reference.AddMinutes(2) }); + + // indicator is not ready yet + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Volume = 1, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.3m, Volume = 1, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 4, Low = 1, Volume = 1, Time = reference.AddMinutes(3) }); + + // indicator is ready + + // The last update used Symbol.GOOG, so the indicator's current Symbol should be GOOG + Assert.AreEqual(Symbols.GOOG, indicator.Ratio.Current.Symbol); + } + } + + protected override string TestFileName => "nhnl_data.csv"; + + protected override string TestColumnName => "NH/NL Ratio"; + } +} diff --git a/Tests/Indicators/NewHighsNewLowsTestsBase.cs b/Tests/Indicators/NewHighsNewLowsTestsBase.cs new file mode 100644 index 000000000000..bdc67f22064e --- /dev/null +++ b/Tests/Indicators/NewHighsNewLowsTestsBase.cs @@ -0,0 +1,128 @@ +/* + * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. + * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +using NUnit.Framework; +using QuantConnect.Data.Consolidators; +using QuantConnect.Data.Market; +using QuantConnect.Indicators; +using System.Collections.Generic; +using static QuantConnect.Tests.Indicators.TestHelper; + +namespace QuantConnect.Tests.Indicators +{ + public abstract class NewHighsNewLowsTestsBase : CommonIndicatorTests + where T : class, IBaseDataBar + { + [Test] + public override void AcceptsRenkoBarsAsInput() + { + IndicatorBase indicator = CreateIndicator(); + if (indicator is IndicatorBase) + { + RenkoConsolidator aaplRenkoConsolidator = new(10000m); + aaplRenkoConsolidator.DataConsolidated += (sender, renkoBar) => + { + Assert.DoesNotThrow(() => indicator.Update(renkoBar)); + }; + + RenkoConsolidator googRenkoConsolidator = new(100000m); + googRenkoConsolidator.DataConsolidated += (sender, renkoBar) => + { + Assert.DoesNotThrow(() => indicator.Update(renkoBar)); + }; + + RenkoConsolidator ibmRenkoConsolidator = new(10000m); + ibmRenkoConsolidator.DataConsolidated += (sender, renkoBar) => + { + Assert.DoesNotThrow(() => indicator.Update(renkoBar)); + }; + + foreach (IReadOnlyDictionary parts in GetCsvFileStream(TestFileName)) + { + TradeBar tradebar = parts.GetTradeBar(); + if (tradebar.Symbol.Value == "AAPL") + { + aaplRenkoConsolidator.Update(tradebar); + } + else if (tradebar.Symbol.Value == "GOOG") + { + googRenkoConsolidator.Update(tradebar); + } + else + { + ibmRenkoConsolidator.Update(tradebar); + } + } + + Assert.IsTrue(indicator.IsReady); + Assert.AreNotEqual(0, indicator.Samples); + IndicatorValueIsNotZeroAfterReceiveRenkoBars(indicator); + aaplRenkoConsolidator.Dispose(); + googRenkoConsolidator.Dispose(); + ibmRenkoConsolidator.Dispose(); + } + } + + [Test] + public override void AcceptsVolumeRenkoBarsAsInput() + { + IndicatorBase indicator = CreateIndicator(); + if (indicator is IndicatorBase) + { + VolumeRenkoConsolidator aaplRenkoConsolidator = new(10000000m); + aaplRenkoConsolidator.DataConsolidated += (sender, renkoBar) => + { + Assert.DoesNotThrow(() => indicator.Update(renkoBar)); + }; + + VolumeRenkoConsolidator googRenkoConsolidator = new(500000m); + googRenkoConsolidator.DataConsolidated += (sender, renkoBar) => + { + Assert.DoesNotThrow(() => indicator.Update(renkoBar)); + }; + + VolumeRenkoConsolidator ibmRenkoConsolidator = new(500000m); + ibmRenkoConsolidator.DataConsolidated += (sender, renkoBar) => + { + Assert.DoesNotThrow(() => indicator.Update(renkoBar)); + }; + + foreach (IReadOnlyDictionary parts in GetCsvFileStream(TestFileName)) + { + TradeBar tradebar = parts.GetTradeBar(); + if (tradebar.Symbol.Value == "AAPL") + { + aaplRenkoConsolidator.Update(tradebar); + } + else if (tradebar.Symbol.Value == "GOOG") + { + googRenkoConsolidator.Update(tradebar); + } + else + { + ibmRenkoConsolidator.Update(tradebar); + } + } + + Assert.IsTrue(indicator.IsReady); + Assert.AreNotEqual(0, indicator.Samples); + IndicatorValueIsNotZeroAfterReceiveVolumeRenkoBars(indicator); + aaplRenkoConsolidator.Dispose(); + googRenkoConsolidator.Dispose(); + ibmRenkoConsolidator.Dispose(); + } + } + } +} diff --git a/Tests/Indicators/NewHighsNewLowsVolumeRatioTests.cs b/Tests/Indicators/NewHighsNewLowsVolumeRatioTests.cs new file mode 100644 index 000000000000..ccc7775fd418 --- /dev/null +++ b/Tests/Indicators/NewHighsNewLowsVolumeRatioTests.cs @@ -0,0 +1,264 @@ +using NUnit.Framework; +using QuantConnect.Data.Market; +using QuantConnect.Indicators; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace QuantConnect.Tests.Indicators +{ + [TestFixture] + internal class NewHighsNewLowsVolumeRatioTests : NewHighsNewLowsTestsBase + { + protected override IndicatorBase CreateIndicator() + { + // For test purposes we use period of two + NewHighsNewLowsVolume nhnlVolumeRatio = new("test_name", 2); + if (SymbolList.Count > 2) + { + SymbolList.Take(3).ToList().ForEach(nhnlVolumeRatio.Add); + } + else + { + nhnlVolumeRatio.Add(Symbols.AAPL); + nhnlVolumeRatio.Add(Symbols.IBM); + nhnlVolumeRatio.Add(Symbols.GOOG); + RenkoBarSize = 5000000; + } + + // Even if the indicator is ready, there may be zero values + ValueCanBeZero = true; + + return nhnlVolumeRatio; + } + + protected override List GetSymbols() + { + return [Symbols.SPY, Symbols.AAPL, Symbols.IBM]; + } + + protected override Action, double> Assertion => (indicator, expected) => + { + // we need to use the Difference sub-indicator + base.Assertion((indicator as NewHighsNewLowsVolume).VolumeRatio, expected); + }; + + [Test] + public void ShouldIgnoreRemovedStocks() + { + NewHighsNewLowsVolume indicator = (NewHighsNewLowsVolume)CreateIndicator(); + DateTime reference = DateTime.Today; + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 0.9m, Volume = 100, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.9m, Volume = 100, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.9m, Volume = 100, Time = reference.AddMinutes(2) }); + + // value is not ready yet + Assert.AreEqual(0m, indicator.VolumeRatio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 0.9m, Volume = 100, Time = reference.AddMinutes(3) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.3m, Volume = 100, Time = reference.AddMinutes(3) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.2m, Volume = 100, Time = reference.AddMinutes(3) }); + + Assert.AreEqual(0.5m, indicator.VolumeRatio.Current.Value); + + indicator.Reset(); + indicator.Remove(Symbols.GOOG); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 0.9m, Volume = 100, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.9m, Volume = 100, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.9m, Volume = 100, Time = reference.AddMinutes(2) }); + + // value is not ready yet + Assert.AreEqual(0m, indicator.VolumeRatio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 0.9m, Volume = 100, Time = reference.AddMinutes(3) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 0.9m, Volume = 100, Time = reference.AddMinutes(3) }); + // new low (ignored) + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 0.2m, Volume = 100, Time = reference.AddMinutes(3) }); + + Assert.AreEqual(200m, indicator.VolumeRatio.Current.Value); + } + + [Test] + public void IgnorePeriodIfAnyStockMissed() + { + NewHighsNewLowsVolume indicator = (NewHighsNewLowsVolume)CreateIndicator(); + indicator.Add(Symbols.MSFT); + DateTime reference = DateTime.Today; + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Volume = 100, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 1, Volume = 100, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 2, Low = 1, Volume = 100, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 2, Low = 1, Volume = 100, Time = reference.AddMinutes(2) }); + + // value is not ready yet + Assert.AreEqual(0m, indicator.VolumeRatio.Current.Value); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Volume = 100, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 0.5m, Volume = 100, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, Close = 3, Low = 1, Volume = 100, Time = reference.AddMinutes(3) }); + + Assert.AreEqual(0m, indicator.VolumeRatio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 4, Low = 1, Volume = 100, Time = reference.AddMinutes(4) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 0.3m, Volume = 100, Time = reference.AddMinutes(4) }); + // no change + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Volume = 100, Time = reference.AddMinutes(4) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 4, Low = 1, Volume = 100, Time = reference.AddMinutes(4) }); + + Assert.AreEqual(2m, indicator.VolumeRatio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 5, Low = 1, Volume = 100, Time = reference.AddMinutes(5) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 2, Low = 0.2m, Volume = 100, Time = reference.AddMinutes(5) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 4, Low = 1, Volume = 100, Time = reference.AddMinutes(5) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 5, Low = 1, Volume = 100, Time = reference.AddMinutes(5) }); + + Assert.AreEqual(3m, indicator.VolumeRatio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 6, Low = 1, Volume = 100, Time = reference.AddMinutes(6) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 3, Low = 1, Volume = 100, Time = reference.AddMinutes(6) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 6, Low = 1, Volume = 100, Time = reference.AddMinutes(6) }); + + Assert.AreEqual(3m, indicator.VolumeRatio.Current.Value); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 7, Low = 1, Volume = 100, Time = reference.AddMinutes(7) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 5, Low = 1, Volume = 100, Time = reference.AddMinutes(7) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.MSFT, High = 7, Low = 1, Volume = 100, Time = reference.AddMinutes(7) }); + + Assert.AreEqual(3m, indicator.VolumeRatio.Current.Value); + } + + [Test] + public override void WarmsUpProperly() + { + NewHighsNewLowsVolume indicator = CreateIndicator() as NewHighsNewLowsVolume; + DateTime reference = DateTime.Today; + + // setup period (unordered) + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Volume = 100, Time = reference.AddMinutes(2) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 0.5m, Low = 0.2m, Volume = 100, Time = reference.AddMinutes(2) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Volume = 100, Time = reference.AddMinutes(2) }); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Volume = 100, Time = reference.AddMinutes(3) }); + // new low + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 0.75m, Low = 0.1m, Volume = 100, Time = reference.AddMinutes(3) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 5, Low = 2, Volume = 100, Time = reference.AddMinutes(3) }); + + Assert.IsTrue(indicator.IsReady); + Assert.AreEqual(2m, indicator.VolumeRatio.Current.Value); + Assert.AreEqual(9, indicator.Samples); + Assert.AreEqual(1, indicator.VolumeRatio.Samples); + } + + [Test] + public void WarmsUpOrdered() + { + NewHighsNewLowsVolume indicator = CreateIndicator() as NewHighsNewLowsVolume; + DateTime reference = DateTime.Today; + + // setup period (ordered) + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Volume = 100, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Volume = 100, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 0.5m, Low = 1, Volume = 100, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Volume = 100, Time = reference.AddMinutes(2) }); + + // indicator is not ready yet + Assert.IsFalse(indicator.IsReady); + + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Volume = 100, Time = reference.AddMinutes(3) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 4, Low = 1, Volume = 100, Time = reference.AddMinutes(3) }); + // new high + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 5, Low = 1, Volume = 100, Time = reference.AddMinutes(3) }); + + Assert.IsTrue(indicator.IsReady); + Assert.AreEqual(300m, indicator.VolumeRatio.Current.Value); + } + + [Test] + public override void IndicatorShouldHaveSymbolAfterUpdates() + { + NewHighsNewLowsVolume indicator = CreateIndicator() as NewHighsNewLowsVolume; + DateTime reference = DateTime.Today; + + for (int i = 0; i < 10; i++) + { + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 1, Low = 1, Volume = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 1, Volume = 1, Time = reference.AddMinutes(1) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 1, Low = 1, Volume = 1, Time = reference.AddMinutes(1) }); + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 2, Low = 1, Volume = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.5m, Volume = 1, Time = reference.AddMinutes(2) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 3, Low = 1, Volume = 1, Time = reference.AddMinutes(2) }); + + // indicator is not ready yet + + indicator.Update(new TradeBar() { Symbol = Symbols.AAPL, High = 3, Low = 1, Volume = 1, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.IBM, High = 1, Low = 0.3m, Volume = 1, Time = reference.AddMinutes(3) }); + indicator.Update(new TradeBar() { Symbol = Symbols.GOOG, High = 4, Low = 1, Volume = 1, Time = reference.AddMinutes(3) }); + + // indicator is ready + + // The last update used Symbol.GOOG, so the indicator's current Symbol should be GOOG + Assert.AreEqual(Symbols.GOOG, indicator.VolumeRatio.Current.Symbol); + } + } + + protected override string TestFileName => "nhnl_data.csv"; + + protected override string TestColumnName => "NH/NL Volume Ratio"; + + /// + /// The final value of this indicator is zero because it uses the Volume of the bars it receives. + /// Since RenkoBar's don't always have Volume, the final current value is zero. Therefore we + /// skip this test + /// + /// + protected override void IndicatorValueIsNotZeroAfterReceiveRenkoBars(IndicatorBase indicator) + { + } + } +} diff --git a/Tests/QuantConnect.Tests.csproj b/Tests/QuantConnect.Tests.csproj index e2cc8706ea9d..f8ced114d264 100644 --- a/Tests/QuantConnect.Tests.csproj +++ b/Tests/QuantConnect.Tests.csproj @@ -344,6 +344,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Tests/TestData/nhnl_data.csv b/Tests/TestData/nhnl_data.csv new file mode 100644 index 000000000000..2b48e39a38c1 --- /dev/null +++ b/Tests/TestData/nhnl_data.csv @@ -0,0 +1,757 @@ +Date,Symbol,Open,High,Low,Close,Volume,NH/NL Difference,NH/NL Ratio,NH/NL Volume Ratio +20190102,AAPL,1548900,1588500,1542400,1579200,28370261,0.0,0.0,0.0 +20190102,GOOG,10171300,10524000,10141300,10458600,1219740,0.0,0.0,0.0 +20190102,IBM,1120000,1159800,1116900,1151900,3244233,0.0,0.0,0.0 +20190103,AAPL,1439500,1457500,1420000,1420900,83238505,0.0,0.0,0.0 +20190103,GOOG,10410000,10567700,10140300,10151900,1468159,0.0,0.0,0.0 +20190103,IBM,1145300,1148500,1126900,1129300,3401399,0.0,0.0,0.0 +20190104,AAPL,1445800,1485400,1438000,1482600,52261612,0.0,0.0,0.0 +20190104,GOOG,10330000,10708600,10275600,10707100,1722662,0.0,0.0,0.0 +20190104,IBM,1149100,1174900,1144800,1172900,3814850,2.0,2.0,5537512.0 +20190107,AAPL,1486300,1488300,1459000,1478900,50933385,2.0,2.0,5537512.0 +20190107,GOOG,10715000,10740000,10539600,10683900,1709957,2.0,2.0,5537512.0 +20190107,IBM,1175000,1188300,1167100,1181000,3247405,3.0,3.0,55890747.0 +20190108,AAPL,1493400,1518200,1485200,1507700,37363174,3.0,3.0,55890747.0 +20190108,GOOG,10761100,10847800,10603000,10765300,1332941,3.0,3.0,55890747.0 +20190108,IBM,1196600,1205400,1189800,1198600,3942624,3.0,3.0,42638739.0 +20190109,AAPL,1511600,1545300,1496300,1533100,41636996,3.0,3.0,42638739.0 +20190109,GOOG,10813400,10826400,10664000,10745400,1027741,3.0,3.0,42638739.0 +20190109,IBM,1209100,1213900,1198800,1206400,3083182,2.0,2.0,44720178.0 +20190110,AAPL,1524500,1539700,1508600,1538000,33478211,2.0,2.0,44720178.0 +20190110,GOOG,10699900,10711500,10576800,10692200,1110320,2.0,2.0,44720178.0 +20190110,IBM,1201600,1218600,1199500,1217400,3176528,0.0,1.0,2.8609121694646586 +20190111,AAPL,1528100,1537000,1515100,1523000,23450358,0.0,1.0,2.8609121694646586 +20190111,GOOG,10619100,10647300,10484800,10571700,1321465,0.0,1.0,2.8609121694646586 +20190111,IBM,1215800,1215800,1202200,1214300,2901424,-1.0,0.0,0.0 +20190114,AAPL,1508700,1512700,1492200,1499900,27532102,-1.0,0.0,0.0 +20190114,GOOG,10469200,10515300,10413000,10444800,966733,-1.0,0.0,0.0 +20190114,IBM,1205100,1206400,1198000,1203400,4254599,-3.0,0.0,0.0 +20190115,AAPL,1502700,1533900,1500500,1530500,26284167,-3.0,0.0,0.0 +20190115,GOOG,10509100,10800500,10470500,10768600,1231237,-3.0,0.0,0.0 +20190115,IBM,1209600,1219300,1208200,1217000,3088304,2.0,2.0,4319541.0 +20190116,AAPL,1530000,1558800,1530000,1549200,27673320,2.0,2.0,4319541.0 +20190116,GOOG,10787800,10920900,10787800,10807700,1112963,2.0,2.0,4319541.0 +20190116,IBM,1215800,1220000,1208300,1215700,3235296,3.0,3.0,32021579.0 +20190117,AAPL,1542200,1576500,1532600,1558600,27463983,3.0,3.0,32021579.0 +20190117,GOOG,10794700,10918000,10741800,10912900,852114,3.0,3.0,32021579.0 +20190117,IBM,1205600,1224000,1205500,1221800,3936493,1.0,2.0,7.976764089254065 +20190118,AAPL,1575200,1578800,1559900,1568200,28994344,1.0,2.0,7.976764089254065 +20190118,GOOG,10983300,11086000,10906900,10982500,1571248,1.0,2.0,7.976764089254065 +20190118,IBM,1232700,1247000,1227200,1238300,5079604,3.0,3.0,35645196.0 +20190122,AAPL,1564000,1567300,1526200,1536900,25079137,3.0,3.0,35645196.0 +20190122,GOOG,10887700,10913200,10634700,10710800,1113354,3.0,3.0,35645196.0 +20190122,IBM,1232200,1238000,1215400,1223700,6851547,-2.0,0.0,0.0 +20190123,AAPL,1541200,1551400,1517000,1539700,20692626,-2.0,0.0,0.0 +20190123,GOOG,10786700,10849300,10593100,10758500,866412,-2.0,0.0,0.0 +20190123,IBM,1312500,1350000,1303200,1328900,20736688,-1.0,0.5,0.9618559047022414 +20190124,AAPL,1539400,1544800,1517400,1527100,21201995,-1.0,0.5,0.9618559047022414 +20190124,GOOG,10741100,10791700,10606500,10743300,896027,-1.0,0.5,0.9618559047022414 +20190124,IBM,1326100,1332000,1314500,1325100,5563047,0.0,0.0,0.0 +20190125,AAPL,1552800,1581400,1543200,1577200,30695002,0.0,0.0,0.0 +20190125,GOOG,10844400,10940000,10813900,10909900,949640,0.0,0.0,0.0 +20190125,IBM,1328700,1344400,1324300,1339900,5155390,2.0,2.0,31644642.0 +20190128,AAPL,1555300,1563300,1536700,1563000,22548976,2.0,2.0,31644642.0 +20190128,GOOG,10801100,10830500,10634700,10702500,1082572,2.0,2.0,31644642.0 +20190128,IBM,1331000,1348100,1326000,1343100,4265756,1.0,1.0,4265756.0 +20190129,AAPL,1562000,1581300,1541100,1546600,31507605,1.0,1.0,4265756.0 +20190129,GOOG,10722300,10751500,10556600,10602300,834511,1.0,1.0,4265756.0 +20190129,IBM,1342900,1354100,1336000,1343400,4141354,0.0,1.0,4.962611637234261 +20190130,AAPL,1632800,1661500,1602300,1652400,55940805,0.0,1.0,4.962611637234261 +20190130,GOOG,10672400,10911900,10668500,10894200,1072214,0.0,1.0,4.962611637234261 +20190130,IBM,1340000,1350300,1332500,1344100,3939387,2.0,2.0,57013019.0 +20190131,AAPL,1661100,1690000,1645600,1663400,32499436,2.0,2.0,57013019.0 +20190131,GOOG,11044700,11173400,10950000,11161800,1260420,2.0,2.0,57013019.0 +20190131,IBM,1344500,1346500,1337400,1344000,3337118,2.0,2.0,33759856.0 +20190201,AAPL,1669300,1689800,1659300,1665400,26100838,2.0,2.0,33759856.0 +20190201,GOOG,11125600,11250000,11045600,11102300,1143535,2.0,2.0,33759856.0 +20190201,IBM,1349700,1351900,1333500,1340800,3312237,2.0,2.0,4455772.0 +20190204,AAPL,1674800,1716600,1672800,1712700,27747804,2.0,2.0,4455772.0 +20190204,GOOG,11120000,11325000,11090000,11325000,1878894,2.0,2.0,4455772.0 +20190204,IBM,1340200,1351800,1329900,1351800,3316380,1.0,2.0,8.933444900765291 +20190205,AAPL,1728600,1750800,1723500,1741000,32540764,1.0,2.0,8.933444900765291 +20190205,GOOG,11235900,11469200,11170300,11460000,3104755,1.0,2.0,8.933444900765291 +20190205,IBM,1352800,1358100,1349300,1355300,3190321,3.0,3.0,38835840.0 +20190206,AAPL,1747000,1755700,1728600,1742800,26390527,3.0,3.0,38835840.0 +20190206,GOOG,11415000,11470000,11127600,11152300,1845545,3.0,3.0,38835840.0 +20190206,IBM,1352200,1366500,1351700,1363300,4333342,3.0,3.0,32569414.0 +20190207,AAPL,1723900,1739400,1703400,1709900,29006527,3.0,3.0,32569414.0 +20190207,GOOG,11048400,11049300,10860000,10987100,1766403,3.0,3.0,32569414.0 +20190207,IBM,1336200,1344600,1321200,1332000,3937685,-3.0,0.0,0.0 +20190208,AAPL,1688800,1706600,1684200,1705000,21210282,-3.0,0.0,0.0 +20190208,GOOG,10868700,10990000,10864400,10950800,871200,-3.0,0.0,0.0 +20190208,IBM,1325500,1337000,1321900,1337000,2394720,-1.0,0.0,0.0 +20190211,AAPL,1710500,1712100,1692500,1694500,18366473,-1.0,0.0,0.0 +20190211,GOOG,10968000,11060000,10928300,10950100,785879,-1.0,0.0,0.0 +20190211,IBM,1342900,1351200,1340000,1340100,2449210,2.0,2.0,3235089.0 +20190212,AAPL,1701300,1710000,1697000,1708900,19540639,2.0,2.0,3235089.0 +20190212,GOOG,11056000,11253500,11052600,11212200,1471781,2.0,2.0,3235089.0 +20190212,IBM,1351500,1361900,1348700,1360300,2894463,2.0,2.0,4366244.0 +20190213,AAPL,1714300,1724800,1699200,1701700,20022816,2.0,2.0,4366244.0 +20190213,GOOG,11248600,11348000,11185000,11205800,939841,2.0,2.0,4366244.0 +20190213,IBM,1369400,1379100,1365100,1375100,3675941,3.0,3.0,24638598.0 +20190214,AAPL,1697600,1712700,1693900,1707900,18491122,3.0,3.0,24638598.0 +20190214,GOOG,11180500,11283500,11100000,11216300,855272,3.0,3.0,24638598.0 +20190214,IBM,1372300,1375900,1362100,1364800,2394993,-1.0,0.0,0.0 +20190215,AAPL,1712200,1717000,1697500,1703800,21513915,-1.0,0.0,0.0 +20190215,GOOG,11297700,11316700,11105800,11135800,1222931,-1.0,0.0,0.0 +20190215,IBM,1377000,1381900,1373900,1380300,3078927,1.0,1.0,3078927.0 +20190219,AAPL,1697200,1714400,1694300,1709400,16853497,1.0,1.0,3078927.0 +20190219,GOOG,11104400,11218600,11099600,11188100,878344,1.0,1.0,3078927.0 +20190219,IBM,1378100,1387000,1373600,1387000,2740525,0.0,1.0,3.120104423779294 +20190220,AAPL,1711900,1733200,1709900,1720900,22718221,0.0,1.0,3.120104423779294 +20190220,GOOG,11199900,11233600,11053000,11144300,912517,0.0,1.0,3.120104423779294 +20190220,IBM,1387600,1392200,1372300,1380300,2989005,0.0,1.0,6.589025001012425 +20190221,AAPL,1718000,1723700,1703100,1711400,15778960,0.0,1.0,6.589025001012425 +20190221,GOOG,11111100,11119800,10923500,10971200,1103655,0.0,1.0,6.589025001012425 +20190221,IBM,1378200,1383300,1373800,1378400,2378211,-1.0,0.0,0.0 +20190222,AAPL,1716000,1730000,1713800,1729700,15409727,-1.0,0.0,0.0 +20190222,GOOG,11024600,11112500,10950000,11106300,886859,-1.0,0.0,0.0 +20190222,IBM,1387300,1393600,1384500,1392600,2550451,1.0,1.0,2550451.0 +20190225,AAPL,1739900,1758700,1739400,1742500,19691132,1.0,1.0,2550451.0 +20190225,GOOG,11170400,11187700,11072300,11089700,1243148,1.0,1.0,2550451.0 +20190225,IBM,1400000,1404500,1393200,1394300,2577238,3.0,3.0,23511518.0 +20190226,AAPL,1737100,1753000,1731600,1743500,14731642,3.0,3.0,23511518.0 +20190226,GOOG,11057500,11196000,10995800,11149300,1068777,3.0,3.0,23511518.0 +20190226,IBM,1396700,1404600,1394800,1397300,2503496,2.0,2.0,3572273.0 +20190227,AAPL,1732500,1750000,1727300,1748800,23019795,2.0,2.0,3572273.0 +20190227,GOOG,11093100,11179900,11010000,11162500,864775,2.0,2.0,3572273.0 +20190227,IBM,1392500,1395600,1384300,1391500,2069284,-2.0,0.0,0.0 +20190228,AAPL,1743200,1749100,1729100,1732000,19986497,-2.0,0.0,0.0 +20190228,GOOG,11118400,11276800,11108300,11206500,1121226,-2.0,0.0,0.0 +20190228,IBM,1387500,1390000,1377300,1381200,2490995,0.0,1.0,0.4501117023518714 +20190301,AAPL,1742800,1751500,1728900,1749700,21191283,0.0,1.0,0.4501117023518714 +20190301,GOOG,11257300,11429900,11243500,11414700,1283817,0.0,1.0,0.4501117023518714 +20190301,IBM,1393100,1400400,1386400,1391700,2598921,3.0,3.0,25074021.0 +20190304,AAPL,1756800,1777500,1739700,1758600,24418623,3.0,3.0,25074021.0 +20190304,GOOG,11461000,11582500,11306200,11478000,1261341,3.0,3.0,25074021.0 +20190304,IBM,1399900,1400800,1371700,1385000,2661368,2.0,3.0,10.64915937968744 +20190305,AAPL,1759200,1760000,1745400,1755100,15511056,2.0,3.0,10.64915937968744 +20190305,GOOG,11515000,11695200,11460500,11616200,1318441,2.0,3.0,10.64915937968744 +20190305,IBM,1383700,1387200,1375600,1379300,2294783,1.0,1.0,1318441.0 +20190306,AAPL,1747600,1754900,1739400,1745100,17521402,1.0,1.0,1318441.0 +20190306,GOOG,11647800,11672400,11554900,11579600,912091,1.0,1.0,1318441.0 +20190306,IBM,1380600,1383600,1367200,1369800,2351144,-2.0,0.0,0.0 +20190307,AAPL,1739100,1744400,1720200,1724700,20419582,-2.0,0.0,0.0 +20190307,GOOG,11539100,11568600,11347500,11435300,1013586,-2.0,0.0,0.0 +20190307,IBM,1366100,1368900,1346500,1353600,3620161,-3.0,0.0,0.0 +20190308,AAPL,1702800,1730800,1695000,1729200,19651510,-3.0,0.0,0.0 +20190308,GOOG,11259800,11471900,11231500,11427400,1018262,-3.0,0.0,0.0 +20190308,IBM,1342500,1352400,1336100,1350400,3403914,-3.0,0.0,0.0 +20190311,AAPL,1754900,1791300,1753500,1789800,26548756,-3.0,0.0,0.0 +20190311,GOOG,11457500,11761900,11441400,11757600,1384014,-3.0,0.0,0.0 +20190311,IBM,1360300,1377300,1358400,1377200,3259429,3.0,3.0,31192199.0 +20190312,AAPL,1799300,1826700,1793700,1809400,27622968,3.0,3.0,31192199.0 +20190312,GOOG,11782400,12000000,11782400,11927700,1869564,3.0,3.0,31192199.0 +20190312,IBM,1385700,1396900,1378600,1382800,3129203,3.0,3.0,32621735.0 +20190313,AAPL,1822900,1832900,1809200,1817200,24264018,3.0,3.0,32621735.0 +20190313,GOOG,11999900,12019900,11919400,11933100,1313900,3.0,3.0,32621735.0 +20190313,IBM,1382800,1393200,1378600,1385400,2527701,2.0,2.0,25577918.0 +20190314,AAPL,1839100,1841000,1825600,1837300,19549079,2.0,2.0,25577918.0 +20190314,GOOG,11945100,11979600,11844800,11858000,994417,2.0,2.0,25577918.0 +20190314,IBM,1385100,1389300,1380700,1388000,2128787,1.0,1.0,19549079.0 +20190315,AAPL,1847800,1873300,1837400,1862100,32967677,1.0,1.0,19549079.0 +20190315,GOOG,11921900,11966200,11825500,11852400,1784155,1.0,1.0,19549079.0 +20190315,IBM,1395800,1403300,1392500,1394300,3635412,1.0,2.0,20.515644100428496 +20190318,AAPL,1858100,1883900,1857900,1880200,22763260,1.0,2.0,20.515644100428496 +20190318,GOOG,11830100,11901900,11773700,11844500,981951,1.0,2.0,20.515644100428496 +20190318,IBM,1398300,1403700,1387200,1402500,2710158,1.0,2.0,25.941638635736407 +20190319,AAPL,1882400,1889900,1859200,1865400,27185557,1.0,2.0,25.941638635736407 +20190319,GOOG,11873100,12004500,11858000,11995500,1034017,1.0,2.0,25.941638635736407 +20190319,IBM,1409600,1417000,1400100,1405300,2654092,3.0,3.0,30873666.0 +20190320,AAPL,1862800,1894900,1847300,1881700,27274230,3.0,3.0,30873666.0 +20190320,GOOG,11976500,12272500,11960400,12240100,1692662,3.0,3.0,30873666.0 +20190320,IBM,1405300,1407000,1389900,1396200,2813292,1.0,2.0,1.06206085378029 +20190321,AAPL,1900200,1963200,1898100,1950500,43361081,1.0,2.0,1.06206085378029 +20190321,GOOG,12169400,12318200,12136700,12317900,919910,1.0,2.0,1.06206085378029 +20190321,IBM,1390000,1421200,1390000,1414500,2821095,3.0,3.0,47102086.0 +20190322,AAPL,1953400,1976900,1907700,1910600,38667194,3.0,3.0,47102086.0 +20190322,GOOG,12263200,12305300,12026500,12059200,1486536,3.0,3.0,47102086.0 +20190322,IBM,1409700,1414400,1389100,1394600,3148502,0.0,1.0,12.28114004691755 +20190325,AAPL,1917100,1919800,1866000,1887700,40970851,0.0,1.0,12.28114004691755 +20190325,GOOG,11976400,12065400,11869800,11924100,1185757,0.0,1.0,12.28114004691755 +20190325,IBM,1390600,1399000,1383600,1392000,2328678,-3.0,0.0,0.0 +20190326,AAPL,1914900,1928800,1845900,1867900,43987220,-3.0,0.0,0.0 +20190326,GOOG,11996100,12029700,11768000,11848500,1784154,-3.0,0.0,0.0 +20190326,IBM,1399300,1410200,1394200,1402200,2009766,-2.0,0.0,0.0 +20190327,AAPL,1888400,1897600,1865400,1885000,26785493,-2.0,0.0,0.0 +20190327,GOOG,11876300,11876300,11591400,11730600,1251820,-2.0,0.0,0.0 +20190327,IBM,1402600,1404800,1384100,1392400,2381589,-1.0,0.0,0.0 +20190328,AAPL,1889300,1895600,1875300,1887100,19466097,-1.0,0.0,0.0 +20190328,GOOG,11698300,11717000,11595000,11684900,878223,-1.0,0.0,0.0 +20190328,IBM,1399100,1404400,1391100,1399500,1901090,0.0,0.0,0.0 +20190329,AAPL,1899500,1900800,1885400,1899400,18639099,0.0,0.0,0.0 +20190329,GOOG,11756900,11794200,11628000,11731100,971516,0.0,0.0,0.0 +20190329,IBM,1405000,1412100,1401500,1411100,2086371,2.0,2.0,20725470.0 +20190401,AAPL,1916400,1916800,1883800,1912400,23096523,2.0,2.0,20725470.0 +20190401,GOOG,11840700,11968000,11818400,11941500,1030256,2.0,2.0,20725470.0 +20190401,IBM,1415100,1433900,1415100,1432400,3079888,3.0,3.0,27206667.0 +20190402,AAPL,1910500,1944600,1910500,1940400,20026095,3.0,3.0,27206667.0 +20190402,GOOG,11957500,12013500,11858100,12004200,616071,3.0,3.0,27206667.0 +20190402,IBM,1431300,1439500,1426000,1430100,2058194,3.0,3.0,22700360.0 +20190403,AAPL,1932500,1965000,1931500,1953500,20033154,3.0,3.0,22700360.0 +20190403,GOOG,12078400,12163300,12005000,12053300,861858,3.0,3.0,22700360.0 +20190403,IBM,1436500,1442200,1430200,1436000,2321998,3.0,3.0,23217010.0 +20190404,AAPL,1948900,1963700,1931400,1957200,17224373,3.0,3.0,23217010.0 +20190404,GOOG,12060000,12160900,12041300,12146800,786602,3.0,3.0,23217010.0 +20190404,IBM,1436200,1441400,1425500,1427600,2466019,-1.0,0.0,0.0 +20190405,AAPL,1964100,1971000,1959300,1969700,16026098,-1.0,0.0,0.0 +20190405,GOOG,12147000,12162200,12050000,12071400,760551,-1.0,0.0,0.0 +20190405,IBM,1432900,1435000,1424600,1433100,2353774,0.0,1.0,6.80868171710623 +20190408,AAPL,1964200,2002300,1963300,2000800,23831141,0.0,1.0,6.80868171710623 +20190408,GOOG,12071500,12085000,11997800,12038400,730048,0.0,1.0,6.80868171710623 +20190408,IBM,1430200,1434200,1428800,1433700,1804889,0.0,1.0,32.643252224511265 +20190409,AAPL,2003400,2028500,1992300,1995000,33104131,0.0,1.0,32.643252224511265 +20190409,GOOG,11960000,12022900,11935000,11981300,696431,0.0,1.0,32.643252224511265 +20190409,IBM,1427600,1429500,1418400,1422100,2473930,-1.0,0.5,10.44175442481156 +20190410,AAPL,1987400,2007400,1981800,2006600,20023619,-1.0,0.5,10.44175442481156 +20190410,GOOG,12002600,12039200,11962800,12021600,614098,-1.0,0.5,10.44175442481156 +20190410,IBM,1422000,1435000,1420100,1430400,2008464,1.0,1.0,2008464.0 +20190411,AAPL,2008500,2010000,1984500,1989400,18037895,1.0,1.0,2008464.0 +20190411,GOOG,12047100,12079800,12002300,12046200,530110,1.0,1.0,2008464.0 +20190411,IBM,1438000,1441100,1430900,1438100,2467900,2.0,2.0,2998010.0 +20190412,AAPL,1992300,2001400,1962100,1988900,25108070,2.0,2.0,2998010.0 +20190412,GOOG,12093000,12184200,12081200,12178600,822510,2.0,2.0,2998010.0 +20190412,IBM,1442600,1444400,1437000,1443600,2271167,1.0,2.0,0.12321444858167115 +20190415,AAPL,1985700,1998400,1980100,1992300,14628164,1.0,2.0,0.12321444858167115 +20190415,GOOG,12177400,12242500,12091100,12216300,992028,1.0,2.0,0.12321444858167115 +20190415,IBM,1444700,1444700,1432700,1439200,2729623,2.0,2.0,3721651.0 +20190416,AAPL,1994600,2013700,1985600,1992500,24268015,2.0,2.0,3721651.0 +20190416,GOOG,12250000,12304200,12201200,12274600,774879,2.0,2.0,3721651.0 +20190416,IBM,1444000,1453900,1440500,1451400,5459515,3.0,3.0,30502409.0 +20190417,AAPL,1995800,2034600,1986100,2031200,27999611,3.0,3.0,30502409.0 +20190417,GOOG,12320300,12405600,12278600,12365200,1049803,3.0,3.0,30502409.0 +20190417,IBM,1373700,1419600,1362800,1390800,11627349,1.0,2.0,2.4983694907583835 +20190418,AAPL,2031200,2041500,2025200,2038600,20443680,1.0,2.0,2.4983694907583835 +20190418,GOOG,12390800,12420800,12346100,12368100,1018437,1.0,2.0,2.4983694907583835 +20190418,IBM,1390000,1404900,1387800,1403300,3958106,2.0,2.0,21462117.0 +20190422,AAPL,2026600,2049400,2023300,2046400,13775526,2.0,2.0,21462117.0 +20190422,GOOG,12329000,12494300,12283000,12490900,662517,2.0,2.0,21462117.0 +20190422,IBM,1394200,1405500,1384800,1388700,3350803,2.0,2.0,14438043.0 +20190423,AAPL,2044300,2077500,2039000,2075100,19810816,2.0,2.0,14438043.0 +20190423,GOOG,12506900,12691500,12462700,12645000,1114144,2.0,2.0,14438043.0 +20190423,IBM,1391500,1409200,1389500,1404100,3072805,3.0,3.0,23997765.0 +20190424,AAPL,2074400,2084800,2070500,2071200,14932007,3.0,3.0,23997765.0 +20190424,GOOG,12652500,12680300,12549500,12550500,700959,3.0,3.0,23997765.0 +20190424,IBM,1406000,1412900,1398500,1399700,2019400,2.0,2.0,16951407.0 +20190425,AAPL,2068400,2077600,2051200,2052400,15970808,2.0,2.0,16951407.0 +20190425,GOOG,12652600,12676500,12520000,12629800,956135,2.0,2.0,16951407.0 +20190425,IBM,1397000,1397000,1377300,1386500,2373830,-1.0,0.0,0.0 +20190426,AAPL,2048300,2050000,2021200,2042900,16420146,-1.0,0.0,0.0 +20190426,GOOG,12665500,12736800,12602800,12718000,1083643,-1.0,0.0,0.0 +20190426,IBM,1392800,1398900,1388200,1394300,1940500,0.0,1.0,0.06599472379843638 +20190429,AAPL,2044000,2059700,2038600,2046100,19605618,0.0,1.0,0.06599472379843638 +20190429,GOOG,12730100,12892800,12663800,12874300,1717098,0.0,1.0,0.06599472379843638 +20190429,IBM,1391500,1396200,1388200,1390800,1946116,1.0,1.0,1717098.0 +20190430,AAPL,2030600,2033900,1991100,2005100,35906353,1.0,1.0,1717098.0 +20190430,GOOG,11850500,11930000,11748700,11894700,5795501,1.0,1.0,1717098.0 +20190430,IBM,1394200,1404400,1386800,1402600,2712449,-2.0,0.3333333333333333,0.061071520136204774 +20190501,AAPL,2099700,2153100,2092300,2105200,58431082,-2.0,0.3333333333333333,0.061071520136204774 +20190501,GOOG,11880100,11884900,11671500,11676500,2457471,-2.0,0.3333333333333333,0.061071520136204774 +20190501,IBM,1406400,1418000,1401900,1405700,2599938,1.0,2.0,24.83488920113401 +20190502,AAPL,2099500,2126500,2081300,2091700,28925386,1.0,2.0,24.83488920113401 +20190502,GOOG,11676600,11737900,11550100,11623600,1797876,1.0,2.0,24.83488920113401 +20190502,IBM,1404900,1412700,1394100,1396400,2728959,-1.0,0.0,0.0 +20190503,AAPL,2107600,2118400,2102300,2117800,18034291,-1.0,0.0,0.0 +20190503,GOOG,11726700,11868800,11689800,11855600,1770247,-1.0,0.0,0.0 +20190503,IBM,1397000,1410000,1397000,1402800,1967201,0.0,0.0,0.0 +20190506,AAPL,2042900,2088400,2035000,2086000,28839202,0.0,0.0,0.0 +20190506,GOOG,11678200,11908500,11662600,11894900,1420016,0.0,0.0,0.0 +20190506,IBM,1382900,1406900,1379000,1404000,2198109,-1.0,0.5,0.04575190163864389 +20190507,AAPL,2059300,2074000,2008300,2028600,34855750,-1.0,0.5,0.04575190163864389 +20190507,GOOG,11804700,11905400,11610500,11746200,1350758,-1.0,0.5,0.04575190163864389 +20190507,IBM,1391800,1394800,1362000,1376200,4062939,-3.0,0.0,0.0 +20190508,AAPL,2020200,2053400,2017600,2029000,22876206,-3.0,0.0,0.0 +20190508,GOOG,11715200,11805300,11656600,11657400,1150107,-3.0,0.0,0.0 +20190508,IBM,1377700,1386700,1371300,1380000,2823027,0.0,0.0,0.0 +20190509,AAPL,2004600,2016800,1966700,2007200,32813078,0.0,0.0,0.0 +20190509,GOOG,11589000,11697700,11508500,11626100,1076230,0.0,0.0,0.0 +20190509,IBM,1348900,1355700,1330300,1353400,3234443,-3.0,0.0,0.0 +20190510,AAPL,1974300,1988500,1927600,1972500,36509516,-3.0,0.0,0.0 +20190510,GOOG,11603000,11726000,11424900,11644900,1196664,-3.0,0.0,0.0 +20190510,IBM,1348800,1357500,1324400,1353200,3404127,-3.0,0.0,0.0 +20190513,AAPL,1876900,1894800,1828500,1857200,50683171,-3.0,0.0,0.0 +20190513,GOOG,11415000,11480000,11220000,11326100,1634334,-3.0,0.0,0.0 +20190513,IBM,1332800,1335500,1309600,1314100,3593331,-3.0,0.0,0.0 +20190514,AAPL,1864100,1897100,1854100,1886600,31680942,-3.0,0.0,0.0 +20190514,GOOG,11371100,11410000,11195200,11203300,1641019,-3.0,0.0,0.0 +20190514,IBM,1318200,1343200,1318100,1333400,2780832,-1.0,0.0,0.0 +20190515,AAPL,1863000,1917500,1860100,1909200,23820574,-1.0,0.0,0.0 +20190515,GOOG,11178700,11714200,11167500,11640600,2011343,-1.0,0.0,0.0 +20190515,IBM,1325900,1345900,1323700,1344000,2134015,2.0,3.0,13.904108846676076 +20190516,AAPL,1899100,1924800,1888400,1901400,28935602,2.0,3.0,13.904108846676076 +20190516,GOOG,11657800,11883600,11626400,11789800,1375292,2.0,3.0,13.904108846676076 +20190516,IBM,1347400,1361000,1346400,1358700,2367170,3.0,3.0,32678064.0 +20190517,AAPL,1870600,1909000,1867600,1889800,28930584,3.0,3.0,32678064.0 +20190517,GOOG,11699500,11802500,11599900,11623000,1054944,3.0,3.0,32678064.0 +20190517,IBM,1346800,1354000,1339400,1342900,2138590,0.0,0.0,0.0 +20190520,AAPL,1836300,1843400,1802900,1830900,33467674,0.0,0.0,0.0 +20190520,GOOG,11445000,11470900,11313500,11383300,1174301,0.0,0.0,0.0 +20190520,IBM,1335300,1354300,1329400,1351200,2969086,-3.0,0.0,0.0 +20190521,AAPL,1852200,1880000,1847000,1865900,24078878,-3.0,0.0,0.0 +20190521,GOOG,11480400,11527800,11379400,11496300,885148,-3.0,0.0,0.0 +20190521,IBM,1360100,1370400,1358300,1364600,1969099,1.0,1.0,1969099.0 +20190522,AAPL,1848600,1857100,1825500,1827900,26908150,1.0,1.0,1969099.0 +20190522,GOOG,11460000,11587500,11453700,11514200,783717,1.0,1.0,1969099.0 +20190522,IBM,1360000,1367500,1357200,1363600,1460512,1.0,1.0,783717.0 +20190523,AAPL,1798500,1805400,1778100,1796700,31309823,1.0,1.0,783717.0 +20190523,GOOG,11425400,11458900,11294200,11405500,1038778,1.0,1.0,783717.0 +20190523,IBM,1351300,1351300,1304500,1323900,4606839,-3.0,0.0,0.0 +20190524,AAPL,1802900,1821400,1786200,1790300,21640795,-3.0,0.0,0.0 +20190524,GOOG,11479700,11499100,11317300,11340000,1023769,-3.0,0.0,0.0 +20190524,IBM,1335300,1342000,1315900,1323000,2291630,0.0,0.0,0.0 +20190528,AAPL,1788900,1805900,1779200,1781700,22752739,0.0,0.0,0.0 +20190528,GOOG,11352400,11517700,11331200,11331800,1075412,0.0,0.0,0.0 +20190528,IBM,1320100,1326400,1302700,1304600,2419010,0.0,1.0,0.4445669922819666 +20190529,AAPL,1764800,1793500,1760000,1773500,26364270,0.0,1.0,0.4445669922819666 +20190529,GOOG,11290000,11294500,11082500,11163600,1425120,0.0,1.0,0.4445669922819666 +20190529,IBM,1300000,1302600,1283300,1296800,3201934,-3.0,0.0,0.0 +20190530,AAPL,1779900,1792300,1766700,1782500,19994104,-3.0,0.0,0.0 +20190530,GOOG,11180000,11231500,11121200,11177900,865165,-3.0,0.0,0.0 +20190530,IBM,1297400,1299700,1289300,1295600,2351813,0.0,0.0,0.0 +20190531,AAPL,1762200,1779900,1749900,1750000,23031208,0.0,0.0,0.0 +20190531,GOOG,11034100,11096000,11001000,11038500,1272882,0.0,0.0,0.0 +20190531,IBM,1284400,1284400,1268600,1270200,2523395,-3.0,0.0,0.0 +20190603,AAPL,1755800,1779200,1702700,1732800,36949732,-3.0,0.0,0.0 +20190603,GOOG,10660200,10670000,10250100,10363100,4745310,-3.0,0.0,0.0 +20190603,IBM,1270000,1285600,1270000,1282600,3463489,-2.0,0.0,0.0 +20190604,AAPL,1754500,1798400,1745200,1796700,27402677,-2.0,0.0,0.0 +20190604,GOOG,10420100,10562100,10337600,10530600,2550546,-2.0,0.0,0.0 +20190604,IBM,1295600,1327400,1290900,1326900,3074020,2.0,2.0,30476697.0 +20190605,AAPL,1842500,1849900,1811400,1825400,26229032,2.0,2.0,30476697.0 +20190605,GOOG,10522000,10535600,10304300,10429500,1991132,2.0,2.0,30476697.0 +20190605,IBM,1332200,1336100,1304700,1314500,2770367,2.0,2.0,28999399.0 +20190606,AAPL,1830900,1854700,1821500,1852300,18722674,2.0,2.0,28999399.0 +20190606,GOOG,10449900,10474700,10334300,10446000,1392091,2.0,2.0,28999399.0 +20190606,IBM,1321900,1326400,1309200,1322000,1962106,1.0,1.0,18722674.0 +20190607,AAPL,1866000,1919200,1857700,1901400,27840129,1.0,1.0,18722674.0 +20190607,GOOG,10504100,10717000,10482700,10660300,1544742,1.0,1.0,18722674.0 +20190607,IBM,1320800,1347200,1320800,1332900,2144277,3.0,3.0,31529148.0 +20190610,AAPL,1923300,1953700,1916100,1925200,23916792,3.0,3.0,31529148.0 +20190610,GOOG,10733900,10928400,10726600,10803800,1308312,3.0,3.0,31529148.0 +20190610,IBM,1343800,1353400,1339100,1347000,2479503,3.0,3.0,27704607.0 +20190611,AAPL,1948400,1960000,1936000,1948100,22798624,3.0,3.0,27704607.0 +20190611,GOOG,10946900,11019900,10775200,10788100,1285869,3.0,3.0,27704607.0 +20190611,IBM,1353200,1364400,1350500,1359700,2771962,3.0,3.0,26856455.0 +20190612,AAPL,1939900,1959700,1933700,1941900,16452770,3.0,3.0,26856455.0 +20190612,GOOG,10780000,10805900,10676100,10773300,962420,3.0,3.0,26856455.0 +20190612,IBM,1354900,1359400,1344100,1348700,1729989,-1.0,0.0,0.0 +20190613,AAPL,1947200,1968000,1936000,1947400,18162145,-1.0,0.0,0.0 +20190613,GOOG,10830000,10942200,10804400,10887900,885444,-1.0,0.0,0.0 +20190613,IBM,1351300,1362700,1350900,1357700,1920879,1.0,1.0,18162145.0 +20190614,AAPL,1916200,1935800,1903000,1927400,15883266,1.0,1.0,18162145.0 +20190614,GOOG,10860200,10925800,10800000,10853500,994158,1.0,1.0,18162145.0 +20190614,IBM,1353500,1356500,1344300,1351900,1527445,-1.0,0.0,0.0 +20190617,AAPL,1929000,1949600,1921700,1939500,12890733,-1.0,0.0,0.0 +20190617,GOOG,10867400,10993700,10860100,10925000,809378,-1.0,0.0,0.0 +20190617,IBM,1353900,1360300,1347000,1349500,1814647,1.0,1.0,809378.0 +20190618,AAPL,1960200,2002900,1952100,1985000,23830038,1.0,1.0,809378.0 +20190618,GOOG,11087000,11165200,10986700,11034700,1208540,1.0,1.0,809378.0 +20190618,IBM,1352000,1371900,1352000,1364200,2276060,3.0,3.0,27314638.0 +20190619,AAPL,1996800,1998900,1973100,1978200,17677106,3.0,3.0,27314638.0 +20190619,GOOG,11050000,11070000,10934200,11025800,1014357,3.0,3.0,27314638.0 +20190619,IBM,1364300,1376700,1362400,1371000,1893849,1.0,1.0,1893849.0 +20190620,AAPL,2003700,2006000,1980300,1994000,18629038,1.0,1.0,1893849.0 +20190620,GOOG,11179900,11201800,11050000,11109500,1003009,1.0,1.0,1893849.0 +20190620,IBM,1389300,1395200,1382100,1388500,2216468,3.0,3.0,21848515.0 +20190621,AAPL,1984400,2008500,1981400,1988000,26177066,3.0,3.0,21848515.0 +20190621,GOOG,11075800,11249000,11071300,11224400,1469439,3.0,3.0,21848515.0 +20190621,IBM,1386900,1395400,1384000,1391800,3222090,3.0,3.0,30868595.0 +20190624,AAPL,1985600,2001600,1981700,1985500,14854581,3.0,3.0,30868595.0 +20190624,GOOG,11191800,11221600,11110000,11158300,1264074,3.0,3.0,30868595.0 +20190624,IBM,1392000,1401400,1390500,1393600,1762740,1.0,1.0,1762740.0 +20190625,AAPL,1984800,1992900,1952900,1955700,19610359,1.0,1.0,1762740.0 +20190625,GOOG,11129300,11154600,10838000,10863400,1352189,1.0,1.0,1762740.0 +20190625,IBM,1394600,1395000,1381300,1383700,2251465,-3.0,0.0,0.0 +20190626,AAPL,1978500,2009900,1973400,1998000,22885387,-3.0,0.0,0.0 +20190626,GOOG,10876900,10933000,10722900,10798000,1591139,-3.0,0.0,0.0 +20190626,IBM,1388700,1396800,1384200,1385300,1612064,0.0,1.0,14.383021847871241 +20190627,AAPL,2004000,2015700,1995700,1997300,15632774,0.0,1.0,14.383021847871241 +20190627,GOOG,10848400,10870000,10751800,10759300,870095,0.0,1.0,14.383021847871241 +20190627,IBM,1387200,1393000,1379600,1385200,1675796,0.0,1.0,9.328566245533466 +20190628,AAPL,1987200,1994900,1970500,1979200,19956663,0.0,1.0,9.328566245533466 +20190628,GOOG,10763600,10810000,10732500,10806200,1252274,0.0,1.0,9.328566245533466 +20190628,IBM,1385700,1391400,1378600,1379200,2567968,-2.0,0.0,0.0 +20190701,AAPL,2032800,2044900,2006500,2016800,24264641,-2.0,0.0,0.0 +20190701,GOOG,10994600,11075800,10937200,10979500,1288236,-2.0,0.0,0.0 +20190701,IBM,1396000,1414900,1392900,1399200,2717318,3.0,3.0,28270195.0 +20190702,AAPL,2014300,2031300,2013600,2027100,15965830,3.0,3.0,28270195.0 +20190702,GOOG,11013900,11117700,10989000,11117700,871863,3.0,3.0,28270195.0 +20190702,IBM,1396700,1404200,1394800,1402000,2091296,1.0,1.0,871863.0 +20190703,AAPL,2032100,2044400,2027000,2044100,9430155,1.0,1.0,871863.0 +20190703,GOOG,11160500,11267700,11138100,11219200,669181,1.0,1.0,871863.0 +20190703,IBM,1407200,1418100,1404900,1414900,1479573,2.0,2.0,2148754.0 +20190705,AAPL,2033500,2050800,2029000,2042500,15239601,2.0,2.0,2148754.0 +20190705,GOOG,11177900,11329200,11150000,11320300,1000689,2.0,2.0,2148754.0 +20190705,IBM,1408700,1414900,1399100,1413700,1819874,2.0,2.0,16240290.0 +20190708,AAPL,2009400,2014000,1984100,2000200,22281039,2.0,2.0,16240290.0 +20190708,GOOG,11259200,11270000,11113200,11163500,1031603,2.0,2.0,16240290.0 +20190708,IBM,1411000,1412800,1402800,1405800,1963230,-2.0,0.0,0.0 +20190709,AAPL,1992000,2015100,1988100,2012200,17873539,-2.0,0.0,0.0 +20190709,GOOG,11122300,11281000,11070000,11245800,1153922,-2.0,0.0,0.0 +20190709,IBM,1406100,1409900,1391300,1393400,2873887,-2.0,0.0,0.0 +20190710,AAPL,2019000,2037300,2015600,2032100,15735306,-2.0,0.0,0.0 +20190710,GOOG,11310000,11421000,11308800,11404800,1089447,-2.0,0.0,0.0 +20190710,IBM,1400000,1419000,1399300,1404600,2178813,3.0,3.0,19003566.0 +20190711,AAPL,2033500,2043900,2017100,2017400,16252329,3.0,3.0,19003566.0 +20190711,GOOG,11429500,11532200,11393000,11442100,1106386,3.0,3.0,19003566.0 +20190711,IBM,1407900,1415400,1403000,1412400,1873952,2.0,2.0,17358715.0 +20190712,AAPL,2025300,2040000,2022000,2032400,15652854,2.0,2.0,17358715.0 +20190712,GOOG,11439900,11472700,11386500,11445600,766543,2.0,2.0,17358715.0 +20190712,IBM,1419200,1429100,1417300,1426900,2255321,1.0,1.0,2255321.0 +20190715,AAPL,2040500,2058700,2040000,2052000,14611018,1.0,1.0,2255321.0 +20190715,GOOG,11455300,11508800,11396200,11505600,809028,1.0,1.0,2255321.0 +20190715,IBM,1428900,1435000,1421400,1433100,2100010,2.0,2.0,16711028.0 +20190716,AAPL,2047400,2061100,2035000,2044900,14612121,2.0,2.0,16711028.0 +20190716,GOOG,11458000,11585800,11450000,11536000,1156894,2.0,2.0,16711028.0 +20190716,IBM,1431600,1440300,1430600,1435200,2924182,3.0,3.0,18693197.0 +20190717,AAPL,2043100,2050900,2032700,2032800,11705771,3.0,3.0,18693197.0 +20190717,GOOG,11524900,11583200,11457100,11464900,1001430,3.0,3.0,18693197.0 +20190717,IBM,1436800,1438000,1419500,1431000,4677082,-2.0,0.0,0.0 +20190718,AAPL,2040000,2058800,2037000,2056600,15514507,-2.0,0.0,0.0 +20190718,GOOG,11410000,11476900,11327300,11468000,959692,-2.0,0.0,0.0 +20190718,IBM,1424500,1503000,1424100,1496300,11889986,0.0,1.0,12.38937700845688 +20190719,AAPL,2057800,2065000,2023600,2025700,18324264,0.0,1.0,12.38937700845688 +20190719,GOOG,11497700,11512700,11296200,11300100,1227100,0.0,1.0,12.38937700845688 +20190719,IBM,1499600,1515800,1495600,1498100,6056454,0.0,1.0,1.2470085463090963 +20190722,AAPL,2037800,2072300,2036100,2072300,19154085,0.0,1.0,1.2470085463090963 +20190722,GOOG,11340700,11392700,11242400,11382800,1075273,0.0,1.0,1.2470085463090963 +20190722,IBM,1501600,1519400,1497000,1497500,3660075,1.0,2.0,21.217086265534427 +20190723,AAPL,2083700,2089100,2073000,2088300,16514267,1.0,2.0,21.217086265534427 +20190723,GOOG,11434700,11469100,11317700,11465600,988570,1.0,2.0,21.217086265534427 +20190723,IBM,1505700,1507200,1483900,1503800,2908133,0.0,1.0,5.678649153941722 +20190724,AAPL,2076700,2091500,2071800,2086700,13148873,0.0,1.0,5.678649153941722 +20190724,GOOG,11311500,11439800,11270000,11381800,1292101,0.0,1.0,5.678649153941722 +20190724,IBM,1501200,1514500,1492000,1500400,2661472,1.0,1.0,13148873.0 +20190725,AAPL,2087200,2092400,2067300,2070500,11966186,1.0,1.0,13148873.0 +20190725,GOOG,11370100,11419000,11210000,11348600,1579386,1.0,1.0,13148873.0 +20190725,IBM,1498000,1506200,1486100,1504100,2388821,-1.0,0.5,0.8834020445943516 +20190726,AAPL,2074000,2097300,2071400,2077500,15726362,-1.0,0.5,0.8834020445943516 +20190726,GOOG,12240400,12656300,12232400,12477400,4327585,-1.0,0.5,0.8834020445943516 +20190726,IBM,1509200,1514000,1501000,1513400,1955575,2.0,2.0,20053947.0 +20190729,AAPL,2084700,2106400,2084100,2096700,19204268,2.0,2.0,20053947.0 +20190729,GOOG,12410000,12472300,12282700,12387500,2056580,2.0,2.0,20053947.0 +20190729,IBM,1511100,1514600,1503300,1509300,1617308,2.0,2.0,20821576.0 +20190730,AAPL,2088300,2106600,2073100,2088800,24740263,2.0,2.0,20821576.0 +20190730,GOOG,12265800,12348700,12232600,12251400,1360406,2.0,2.0,20821576.0 +20190730,IBM,1500000,1503900,1492400,1497700,2278632,0.0,1.0,10.857507048088502 +20190731,AAPL,2164000,2213700,2113000,2127800,63857734,0.0,1.0,10.857507048088502 +20190731,GOOG,12233300,12512300,12071100,12166800,1526178,0.0,1.0,10.857507048088502 +20190731,IBM,1497000,1501800,1463900,1482400,2748127,0.0,1.0,15.296969214878208 +20190801,AAPL,2140100,2180300,2067300,2084500,51934597,0.0,1.0,15.296969214878208 +20190801,GOOG,12143600,12343300,12055100,12094800,1804644,0.0,1.0,15.296969214878208 +20190801,IBM,1489000,1528100,1485000,1503000,5835516,-1.0,0.5,0.10858947561243003 +20190802,AAPL,2051500,2064300,2016300,2040900,36037467,-1.0,0.5,0.10858947561243003 +20190802,GOOG,12007400,12071000,11889200,11936300,1455908,-1.0,0.5,0.10858947561243003 +20190802,IBM,1490300,1528900,1455900,1472800,7643491,-2.0,0.3333333333333333,0.1693403126393401 +20190805,AAPL,1978800,1986500,1925800,1932200,45466995,-2.0,0.3333333333333333,0.1693403126393401 +20190805,GOOG,11706000,11752400,11401800,11523200,2267696,-2.0,0.3333333333333333,0.1693403126393401 +20190805,IBM,1449800,1451000,1391700,1407500,6186074,-3.0,0.0,0.0 +20190806,AAPL,1964300,1980700,1940400,1969800,32111414,-3.0,0.0,0.0 +20190806,GOOG,11628500,11800000,11598900,11693600,1363456,-3.0,0.0,0.0 +20190806,IBM,1420000,1424700,1393100,1407300,4294639,0.0,0.0,0.0 +20190807,AAPL,1954900,1995600,1938200,1991400,29406192,0.0,0.0,0.0 +20190807,GOOG,11567500,11784400,11491600,11738200,1214158,0.0,0.0,0.0 +20190807,IBM,1390000,1395800,1364800,1391300,5028053,0.0,1.0,5.848425225430201 +20190808,AAPL,2003100,2035300,1993900,2034500,23463801,0.0,1.0,5.848425225430201 +20190808,GOOG,11832200,12050100,11733800,12045100,1254711,0.0,1.0,5.848425225430201 +20190808,IBM,1384500,1404200,1377800,1401300,4344213,2.0,2.0,24718512.0 +20190809,AAPL,2013000,2027600,1992900,2009900,21848205,2.0,2.0,24718512.0 +20190809,GOOG,11980000,12039700,11835200,11881400,917903,2.0,2.0,24718512.0 +20190809,IBM,1393000,1393000,1353500,1361200,4720674,-1.0,0.0,0.0 +20190812,AAPL,1994600,2020600,1991500,2005000,19913300,-1.0,0.0,0.0 +20190812,GOOG,11792300,11848600,11675000,11742300,865880,-1.0,0.0,0.0 +20190812,IBM,1356600,1358700,1331800,1340900,3390677,-3.0,0.0,0.0 +20190813,AAPL,2010000,2121400,2008300,2089800,43883110,-3.0,0.0,0.0 +20190813,GOOG,11714600,12049300,11714600,11972600,1117326,-3.0,0.0,0.0 +20190813,IBM,1338100,1365700,1328500,1357800,3939008,1.0,2.0,11.424306830552261 +20190814,AAPL,2032800,2064400,2025000,2027500,31227195,1.0,2.0,11.424306830552261 +20190814,GOOG,11763700,11823600,11607900,11641300,1330650,1.0,2.0,11.424306830552261 +20190814,IBM,1339100,1341600,1309800,1312400,3912510,-2.0,0.0,0.0 +20190815,AAPL,2034600,2051500,1996700,2016800,24652850,-2.0,0.0,0.0 +20190815,GOOG,11684000,11759200,11620800,11675700,1095137,-2.0,0.0,0.0 +20190815,IBM,1314200,1323600,1302500,1318800,3303365,-2.0,0.0,0.0 +20190816,AAPL,2041700,2071600,2038500,2064400,24842738,-2.0,0.0,0.0 +20190816,GOOG,11795500,11826800,11715800,11776000,1161671,-2.0,0.0,0.0 +20190816,IBM,1330400,1345900,1329800,1337400,2406250,3.0,3.0,28410659.0 +20190819,AAPL,2106900,2127300,2100400,2103400,21632067,3.0,3.0,28410659.0 +20190819,GOOG,11906000,12069900,11900900,11985300,1003576,3.0,3.0,28410659.0 +20190819,IBM,1348800,1363200,1348800,1350300,2773650,3.0,3.0,25409293.0 +20190820,AAPL,2107800,2133500,2103200,2103500,21348212,3.0,3.0,25409293.0 +20190820,GOOG,11953900,11961100,11820000,11826900,682728,3.0,3.0,25409293.0 +20190820,IBM,1351100,1352700,1328200,1331000,2504433,0.0,1.0,8.524169742213108 +20190821,AAPL,2129700,2136500,2116100,2126700,18922195,0.0,1.0,8.524169742213108 +20190821,GOOG,11920600,11990000,11871100,11912400,646709,0.0,1.0,8.524169742213108 +20190821,IBM,1347100,1359000,1338000,1342800,2467302,1.0,1.0,18922195.0 +20190822,AAPL,2131900,2144300,2107500,2124500,19534453,1.0,1.0,18922195.0 +20190822,GOOG,11940700,11980500,11784500,11895000,784498,1.0,1.0,18922195.0 +20190822,IBM,1349900,1356400,1338500,1343400,2191473,0.0,1.0,24.900577184390528 +20190823,AAPL,2093900,2120500,2010000,2026300,41268018,0.0,1.0,24.900577184390528 +20190823,GOOG,11820500,11940800,11476000,11517200,1399418,0.0,1.0,24.900577184390528 +20190823,IBM,1336000,1342000,1288300,1295700,3740545,-3.0,0.0,0.0 +20190826,AAPL,2058900,2071900,2050600,2066000,23135836,-3.0,0.0,0.0 +20190826,GOOG,11605000,11694700,11528000,11694700,1029694,-3.0,0.0,0.0 +20190826,IBM,1310100,1313000,1291800,1299900,2342907,0.0,0.0,0.0 +20190827,AAPL,2078100,2085500,2035400,2041300,19567155,0.0,0.0,0.0 +20190827,GOOG,11805300,11829500,11615600,11682700,884564,0.0,0.0,0.0 +20190827,IBM,1310800,1316900,1303300,1311700,3754502,0.0,0.0,0.0 +20190828,AAPL,2041000,2057200,2033300,2055200,14183557,0.0,0.0,0.0 +20190828,GOOG,11626900,11762100,11572000,11710200,625006,0.0,0.0,0.0 +20190828,IBM,1303300,1328800,1300600,1327200,2210239,0.0,1.0,0.15583107960859183 +20190829,AAPL,2086900,2093200,2066500,2091000,18608188,0.0,1.0,0.15583107960859183 +20190829,GOOG,11820700,11964100,11811200,11930400,978995,0.0,1.0,0.15583107960859183 +20190829,IBM,1341300,1356900,1340400,1349300,2518503,3.0,3.0,22105686.0 +20190830,AAPL,2101500,2104500,2072000,2087400,17065976,3.0,3.0,22105686.0 +20190830,GOOG,11985000,11995000,11838100,11884200,846644,3.0,3.0,22105686.0 +20190830,IBM,1356800,1360600,1343800,1354600,2001659,3.0,3.0,19914279.0 +20190903,AAPL,2064200,2069800,2042200,2056900,17995638,3.0,3.0,19914279.0 +20190903,GOOG,11784700,11867500,11632000,11682400,1293007,3.0,3.0,19914279.0 +20190903,IBM,1346700,1349000,1333600,1341500,2033141,-3.0,0.0,0.0 +20190904,AAPL,2083900,2094800,2073100,2092500,17133945,-3.0,0.0,0.0 +20190904,GOOG,11784500,11834800,11707600,11814100,967215,-3.0,0.0,0.0 +20190904,IBM,1358500,1364300,1351500,1363100,1561819,1.0,1.0,1561819.0 +20190905,AAPL,2118500,2139600,2115100,2132800,20682004,1.0,1.0,1561819.0 +20190905,GOOG,11923200,12130400,11915300,12112300,1284567,1.0,1.0,1561819.0 +20190905,IBM,1383500,1417000,1380500,1409700,4210893,3.0,3.0,26177464.0 +20190906,AAPL,2139800,2144200,2125100,2132700,17454572,3.0,3.0,26177464.0 +20190906,GOOG,12073900,12121000,12026000,12049300,916327,3.0,3.0,26177464.0 +20190906,IBM,1415200,1415200,1404600,1405500,2228125,1.0,1.0,17454572.0 +20190909,AAPL,2148600,2164400,2110700,2141500,23787972,1.0,1.0,17454572.0 +20190909,GOOG,12076600,12200000,11927200,12049200,1345648,1.0,1.0,17454572.0 +20190909,IBM,1405900,1430100,1404600,1426200,3474580,2.0,3.0,1.2026329945234508 +20190910,AAPL,2138100,2167800,2117100,2167700,28051341,2.0,3.0,1.2026329945234508 +20190910,GOOG,11955400,12100000,11944700,12074500,1131329,2.0,3.0,1.2026329945234508 +20190910,IBM,1430000,1454600,1429600,1450200,4363217,2.0,2.0,32414558.0 +20190911,AAPL,2181200,2236400,2177300,2235700,40687303,2.0,2.0,32414558.0 +20190911,GOOG,12041800,12225900,12022000,12201700,1150453,2.0,2.0,32414558.0 +20190911,IBM,1448500,1450800,1427200,1436000,3087123,2.0,2.0,41837756.0 +20190912,AAPL,2248000,2264200,2228600,2230900,27809109,2.0,2.0,41837756.0 +20190912,GOOG,12249800,12416800,12230000,12340000,1554159,2.0,2.0,41837756.0 +20190912,IBM,1440300,1440700,1418800,1436100,1985446,1.0,2.0,14.789255411630435 +20190913,AAPL,2200100,2207900,2170200,2188000,36334641,1.0,2.0,14.789255411630435 +20190913,GOOG,12313500,12408800,12270100,12392200,1136449,1.0,2.0,14.789255411630435 +20190913,IBM,1440000,1446500,1432600,1436400,1660207,-1.0,0.0,0.0 +20190916,AAPL,2177400,2201300,2175600,2199000,18858994,-1.0,0.0,0.0 +20190916,GOOG,12304700,12395600,12256000,12313000,938240,-1.0,0.0,0.0 +20190916,IBM,1425000,1435900,1422700,1424300,1473455,0.0,0.0,0.0 +20190917,AAPL,2198700,2208200,2191200,2206500,15950731,0.0,0.0,0.0 +20190917,GOOG,12316800,12350500,12236700,12291600,801300,0.0,0.0,0.0 +20190917,IBM,1424700,1424800,1406900,1421800,1965391,-1.0,0.5,5.765273751206767 +20190918,AAPL,2211300,2228500,2194500,2227700,22852282,-1.0,0.5,5.765273751206767 +20190918,GOOG,12282800,12356100,12163100,12326500,957556,-1.0,0.5,5.765273751206767 +20190918,IBM,1420000,1422900,1405300,1422100,1732555,-1.0,0.5,8.494921585020098 +20190919,AAPL,2221200,2237600,2203700,2209500,19957797,-1.0,0.5,8.494921585020098 +20190919,GOOG,12320200,12444900,12320200,12386400,898159,-1.0,0.5,8.494921585020098 +20190919,IBM,1425300,1450100,1424600,1429400,2760621,3.0,3.0,23616577.0 +20190920,AAPL,2213900,2225500,2174800,2176900,31800687,3.0,3.0,23616577.0 +20190920,GOOG,12347500,12433200,12228100,12296800,1527184,3.0,3.0,23616577.0 +20190920,IBM,1435100,1438300,1418300,1418300,3679511,-1.0,0.0,0.0 +20190923,AAPL,2189100,2198400,2176500,2186800,16559468,-1.0,0.0,0.0 +20190923,GOOG,12271200,12392300,12240000,12340900,924827,-1.0,0.0,0.0 +20190923,IBM,1411900,1422100,1405600,1420300,1450872,-1.0,0.0,0.0 +20190924,AAPL,2211400,2224800,2171900,2176800,27421294,-1.0,0.0,0.0 +20190924,GOOG,12400000,12467800,12110200,12190900,1369997,-1.0,0.0,0.0 +20190924,IBM,1422800,1428900,1410700,1417800,2612966,-1.0,0.5,0.047583729399282584 +20190925,AAPL,2187500,2215000,2171500,2209900,19455919,-1.0,0.5,0.047583729399282584 +20190925,GOOG,12164300,12484000,12100000,12463100,1342641,-1.0,0.5,0.047583729399282584 +20190925,IBM,1418700,1436000,1408600,1432000,1927961,0.0,1.0,0.15725136740235862 +20190926,AAPL,2198800,2209400,2188300,2198900,16281412,0.0,1.0,0.15725136740235862 +20190926,GOOG,12419900,12459800,12324500,12420000,1336283,0.0,1.0,0.15725136740235862 +20190926,IBM,1431100,1438400,1414100,1436000,1821053,1.0,1.0,1821053.0 +20190927,AAPL,2204300,2209600,2172800,2188500,23029276,1.0,1.0,1821053.0 +20190927,GOOG,12425000,12444600,12144600,12250800,1168550,1.0,1.0,1821053.0 +20190927,IBM,1441100,1450700,1423800,1433100,1905797,1.0,1.0,1905797.0 +20190930,AAPL,2209300,2245800,2208000,2239800,22658210,1.0,1.0,1905797.0 +20190930,GOOG,12214100,12260000,12123400,12186300,1184162,1.0,1.0,1905797.0 +20190930,IBM,1437400,1465700,1437400,1454100,3060246,1.0,2.0,21.718697272839357 +20191001,AAPL,2251300,2282000,2241900,2245800,32509565,1.0,2.0,21.718697272839357 +20191001,GOOG,12207900,12312500,12035800,12051700,1130161,1.0,2.0,21.718697272839357 +20191001,IBM,1456000,1473500,1435400,1436200,2484575,1.0,2.0,30.963853822596956 +20191002,AAPL,2230900,2235900,2179300,2189600,31739723,1.0,2.0,30.963853822596956 +20191002,GOOG,11969300,11969800,11717600,11771900,1373217,1.0,2.0,30.963853822596956 +20191002,IBM,1421000,1422700,1405900,1417700,2622675,-3.0,0.0,0.0 +20191003,AAPL,2185300,2209600,2151500,2208100,26301723,-3.0,0.0,0.0 +20191003,GOOG,11822500,11894900,11620600,11873100,1506514,-3.0,0.0,0.0 +20191003,IBM,1415000,1420600,1391900,1419800,2531777,-3.0,0.0,0.0 +20191004,AAPL,2257100,2274900,2239000,2270100,31236611,-3.0,0.0,0.0 +20191004,GOOG,11924100,12115400,11890400,12088400,1012930,-3.0,0.0,0.0 +20191004,IBM,1421300,1430500,1410300,1429900,1697755,3.0,3.0,33947296.0 +20191007,AAPL,2263100,2299300,2258600,2270600,28675249,3.0,3.0,33947296.0 +20191007,GOOG,12050400,12184000,12040000,12072500,762527,3.0,3.0,33947296.0 +20191007,IBM,1423700,1427000,1412200,1412600,1672475,2.0,2.0,29437776.0 +20191008,AAPL,2258800,2280600,2243300,2243900,25163243,2.0,2.0,29437776.0 +20191008,GOOG,11964300,12060800,11890100,11892400,922604,2.0,2.0,29437776.0 +20191008,IBM,1401500,1404700,1382500,1383800,2699773,-2.0,0.0,0.0 +20191009,AAPL,2270800,2277900,2256500,2270000,17033593,-2.0,0.0,0.0 +20191009,GOOG,12001100,12083500,11974300,12019300,768220,-2.0,0.0,0.0 +20191009,IBM,1397800,1403300,1388000,1396300,2215673,0.0,0.0,0.0 +20191010,AAPL,2279000,2304400,2273000,2300900,26646576,0.0,0.0,0.0 +20191010,GOOG,12002600,12150000,11973400,12089500,725405,0.0,0.0,0.0 +20191010,IBM,1398400,1417800,1395700,1411300,2221612,3.0,3.0,29593593.0 +20191011,AAPL,2329500,2376400,2323000,2362200,38743375,3.0,3.0,29593593.0 +20191011,GOOG,12220100,12285500,12137000,12145700,1141581,3.0,3.0,29593593.0 +20191011,IBM,1427500,1445000,1426100,1426700,2578804,3.0,3.0,42463760.0 +20191014,AAPL,2351000,2381400,2346700,2358900,22169934,3.0,3.0,42463760.0 +20191014,GOOG,12137800,12263300,12119700,12171300,786716,3.0,3.0,42463760.0 +20191014,IBM,1423100,1424300,1413200,1419900,1938501,1.0,1.0,22169934.0 +20191015,AAPL,2363900,2376500,2348800,2353200,18817360,1.0,1.0,22169934.0 +20191015,GOOG,12216800,12472000,12202900,12425100,1267548,1.0,1.0,22169934.0 +20191015,IBM,1425400,1437200,1418100,1429300,2580404,1.0,1.0,1267548.0 +20191016,AAPL,2333700,2352400,2332000,2343900,16250144,1.0,1.0,1267548.0 +20191016,GOOG,12408300,12547400,12382000,12436500,975593,1.0,1.0,1267548.0 +20191016,IBM,1424500,1429500,1414000,1420400,4356894,0.0,1.0,0.060035960296721064 +20191017,AAPL,2350900,2361500,2335300,2352900,15525663,0.0,1.0,0.060035960296721064 +20191017,GOOG,12509400,12634600,12498600,12530600,853693,0.0,1.0,0.060035960296721064 +20191017,IBM,1350000,1360000,1329200,1342500,14363555,0.0,1.0,0.05943465945582413 +20191018,AAPL,2343600,2375800,2342900,2362800,21645988,0.0,1.0,0.05943465945582413 +20191018,GOOG,12542200,12590600,12410700,12454900,1218185,0.0,1.0,0.05943465945582413 +20191018,IBM,1343900,1344900,1322700,1340900,6279388,0.0,1.0,3.4471493081809883 +20191021,AAPL,2376500,2409900,2373200,2405300,19185571,0.0,1.0,3.4471493081809883 +20191021,GOOG,12517900,12549300,12405700,12460400,871520,0.0,1.0,3.4471493081809883 +20191021,IBM,1325400,1330900,1309000,1325800,5444353,-1.0,0.5,3.0376752350783494 +20191022,AAPL,2411700,2422000,2396200,2399700,19151854,-1.0,0.5,3.0376752350783494 +20191022,GOOG,12489900,12506200,12413900,12429400,960662,-1.0,0.5,3.0376752350783494 +20191022,IBM,1325300,1340500,1316100,1339400,3711584,1.0,1.0,19151854.0 +20191023,AAPL,2421000,2432400,2412200,2431400,17279116,1.0,1.0,19151854.0 +20191023,GOOG,12414700,12598900,12414700,12592400,830273,1.0,1.0,19151854.0 +20191023,IBM,1335200,1345600,1327300,1343900,3112861,3.0,3.0,21222250.0 +20191024,AAPL,2445100,2448000,2418100,2436000,15751993,3.0,3.0,21222250.0 +20191024,GOOG,12614500,12640000,12539300,12604600,908331,3.0,3.0,21222250.0 +20191024,IBM,1347900,1350700,1333100,1340800,2249594,3.0,3.0,18909918.0 +20191025,AAPL,2431700,2467300,2428800,2465800,15719212,3.0,3.0,18909918.0 +20191025,GOOG,12531100,12695400,12500000,12650700,1085974,3.0,3.0,18909918.0 +20191025,IBM,1341000,1359200,1341000,1354100,2267458,3.0,3.0,19072644.0 +20191028,AAPL,2475000,2492500,2467300,2490400,21869429,3.0,3.0,19072644.0 +20191028,GOOG,12760000,12993300,12725400,12901800,2032974,3.0,3.0,19072644.0 +20191028,IBM,1360000,1366100,1354500,1359700,2629152,3.0,3.0,26531555.0 +20191029,AAPL,2490100,2497400,2425700,2432900,32432237,3.0,3.0,26531555.0 +20191029,GOOG,12765900,12815900,12571000,12628200,1703363,3.0,3.0,26531555.0 +20191029,IBM,1354400,1355700,1334400,1338200,3793673,-1.0,0.5,0.8952773581119149 +20191030,AAPL,2449000,2453000,2412100,2433000,25182163,-1.0,0.5,0.8952773581119149 +20191030,GOOG,12564400,12693600,12518500,12612000,1257190,-1.0,0.5,0.8952773581119149 +20191030,IBM,1338200,1352800,1332600,1352500,1995841,-3.0,0.0,0.0 +20191031,AAPL,2472000,2491800,2423700,2488400,29358225,-3.0,0.0,0.0 +20191031,GOOG,12612800,12675500,12507900,12602000,1125543,-3.0,0.0,0.0 +20191031,IBM,1351000,1351100,1332300,1337500,2406865,-2.0,0.0,0.0 +20191101,AAPL,2495400,2559300,2491700,2558300,34738822,-2.0,0.0,0.0 +20191101,GOOG,12649200,12746200,12602900,12745000,1437033,-2.0,0.0,0.0 +20191101,IBM,1345000,1355600,1340900,1355300,2494236,3.0,3.0,38670091.0 +20191104,AAPL,2573700,2578500,2553800,2574800,23068018,3.0,3.0,38670091.0 +20191104,GOOG,12771000,12941000,12762700,12909600,1330494,3.0,3.0,38670091.0 +20191104,IBM,1364100,1377400,1362300,1376800,2675125,3.0,3.0,27073637.0 +20191105,AAPL,2570600,2581900,2563200,2571500,17418674,3.0,3.0,27073637.0 +20191105,GOOG,12934500,12989300,12913100,12918200,1092319,3.0,3.0,27073637.0 +20191105,IBM,1378000,1387600,1376500,1378900,2148099,3.0,3.0,20659092.0 +20191106,AAPL,2568700,2574900,2553600,2572400,15127808,3.0,3.0,20659092.0 +20191106,GOOG,12894600,12934200,12827400,12913400,925635,3.0,3.0,20659092.0 +20191106,IBM,1379300,1387700,1375500,1387700,2968964,0.0,1.0,0.19625870449968694 +20191107,AAPL,2587400,2603500,2581100,2594900,21971865,0.0,1.0,0.19625870449968694 +20191107,GOOG,12947300,13238000,12941200,13088600,1894197,0.0,1.0,0.19625870449968694 +20191107,IBM,1378700,1391400,1375900,1376900,2563423,3.0,3.0,26429485.0 +20191108,AAPL,2587000,2604400,2568500,2601400,15707487,3.0,3.0,26429485.0 +20191108,GOOG,13054800,13181900,13035300,13113100,1161270,3.0,3.0,26429485.0 +20191108,IBM,1375800,1376100,1362200,1376000,1881670,0.0,1.0,8.347631093656167 +20191111,AAPL,2583000,2624700,2582700,2622000,19212474,0.0,1.0,8.347631093656167 +20191111,GOOG,13033700,13070000,12974600,12989200,902335,0.0,1.0,8.347631093656167 +20191111,IBM,1371400,1371400,1350000,1354500,2089368,0.0,1.0,9.195351895884306 +20191112,AAPL,2615600,2627900,2609200,2619800,19134367,0.0,1.0,9.195351895884306 +20191112,GOOG,13008900,13100000,12955000,12987900,851300,0.0,1.0,9.195351895884306 +20191112,IBM,1357000,1366400,1350200,1356000,2343046,0.0,1.0,22.476643956302127 +20191113,AAPL,2611300,2647800,2610500,2644700,23793564,0.0,1.0,22.476643956302127 +20191113,GOOG,12940700,13040000,12935100,12974400,739932,0.0,1.0,22.476643956302127 +20191113,IBM,1352800,1355800,1338500,1344700,2444171,-1.0,0.5,7.472611281733035 +20191114,AAPL,2638800,2648800,2620900,2626900,19914659,-1.0,0.5,7.472611281733035 +20191114,GOOG,12968900,13170500,12956200,13115800,1053847,-1.0,0.5,7.472611281733035 +20191114,IBM,1341300,1343300,1333400,1339900,3652342,1.0,2.0,5.741112414992901 +20191115,AAPL,2637000,2657800,2630100,2657500,22034209,1.0,2.0,5.741112414992901 +20191115,GOOG,13162100,13348800,13142200,13348600,1385295,1.0,2.0,5.741112414992901 +20191115,IBM,1343900,1351200,1340300,1343600,2726635,2.0,2.0,23419504.0 +20191118,AAPL,2657900,2674300,2642300,2671200,17721094,2.0,2.0,23419504.0 +20191118,GOOG,13336400,13359400,13175000,13206500,1209170,2.0,2.0,23419504.0 +20191118,IBM,1343000,1344700,1332300,1342600,2344828,1.0,2.0,8.073199398847166 +20191119,AAPL,2678600,2680000,2654000,2662900,14461687,1.0,2.0,8.073199398847166 +20191119,GOOG,13273900,13278700,13128500,13151300,978451,1.0,2.0,8.073199398847166 +20191119,IBM,1348800,1353800,1344600,1345000,2113812,1.0,2.0,16.94055093203441 +20191120,AAPL,2655500,2660800,2604000,2632200,21910862,1.0,2.0,16.94055093203441 +20191120,GOOG,13117400,13152200,12910000,13028600,1045769,1.0,2.0,16.94055093203441 +20191120,IBM,1343300,1344600,1327600,1331700,2656759,-3.0,0.0,0.0 +20191121,AAPL,2639800,2640100,2611800,2620100,25496077,-3.0,0.0,0.0 +20191121,GOOG,13016400,13125900,12927800,13011200,823543,-3.0,0.0,0.0 +20191121,IBM,1334000,1341700,1330000,1338200,1922589,0.0,0.0,0.0 +20191122,AAPL,2625500,2631800,2608400,2618400,14050291,0.0,0.0,0.0 +20191122,GOOG,13050000,13085700,12913200,12953500,1129508,0.0,0.0,0.0 +20191122,IBM,1341900,1346500,1335900,1342800,1854309,1.0,1.0,1854309.0 +20191125,AAPL,2626400,2664400,2625200,2664200,14952237,1.0,1.0,1854309.0 +20191125,GOOG,12993600,13114600,12977200,13069500,824157,1.0,1.0,1854309.0 +20191125,IBM,1345800,1360000,1343500,1359600,1951649,2.0,2.0,16903886.0 +20191126,AAPL,2669300,2672100,2625000,2641000,14612190,2.0,2.0,16903886.0 +20191126,GOOG,13093300,13150000,13052200,13135400,808707,2.0,2.0,16903886.0 +20191126,IBM,1360800,1360800,1347700,1350600,2161558,3.0,3.0,17582455.0 +20191127,AAPL,2656300,2679800,2653100,2679400,14257370,3.0,3.0,17582455.0 +20191127,GOOG,13149200,13183600,13099400,13135000,839355,3.0,3.0,17582455.0 +20191127,IBM,1354200,1357100,1336200,1337400,2736584,1.0,2.0,5.516631318461264 +20191129,AAPL,2666000,2680000,2659000,2671800,8740858,1.0,2.0,5.516631318461264 +20191129,GOOG,13071100,13103600,13039700,13044800,443442,1.0,2.0,5.516631318461264 +20191129,IBM,1335000,1344900,1330300,1344600,1258007,-1.0,0.5,5.137302381675854 +20191202,AAPL,2675900,2682500,2634500,2640900,19883796,-1.0,0.5,5.137302381675854 +20191202,GOOG,13034900,13058300,12810000,12897700,1228578,-1.0,0.5,5.137302381675854 +20191202,IBM,1345000,1345000,1324800,1329500,2379052,-2.0,0.3333333333333333,0.8464277988062539 +20191203,AAPL,2582500,2595300,2562900,2595200,25349659,-2.0,0.3333333333333333,0.8464277988062539 +20191203,GOOG,12798700,12986400,12786700,12952700,1020330,-2.0,0.3333333333333333,0.8464277988062539 +20191203,IBM,1318400,1324400,1307000,1320900,2988726,-3.0,0.0,0.0 +20191204,AAPL,2610700,2633100,2606900,2617400,14277781,-3.0,0.0,0.0 +20191204,GOOG,13071100,13258300,13047000,13203000,1375828,-3.0,0.0,0.0 +20191204,IBM,1328100,1336600,1319600,1320000,2572145,1.0,1.0,1375828.0 +20191205,AAPL,2637500,2658900,2627300,2655800,15167492,1.0,1.0,1375828.0 +20191205,GOOG,13293300,13296000,13163100,13287200,1000657,1.0,1.0,1375828.0 +20191205,IBM,1329500,1332400,1316300,1319000,3036627,2.0,2.0,16168149.0 +20191206,AAPL,2675000,2710000,2673000,2707000,22748535,2.0,2.0,16168149.0 +20191206,GOOG,13338700,13444200,13331200,13406200,1105070,2.0,2.0,16168149.0 +20191206,IBM,1328500,1338900,1327000,1332000,2927403,3.0,3.0,26781008.0 +20191209,AAPL,2700700,2707900,2649100,2669200,27578946,3.0,3.0,26781008.0 +20191209,GOOG,13382400,13595600,13370200,13435500,1182862,3.0,3.0,26781008.0 +20191209,IBM,1334000,1345600,1332600,1339400,2232481,2.0,2.0,3415343.0 +20191210,AAPL,2686000,2700700,2658600,2686200,20123240,2.0,2.0,3415343.0 +20191210,GOOG,13424900,13499500,13355200,13449500,929248,2.0,2.0,3415343.0 +20191210,IBM,1340700,1348400,1335600,1339000,2724122,1.0,1.0,2724122.0 +20191211,AAPL,2688000,2711000,2685000,2707400,16804424,1.0,1.0,2724122.0 +20191211,GOOG,13473400,13517500,13427000,13450200,704154,1.0,1.0,2724122.0 +20191211,IBM,1341000,1345000,1336800,1337600,2712692,1.0,1.0,16804424.0 +20191212,AAPL,2678200,2725500,2673200,2714600,30574418,1.0,1.0,16804424.0 +20191212,GOOG,13459400,13554200,13403500,13499300,1095676,1.0,1.0,16804424.0 +20191212,IBM,1337400,1356600,1336600,1353200,2732737,3.0,3.0,34402831.0 +20191213,AAPL,2714400,2753000,2709300,2752500,29562777,3.0,3.0,34402831.0 +20191213,GOOG,13497800,13531400,13437700,13478300,1184357,3.0,3.0,34402831.0 +20191213,IBM,1345800,1355000,1340100,1342300,2059243,1.0,1.0,29562777.0 +20191216,AAPL,2769900,2807900,2769500,2798600,26440928,1.0,1.0,29562777.0 +20191216,GOOG,13560000,13647500,13521000,13614400,1139317,1.0,1.0,29562777.0 +20191216,IBM,1347000,1354500,1338600,1341200,2164923,2.0,2.0,27580245.0 +20191217,AAPL,2796600,2817700,2788000,2804400,24199828,2.0,2.0,27580245.0 +20191217,GOOG,13635600,13650000,13514300,13548400,1499801,2.0,2.0,27580245.0 +20191217,IBM,1343300,1346900,1334600,1342300,2260885,1.0,2.0,11.367065994068694 +20191218,AAPL,2797100,2819000,2791200,2797100,22958590,1.0,2.0,11.367065994068694 +20191218,GOOG,13574500,13605200,13511400,13519400,1012765,1.0,2.0,11.367065994068694 +20191218,IBM,1345100,1350000,1341700,1344500,2112294,0.0,1.0,22.669217439386234 +20191219,AAPL,2795100,2811800,2789500,2800300,17549156,0.0,1.0,22.669217439386234 +20191219,GOOG,13518200,13584500,13488900,13562000,1083615,0.0,1.0,22.669217439386234 +20191219,IBM,1344600,1347100,1341900,1344800,2381597,-1.0,0.0,0.0 +20191220,AAPL,2821700,2826500,2785600,2792800,28653733,-1.0,0.0,0.0 +20191220,GOOG,13633500,13637000,13490000,13492900,1666550,-1.0,0.0,0.0 +20191220,IBM,1357400,1364100,1350300,1356200,4239216,2.0,3.0,1.206108083718097 +20191223,AAPL,2805800,2842500,2803700,2839700,18669478,2.0,3.0,1.206108083718097 +20191223,GOOG,13574300,13598000,13465900,13483400,710157,2.0,3.0,1.206108083718097 +20191223,IBM,1357000,1361200,1350100,1355600,1898481,0.0,1.0,26.28922618519567 +20191224,AAPL,2845200,2848900,2829300,2842700,9434609,0.0,1.0,26.28922618519567 +20191224,GOOG,13485000,13504800,13428200,13434800,273972,0.0,1.0,26.28922618519567 +20191224,IBM,1356200,1356200,1346100,1349600,1012044,-1.0,0.5,7.336307635363791 +20191226,AAPL,2848200,2899800,2847000,2899100,20594335,-1.0,0.5,7.336307635363791 +20191226,GOOG,13468600,13613800,13444300,13604000,575477,-1.0,0.5,7.336307635363791 +20191226,IBM,1349700,1353000,1346600,1349000,1481367,2.0,2.0,21169812.0 +20191227,AAPL,2910600,2939700,2881100,2898200,32582221,2.0,2.0,21169812.0 +20191227,GOOG,13625800,13647500,13493100,13513400,907153,2.0,2.0,21169812.0 +20191227,IBM,1350000,1357500,1348800,1352800,2180289,3.0,3.0,35669663.0 +20191230,AAPL,2895700,2926900,2852300,2917000,33654017,3.0,3.0,35669663.0 +20191230,GOOG,13516700,13527900,13339900,13363700,922092,3.0,3.0,35669663.0 +20191230,IBM,1352500,1353000,1325000,1327600,3309507,-2.0,0.0,0.0 +20191231,AAPL,2899300,2936800,2895200,2933700,21171424,-2.0,0.0,0.0 +20191231,GOOG,13330900,13383100,13292100,13368700,708707,-2.0,0.0,0.0 +20191231,IBM,1325500,1341200,1324000,1340200,2844027,-2.0,0.0,0.0