/* * 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 System; using System.Linq; using Newtonsoft.Json; using NUnit.Framework; using QuantConnect.Algorithm.Framework.Alphas; using QuantConnect.Securities; namespace QuantConnect.Tests.Algorithm.Framework { [TestFixture, Parallelizable(ParallelScope.All)] public class InsightTests { [Test] public void HasReferenceTypeEqualitySemantics() { var one = Insight.Price(Symbols.SPY, Time.OneSecond, InsightDirection.Up); var two = Insight.Price(Symbols.SPY, Time.OneSecond, InsightDirection.Up); Assert.AreNotEqual(one, two); Assert.AreEqual(one, one); Assert.AreEqual(two, two); } [Test] public void SurvivesRoundTripSerializationUsingJsonConvert() { var time = new DateTime(2000, 01, 02, 03, 04, 05, 06); var insight = new Insight(time, Symbols.SPY, Time.OneMinute, InsightType.Volatility, InsightDirection.Up, 1, 2, "source-model", 1); Insight.Group(insight); insight.ReferenceValueFinal = 10; var serialized = JsonConvert.SerializeObject(insight); var deserialized = JsonConvert.DeserializeObject(serialized); Assert.AreEqual(insight.CloseTimeUtc, deserialized.CloseTimeUtc); Assert.AreEqual(insight.Confidence, deserialized.Confidence); Assert.AreEqual(insight.Direction, deserialized.Direction); Assert.AreEqual(insight.EstimatedValue, deserialized.EstimatedValue); Assert.AreEqual(insight.GeneratedTimeUtc, deserialized.GeneratedTimeUtc); Assert.AreEqual(insight.GroupId, deserialized.GroupId); Assert.AreEqual(insight.Id, deserialized.Id); Assert.AreEqual(insight.Magnitude, deserialized.Magnitude); Assert.AreEqual(insight.Period, deserialized.Period); Assert.AreEqual(insight.SourceModel, deserialized.SourceModel); Assert.AreEqual(insight.Score.Direction, deserialized.Score.Direction); Assert.AreEqual(insight.Score.Magnitude, deserialized.Score.Magnitude); Assert.AreEqual(insight.Score.UpdatedTimeUtc, deserialized.Score.UpdatedTimeUtc); Assert.AreEqual(insight.Score.IsFinalScore, deserialized.Score.IsFinalScore); Assert.AreEqual(insight.Symbol, deserialized.Symbol); Assert.AreEqual(insight.Type, deserialized.Type); Assert.AreEqual(insight.Weight, deserialized.Weight); Assert.AreEqual(insight.ReferenceValueFinal, deserialized.ReferenceValueFinal); } [Test] public void CancelInsight() { var time = new DateTime(2000, 01, 02, 03, 04, 05, 06); var insight = new Insight(time, Symbols.SPY, Time.OneMinute, InsightType.Volatility, InsightDirection.Up, 1, 2, "source-model"); insight.Cancel(time.AddMinutes(1)); Assert.AreEqual(TimeSpan.FromSeconds(59), insight.Period); insight.Cancel(time.AddDays(1)); Assert.AreEqual(TimeSpan.FromSeconds(59), insight.Period); } [Test] public void SerializationUsingJsonConvertTrimsEstimatedValue() { var time = new DateTime(2000, 01, 02, 03, 04, 05, 06); var insight = new Insight(time, Symbols.SPY, Time.OneMinute, InsightType.Volatility, InsightDirection.Up, 1, 2, "source-model"); insight.EstimatedValue = 0.00001m; insight.Score.SetScore(InsightScoreType.Direction, 0.00001, DateTime.UtcNow); insight.Score.SetScore(InsightScoreType.Magnitude, 0.00001, DateTime.UtcNow); var serialized = JsonConvert.SerializeObject(insight); var deserialized = JsonConvert.DeserializeObject(serialized); Assert.AreEqual(0, deserialized.EstimatedValue); Assert.AreEqual(0, deserialized.Score.Direction); Assert.AreEqual(0, deserialized.Score.Magnitude); } [Test] public void SurvivesRoundTripCopy() { var time = new DateTime(2000, 01, 02, 03, 04, 05, 06); var original = new Insight(time, Symbols.SPY, Time.OneMinute, InsightType.Volatility, InsightDirection.Up, 1, 2, "source-model", 1); original.ReferenceValueFinal = 10; Insight.Group(original); var copy = original.Clone(); Assert.AreEqual(original.CloseTimeUtc, copy.CloseTimeUtc); Assert.AreEqual(original.Confidence, copy.Confidence); Assert.AreEqual(original.Direction, copy.Direction); Assert.AreEqual(original.EstimatedValue, copy.EstimatedValue); Assert.AreEqual(original.GeneratedTimeUtc, copy.GeneratedTimeUtc); Assert.AreEqual(original.GroupId, copy.GroupId); Assert.AreEqual(original.Id, copy.Id); Assert.AreEqual(original.Magnitude, copy.Magnitude); Assert.AreEqual(original.Period, copy.Period); Assert.AreEqual(original.SourceModel, copy.SourceModel); Assert.AreEqual(original.Score.Direction, copy.Score.Direction); Assert.AreEqual(original.Score.Magnitude, copy.Score.Magnitude); Assert.AreEqual(original.Score.UpdatedTimeUtc, copy.Score.UpdatedTimeUtc); Assert.AreEqual(original.Score.IsFinalScore, copy.Score.IsFinalScore); Assert.AreEqual(original.Symbol, copy.Symbol); Assert.AreEqual(original.Type, copy.Type); Assert.AreEqual(original.Weight, copy.Weight); Assert.AreEqual(original.ReferenceValueFinal, copy.ReferenceValueFinal); } [Test] public void GroupAssignsGroupId() { var insight1 = Insight.Price(Symbols.SPY, Time.OneMinute, InsightDirection.Up); var insight2 = Insight.Price(Symbols.SPY, Time.OneMinute, InsightDirection.Up); var group = Insight.Group(insight1, insight2).ToList(); foreach (var member in group) { Assert.IsTrue(member.GroupId.HasValue); } var groupId = insight1.GroupId.Value; foreach (var member in group) { Assert.AreEqual(groupId, member.GroupId); } } [Test] public void GroupThrowsExceptionIfInsightAlreadyHasGroupId() { var insight1 = Insight.Price(Symbols.SPY, Time.OneMinute, InsightDirection.Up); Insight.Group(insight1); Assert.That(() => Insight.Group(insight1), Throws.InvalidOperationException); } [Test] [TestCase(Resolution.Tick, 1)] [TestCase(Resolution.Tick, 10)] [TestCase(Resolution.Tick, 100)] [TestCase(Resolution.Second, 1)] [TestCase(Resolution.Second, 10)] [TestCase(Resolution.Second, 100)] [TestCase(Resolution.Minute, 1)] [TestCase(Resolution.Minute, 10)] [TestCase(Resolution.Minute, 100)] [TestCase(Resolution.Hour, 1)] [TestCase(Resolution.Hour, 10)] [TestCase(Resolution.Hour, 100)] [TestCase(Resolution.Daily, 1)] [TestCase(Resolution.Daily, 10)] [TestCase(Resolution.Daily, 100)] public void SetPeriodAndCloseTimeUsingResolutionBarCount(Resolution resolution, int barCount) { var generatedTimeUtc = new DateTime(2018, 08, 06, 13, 31, 0).ConvertToUtc(TimeZones.NewYork); var symbol = Symbols.SPY; var insight = Insight.Price(symbol, resolution, barCount, InsightDirection.Up); insight.GeneratedTimeUtc = generatedTimeUtc; var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType); insight.SetPeriodAndCloseTime(exchangeHours); var expectedCloseTime = Insight.ComputeCloseTime(exchangeHours, insight.GeneratedTimeUtc, resolution, barCount); Assert.AreEqual(expectedCloseTime, insight.CloseTimeUtc); Assert.AreEqual(expectedCloseTime - generatedTimeUtc, insight.Period); } [Test] [TestCase(Resolution.Second, 1)] [TestCase(Resolution.Second, 10)] [TestCase(Resolution.Second, 100)] [TestCase(Resolution.Minute, 1)] [TestCase(Resolution.Minute, 10)] [TestCase(Resolution.Minute, 100)] [TestCase(Resolution.Hour, 1)] [TestCase(Resolution.Hour, 10)] [TestCase(Resolution.Hour, 100)] [TestCase(Resolution.Daily, 1)] [TestCase(Resolution.Daily, 10)] [TestCase(Resolution.Daily, 100)] public void SetPeriodAndCloseTimeUsingPeriod(Resolution resolution, int barCount) { var period = resolution.ToTimeSpan().Multiply(barCount); var generatedTimeUtc = new DateTime(2018, 08, 06, 13, 31, 0).ConvertToUtc(TimeZones.NewYork); var symbol = Symbols.SPY; var insight = Insight.Price(symbol, period, InsightDirection.Up); insight.GeneratedTimeUtc = generatedTimeUtc; var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType); insight.SetPeriodAndCloseTime(exchangeHours); Assert.AreEqual(Time.Max(period, Time.OneSecond), insight.Period); var expectedCloseTime = Insight.ComputeCloseTime(exchangeHours, insight.GeneratedTimeUtc, period); Assert.AreEqual(expectedCloseTime, insight.CloseTimeUtc); } [Test] [TestCase(Resolution.Tick, 1)] [TestCase(Resolution.Tick, 10)] [TestCase(Resolution.Tick, 100)] [TestCase(Resolution.Second, 1)] [TestCase(Resolution.Second, 10)] [TestCase(Resolution.Second, 100)] [TestCase(Resolution.Minute, 1)] [TestCase(Resolution.Minute, 10)] [TestCase(Resolution.Minute, 100)] [TestCase(Resolution.Hour, 1)] [TestCase(Resolution.Hour, 10)] [TestCase(Resolution.Hour, 100)] [TestCase(Resolution.Daily, 1)] [TestCase(Resolution.Daily, 10)] [TestCase(Resolution.Daily, 100)] public void SetPeriodAndCloseTimeUsingCloseTime(Resolution resolution, int barCount) { // consistency test -- first compute expected close time and then back-compute period to verify var symbol = Symbols.SPY; var generatedTimeUtc = new DateTime(2018, 08, 06, 13, 31, 0).ConvertToUtc(TimeZones.NewYork); var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType); var baseline = Insight.Price(symbol, resolution, barCount, InsightDirection.Up); baseline.GeneratedTimeUtc = generatedTimeUtc; baseline.SetPeriodAndCloseTime(exchangeHours); var baselineCloseTimeLocal = baseline.CloseTimeUtc.ConvertFromUtc(TimeZones.NewYork); var insight = Insight.Price(symbol, baselineCloseTimeLocal, baseline.Direction); insight.GeneratedTimeUtc = generatedTimeUtc; insight.SetPeriodAndCloseTime(exchangeHours); Assert.AreEqual(baseline.Period, insight.Period); Assert.AreEqual(baseline.CloseTimeUtc, insight.CloseTimeUtc); } [Test] [TestCase("SPY", SecurityType.Equity, Market.USA, 2018, 12, 4, 9, 30)] [TestCase("EURUSD", SecurityType.Forex, Market.FXCM, 2018, 12, 4, 0, 0)] public void SetPeriodAndCloseTimeUsingExpiryEndOfDay(string ticker, SecurityType securityType, string market, int year, int month, int day, int hour, int minute) { var symbol = Symbol.Create(ticker, securityType, market); var generatedTimeUtc = new DateTime(2018, 12, 3, 9, 31, 0).ConvertToUtc(TimeZones.NewYork); SetPeriodAndCloseTimeUsingExpiryFuncOrDateTime( Insight.Price(symbol, Expiry.EndOfDay, InsightDirection.Up), generatedTimeUtc, new DateTime(year, month, day, hour, minute, 0).ConvertToUtc(TimeZones.NewYork)); } [Test] [TestCase("SPY", SecurityType.Equity, Market.USA, 2018, 12, 10, 9, 30)] [TestCase("EURUSD", SecurityType.Forex, Market.FXCM, 2018, 12, 10, 0, 0)] public void SetPeriodAndCloseTimeUsingExpiryEndOfWeek(string ticker, SecurityType securityType, string market, int year, int month, int day, int hour, int minute) { var symbol = Symbol.Create(ticker, securityType, market); var generatedTime = new DateTime(2018, 12, 3, 9, 31, 0); var generatedTimeUtc = generatedTime.ConvertToUtc(TimeZones.NewYork); // Using Expiry Func SetPeriodAndCloseTimeUsingExpiryFuncOrDateTime( Insight.Price(symbol, Expiry.EndOfWeek, InsightDirection.Up), generatedTimeUtc, new DateTime(year, month, day, hour, minute, 0).ConvertToUtc(TimeZones.NewYork)); // Using DateTime SetPeriodAndCloseTimeUsingExpiryFuncOrDateTime( Insight.Price(symbol, Expiry.EndOfWeek(generatedTime), InsightDirection.Up), generatedTimeUtc, new DateTime(year, month, day, hour, minute, 0).ConvertToUtc(TimeZones.NewYork)); } [Test] [TestCase("SPY", SecurityType.Equity, Market.USA, 2019, 1, 2, 9, 30)] [TestCase("EURUSD", SecurityType.Forex, Market.FXCM, 2019, 1, 2, 0, 0)] public void SetPeriodAndCloseTimeUsingExpiryEndOfMonth(string ticker, SecurityType securityType, string market, int year, int month, int day, int hour, int minute) { var symbol = Symbol.Create(ticker, securityType, market); var generatedTime = new DateTime(2018, 12, 3, 9, 31, 0); var generatedTimeUtc = generatedTime.ConvertToUtc(TimeZones.NewYork); // Using Expiry Func SetPeriodAndCloseTimeUsingExpiryFuncOrDateTime( Insight.Price(symbol, Expiry.EndOfMonth, InsightDirection.Up), generatedTimeUtc, new DateTime(year, month, day, hour, minute, 0).ConvertToUtc(TimeZones.NewYork)); // Using DateTime SetPeriodAndCloseTimeUsingExpiryFuncOrDateTime( Insight.Price(symbol, Expiry.EndOfMonth(generatedTime), InsightDirection.Up), generatedTimeUtc, new DateTime(year, month, day, hour, minute, 0).ConvertToUtc(TimeZones.NewYork)); } [Test] [TestCase("SPY", SecurityType.Equity, Market.USA, 2019, 1, 3, 9, 31)] [TestCase("EURUSD", SecurityType.Forex, Market.FXCM, 2019, 1, 3, 9, 31)] public void SetPeriodAndCloseTimeUsingExpiryOneMonth(string ticker, SecurityType securityType, string market, int year, int month, int day, int hour, int minute) { var symbol = Symbol.Create(ticker, securityType, market); var generatedTime = new DateTime(2018, 12, 3, 9, 31, 0); var generatedTimeUtc = generatedTime.ConvertToUtc(TimeZones.NewYork); // Using Expiry Func SetPeriodAndCloseTimeUsingExpiryFuncOrDateTime( Insight.Price(symbol, Expiry.OneMonth, InsightDirection.Up), generatedTimeUtc, new DateTime(year, month, day, hour, minute, 0).ConvertToUtc(TimeZones.NewYork)); // Using DateTime SetPeriodAndCloseTimeUsingExpiryFuncOrDateTime( Insight.Price(symbol, Expiry.OneMonth(generatedTime), InsightDirection.Up), generatedTimeUtc, new DateTime(year, month, day, hour, minute, 0).ConvertToUtc(TimeZones.NewYork)); } private void SetPeriodAndCloseTimeUsingExpiryFuncOrDateTime(Insight insight, DateTime generatedTimeUtc, DateTime expected) { var symbol = insight.Symbol; insight.GeneratedTimeUtc = generatedTimeUtc; var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType); insight.SetPeriodAndCloseTime(exchangeHours); Assert.AreEqual(expected, insight.CloseTimeUtc); } [Test] public void ComputeCloseTimeHandlesFractionalDays() { var symbol = Symbols.SPY; // Friday @ 3PM + 2.5 days => Wednesday @ 12:45 by counting 2 dates (Mon, Tues@3PM) and then half a trading day (+3.25hrs) => Wed@11:45AM var generatedTimeUtc = new DateTime(2018, 08, 03, 12+3, 0, 0).ConvertToUtc(TimeZones.NewYork); var expectedClosedTimeUtc = new DateTime(2018, 08, 08, 11, 45, 0).ConvertToUtc(TimeZones.NewYork); var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType); var actualCloseTimeUtc = Insight.ComputeCloseTime(exchangeHours, generatedTimeUtc, TimeSpan.FromDays(2.5)); Assert.AreEqual(expectedClosedTimeUtc, actualCloseTimeUtc); } [Test] public void ComputeCloseTimeHandlesFractionalHours() { var symbol = Symbols.SPY; // Friday @ 3PM + 2.5 hours => Monday @ 11:00 (1 hr on Friday, 1.5 hours on Monday) var generatedTimeUtc = new DateTime(2018, 08, 03, 12 + 3, 0, 0).ConvertToUtc(TimeZones.NewYork); var expectedClosedTimeUtc = new DateTime(2018, 08, 06, 11, 0, 0).ConvertToUtc(TimeZones.NewYork); var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType); var actualCloseTimeUtc = Insight.ComputeCloseTime(exchangeHours, generatedTimeUtc, TimeSpan.FromHours(2.5)); Assert.AreEqual(expectedClosedTimeUtc, actualCloseTimeUtc); } [Test] public void ComputeCloseHandlesOffsetHourOverMarketClosuresUsingTimeSpan() { var symbol = Symbols.SPY; // Friday @ 3:59PM + 1 hours => Monday @ 10:29 (1 min on Friday, 59 min on Monday) var generatedTimeUtc = new DateTime(2018, 08, 03, 12 + 3, 59, 0).ConvertToUtc(TimeZones.NewYork); var expectedClosedTimeUtc = new DateTime(2018, 08, 06, 10, 29, 0).ConvertToUtc(TimeZones.NewYork); var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType); var actualCloseTimeUtc = Insight.ComputeCloseTime(exchangeHours, generatedTimeUtc, TimeSpan.FromHours(1)); Assert.AreEqual(expectedClosedTimeUtc, actualCloseTimeUtc); } [Test] public void ComputeCloseHandlesOffsetHourOverMarketClosuresUsingResolutionBarCount() { var symbol = Symbols.SPY; // Friday @ 3:59PM + 1 hours => Monday @ 10:29 (1 min on Friday, 59 min on Monday) var generatedTimeUtc = new DateTime(2018, 08, 03, 12 + 3, 59, 0).ConvertToUtc(TimeZones.NewYork); var expectedClosedTimeUtc = new DateTime(2018, 08, 06, 10, 29, 0).ConvertToUtc(TimeZones.NewYork); var exchangeHours = MarketHoursDatabase.FromDataFolder().GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType); var actualCloseTimeUtc = Insight.ComputeCloseTime(exchangeHours, generatedTimeUtc, Resolution.Hour, 1); Assert.AreEqual(expectedClosedTimeUtc, actualCloseTimeUtc); } [Test] public void SetPeriodAndCloseTimeThrowsWhenGeneratedTimeUtcNotSet() { var insight = Insight.Price(Symbols.SPY, Time.OneDay, InsightDirection.Up); var exchangeHours = SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork); Assert.That(() => insight.SetPeriodAndCloseTime(exchangeHours), Throws.InvalidOperationException); } [Test] public void SetPeriodAndCloseTimeDoesNotThrowWhenGeneratedTimeUtcIsSet() { var insight = Insight.Price(Symbols.SPY, Time.OneDay, InsightDirection.Up); var exchangeHours = SecurityExchangeHours.AlwaysOpen(TimeZones.NewYork); insight.GeneratedTimeUtc = new DateTime(2018, 08, 07, 00, 33, 00).ConvertToUtc(TimeZones.NewYork); Assert.That(() => insight.SetPeriodAndCloseTime(exchangeHours), Throws.Nothing); } [Test] public void IsExpiredUsesOpenIntervalSemantics() { var generatedTime = new DateTime(2000, 01, 01); var insight = Insight.Price(Symbols.SPY, Time.OneMinute, InsightDirection.Up); insight.GeneratedTimeUtc = generatedTime; insight.CloseTimeUtc = insight.GeneratedTimeUtc + insight.Period; Assert.IsFalse(insight.IsExpired(insight.CloseTimeUtc)); Assert.IsTrue(insight.IsExpired(insight.CloseTimeUtc.AddTicks(1))); } [Test] public void IsActiveUsesClosedIntervalSemantics() { var generatedTime = new DateTime(2000, 01, 01); var insight = Insight.Price(Symbols.SPY, Time.OneMinute, InsightDirection.Up); insight.GeneratedTimeUtc = generatedTime; insight.CloseTimeUtc = insight.GeneratedTimeUtc + insight.Period; Assert.IsTrue(insight.IsActive(insight.CloseTimeUtc)); Assert.IsFalse(insight.IsActive(insight.CloseTimeUtc.AddTicks(1))); } [Test] public void ConstructorsSetsCorrectValues() { var tag = "Insight Tag"; Assert.Multiple(() => { var insight1 = new Insight(Symbols.SPY, Time.OneDay, InsightType.Price, InsightDirection.Up, tag); AssertInsigthValues(insight1, Symbols.SPY, Time.OneDay, InsightType.Price, InsightDirection.Up, null, null, null, null, tag, default(DateTime), default(DateTime)); var insight2 = new Insight(Symbols.SPY, Time.OneDay, InsightType.Price, InsightDirection.Up, 1.0, 0.5, "Model", 0.25, tag); AssertInsigthValues(insight2, Symbols.SPY, Time.OneDay, InsightType.Price, InsightDirection.Up, 1.0, 0.5, "Model", 0.25, tag, default(DateTime), default(DateTime)); var insight3 = new Insight(Symbols.SPY, time => time.AddDays(1), InsightType.Price, InsightDirection.Up, tag); AssertInsigthValues(insight3, Symbols.SPY, new TimeSpan(0), InsightType.Price, InsightDirection.Up, null, null, null, null, tag, default(DateTime), default(DateTime)); var insight4 = new Insight(Symbols.SPY, time => time.AddDays(1), InsightType.Price, InsightDirection.Up, 1.0, 0.5, "Model", 0.25, tag); AssertInsigthValues(insight4, Symbols.SPY, new TimeSpan(0), InsightType.Price, InsightDirection.Up, 1.0, 0.5, "Model", 0.25, tag, default(DateTime), default(DateTime)); var generatedTime = new DateTime(2024, 05, 23); var insight5 = new Insight(generatedTime, Symbols.SPY, Time.OneDay, InsightType.Price, InsightDirection.Up, 1.0, 0.5, "Model", 0.25, tag); AssertInsigthValues(insight5, Symbols.SPY, Time.OneDay, InsightType.Price, InsightDirection.Up, 1.0, 0.5, "Model", 0.25, tag, generatedTime, generatedTime + Time.OneDay); }); } private static void AssertInsigthValues(Insight insight, Symbol symbol, TimeSpan period, InsightType type, InsightDirection direction, double? magnitude, double? confidence, string sourceModel, double? weight, string tag, DateTime generatedTimeUtc, DateTime closeTimeUtc) { Assert.AreEqual(symbol, insight.Symbol); Assert.AreEqual(period, insight.Period); Assert.AreEqual(type, insight.Type); Assert.AreEqual(direction, insight.Direction); Assert.AreEqual(magnitude, insight.Magnitude); Assert.AreEqual(confidence, insight.Confidence); Assert.AreEqual(sourceModel, insight.SourceModel); Assert.AreEqual(weight, insight.Weight); Assert.AreEqual(tag, insight.Tag); Assert.AreEqual(generatedTimeUtc, insight.GeneratedTimeUtc); Assert.AreEqual(closeTimeUtc, insight.CloseTimeUtc); } } }