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

77 lines
5.1 KiB
C#

using MarketData.DataAccess;
using MarketData.MarketDataModel;
using MarketData.Utils;
using MarketData.Generator;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MarketData.DividendRiskParity
{
public class DividendRiskParityGenerator
{
public static DividendRiskParityResult GenerateDividendRiskParity(Price currentPrice, double aum, DividendRiskParityPositionCollection dividendRiskParityCollection)
{
DateGenerator dateGenerator = new DateGenerator();
DividendRiskParityResult dividendRiskParityResult = new DividendRiskParityResult();
if (null == dividendRiskParityCollection || 0 == dividendRiskParityCollection.Count) return null;
CalculateWeightsAndExposures(currentPrice, dividendRiskParityCollection);
CalculateDividendYield(dividendRiskParityCollection,currentPrice);
double totalExposure = dividendRiskParityCollection.Sum(x => x.Exposure);
double totalWeightedDividendPercent = dividendRiskParityCollection.Sum(x => x.WeightedDividendPercent);
double totalGainLoss = dividendRiskParityCollection.Sum(x => x.GainLoss);
dividendRiskParityResult.Symbol = dividendRiskParityCollection.Take(1).FirstOrDefault().Symbol;
dividendRiskParityResult.CostBasis = totalExposure / dividendRiskParityCollection.Sum(x => x.Shares);
dividendRiskParityResult.Aum = aum;
dividendRiskParityResult.AllocationPercent = ((totalExposure) / aum) * 100.00;
dividendRiskParityResult.AnnualDividend = totalExposure * (totalWeightedDividendPercent / 100.00);
if (totalGainLoss < 0.00) dividendRiskParityResult.DividendYearsToParity = Math.Abs(totalGainLoss) / dividendRiskParityResult.AnnualDividend;
else dividendRiskParityResult.DividendYearsToParity = double.NaN;
dividendRiskParityResult.DaysSinceLastTraded = Math.Abs(dateGenerator.DaysBetweenActual(dividendRiskParityCollection.Where(x => !x.TypeOfPosition.Equals(DividendRiskParityPosition.PositionType.Proforma)).Max(x => x.TradeDate), currentPrice.Date));
dividendRiskParityResult.CurrentPrice = currentPrice;
dividendRiskParityResult.CurrentDividendPercent = DividendHistoryGenerator.GetDividendYield(dividendRiskParityResult.Symbol, currentPrice) * 100.00;
DividendRiskParityPosition proformaPosition = dividendRiskParityCollection.Where(x => x.TypeOfPosition.Equals(DividendRiskParityPosition.PositionType.Proforma)).FirstOrDefault();
if (null != proformaPosition) dividendRiskParityResult.AdditionalDividendPerYer = (dividendRiskParityResult.CurrentDividendPercent / 100) * proformaPosition.Exposure;
dividendRiskParityResult.ParityPrice = EquilibriumGenerator.GenerateEquilibriumPrice(dividendRiskParityCollection, currentPrice);
dividendRiskParityResult.ParityPercent = ((currentPrice.Close - dividendRiskParityResult.ParityPrice.Close) / dividendRiskParityResult.ParityPrice.Close) * 100.00;
dividendRiskParityResult.YieldPercent=(dividendRiskParityResult.AnnualDividend/totalExposure)*100.00;
return dividendRiskParityResult;
}
private static void CalculateWeightsAndExposures(Price currentPrice, DividendRiskParityPositionCollection dividendRiskParityCollection)
{
foreach (DividendRiskParityPosition dividendRiskParityPosition in dividendRiskParityCollection)
{
dividendRiskParityPosition.CurrentPrice=currentPrice.Close;
dividendRiskParityPosition.Exposure = dividendRiskParityPosition.PurchasePrice * dividendRiskParityPosition.Shares;
dividendRiskParityPosition.GainLoss = (dividendRiskParityPosition.Shares * currentPrice.Close) - dividendRiskParityPosition.Exposure;
dividendRiskParityPosition.GainLossPercent=(((dividendRiskParityPosition.Shares * currentPrice.Close)-dividendRiskParityPosition.Exposure)/dividendRiskParityPosition.Exposure);
}
double totalExposure = dividendRiskParityCollection.Sum(x => x.Exposure);
foreach (DividendRiskParityPosition dividendRiskParityPosition in dividendRiskParityCollection)
{
dividendRiskParityPosition.Weight = dividendRiskParityPosition.Exposure / totalExposure;
}
}
private static void CalculateDividendYield(DividendRiskParityPositionCollection dividendRiskParityCollection,Price currentPrice)
{
double totalExposure = dividendRiskParityCollection.Sum(x => x.Exposure);
double weightAdjustedYield = double.NaN;
foreach (DividendRiskParityPosition dividendRiskParityPosition in dividendRiskParityCollection)
{
Price price = new Price();
price.Close = dividendRiskParityPosition.PurchasePrice;
price.Date = DateTime.Now;
double dividendYield=DividendHistoryGenerator.GetDividendYield(dividendRiskParityPosition.Symbol,price);
if (double.IsNaN(dividendYield)) continue;
if (double.IsNaN(weightAdjustedYield)) weightAdjustedYield = 0.00;
dividendRiskParityPosition.WeightedDividendPercent = (dividendYield * ((dividendRiskParityPosition.Exposure / totalExposure)))*100.00;
dividendRiskParityPosition.DividendPayment = dividendYield * dividendRiskParityPosition.Exposure;
}
}
}
}