using MarketData.DataAccess; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MarketData.MarketDataModel { // ******************************************************************************************************************************************************** // ******************************************** U N I T T E S T F O R J O E L G R E E N B L A T T M E T H O D O L O G Y *************************** // ******************************************************************************************************************************************************** public class TLBItemList : List { public TLBItemList() { } public TLBItemList(TLBItemList itemList) { foreach(TLBItem item in itemList)Add(item); } public static void ApplyTLBRanks(TLBItemList items) { Dictionary itemsBySymbol=new Dictionary(); Dictionary itemsRankedByROC=new Dictionary(); Dictionary itemsRankedByROIC=new Dictionary(); Dictionary itemsRankedByEarningsYield=new Dictionary(); foreach(TLBItem item in items) { if(!itemsBySymbol.ContainsKey(item.Symbol)) { itemsBySymbol.Add(item.Symbol,item); } } TLBItemList itemsCopyByROC=new TLBItemList(items); TLBItemList itemsCopyByROIC=new TLBItemList(items); TLBItemList itemsCopyByEarningsYield=new TLBItemList(items); itemsCopyByROC.Sort(new TLBListByROC()); itemsCopyByROIC.Sort(new TLBListByROIC()); itemsCopyByEarningsYield.Sort(new TLBListByEarningsYield()); for(int index=0;index { public int Compare(TLBItem v1,TLBItem v2) { if(double.IsNaN(v1.ROC)&&double.IsNaN(v2.ROC))return 0; else if(double.IsNaN(v1.ROC))return -1; else if(double.IsNaN(v2.ROC))return 1; return v1.ROC.CompareTo(v2.ROC); } } public class TLBListByROIC : IComparer { public int Compare(TLBItem v1,TLBItem v2) { if(double.IsNaN(v1.ROIC)&&double.IsNaN(v2.ROIC))return 0; else if(double.IsNaN(v1.ROIC))return -1; else if(double.IsNaN(v2.ROIC))return 1; return v1.ROIC.CompareTo(v2.ROIC); } } public class TLBListByEarningsYield : IComparer { public int Compare(TLBItem v1,TLBItem v2) { if(double.IsNaN(v1.EarningsYield)&&double.IsNaN(v2.EarningsYield))return 0; else if(double.IsNaN(v1.EarningsYield))return -1; else if(double.IsNaN(v2.EarningsYield))return 1; return v1.EarningsYield.CompareTo(v2.EarningsYield); } } public class TLBItem { public String Symbol{get;set;} public double EBIT{get;set;} public double EarningsYield{get;set;} public double EnterpriseValue{get;set;} public double WorkingCapital{get;set;} public double PPE{get;set;} public double ROIC{get;set;} public double ROC{get;set;} public double TLBRankROIC{get;set;} public double TLBRankROC{get;set;} } // The sorting of the ranks will be from lowest to highest. The largest ROICS will have the largest ranks and the largest EarningsYields will have the largest ranks. // This sorting is opposite to how Joel sorted his lists. Joel's lists wind up with the best candidates having the lowest ranks while this one winds up with the // best candidates having the highest ranks. This can be seen when visiting the Valuations view and changing the sort to TLBRankROIC with the highest valued ranks // on top. These will be the top candidates. public class TLBRankGenerator { private TLBRankGenerator() { } // ******************************************************************************************************************************************************************* // ********************************************** T H E L I T T L E B O O K R A N K G E N E R A T O R U N I T T E S T **** ********************************** // ******************************************************************************************************************************************************************* public static TLBItemList ApplyTLBRanks() { List symbols=PricingDA.GetSymbols(); TLBItemList tlbList=new TLBItemList(); foreach(String symbol in symbols) { double earningsYield=double.NaN; double roc=double.NaN; double roic=double.NaN; Console.WriteLine("Working on "+symbol); BalanceSheet balanceSheet = BalanceSheetDA.GetBalanceSheet(symbol,BalanceSheet.PeriodType.Annual); TimeSeriesCollection workingCapitalCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.WorkingCapital); TimeSeriesCollection roicCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.ROIC); Fundamental fundamental=FundamentalDA.GetFundamental(symbol); if(null==fundamental)continue; TLBItem tlbItem=new TLBItem(); if(!double.IsNaN(fundamental.EBIT)&&!double.IsNaN(fundamental.EnterpriseValue)&&fundamental.EnterpriseValue>0.00&&fundamental.EBIT>0.00) { earningsYield=fundamental.EBIT/fundamental.EnterpriseValue; } if(!double.IsNaN(fundamental.EBIT)&&null!=balanceSheet&&!double.IsNaN(balanceSheet.NetFixedAssets)) { roc=fundamental.EBIT/balanceSheet.NetFixedAssets; } if(null!=roicCollection && roicCollection.Count>0)roic=roicCollection[0].Value; tlbItem.Symbol=symbol; tlbItem.EBIT=fundamental.EBIT; tlbItem.EarningsYield=earningsYield; tlbItem.EnterpriseValue=fundamental.EnterpriseValue; tlbItem.ROC=roc*100.00; tlbItem.ROIC=roic; tlbList.Add(tlbItem); } TLBItemList.ApplyTLBRanks(tlbList); return tlbList; } // ******************************************************************************************************************************************************************* // ********************************************** T H E L I T T L E B O O K R A N K G E N E R A T O R F O R V A L U A T I O N ********************************** // ******************************************************************************************************************************************************************* public static void ApplyTLBRanks(Valuations valuations) { Dictionary valuationsBySymbol=new Dictionary(); Dictionary valuationsRankedByROIC=new Dictionary(); Dictionary valuationsRankedByROC=new Dictionary(); Dictionary valuationsRankedByEarningsYield=new Dictionary(); foreach(Valuation valuation in valuations) { if(!valuationsBySymbol.ContainsKey(valuation.Symbol))valuationsBySymbol.Add(valuation.Symbol,valuation); } Valuations valuationsCopyByROIC=new Valuations(valuations); valuationsCopyByROIC.Sort(new ValuationsByROIC()); Valuations valuationsCopyByROC=new Valuations(valuations); valuationsCopyByROC.Sort(new ValuationsByROC()); Valuations valuationsCopyByEarningsYield=new Valuations(valuations); valuationsCopyByEarningsYield.Sort(new ValuationsByEarningsYield()); for(int index=0;index