113 lines
6.7 KiB
C#
Executable File
113 lines
6.7 KiB
C#
Executable File
using MarketData.Cache;
|
|
using MarketData.DataAccess;
|
|
using MarketData.MarketDataModel;
|
|
using MarketData.Utils;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace MarketData.Generator
|
|
{
|
|
public class DividendHistoryGenerator
|
|
{
|
|
private DividendHistoryGenerator()
|
|
{
|
|
}
|
|
public static double GetDividendYield(String symbol)
|
|
{
|
|
try
|
|
{
|
|
Price currentPrice=PricingDA.GetPrice(symbol);
|
|
return GetDividendYield(symbol,currentPrice);
|
|
}
|
|
catch(Exception exception)
|
|
{
|
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("{0}",exception.ToString()));
|
|
return double.NaN;
|
|
}
|
|
}
|
|
public static double GetDividendYield(String symbol,Price currentPrice)
|
|
{
|
|
try
|
|
{
|
|
int currentYear=DateTime.Now.Year;
|
|
int priorYear=currentYear-1;
|
|
|
|
DividendHistory dividendHistory=DividendHistoryCache.GetInstance().GetDividendHistory(symbol,new int[]{currentYear, priorYear});
|
|
if(null==currentPrice||double.IsNaN(currentPrice.Close)||!currentPrice.Date.Year.Equals(currentYear)) return double.NaN;
|
|
DividendHistory lastYearsDividendPayments=new DividendHistory((from DividendHistoryItem item in dividendHistory where item.DivExDate.Year==priorYear&&null!=item.CashAmount select item).ToList());
|
|
DividendHistory currentYearsDividendPayments=new DividendHistory((from DividendHistoryItem item in dividendHistory where item.DivExDate.Year==currentYear&&null!=item.CashAmount select item).ToList());
|
|
if(currentYearsDividendPayments.HasConsecutivePayments(3)) return (currentYearsDividendPayments.Average(x => x.CashAmount.Value)*12)/currentPrice.Close;
|
|
if(0==lastYearsDividendPayments.Count&&0==currentYearsDividendPayments.Count) return double.NaN;
|
|
double lastYearsAverageDividendPayment=lastYearsDividendPayments.Count()>1?lastYearsDividendPayments.Average(x => x.CashAmount.Value):double.NaN;
|
|
|
|
// calculate last years min and max dividend payments in order to determine if there were special payments
|
|
double lastYearMinDividendPayment=lastYearsDividendPayments.Count>0?lastYearsDividendPayments.Min(x => x.CashAmount.Value):0.00;
|
|
DividendHistory lastYearsSpecialPayments=lastYearsDividendPayments.Count>0?new DividendHistory((from DividendHistoryItem item in lastYearsDividendPayments where item.CashAmount.Value>3*lastYearMinDividendPayment select item).ToList()):new DividendHistory();
|
|
bool lastYearHasSpecialItems=lastYearsSpecialPayments.Count()>0?true:false;
|
|
|
|
if(0==currentYearsDividendPayments.Count) // if no dividends in current year then go back to last year
|
|
{
|
|
if(lastYearHasSpecialItems) lastYearsDividendPayments=new DividendHistory(lastYearsDividendPayments.Where(x => !lastYearsSpecialPayments.Any(z => z.DivExDate==x.DivExDate)).ToList());
|
|
else if(1==lastYearsDividendPayments.Count) return lastYearsDividendPayments[0].CashAmount.Value/currentPrice.Close;
|
|
return lastYearsDividendPayments.Sum(x => x.CashAmount.Value)/currentPrice.Close;
|
|
}
|
|
double currentYearMaxDividendPayment=currentYearsDividendPayments.Max(x => x.CashAmount.Value);
|
|
double currentYearMinDividendPayment=currentYearsDividendPayments.Min(x => x.CashAmount.Value);
|
|
DividendHistory currentYearsSpecialPayments=new DividendHistory((from DividendHistoryItem item in currentYearsDividendPayments where item.CashAmount.Value>3*currentYearMinDividendPayment select item).ToList());
|
|
bool currentYearhasSpecialItems=currentYearsSpecialPayments.Count()>0?true:false;
|
|
double currentYearsAverageDividendPayment=currentYearsDividendPayments.Average(x => x.CashAmount.Value);
|
|
if(1==lastYearsDividendPayments.Count&&1==currentYearsDividendPayments.Count) return currentYearsAverageDividendPayment/currentPrice.Close;
|
|
if(0==lastYearsDividendPayments.Count) // there was no dividend payment last year. check if this years is a special dividend (>25%)
|
|
{
|
|
double dividendPayment=currentYearsDividendPayments.Average(x => x.CashAmount.Value);
|
|
double dividendYield=dividendPayment/currentPrice.Close;
|
|
if(dividendYield>=.25) return dividendYield;
|
|
}
|
|
if(4==lastYearsDividendPayments.Count)
|
|
{
|
|
if(currentYearhasSpecialItems) // exclude special payments from consideration
|
|
{
|
|
currentYearsDividendPayments=new DividendHistory(currentYearsDividendPayments.Where(x => !currentYearsSpecialPayments.Any(z => z.DivExDate==x.DivExDate)).ToList());
|
|
double dividendYield=currentYearsDividendPayments.Average(x => x.CashAmount.Value);
|
|
dividendYield*=4.00;
|
|
dividendYield/=currentPrice.Close;
|
|
return dividendYield;
|
|
}
|
|
if(1==currentYearsDividendPayments.Count&&lastYearHasSpecialItems) // if only one payment this year and last year has a special payment then use last year minus special payment
|
|
{
|
|
lastYearsDividendPayments=new DividendHistory(lastYearsDividendPayments.Where(x => !lastYearsSpecialPayments.Any(z => z.DivExDate==x.DivExDate)).ToList());
|
|
double dividendYield=lastYearsDividendPayments.Average(x => x.CashAmount.Value);
|
|
dividendYield*=4.00;
|
|
dividendYield/=currentPrice.Close;
|
|
return dividendYield;
|
|
}
|
|
return (currentYearsAverageDividendPayment*4.00)/currentPrice.Close;
|
|
}
|
|
if(3==currentYearsDividendPayments.Count)
|
|
{
|
|
if(currentYearhasSpecialItems) // exclude special payments from consideration
|
|
{
|
|
currentYearsDividendPayments=new DividendHistory(currentYearsDividendPayments.Where(x => !currentYearsSpecialPayments.Any(z => z.DivExDate==x.DivExDate)).ToList());
|
|
double dividendYield=currentYearsDividendPayments.Average(x => x.CashAmount.Value);
|
|
dividendYield*=4.00;
|
|
dividendYield/=currentPrice.Close;
|
|
return dividendYield;
|
|
}
|
|
else return (currentYearsAverageDividendPayment*4.00)/currentPrice.Close;
|
|
}
|
|
if(2==lastYearsDividendPayments.Count) return Math.Min(lastYearsDividendPayments.Sum(x => x.CashAmount.Value),currentYearsDividendPayments.Sum(x => x.CashAmount.Value))/currentPrice.Close;
|
|
return (currentYearsDividendPayments.Average(x => x.CashAmount.Value)*4.00)/currentPrice.Close;
|
|
}
|
|
catch(Exception exception)
|
|
{
|
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("{0}",exception.ToString()));
|
|
return double.NaN;
|
|
}
|
|
}
|
|
}
|
|
}
|