205 lines
9.6 KiB
C#
205 lines
9.6 KiB
C#
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<TLBItem>
|
|
{
|
|
public TLBItemList()
|
|
{
|
|
}
|
|
public TLBItemList(TLBItemList itemList)
|
|
{
|
|
foreach(TLBItem item in itemList)Add(item);
|
|
}
|
|
public static void ApplyTLBRanks(TLBItemList items)
|
|
{
|
|
Dictionary<String,TLBItem> itemsBySymbol=new Dictionary<String,TLBItem>();
|
|
Dictionary<String,int> itemsRankedByROC=new Dictionary<String,int>();
|
|
Dictionary<String,int> itemsRankedByROIC=new Dictionary<String,int>();
|
|
Dictionary<String,int> itemsRankedByEarningsYield=new Dictionary<String,int>();
|
|
|
|
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<itemsCopyByROC.Count;index++)
|
|
{
|
|
String symbol=itemsCopyByROC[index].Symbol;
|
|
if(!itemsRankedByROC.ContainsKey(symbol))itemsRankedByROC.Add(symbol,index);
|
|
}
|
|
for(int index=0;index<itemsCopyByROIC.Count;index++)
|
|
{
|
|
String symbol=itemsCopyByROIC[index].Symbol;
|
|
if(!itemsRankedByROIC.ContainsKey(symbol))itemsRankedByROIC.Add(symbol,index);
|
|
}
|
|
for(int index=0;index<itemsCopyByEarningsYield.Count;index++)
|
|
{
|
|
String symbol=itemsCopyByEarningsYield[index].Symbol;
|
|
if(!itemsRankedByEarningsYield.ContainsKey(symbol))itemsRankedByEarningsYield.Add(symbol,index);
|
|
}
|
|
|
|
for(int index=0;index<items.Count;index++)
|
|
{
|
|
TLBItem tlbItem=items[index];
|
|
tlbItem.TLBRankROC=itemsRankedByROC[tlbItem.Symbol]+itemsRankedByEarningsYield[tlbItem.Symbol];
|
|
tlbItem.TLBRankROIC=itemsRankedByROIC[tlbItem.Symbol]+itemsRankedByEarningsYield[tlbItem.Symbol];
|
|
}
|
|
}
|
|
}
|
|
public class TLBListByROC : IComparer<TLBItem>
|
|
{
|
|
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<TLBItem>
|
|
{
|
|
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<TLBItem>
|
|
{
|
|
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<String> 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<String,Valuation> valuationsBySymbol=new Dictionary<String,Valuation>();
|
|
Dictionary<String,int> valuationsRankedByROIC=new Dictionary<String,int>();
|
|
Dictionary<String,int> valuationsRankedByROC=new Dictionary<String,int>();
|
|
Dictionary<String,int> valuationsRankedByEarningsYield=new Dictionary<String,int>();
|
|
|
|
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<valuationsCopyByROIC.Count;index++)
|
|
{
|
|
String symbol=valuationsCopyByROIC[index].Symbol;
|
|
if(!valuationsRankedByROIC.ContainsKey(symbol))valuationsRankedByROIC.Add(symbol,index);
|
|
}
|
|
for(int index=0;index<valuationsCopyByROC.Count;index++)
|
|
{
|
|
String symbol=valuationsCopyByROC[index].Symbol;
|
|
if(!valuationsRankedByROC.ContainsKey(symbol))valuationsRankedByROC.Add(symbol,index);
|
|
}
|
|
for(int index=0;index<valuationsCopyByEarningsYield.Count;index++)
|
|
{
|
|
String symbol=valuationsCopyByEarningsYield[index].Symbol;
|
|
if(!valuationsRankedByEarningsYield.ContainsKey(symbol))valuationsRankedByEarningsYield.Add(symbol,index);
|
|
}
|
|
for(int index=0;index<valuations.Count;index++)
|
|
{
|
|
Valuation valuation=valuations[index];
|
|
valuation.TLBRankROIC=valuationsRankedByROIC[valuation.Symbol]+valuationsRankedByEarningsYield[valuation.Symbol];
|
|
valuation.TLBRankROC=valuationsRankedByROC[valuation.Symbol]+valuationsRankedByEarningsYield[valuation.Symbol];
|
|
}
|
|
}
|
|
}
|
|
}
|