Files
marketdata/MarketDataLib/Generator/DividendHistoryGenerator.cs
2024-02-22 14:52:53 -05:00

115 lines
6.7 KiB
C#

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});
// DividendHistory dividendHistory=DividendHistoryDA.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;
}
}
}
}