using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.Extensions.Configuration; using MarketData.DataAccess; using MarketData.Generator.CMMomentum; using MarketData.Helper; using MarketData.MarketDataModel; using MarketData.Utils; using MarketData; using MarketData.Configuration; using System.Diagnostics; using System.Net.Http.Headers; namespace MarketDataUnitTests; [TestClass] public class MarketDataUnitTestClass { private IConfigurationBuilder builder; private IConfiguration configuration; public MarketDataUnitTestClass() { builder = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); IConfigurationRoot configurationRoot = builder.Build(); configuration = configurationRoot; GlobalConfig.Instance.Configuration = configuration; CreateLogging("unittest"); } private static bool CreateLogging(String task) { if (String.IsNullOrEmpty(task)) return false; task = task.ToLower(); MDTrace.LogLevel = LogLevel.DEBUG; String logFolder = "/logs"; DateTime currentDate = DateTime.Now; String strLogFile = "marketdata_" + task + ".log"; String currentWorkingDirectory = Directory.GetCurrentDirectory(); Console.WriteLine($"Current directory is {currentWorkingDirectory}"); Utility.EnsureLogFolder(currentWorkingDirectory + logFolder); Utility.ExpireLogs(currentWorkingDirectory + logFolder, 1); Trace.Listeners.Remove("Default"); Console.WriteLine($"Adding Trace Listener :{currentWorkingDirectory + logFolder + "/" + strLogFile}"); Trace.Listeners.Add(new TextWriterTraceListener(currentWorkingDirectory + logFolder + "/" + strLogFile)); MDTrace.WriteLine($"Trace Listener added."); Utility.ShowLogs(currentWorkingDirectory + logFolder); return true; } [TestMethod] public void CNNPredictionTest() { String cnnHostName = "10.0.0.240"; CMCandidate cmCandidate = new CMCandidate(); CMParams cmParams = new CMParams(); cmParams.UseCNN = true; cmParams.UseCNNHost = "http://" + cnnHostName + ":5000"; cmParams.UseCNNDayCount = 270; cmParams.UseCNNRewardPercentDecimal = 0.25; cmCandidate.Symbol = "MIDD"; cmCandidate.TradeDate = DateTime.Parse("07-01-2024"); bool result = CMMomentumGenerator.PredictCandidate(cmCandidate, cmParams); Assert.IsTrue(result); } [TestMethod] public void ETFHoldingsYahooRetrieval() { String[] etfSymbols = { "JFNNX", "ACWX", "ACES", "BBH" }; List results = new List(); foreach (String etfSymbol in etfSymbols) { ETFHoldings etfHoldings = MarketDataHelper.GetETFHoldings(etfSymbol); if (null != etfHoldings && 0 != etfHoldings.Count) { results.Add(MarketDataHelper.GetETFHoldings(etfSymbol)); } try { Thread.Sleep(500); } catch (Exception) {; } } bool result = results.Any(x => x != null); Assert.IsTrue(result, String.Format("{0} items failed.", etfSymbols.Length)); } [TestMethod] public void LatestPriceRetrieval() { String symbol = "AAPL"; Price price = MarketDataHelper.GetLatestPrice(symbol); Assert.IsTrue(null != price && price.IsValid); } [TestMethod] public void LatestPriceGoogleRetrieval() { String symbol = "AAPL"; Price price = MarketDataHelper.GetLatestPriceGoogle(symbol); Assert.IsTrue(null != price && price.IsValid); } // The GetLatestPriceYahoo feed may return a price that only contains the previous close. // This can happen after market hours and does not mean that the feed is broken. [TestMethod] public void LatestPriceYahooRetrieval() { String symbol = "JFNNX"; Price price = MarketDataHelper.GetLatestPriceYahoo(symbol); Assert.IsTrue(null != price, "No Price from Yahoo"); Assert.IsTrue(price.IsValid || !double.IsNaN(price.PrevClose), "The feed is not working."); } [TestMethod] public void DailyPricesYahoo() { String symbol = "AAPL"; DateGenerator dateGenerator = new DateGenerator(); DateTime lastBusinessDate = DateTime.Now; lastBusinessDate = dateGenerator.GetPrevBusinessDay(lastBusinessDate); DateTime startDate = lastBusinessDate; DateTime endDate = startDate; Prices prices = MarketDataHelper.GetDailyPrices(symbol, startDate, endDate); Assert.IsTrue(null != prices, "No Price from DailyPricesYahoo"); } [TestMethod] public void ConsumerPriceIndexBureauOfLaborStatisticsRetrieval() { PriceIndices priceIndices = MarketDataHelper.GetConsumerPriceIndices(); Assert.IsTrue(null != priceIndices && priceIndices.Count > 0); } // Yahoo Fundamental feed is very poor quality and lots of misses. It's a last resort. [TestMethod] public void FundamentalYahooRetrieval() { String symbol = "AAPL"; Fundamental fundamental = MarketDataHelper.GetFundamental(symbol); Assert.IsTrue(null != fundamental); // Assert.IsTrue(!Utility.IsEpoch(fundamental.NextEarningsDate),"NextEarningsDate"); // Assert.IsTrue(!double.IsNaN(fundamental.Beta),"Beta"); Assert.IsTrue(!double.IsNaN(fundamental.Low52), "Low52"); Assert.IsTrue(!double.IsNaN(fundamental.High52), "High52"); Assert.IsTrue(!double.IsNaN(fundamental.Volume), "Volume"); // Assert.IsTrue(!double.IsNaN(fundamental.MarketCap),"MarketCap"); Assert.IsTrue(!double.IsNaN(fundamental.PE), "PE"); Assert.IsTrue(!double.IsNaN(fundamental.EPS), "EPS"); Assert.IsTrue(!double.IsNaN(fundamental.PEG), "PEG"); Assert.IsTrue(!double.IsNaN(fundamental.ReturnOnAssets), "ReturnOnAssets"); Assert.IsTrue(!double.IsNaN(fundamental.ReturnOnEquity), "ReturnOnEquity"); Assert.IsTrue(!double.IsNaN(fundamental.TotalCash), "TotalCash"); Assert.IsTrue(!double.IsNaN(fundamental.TotalDebt), "TotalDebt"); Assert.IsTrue(!double.IsNaN(fundamental.SharesOutstanding), "SharesOutstanding"); Assert.IsTrue(!double.IsNaN(fundamental.Revenue), "Revenue"); Assert.IsTrue(!double.IsNaN(fundamental.RevenuePerShare), "RevenuePerShare"); Assert.IsTrue(!double.IsNaN(fundamental.QtrlyRevenueGrowth), "QtrlyRevenueGrowth"); // Assert.IsTrue(!double.IsNaN(fundamental.GrossProfit),"GrossProfit"); Assert.IsTrue(!double.IsNaN(fundamental.EBITDA), "EBITDA"); Assert.IsTrue(!double.IsNaN(fundamental.NetIncomeAvailableToCommon), "NetIncomeAvailableToCommon"); Assert.IsTrue(!double.IsNaN(fundamental.BookValuePerShare), "BookValuePerShare"); Assert.IsTrue(!double.IsNaN(fundamental.OperatingCashflow), "OperatingCashflow"); Assert.IsTrue(!double.IsNaN(fundamental.LeveragedFreeCashflow), "LeveragedFreeCashflow"); Assert.IsTrue(!double.IsNaN(fundamental.Equity), "Equity"); Assert.IsTrue(!double.IsNaN(fundamental.TrailingPE), "TrailingPE"); Assert.IsTrue(!double.IsNaN(fundamental.EnterpriseValue), "EnterpriseValue"); Assert.IsTrue(!double.IsNaN(fundamental.EBIT), "EBIT"); Assert.IsTrue(!double.IsNaN(fundamental.DebtToEquity), "DebtToEquity"); } [TestMethod] public void DividendHistoryRetrieval() { Dictionary items = new Dictionary(); String dividendSymbol1 = "AAPL"; String dividendSymbol2 = "ZIM"; String dividendSymbol3 = "IVR"; DividendHistory dividendHistory1 = MarketDataHelper.GetDividendHistory(dividendSymbol1); DividendHistory dividendHistory2 = MarketDataHelper.GetDividendHistory(dividendSymbol2); DividendHistory dividendHistory3 = MarketDataHelper.GetDividendHistory(dividendSymbol3); Assert.IsTrue((null != dividendHistory1 && dividendHistory1.Count > 0) || (null != dividendHistory2 && dividendHistory2.Count > 0) || (null != dividendHistory3 && dividendHistory3.Count > 0)); } [TestMethod] public void PremarketRetrieval() { PremarketElements premarketElements = MarketDataHelper.GetPremarketData(); Assert.IsTrue(null != premarketElements && premarketElements.Count > 0); } [TestMethod] public void EarningsAnnouncementsaRetrieval() { String symbol="MIDD"; EarningsAnnouncements earningsAnnouncements=MarketDataHelper.GetEarningsAnnouncements(symbol); Assert.IsTrue(null!=earningsAnnouncements && earningsAnnouncements.Count>0); } [TestMethod] public void ZacksRankRetrieval() { String symbol = "MIDD"; ZacksRank zacksRank = MarketDataHelper.GetZacksRank(symbol); Assert.IsTrue(null != zacksRank && null != zacksRank.Rank); } [TestMethod] public void GetSplitsRetrieval() { Splits splits=MarketDataHelper.GetSplits(); Assert.IsTrue(null!=splits && splits.Count>0); } [TestMethod] public void GDPPerCapitaRetrieval() { EconomicIndicators economicIndicators = MarketDataHelper.GetGDPPerCapita(); Assert.IsTrue(null != economicIndicators && economicIndicators.Count > 0); } [TestMethod] public void LatestAnalystRatingsRetrieval() { AnalystRatings analystRatings=MarketDataHelper.GetLatestAnalystRatings(); Assert.IsTrue(null!=analystRatings && analystRatings.Count>0); } [TestMethod] public void AnalystRatingsMarketBeatRetrieval() { String symbol = "AAPL"; AnalystRatings analystRatings = MarketDataHelper.GetAnalystRatingsMarketBeat(symbol); Assert.IsTrue(null != analystRatings && analystRatings.Count > 0); } [TestMethod] public void SECCIKRetrieval() { String symbol="AAPL"; String strCik=MarketDataHelper.GetCIK(symbol); Assert.IsTrue(null!=strCik); } [TestMethod] public void SECFilingsRetrieval() { String symbol="AAPL"; String strCik=MarketDataHelper.GetCIK(symbol); Assert.IsTrue(null!=strCik); SECFilings secFilings=MarketDataHelper.GetSECFilings(symbol,strCik,1); Assert.IsTrue(null!=secFilings && secFilings.Count>0); } [TestMethod] public void YieldCurveRetrieval() { DateGenerator dateGenerator= new DateGenerator(); DateTime analysisDate=dateGenerator.FindPrevBusinessDay(DateTime.Now); YieldCurve yieldCurve=MarketDataHelper.GetYieldCurve(analysisDate.Year); Assert.IsTrue(null!=yieldCurve && yieldCurve.Count>0); Assert.IsTrue(yieldCurve[yieldCurve.Count-1].Date.Month.Equals(analysisDate.Month)); } [TestMethod] public void InsiderTransactionRetrieval() { DateTime now = DateTime.Now; DateGenerator dateGenerator = new DateGenerator(); InsiderTransactions insiderTransactions = InsiderTransactionDA.GetLatestInsiderTransactions(); Assert.IsTrue(null!=insiderTransactions && insiderTransactions.Count>0); InsiderTransaction insiderTransaction = insiderTransactions[0]; int daysBetween = dateGenerator.DaysBetween(now, insiderTransaction.TransactionDate)+1; Assert.IsTrue(daysBetween<10); InsiderTransactions latestTransactions=MarketDataHelper.GetInsiderTransactions(insiderTransaction.Symbol,daysBetween); Assert.IsTrue(null!=latestTransactions && latestTransactions.Count>0); } [TestMethod] public void CompanyProfileRetrieval() { String symbol="MOD"; CompanyProfile companyProfile=MarketDataHelper.GetCompanyProfile(symbol); Assert.IsTrue(null!=companyProfile); } // Test all feeds [TestMethod] public void HeadlinesRetrieval() { String symbol="AAPL"; Headlines companyHeadlines = HeadlinesMarketDataHelper.GetHeadlinesEx(symbol); Assert.IsTrue(null!=companyHeadlines && companyHeadlines.Count>0); } // Test MarketWatch feed // https://www.marketwatch.com/investing/stock/AAPL?mod=search_symbol [TestMethod] public void HeadlinesMarketWatchRetrieval() { String symbol="MIDD"; Headlines companyHeadlines = MarketDataHelper.GetCompanyHeadlinesMarketWatch(symbol); Assert.IsTrue(null!=companyHeadlines && companyHeadlines.Count>0); } // Test NASDAQ Headlines feed [TestMethod] public void HeadlinesNASDAQRetrieval() { String symbol="AAPL"; Headlines companyHeadlines = MarketDataHelper.GetCompanyHeadlinesNASDAQ(symbol); Assert.IsTrue(null!=companyHeadlines && companyHeadlines.Count>0); } // Test SEEKING ALPHA Headlines feed [TestMethod] public void HeadlinesSeekingAlphaRetrieval() { String symbol = "GLD"; Headlines companyHeadlines = MarketDataHelper.GetCompanyHeadlinesSeekingAlpha(symbol); Assert.IsTrue(null != companyHeadlines && companyHeadlines.Count > 0); } [TestMethod] public void HeadlinesSeekingAlphaV3Retrieval() { String symbol="MIDD"; Headlines companyHeadlines = MarketDataHelper.GetCompanyHeadlinesSeekingAlphaV3(symbol, true); Assert.IsTrue(null!=companyHeadlines && companyHeadlines.Count>0); } [TestMethod] public void AnalystPriceTargetMarketBeatRetrieval() { String symbol="MGPI"; AnalystPriceTarget analystPriceTarget=MarketDataHelper.GetAnalystPriceTargetMarketBeat(symbol); Assert.IsTrue(null!=analystPriceTarget); Assert.IsTrue(!Double.IsNaN(analystPriceTarget.HighTargetPrice)); Assert.IsTrue(!Double.IsNaN(analystPriceTarget.LowTargetPrice)); Assert.IsTrue(!Double.IsNaN(analystPriceTarget.MeanTargetPrice)); Assert.IsTrue(!Double.IsNaN(analystPriceTarget.MedianTargetPrice)); } [TestMethod] public void HistoricalRetrieval() { String symbol="AAPL"; Dictionary timeSeries=MarketDataHelper.GetHistoricalValues(symbol); Assert.IsTrue(null!=timeSeries); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.ROA),"Missing ROA"); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.ROIC),"Missing ROIC"); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.BVPS),"Missing BVPS"); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.Inventory),"Missing Inventory"); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.AccountsReceivable),"Missing AccountsReceivable"); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.COGS),"Missing COGS"); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.OperatingIncome),"Missing OperatingIncome"); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.InterestExpense),"Missing InterestExpense"); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.TaxRate),"Missing TaxRate"); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.Revenue),"Missing Revenue"); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.NetIncomeAvailableToCommonShareholders),"Missing NetIncomeAvailableToCommonShareholders"); Assert.IsTrue(timeSeries.ContainsKey(TimeSeriesElement.ElementType.OperatingCashflow),"Missing OperatingCashflow"); } [TestMethod] public void IncomeStatementNASDAQRetrieval() { String symbol="MIDD"; List incomeStatements=MarketDataHelper.GetIncomeStatementNASDAQ(symbol,IncomeStatement.PeriodType.Annual); Assert.IsTrue(null!=incomeStatements && incomeStatements.Count>0); } [TestMethod] public void IncomeStatementFinVizRetrievsl() { String symbol="MIDD"; List incomeStatements=MarketDataHelper.GetIncomeStatementFinViz(symbol,IncomeStatement.PeriodType.Annual); Assert.IsTrue(null!=incomeStatements && incomeStatements.Count>0); } [TestMethod] public void BalanceSheetNASDAQRetrieval() { String symbol="MIDD"; List balanceSheets = MarketDataHelper.GetBalanceSheetNASDAQ(symbol, BalanceSheet.PeriodType.Annual); Assert.IsTrue(null != balanceSheets && balanceSheets.Count > 0); BalanceSheet balanceSheet = balanceSheets[0]; Assert.IsTrue(!double.IsNaN(balanceSheet.CashAndCashEquivalents),"CashAndCashEquivalents"); Assert.IsTrue(!double.IsNaN(balanceSheet.DeferredLongTermLiabilities),"DeferredLongTermLiabilities"); Assert.IsTrue(!double.IsNaN(balanceSheet.IntangibleAssets),"IntangibleAssets"); Assert.IsTrue(!double.IsNaN(balanceSheet.Inventory),"Inventory"); Assert.IsTrue(!double.IsNaN(balanceSheet.LongTermDebt),"LongTermDebt"); Assert.IsTrue(!double.IsNaN(balanceSheet.NetCurrentAssetValue),"NetCurrentAssetValue"); Assert.IsTrue(!double.IsNaN(balanceSheet.NetFixedAssets),"NetFixedAssets"); Assert.IsTrue(!double.IsNaN(balanceSheet.OtherLiabilities),"OtherLiabilities"); Assert.IsTrue(!double.IsNaN(balanceSheet.PropertyPlantAndEquipment),"PropertyPlantAndEquipment"); Assert.IsTrue(!double.IsNaN(balanceSheet.TotalAssets),"TotalAssets"); Assert.IsTrue(!double.IsNaN(balanceSheet.TotalCurrentAssets),"TotalCurrentAssets"); Assert.IsTrue(!double.IsNaN(balanceSheet.TotalCurrentLiabilities),"TotalCurrentLiabilities"); Assert.IsTrue(!double.IsNaN(balanceSheet.TotalLiabilities),"TotalLiabilities"); } [TestMethod] public void CashflowStatementMorningStarRetrieval() { String[] symbols = {"AZEK", "CPRT", "DOCU", "ESTC", "HLNE"}; Dictionary> cashflowStatementsDict = new Dictionary>(); foreach(String symbol in symbols) { List cashflowStatements = MarketDataHelper.GetCashflowStatement(symbol, CashflowStatement.PeriodType.Annual); if(null == cashflowStatements)continue; cashflowStatementsDict.Add(symbol, cashflowStatements); } Assert.IsTrue(cashflowStatementsDict.Count!=0,"Error retrieving cashflow statements."); List keys = cashflowStatementsDict.Keys.ToList(); foreach(String key in keys) { List cashflowStatements = cashflowStatementsDict[key]; CashflowStatement cashflowStatement = cashflowStatements[0]; Assert.IsTrue(!double.IsNaN(cashflowStatement.DepreciationAndAmortization), $"DepreciationAndAmortization for {key}"); Assert.IsTrue(!double.IsNaN(cashflowStatement.DeferredIncomeTaxes), $"DeferredIncomeTaxes for {key}"); Assert.IsTrue(!double.IsNaN(cashflowStatement.StockBasedCompensation), $"StockBasedCompensation for {key}"); Assert.IsTrue(!double.IsNaN(cashflowStatement.AccountsReceivable), $"AccountsReceivable for {key}"); Assert.IsTrue(!double.IsNaN(cashflowStatement.Inventory), $"Inventory for {key}"); Assert.IsTrue(!double.IsNaN(cashflowStatement.AccountsPayable), $"AccountsPayable for {key}"); Assert.IsTrue(!double.IsNaN(cashflowStatement.AccruedLiabilities), $"AccruedLiabilities for {key}"); Assert.IsTrue(!double.IsNaN(cashflowStatement.OperatingCashflow), $"OperatingCashflow for {key}"); Assert.IsTrue(!double.IsNaN(cashflowStatement.FreeCashflow), $"FreeCashflow for {key}"); } } [TestMethod] public void CurrencyConversionXERetrieval() { DateGenerator dateGenerator = new DateGenerator(); String sourceCurrency="USD"; DateTime analysisDate = DateTime.Now; analysisDate = dateGenerator.FindPrevBusinessDay(analysisDate); CurrencyConversionCollection currencyConversionCollection = MarketDataHelper.GetCurrencyConversion(sourceCurrency,analysisDate); Assert.IsTrue(null!=currencyConversionCollection && currencyConversionCollection.Count>0); } [TestMethod] public void FundamentalFinVizRetrieval() { String symbol = "MIDD"; Fundamental fundamental=MarketDataHelper.GetFundamentalFinViz(symbol); Assert.IsTrue(null!=fundamental); Assert.IsTrue(!Utility.IsEpoch(fundamental.NextEarningsDate),"NextEarningsDate"); Assert.IsTrue(!double.IsNaN(fundamental.Beta),"Beta"); Assert.IsTrue(!double.IsNaN(fundamental.Low52),"Low52"); Assert.IsTrue(!double.IsNaN(fundamental.High52),"High52"); Assert.IsTrue(!double.IsNaN(fundamental.Volume),"Volume"); Assert.IsTrue(!double.IsNaN(fundamental.MarketCap),"MarketCap"); Assert.IsTrue(!double.IsNaN(fundamental.PE),"PE"); Assert.IsTrue(!double.IsNaN(fundamental.EPS),"EPS"); Assert.IsTrue(!double.IsNaN(fundamental.PEG),"PEG"); Assert.IsTrue(!double.IsNaN(fundamental.ReturnOnAssets),"ReturnOnAssets"); Assert.IsTrue(!double.IsNaN(fundamental.ReturnOnEquity),"ReturnOnEquity"); Assert.IsTrue(!double.IsNaN(fundamental.TotalCash),"TotalCash"); Assert.IsTrue(!double.IsNaN(fundamental.TotalDebt),"TotalDebt"); Assert.IsTrue(!double.IsNaN(fundamental.SharesOutstanding),"SharesOutstanding"); Assert.IsTrue(!double.IsNaN(fundamental.Revenue),"Revenue"); Assert.IsTrue(!double.IsNaN(fundamental.RevenuePerShare),"RevenuePerShare"); Assert.IsTrue(!double.IsNaN(fundamental.QtrlyRevenueGrowth),"QtrlyRevenueGrowth"); Assert.IsTrue(!double.IsNaN(fundamental.GrossProfit),"GrossProfit"); Assert.IsTrue(!double.IsNaN(fundamental.EBITDA),"EBITDA"); Assert.IsTrue(!double.IsNaN(fundamental.NetIncomeAvailableToCommon),"NetIncomeAvailableToCommon"); Assert.IsTrue(!double.IsNaN(fundamental.BookValuePerShare),"BookValuePerShare"); Assert.IsTrue(!double.IsNaN(fundamental.OperatingCashflow),"OperatingCashflow"); Assert.IsTrue(!double.IsNaN(fundamental.LeveragedFreeCashflow),"LeveragedFreeCashflow"); Assert.IsTrue(!double.IsNaN(fundamental.Equity),"Equity"); Assert.IsTrue(!double.IsNaN(fundamental.TrailingPE),"TrailingPE"); Assert.IsTrue(!double.IsNaN(fundamental.EnterpriseValue),"EnterpriseValue"); Assert.IsTrue(!double.IsNaN(fundamental.EBIT),"EBIT"); Assert.IsTrue(!double.IsNaN(fundamental.DebtToEquity),"DebtToEquity"); } [TestMethod] public void GetDailyPricesYahooRetrieval() { String symbol="MIDD"; DateTime analysisDate=DateTime.Now; DateGenerator dateGenerator = new DateGenerator(); analysisDate=dateGenerator.FindPrevBusinessDay(analysisDate); Prices prices=MarketDataHelper.GetDailyPrices(symbol,analysisDate,analysisDate); Assert.IsTrue(null!=prices && prices.Count>0,"No Price"); } }