77 lines
5.1 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|