Files
ARM64/MarketData/MarketDataLib/Generator/ValuationGenerator.cs
2025-03-25 21:42:32 -04:00

550 lines
34 KiB
C#
Executable File

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MarketData.DataAccess;
using MarketData.Numerical;
using MarketData.MarketDataModel;
using MarketData.Utils;
namespace MarketData.Generator
{
public class ValuationGenerator
{
public delegate bool OnItemCompleteHandler(Valuation valuation);
public delegate void OnErrorItemHandler(String symbol,String message);
private ValuationGenerator()
{
}
public static Valuations GenerateValuations(List<String> symbols,OnItemCompleteHandler onItemCompleteHandler=null,OnErrorItemHandler onErrorItemHandler=null)
{
try
{
Valuations valuations = new Valuations();
valuations.ValuationDate = DateTime.Now;
Prices pricesIndex90 = PricingDA.GetPrices("SPY",90);
Prices pricesIndex720 = PricingDA.GetPrices("SPY", 720);
for (int index = 0; index < symbols.Count; index++)
{
Valuation valuation=GenerateValuation(symbols[index],pricesIndex90,pricesIndex720,onItemCompleteHandler,onErrorItemHandler);
if (null == valuation) continue;
valuations.Add(valuation);
if (null != onItemCompleteHandler)
{
if (!onItemCompleteHandler(valuation)) break;
}
}
TLBRankGenerator.ApplyTLBRanks(valuations);
AcquirersMultipeGenerator.ApplyRanks(valuations);
return valuations;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString());
return null;
}
}
public static Valuations GenerateValuations(OnItemCompleteHandler onItemCompleteHandler=null,OnErrorItemHandler onErrorItemHandler=null)
{
try
{
List<String> symbols = PricingDA.GetSymbols();
Valuations valuations = new Valuations();
valuations.ValuationDate = DateTime.Now;
Prices pricesIndex90 = PricingDA.GetPrices("SPY",90);
Prices pricesIndex720 = PricingDA.GetPrices("SPY", 720);
for (int index = 0; index < symbols.Count; index++)
{
Valuation valuation=GenerateValuation(symbols[index],pricesIndex90,pricesIndex720,onItemCompleteHandler,onErrorItemHandler);
if (null == valuation) continue;
valuations.Add(valuation);
if (null != onItemCompleteHandler)
{
if (!onItemCompleteHandler(valuation)) break;
}
}
TLBRankGenerator.ApplyTLBRanks(valuations);
AcquirersMultipeGenerator.ApplyRanks(valuations);
return valuations;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,exception.ToString());
return null;
}
}
public static Valuation GenerateValuation(String symbol,Prices pricesIndex90,Prices pricesIndex720,OnItemCompleteHandler onItemCompleteHandler=null,OnErrorItemHandler onErrorItemHandler=null)
{
try
{
Valuation valuation = new Valuation();
symbol = symbol.ToUpper();
String companyName = PricingDA.GetNameForSymbol(symbol);
Price price = PricingDA.GetPrice(symbol);
CompanyProfile companyProfile=CompanyProfileDA.GetCompanyProfile(symbol);
Prices pricesSymbol90=PricingDA.GetPrices(symbol,90);
Prices pricesSymbol720=PricingDA.GetPrices(symbol,720);
if (null == price)
{
if (null != onErrorItemHandler) onErrorItemHandler(symbol, "No Prices.");
return null;
}
IncomeStatement incomeStatement=IncomeStatementDA.GetIncomeStatement(symbol,IncomeStatement.PeriodType.Annual);
CashflowStatement cashflowStatement=CashflowStatementDA.GetCashflowStatement(symbol,CashflowStatement.PeriodType.Annual);
BalanceSheet balanceSheet = BalanceSheetDA.GetBalanceSheet(symbol,BalanceSheet.PeriodType.Annual);
TimeSeriesCollection bookValuePerShareCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.BVPS);
TimeSeriesCollection epsCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.EPS);
TimeSeriesCollection roicCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.ROIC);
TimeSeriesCollection revenueCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.Revenue);
TimeSeriesCollection freeCashflowCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.FreeCashflow);
TimeSeriesCollection operatingCashflowCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.OperatingCashflow);
TimeSeriesCollection workingCapitalCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.WorkingCapital);
if (null == bookValuePerShareCollection || 0 == bookValuePerShareCollection.Count)
{
bookValuePerShareCollection=new TimeSeriesCollection();
TimeSeriesElement timeSeriesElement=new TimeSeriesElement();
timeSeriesElement.AsOf=DateTime.Now;
timeSeriesElement.Value=0;
bookValuePerShareCollection.Add(new TimeSeriesElement());
}
Fundamental fundamental = FundamentalDA.GetFundamental(symbol);
if (null == fundamental)
{
if (null != onErrorItemHandler) onErrorItemHandler(symbol, "No Fundamental Data.");
return null;
}
AnalystPriceTarget analystPriceTarget = AnalystPriceTargetDA.GetAnalystPriceTarget(symbol);
// These series are ordered by date with the latest date appearing at the lowest ordinal index.
float[] bookValuesPerShareSeries = bookValuePerShareCollection.ToFloat();
float[] epsSeries = epsCollection.ToFloat();
float[] roicSeries = roicCollection.ToFloat();
float[] revenueSeries = revenueCollection.ToFloat();
float[] freeCashflowSeries = freeCashflowCollection.ToFloat();
float[] operatingCashflowSeries = operatingCashflowCollection.ToFloat();
float[] workingCapitalSeries = workingCapitalCollection.ToFloat();
double averageGrowth = Numerics.AverageReturn(ref bookValuesPerShareSeries);
double averageGrowth2Year = Numerics.AverageReturnTop(ref bookValuesPerShareSeries, 2);
double averageGrowth4Year = Numerics.AverageReturnTop(ref bookValuesPerShareSeries, 4);
double epsGrowth = Numerics.AverageReturn(ref epsSeries);
double epsGrowth2Year = Numerics.AverageReturnTop(ref epsSeries, 2);
double epsGrowth4Year = Numerics.AverageReturnTop(ref epsSeries, 4);
double roic = Numerics.Mean(ref roicSeries);
double revenueGrowth = Numerics.AverageReturn(ref revenueSeries);
double revenueGrowth2Year = Numerics.AverageReturnTop(ref revenueSeries, 2);
double revenueGrowth4Year = Numerics.AverageReturnTop(ref revenueSeries, 4);
double freeCashflowGrowth = Numerics.AverageReturn(ref freeCashflowSeries);
double averageOperatingCashflow = Numerics.Mean(ref operatingCashflowSeries);
double averageWorkingCapital = Numerics.Mean(ref workingCapitalSeries);
double latestPrice = price.Close;
// Shares Oustanding
valuation.SharesOutstanding=fundamental.SharesOutstanding;
// Dividend Yield
valuation.DividendYield=DividendHistoryGenerator.GetDividendYield(symbol);
// Benjamin Graham Formula. EPS=Trailing Twelve month, 8.5=PE base for no growth company, g=reasonably expected 7-10 year growth rate
double intrinsicValue =GrahamGenerator.IntrinsicValue(fundamental.EPS,epsGrowth);
valuation.FundamentalValue=GrahamGenerator.GrahamNumber(fundamental.EPS,fundamental.BookValuePerShare);
if(0!=fundamental.SharesOutstanding&&!double.IsNaN(fundamental.SharesOutstanding)&&null!=balanceSheet&&!double.IsNaN(balanceSheet.NetCurrentAssetValue))valuation.NetCurrentAssetValuePerShare=balanceSheet.NetCurrentAssetValue/fundamental.SharesOutstanding;
else valuation.NetCurrentAssetValuePerShare=double.NaN;
valuation.DebtToEquity=fundamental.DebtToEquity;
// **************************************************************************************************************************************************
valuation.MarketCap=fundamental.MarketCap;
valuation.EnterpriseValue=fundamental.EnterpriseValue;
valuation.EBIT=fundamental.EBIT;
// ******************************************************* T H E L I T T L E B O O K *******************************************************
// Calculate the earnings yield to be used by TLB rankings (TLB=The Little Book)
// earnings_yield=EBIT/EnterpriseValue
if(!double.IsNaN(fundamental.EBIT)&&null!=balanceSheet&&!double.IsNaN(balanceSheet.NetFixedAssets))
{
valuation.LatestROC=fundamental.EBIT/balanceSheet.NetFixedAssets;
}
else valuation.LatestROC=double.NaN;
if(!double.IsNaN(fundamental.EBIT)&&!double.IsNaN(fundamental.EnterpriseValue)&&fundamental.EnterpriseValue>0.00&&fundamental.EBIT>0.00)
{
valuation.EarningsYield=fundamental.EBIT/fundamental.EnterpriseValue;
}
else valuation.EarningsYield=double.NaN;
// ******************************************************** T H E A C Q U I R E R S M U L T I P L E ********************************************
if(null!=fundamental&&!double.IsNaN(fundamental.EnterpriseValue)&&null!=cashflowStatement&&!double.IsNaN(cashflowStatement.DepreciationAndAmortization)&&null!=incomeStatement&&!double.IsNaN(incomeStatement.TotalRevenue)&&!double.IsNaN(incomeStatement.CostOfRevenue)&&!double.IsNaN(incomeStatement.SGA))
{
valuation.OperatingEarnings=incomeStatement.TotalRevenue-(cashflowStatement.DepreciationAndAmortization+incomeStatement.CostOfRevenue+incomeStatement.SGA);
valuation.AcquirersMultiple=fundamental.EnterpriseValue/valuation.OperatingEarnings;
}
else
{
valuation.OperatingEarnings=double.NaN;
valuation.AcquirersMultiple=double.NaN;
}
// ******************************************************************** S E C F O R M 1 3 D *********************************************************************************************
SEC13Info sec13Info=SECFilingDA.GetSEC13Info(symbol);
if(sec13Info.SEC13)
{
valuation.SEC13=true;
valuation.SEC13FilingDate=sec13Info.MostRecentFilingDate;
}
// *****************************************************************************************************************************************************************************************
valuation.Company=companyName.Replace(",", "");
valuation.Symbol=symbol;
valuation.NextEarningsDate=fundamental.NextEarningsDate;
valuation.Beta90 = BetaGenerator.Beta(symbol, PricingDA.GetLatestDate(symbol),3);
valuation.Beta720 = BetaGenerator.Beta(symbol, PricingDA.GetLatestDate(symbol),24);
if (null != roicSeries && roicSeries.Length > 0)
{
valuation.ROICDates = Utility.FormatDates(roicCollection[roicCollection.Count - 1].AsOf, roicCollection[0].AsOf);
TimeSeriesElement[] roicTimeSeriesElement=(from roicItem in roicCollection select roicItem).OrderBy(roicItem => roicItem.AsOf).ToArray();
double[] orderedROICValues=(from element in roicTimeSeriesElement select element.Value).ToArray();
valuation.ROICSlope = Numerics.Slope(orderedROICValues);
valuation.LatestROIC=roicCollection[0].Value;
}
if (null != revenueSeries && revenueSeries.Length > 0 && null != balanceSheet && !double.IsNaN(balanceSheet.LongTermDebt))
{
double latestRevenue = revenueSeries[0];
valuation.LongTermDebt=balanceSheet.LongTermDebt;
valuation.Revenue=latestRevenue;
if (latestRevenue * 3 > balanceSheet.LongTermDebt) valuation.DebtLoad="Pass";
else valuation.DebtLoad="Fail";
}
else
{
valuation.LongTermDebt=double.NaN;
valuation.Revenue=double.NaN;
valuation.DebtLoad="N/A";
}
valuation.AverageROIC=roic / 100.00;
if (null != bookValuePerShareCollection && 0 != bookValuePerShareCollection.Count)
{
valuation.BVPS = bookValuePerShareCollection[0].Value;
valuation.BVPSDates = Utility.FormatDates(bookValuePerShareCollection[bookValuePerShareCollection.Count - 1].AsOf, bookValuePerShareCollection[0].AsOf);
}
else valuation.BVPSDates = "N/A";
valuation.AverageEquityGrowth=averageGrowth;
valuation.AverageEquityGrowth2Y=averageGrowth2Year;
valuation.AverageEquityGrowth4Y=averageGrowth4Year;
if (null != epsCollection && epsCollection.Count > 0) valuation.EPSDates = Utility.FormatDates(epsCollection[epsCollection.Count - 1].AsOf, epsCollection[0].AsOf);
else valuation.EPSDates="N/A";
valuation.AverageEPSGrowth=epsGrowth;
valuation.AverageEPSGrowth2Y=epsGrowth2Year;
valuation.AverageEPSGrowth4Y=epsGrowth4Year;
if (null != revenueCollection && revenueCollection.Count > 0) valuation.RevenueDates = Utility.FormatDates(revenueCollection[revenueCollection.Count - 1].AsOf, revenueCollection[0].AsOf);
else valuation.RevenueDates="N/A";
valuation.AverageRevenueGrowth=revenueGrowth;
valuation.AverageRevenueGrowth2Y=revenueGrowth2Year;
valuation.AverageRevenueGrowth4Y=revenueGrowth4Year;
valuation.AverageFreeCashflowGrowth=freeCashflowGrowth;
valuation.AverageOperatingCashflow=averageOperatingCashflow;
valuation.OperatingCashflow=null!=operatingCashflowSeries&&operatingCashflowSeries.Length>0?operatingCashflowSeries[0]:double.NaN;
valuation.AverageWorkingCapital=averageWorkingCapital;
if(null!=companyProfile)
{
valuation.Industry=companyProfile.Industry;
valuation.Sector=companyProfile.Sector;
}
valuation.EPS=fundamental.EPS;
valuation.PE=latestPrice / fundamental.EPS;
valuation.PEG = fundamental.PEG;
if(!double.IsNaN(valuation.BVPS)&&!double.IsNaN(latestPrice))valuation.PBVPS=latestPrice/valuation.BVPS;
if (!double.IsNaN(valuation.PE) && !double.IsNaN(valuation.PEG)) valuation.ImpliedEarningsGrowth = (valuation.PE / valuation.PEG) / 100.00;
StickerPrice stickerPrice = new StickerPrice(symbol);
valuation.BVPSItems = stickerPrice.BVPSItems;
valuation.AverageBVPSGrowth = stickerPrice.AverageBVPSGrowth;
valuation.LowPE=stickerPrice.LowPE;
valuation.TrailingPE=stickerPrice.TrailingPE;
valuation.AverageLowTrailing=stickerPrice.AverageLowTrailing;
valuation.CurrentStockEstimatePrice=stickerPrice.CurrentStockEstimatePrice;
valuation.PriceEstimate10Y=stickerPrice.PriceEstimate10y;
valuation.TodaysPriceForRequiredReturn=stickerPrice.TodaysPriceForRequiredReturn;
valuation.MOS=stickerPrice.MarginOfSafety;
valuation.MOS80=stickerPrice.MarginOfSafety80Pcnt;
valuation.IntrinsicValue=intrinsicValue;
valuation.RGV=intrinsicValue/latestPrice;
valuation.LatestPrice=latestPrice;
if (null != analystPriceTarget)
{
valuation.MeanTargetPrice=analystPriceTarget.MeanTargetPrice;
valuation.LowTargetPrice=analystPriceTarget.LowTargetPrice;
valuation.HighTargetPrice=analystPriceTarget.HighTargetPrice;
}
else
{
valuation.MeanTargetPrice=double.NaN;
valuation.LowTargetPrice=double.NaN;
valuation.HighTargetPrice=double.NaN;
}
valuation.UpsidePcnt = double.IsNaN(valuation.HighTargetPrice)||0>=valuation.HighTargetPrice ? double.NaN : (valuation.HighTargetPrice - valuation.LatestPrice) / valuation.LatestPrice;
valuation.DownsidePcnt=double.IsNaN(valuation.LowTargetPrice)||0>=valuation.LowTargetPrice?double.NaN:(valuation.LowTargetPrice-valuation.LatestPrice)/valuation.LatestPrice;
valuation.Bargain=latestPrice < stickerPrice.MarginOfSafety ? true : false;
valuation.Bargain80=latestPrice < stickerPrice.MarginOfSafety80Pcnt ? true : false;
return valuation;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,"Error calculating sticker for '" + symbol + "', exception was " + exception.ToString());
return null;
}
}
public static Valuation GenerateValuationWithOverride(String symbol,Prices pricesIndex90,Prices pricesIndex720,double bvpsGrowthOverride,OnItemCompleteHandler onItemCompleteHandler=null,OnErrorItemHandler onErrorItemHandler=null)
{
try
{
Valuation valuation = new Valuation();
symbol = symbol.ToUpper();
String companyName = PricingDA.GetNameForSymbol(symbol);
Price price = PricingDA.GetPrice(symbol);
CompanyProfile companyProfile=CompanyProfileDA.GetCompanyProfile(symbol);
Prices pricesSymbol90=PricingDA.GetPrices(symbol,90);
Prices pricesSymbol720=PricingDA.GetPrices(symbol,720);
if (null == price)
{
if (null != onErrorItemHandler) onErrorItemHandler(symbol, "No Prices.");
return null;
}
BalanceSheet balanceSheet = BalanceSheetDA.GetBalanceSheet(symbol,BalanceSheet.PeriodType.Annual);
IncomeStatement incomeStatement=IncomeStatementDA.GetIncomeStatement(symbol,IncomeStatement.PeriodType.Annual);
CashflowStatement cashflowStatement=CashflowStatementDA.GetCashflowStatement(symbol,CashflowStatement.PeriodType.Annual);
// These series are ordered by date with the latest date appearing at the lowest ordinal index
TimeSeriesCollection bookValuePerShareCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.BVPS);
TimeSeriesCollection epsCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.EPS);
TimeSeriesCollection roicCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.ROIC);
TimeSeriesCollection revenueCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.Revenue);
TimeSeriesCollection freeCashflowCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.FreeCashflow);
TimeSeriesCollection operatingCashflowCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.OperatingCashflow);
TimeSeriesCollection workingCapitalCollection = HistoricalDA.GetTimeSeries(symbol, TimeSeriesElement.ElementType.WorkingCapital);
if (null == bookValuePerShareCollection || 0 == bookValuePerShareCollection.Count)
{
bookValuePerShareCollection=new TimeSeriesCollection();
TimeSeriesElement timeSeriesElement=new TimeSeriesElement();
timeSeriesElement.AsOf=DateTime.Now;
timeSeriesElement.Value=0;
bookValuePerShareCollection.Add(new TimeSeriesElement());
}
Fundamental fundamental = FundamentalDA.GetFundamental(symbol);
if (null == fundamental)
{
if (null != onErrorItemHandler) onErrorItemHandler(symbol, "No Fundamental Data.");
return null;
}
AnalystPriceTarget analystPriceTarget = AnalystPriceTargetDA.GetAnalystPriceTarget(symbol);
float[] bookValuesPerShareSeries = bookValuePerShareCollection.ToFloat();
float[] epsSeries = epsCollection.ToFloat();
float[] roicSeries = roicCollection.ToFloat();
float[] revenueSeries = revenueCollection.ToFloat();
float[] freeCashflowSeries = freeCashflowCollection.ToFloat();
float[] operatingCashflowSeries = operatingCashflowCollection.ToFloat();
float[] workingCapitalSeries = workingCapitalCollection.ToFloat();
double averageGrowth = bvpsGrowthOverride;
double averageGrowth2Year = bvpsGrowthOverride;
double averageGrowth4Year = bvpsGrowthOverride;
double epsGrowth = Numerics.AverageReturn(ref epsSeries);
double epsGrowth2Year = Numerics.AverageReturnTop(ref epsSeries, 2);
double epsGrowth4Year = Numerics.AverageReturnTop(ref epsSeries, 4);
double roic = Numerics.Mean(ref roicSeries);
double revenueGrowth = Numerics.AverageReturn(ref revenueSeries);
double revenueGrowth2Year = Numerics.AverageReturnTop(ref revenueSeries, 2);
double revenueGrowth4Year = Numerics.AverageReturnTop(ref revenueSeries, 4);
double freeCashflowGrowth = Numerics.AverageReturn(ref freeCashflowSeries);
double averageOperatingCashflow = Numerics.Mean(ref operatingCashflowSeries);
double averageWorkingCapital = Numerics.Mean(ref workingCapitalSeries);
double latestPrice = price.Close;
// Shares Oustanding
valuation.SharesOutstanding=fundamental.SharesOutstanding;
// Dividend Yield
valuation.DividendYield=DividendHistoryGenerator.GetDividendYield(symbol);
// Benjamin Graham Formula. EPS=Trailing Twelve month, 8.5=PE base for no growth company, g=reasonably expected 7-10 year growth rate
double intrinsicValue = GrahamGenerator.IntrinsicValue(fundamental.EPS,epsGrowth);
valuation.FundamentalValue=GrahamGenerator.GrahamNumber(fundamental.EPS,fundamental.BookValuePerShare);
if(0!=fundamental.SharesOutstanding&&!double.IsNaN(fundamental.SharesOutstanding)&&null!=balanceSheet&&!double.IsNaN(balanceSheet.NetCurrentAssetValue))valuation.NetCurrentAssetValuePerShare=balanceSheet.NetCurrentAssetValue/fundamental.SharesOutstanding;
else valuation.NetCurrentAssetValuePerShare=double.NaN;
valuation.DebtToEquity=fundamental.DebtToEquity;
// **************************************************************************************************************************************************
valuation.MarketCap=fundamental.MarketCap;
valuation.EnterpriseValue=fundamental.EnterpriseValue;
valuation.EBIT=fundamental.EBIT;
// ******************************************************* T H E L I T T L E B O O K *******************************************************
// Calculate the earnings yield to be used by TLB rankings (TLB=The Little Book)
// earnings_yield=EBIT/EnterpriseValue
if(!double.IsNaN(fundamental.EBIT)&&!double.IsNaN(fundamental.EnterpriseValue)&&fundamental.EnterpriseValue>0.00&&fundamental.EBIT>0.00)
{
valuation.EarningsYield=fundamental.EBIT/fundamental.EnterpriseValue;
}
else valuation.EarningsYield=double.NaN;
// ******************************************************** T H E A C Q U I R E R S M U L T I P L E ********************************************
if(null!=fundamental&&!double.IsNaN(fundamental.EnterpriseValue)&&null!=cashflowStatement&&!double.IsNaN(cashflowStatement.DepreciationAndAmortization)&&null!=incomeStatement&&!double.IsNaN(incomeStatement.TotalRevenue)&&!double.IsNaN(incomeStatement.CostOfRevenue)&&!double.IsNaN(incomeStatement.SGA))
{
valuation.OperatingEarnings=incomeStatement.TotalRevenue-(cashflowStatement.DepreciationAndAmortization+incomeStatement.CostOfRevenue+incomeStatement.SGA);
valuation.AcquirersMultiple=fundamental.EnterpriseValue/valuation.OperatingEarnings;
}
else
{
valuation.OperatingEarnings=double.NaN;
valuation.AcquirersMultiple=double.NaN;
}
// ******************************************************************** S E C F O R M 1 3 D *********************************************************************************************
SEC13Info sec13Info=SECFilingDA.GetSEC13Info(symbol);
if(sec13Info.SEC13)
{
valuation.SEC13=true;
valuation.SEC13FilingDate=sec13Info.MostRecentFilingDate;
}
// *****************************************************************************************************************************************************************************************
if(null!=companyProfile)
{
valuation.Industry=companyProfile.Industry;
valuation.Sector=companyProfile.Sector;
}
valuation.Company=companyName.Replace(",", "");
valuation.Symbol=symbol;
valuation.NextEarningsDate=fundamental.NextEarningsDate;
valuation.Beta90 = BetaGenerator.Beta(symbol, PricingDA.GetLatestDate(symbol), 3);
valuation.Beta720 = BetaGenerator.Beta(symbol, PricingDA.GetLatestDate(symbol), 24);
if (null != roicSeries && roicSeries.Length > 0)
{
valuation.ROICDates = Utility.FormatDates(roicCollection[roicCollection.Count - 1].AsOf, roicCollection[0].AsOf);
TimeSeriesElement[] roicTimeSeriesElement=(from roicItem in roicCollection select roicItem).OrderBy(roicItem => roicItem.AsOf).ToArray();
double[] orderedROICValues=(from element in roicTimeSeriesElement select element.Value).ToArray();
valuation.ROICSlope = Numerics.Slope(orderedROICValues);
valuation.LatestROIC=roicCollection[0].Value;
}
if (null != revenueSeries && revenueSeries.Length > 0 && null != balanceSheet && !double.IsNaN(balanceSheet.LongTermDebt))
{
double latestRevenue = revenueSeries[0];
valuation.LongTermDebt=balanceSheet.LongTermDebt;
valuation.Revenue=latestRevenue;
if (latestRevenue * 3 > balanceSheet.LongTermDebt) valuation.DebtLoad="Pass";
else valuation.DebtLoad="Fail";
}
else
{
valuation.LongTermDebt=double.NaN;
valuation.Revenue=double.NaN;
valuation.DebtLoad="N/A";
}
valuation.AverageROIC=roic / 100.00;
if (null != bookValuePerShareCollection && 0 != bookValuePerShareCollection.Count)
{
valuation.BVPS = bookValuePerShareCollection[0].Value;
valuation.BVPSDates = Utility.FormatDates(bookValuePerShareCollection[bookValuePerShareCollection.Count - 1].AsOf, bookValuePerShareCollection[0].AsOf);
}
else valuation.BVPSDates = "N/A";
valuation.AverageEquityGrowth=averageGrowth;
valuation.AverageEquityGrowth2Y=averageGrowth2Year;
valuation.AverageEquityGrowth4Y=averageGrowth4Year;
if (null != epsCollection && epsCollection.Count > 0) valuation.EPSDates = Utility.FormatDates(epsCollection[epsCollection.Count - 1].AsOf, epsCollection[0].AsOf);
else valuation.EPSDates="N/A";
valuation.AverageEPSGrowth=epsGrowth;
valuation.AverageEPSGrowth2Y=epsGrowth2Year;
valuation.AverageEPSGrowth4Y=epsGrowth4Year;
if (null != revenueCollection && revenueCollection.Count > 0) valuation.RevenueDates = Utility.FormatDates(revenueCollection[revenueCollection.Count - 1].AsOf, revenueCollection[0].AsOf);
else valuation.RevenueDates="N/A";
valuation.AverageRevenueGrowth=revenueGrowth;
// if (null != fundamental) valuation.AverageRevenueGrowthQtr=fundamental.QtrlyRevenueGrowth / 100.00;
// else valuation.AverageRevenueGrowthQtr=double.NaN;
valuation.AverageRevenueGrowth2Y=revenueGrowth2Year;
valuation.AverageRevenueGrowth4Y=revenueGrowth4Year;
valuation.AverageFreeCashflowGrowth=freeCashflowGrowth;
valuation.AverageOperatingCashflow=averageOperatingCashflow;
valuation.OperatingCashflow=null!=operatingCashflowSeries&&operatingCashflowSeries.Length>0?operatingCashflowSeries[0]:double.NaN;
valuation.AverageWorkingCapital=averageWorkingCapital;
valuation.EPS=fundamental.EPS;
valuation.PE=latestPrice / fundamental.EPS;
valuation.PEG = fundamental.PEG;
if(!double.IsNaN(valuation.BVPS)&&!double.IsNaN(latestPrice))valuation.PBVPS=latestPrice/valuation.BVPS;
if (!double.IsNaN(valuation.PE) && !double.IsNaN(valuation.PEG)) valuation.ImpliedEarningsGrowth = (valuation.PE / valuation.PEG) / 100.00;
StickerPrice stickerPrice = new StickerPrice(symbol,bvpsGrowthOverride);
valuation.BVPSItems = stickerPrice.BVPSItems;
valuation.AverageBVPSGrowth = stickerPrice.AverageBVPSGrowth;
valuation.LowPE=stickerPrice.LowPE;
valuation.TrailingPE=stickerPrice.TrailingPE;
valuation.AverageLowTrailing=stickerPrice.AverageLowTrailing;
valuation.CurrentStockEstimatePrice=stickerPrice.CurrentStockEstimatePrice;
valuation.PriceEstimate10Y=stickerPrice.PriceEstimate10y;
valuation.TodaysPriceForRequiredReturn=stickerPrice.TodaysPriceForRequiredReturn;
valuation.MOS=stickerPrice.MarginOfSafety;
valuation.MOS80=stickerPrice.MarginOfSafety80Pcnt;
valuation.IntrinsicValue=intrinsicValue;
valuation.RGV=intrinsicValue/latestPrice;
valuation.LatestPrice=latestPrice;
if (null != analystPriceTarget)
{
valuation.MeanTargetPrice=analystPriceTarget.MeanTargetPrice;
valuation.LowTargetPrice=analystPriceTarget.LowTargetPrice;
valuation.HighTargetPrice=analystPriceTarget.HighTargetPrice;
}
else
{
valuation.MeanTargetPrice=double.NaN;
valuation.LowTargetPrice=double.NaN;
valuation.HighTargetPrice=double.NaN;
}
valuation.UpsidePcnt = double.IsNaN(valuation.HighTargetPrice)||0>=valuation.HighTargetPrice ? double.NaN : (valuation.HighTargetPrice - valuation.LatestPrice) / valuation.LatestPrice;
valuation.DownsidePcnt=double.IsNaN(valuation.LowTargetPrice)||0>=valuation.LowTargetPrice?double.NaN:(valuation.LowTargetPrice-valuation.LatestPrice)/valuation.LatestPrice;
valuation.Bargain=latestPrice < stickerPrice.MarginOfSafety ? true : false;
valuation.Bargain80=latestPrice < stickerPrice.MarginOfSafety80Pcnt ? true : false;
return valuation;
}
catch (Exception exception)
{
MDTrace.WriteLine(LogLevel.DEBUG,"Error calculating sticker for '" + symbol + "', exception was " + exception.ToString());
return null;
}
}
public static String ToString(Valuation valuation)
{
StringBuilder sb = new StringBuilder();
sb.Append(valuation.Company).Append(",");
sb.Append(valuation.Symbol).Append(",");
sb.Append(Utility.DateTimeToStringMMHDDHYYYY(valuation.NextEarningsDate)).Append(",");
sb.Append(Utility.FormatNumber(valuation.LongTermDebt)).Append(",");
sb.Append(Utility.FormatNumber(valuation.Revenue)).Append(",");
sb.Append(valuation.DebtLoad).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageROIC)).Append(",");
sb.Append(valuation.BVPSDates).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageEquityGrowth)).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageEquityGrowth2Y)).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageEquityGrowth4Y)).Append(",");
sb.Append(valuation.EPSDates).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageEPSGrowth)).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageEPSGrowth2Y)).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageEPSGrowth4Y)).Append(",");
sb.Append(valuation.RevenueDates).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageRevenueGrowth)).Append(",");
// sb.Append(valuation.AverageRevenueGrowthQtr).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageRevenueGrowth2Y)).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageRevenueGrowth4Y)).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageFreeCashflowGrowth)).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageOperatingCashflow)).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageWorkingCapital)).Append(",");
sb.Append(Utility.FormatNumber(valuation.BVPS)).Append(",");
sb.Append(Utility.FormatNumber(valuation.EPS)).Append(",");
sb.Append(Utility.FormatNumber(valuation.PE)).Append(",");
sb.Append(Utility.FormatNumber(valuation.PEG)).Append(",");
sb.Append(Utility.FormatNumber(valuation.ImpliedEarningsGrowth)).Append(",");
sb.Append(Utility.FormatNumber(valuation.LowPE)).Append(",");
sb.Append(Utility.FormatNumber(valuation.TrailingPE)).Append(",");
sb.Append(Utility.FormatNumber(valuation.AverageLowTrailing)).Append(",");
sb.Append(Utility.FormatNumber(valuation.CurrentStockEstimatePrice)).Append(",");
sb.Append(Utility.FormatNumber(valuation.PriceEstimate10Y)).Append(",");
sb.Append(Utility.FormatNumber(valuation.TodaysPriceForRequiredReturn)).Append(",");
sb.Append(Utility.FormatNumber(valuation.MOS)).Append(",");
sb.Append(Utility.FormatNumber(valuation.MOS80)).Append(",");
sb.Append(Utility.FormatNumber(valuation.IntrinsicValue)).Append(",");
sb.Append(Utility.FormatNumber(valuation.RGV)).Append(",");
sb.Append(Utility.FormatNumber(valuation.LatestPrice)).Append(",");
sb.Append(Utility.FormatNumber(valuation.UpsidePcnt)).Append(",");
sb.Append(Utility.FormatNumber(valuation.DownsidePcnt)).Append(",");
sb.Append(Utility.FormatNumber(valuation.MeanTargetPrice)).Append(",");
sb.Append(Utility.FormatNumber(valuation.LowTargetPrice)).Append(",");
sb.Append(Utility.FormatNumber(valuation.HighTargetPrice)).Append(",");
sb.Append(valuation.Bargain ? true : false).Append(",");
sb.Append(valuation.Bargain80 ? true : false).Append(",");
sb.Append(Utility.FormatNumber(valuation.DividendYield));
return sb.ToString();
}
public static String Heading()
{
StringBuilder sb = new StringBuilder();
sb.Append("Company,Symbol,NextEarningDate,LongTermDebt,Revenue,DebtLoad,ROIC(Avg%),BVPSDates,AvgEquityGrowth(AvgBVPS%),AvgEquityGrowth_2Y(AvgBVPS%),AvgEquityGrowth_4Y(AvgBVPS%),EPSDates,EPSGrowth(Avg%),EPSGrowth_2Y(Avg%),EPSGrowth_4Y(Avg%),RevenueDates,RevenueGrowth(Avg%),RevenueGrowth_QTR(Avg%),RevenueGrowth_2Y(Avg%),RevenueGrowth_4Y(Avg%),FreeCashflowGrowth(Avg%),OperatingCashflow(Avg),WorkingCapital(Avg),BVPS,EPS,PE,PEG,ImpliedEarningsGrowth,LowPE,TrailingPE,AverageLowTrailing,CurrentStockEstimatePrice,PriceEstimate10y,TodaysPriceForRequiredReturn,MOS,MOS(80%),IntrinsicValue,RGV(sb>1),LatestPrice,UpsidePcnt,DownsidePcnt,MeanTargetPrice,LowTargetPrice,HighPrice,Bargain(MOS),Bargain(MOS80%),DividendYield");
return sb.ToString();
}
}
}