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

91 lines
3.8 KiB
C#

using MarketData.DataAccess;
using MarketData.MarketDataModel;
using MarketData.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MarketData.Generator
{
public class RiskFreeRateGenerator
{
private RiskFreeRateGenerator()
{
}
public static Price GeneratePriceAtRiskFreeRate(PortfolioTrades portfolioTrades)
{
Price price=new Price();
double cumulativePortfolioInvestment=0;
if(null==portfolioTrades||0==portfolioTrades.Count) return null;
double totalShares=(from PortfolioTrade portfolioTrade in portfolioTrades select portfolioTrade.Shares).Sum();
List<int> yearsToProcess=GetYearsToProcess(portfolioTrades);
foreach(int processYear in yearsToProcess)
{
cumulativePortfolioInvestment=GetInvestmentForYear(portfolioTrades,processYear,cumulativePortfolioInvestment);
if(double.NaN.Equals(cumulativePortfolioInvestment)) return null;
}
price.Close=price.Open=price.High=price.Low=price.AdjClose=cumulativePortfolioInvestment/totalShares;
price.Date=DateTime.Now;
return price;
}
private static List<int> GetYearsToProcess(PortfolioTrades portfolioTrades)
{
List<int> investmentYears=new List<int>();
int startingYear=portfolioTrades[0].TradeDate.Year;
int endingYear=DateTime.Now.Year;
for(int processYear=startingYear;processYear<=endingYear;processYear++)
{
investmentYears.Add(processYear);
}
return investmentYears;
}
private static double GetInvestmentForYear(PortfolioTrades portfolioTrades,int investmentYear,double initialInvestment)
{
double cumulativeYearInvestment=0;
DateTime yearEnd=new DateTime(investmentYear,12,31);
DateTime startOfYear=new DateTime(investmentYear,1,1);
double riskFreeRate;
PortfolioTrades tradesInYear=new PortfolioTrades((from PortfolioTrade portfolioTrade in portfolioTrades where portfolioTrade.TradeDate.Year.Equals(investmentYear) select portfolioTrade).ToList());
if(0.00!=initialInvestment)
{
riskFreeRate=YieldCurveDA.GetRiskFreeRate1Yr(startOfYear,10);
if(double.NaN.Equals(riskFreeRate)) return double.NaN;
riskFreeRate/=100.00;
double fractionOfYearHeld=1.00;
if(yearEnd>DateTime.Now)
{
fractionOfYearHeld=GetFractionOfYearHeld(DateTime.Now,startOfYear);
cumulativeYearInvestment=initialInvestment*Math.Pow(1.00+riskFreeRate,fractionOfYearHeld);
}
else cumulativeYearInvestment=initialInvestment*Math.Pow(1.00+riskFreeRate,fractionOfYearHeld);
}
foreach(PortfolioTrade portfolioTrade in tradesInYear)
{
riskFreeRate=YieldCurveDA.GetRiskFreeRate1Yr(portfolioTrade.TradeDate,10); // suggestion: move this database call out of the inner loop
if(double.NaN.Equals(riskFreeRate)) return double.NaN;
riskFreeRate/=100.00;
double fractionOfYearHeld=GetFractionOfYearHeld(portfolioTrade,yearEnd);
double tradeInvestment=portfolioTrade.Exposure()*Math.Pow((1.00+riskFreeRate),fractionOfYearHeld);
cumulativeYearInvestment+=tradeInvestment;
}
return cumulativeYearInvestment;
}
private static double GetFractionOfYearHeld(PortfolioTrade portfolioTrade,DateTime yearEnd)
{
DateGenerator dateGenerator=new DateGenerator();
double fractionOfYearHeld=dateGenerator.DaysBetween(portfolioTrade.TradeDate,yearEnd)/365.00;
return fractionOfYearHeld;
}
private static double GetFractionOfYearHeld(DateTime effectiveDate,DateTime yearEnd)
{
DateGenerator dateGenerator=new DateGenerator();
double fractionOfYearHeld=dateGenerator.DaysBetween(effectiveDate,yearEnd)/365.00;
return fractionOfYearHeld;
}
}
}