91 lines
3.8 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|