public decimal CalculateDailyMTD(DailyPnL current, DailyPnL prior) { var convertedPriorDaily = prior.MTDPercentageReturn.Value + 1; var convertedCurrentDaily = current.DailyPercentageReturn.HasValue ? current.DailyPercentageReturn.Value + 1 : 1; return(Math.Round((convertedPriorDaily * convertedCurrentDaily) - 1, 16)); }
public decimal CalculateDailyYTD(DailyPnL current, DailyPnL prior) { var convertedPriorYTD = prior.YTDPercentageReturn.Value + 1; var convertedCurrentMTD = current.MTDPercentageReturn.HasValue ? current.MTDPercentageReturn.Value + 1 : 1; //return (convertedPriorYTD * convertedCurrentMTD) - 1; return(Math.Round((convertedPriorYTD * convertedCurrentMTD) - 1, 16)); }
public bool Run(PostingEngineEnvironment env) { env.CallBack?.Invoke($"{Module} Started"); env.CallBack?.Invoke("Getting Daily Pnl Data"); var performanceRecords = DailyPnL.GetList(env.ConnectionString); env.CallBack?.Invoke($"{Module} Running the calculation"); var dailyPerformanceResult = new DailyPnlCalculator().CalculateDailyPerformance(performanceRecords); var dailyPerformance = dailyPerformanceResult.GetType().GetProperty("payload") ?.GetValue(dailyPerformanceResult, null); bool insertDailyPnl = UpdateDailyPnl((List <DailyPnL>)dailyPerformance, env.ConnectionString); env.CallBack?.Invoke($"{Module} Finished"); return(true); }
/// <summary> /// I already have a populated database, and as a result I should be able to have the system /// recalculate when I finish the EOD / SOD process /// </summary> /// <param name="performanceRecords"></param> /// <returns></returns> public object CalculateDailyPerformance(List <DailyPnL> performanceRecords) { var sorted = performanceRecords.OrderBy(x => x.BusinessDate).ThenBy(x => x.RowId).ToList(); var groupedByPortfolio = sorted.GroupBy(x => x.PortFolio).Select(x => new { Portfolio = x.Key, YearlyData = x.ToList().GroupBy(y => y.BusinessDate.Year).Select(z => new { Year = z.Key, MonthlyData = z.ToList().GroupBy(w => w.BusinessDate.Month) }) }).ToList(); //var groupedByYear = sorted.GroupBy(x => x.PerformanceDate.Year).ToList(); DailyPnL priorData = null; int monthIndex = 0; int totalMonthlyRecords = 0; DailyPnL priorDataYearlyPnl = priorData; DailyPnL priorDataQuarterlyPnl = priorData; DailyPnL priorDataInceptionPnl = priorData; DailyPnL priorDataForQuarter = priorData; DailyPnL priorDataForYear = priorData; DailyPnL priorDataForInception = priorData; Dictionary <int, int> quarterCount = new Dictionary <int, int>(); InitializeQuarterDictionary(quarterCount); foreach (var portfolio in groupedByPortfolio) { foreach (var year in portfolio.YearlyData) { foreach (var month in year.MonthlyData) { totalMonthlyRecords = month.Count() - 1; monthIndex = 0; foreach (var item in month) { if (!item.ExistingRecord) { if (priorData != null) { item.MTDPercentageReturn = CalculateDailyMTD(item, priorData); item.MTDPnL = CalculateDailyPnl(item.Day, priorData.MTDPnL); } else { item.MTDPercentageReturn = item.DailyPercentageReturn; item.MTDPnL = item.Day; } if (priorDataForYear != null) { item.YTDPercentageReturn = CalculateDailyYTD(item, priorDataForYear); } else { item.YTDPercentageReturn = item.MTDPercentageReturn; } if (priorDataForInception != null) { item.ITDPercentageReturn = CalculateDailyITD(item, priorDataForInception); } else { item.ITDPercentageReturn = item.MTDPercentageReturn; } if (priorDataForQuarter != null) { if (CheckForBeginningOfQuarter(item.BusinessDate)) { item.QTDPercentageReturn = item.MTDPercentageReturn; } else { if (IfDatesLieInTheSameQuarter(priorDataForQuarter.BusinessDate, item.BusinessDate)) { item.QTDPercentageReturn = CalculateDailyQTD(item, priorDataForQuarter); } else { item.QTDPercentageReturn = item.MTDPercentageReturn; } } } else { item.QTDPercentageReturn = item.MTDPercentageReturn; } //Calculations for QTD,YTD,ITD values. if (priorDataQuarterlyPnl != null) { if (CheckForBeginningOfQuarter(item.BusinessDate)) { item.QTDPnL = item.MTDPnL; } else { item.QTDPnL = CalculateDailyPnl(item.Day, priorDataQuarterlyPnl.QTDPnL); } } else { item.QTDPnL = item.MTDPnL; } if (priorDataYearlyPnl != null) { item.YTDPnL = CalculateDailyPnl(item.Day, priorDataYearlyPnl.YTDPnL); } else { item.YTDPnL = item.MTDPnL; } if (priorDataInceptionPnl != null) { item.ITDPnL = CalculateDailyPnl(item.Day, priorDataInceptionPnl.ITDPnL); } else { item.ITDPnL = item.MTDPnL; } } priorData = item; priorDataQuarterlyPnl = item; priorDataYearlyPnl = item; priorDataInceptionPnl = item; //We have reached the end of the month. At this point, the calculated value of MTD represents MTD returns for that month. //We will use this value of MTD as reference for QTD,YTD,ITD percentage/returns calculation. if (monthIndex == totalMonthlyRecords) { priorDataForYear = item; priorDataForQuarter = item; priorDataForInception = item; } monthIndex++; } priorData = null; } priorDataForYear = null; priorDataYearlyPnl = null; priorDataQuarterlyPnl = null; priorDataForQuarter = null; } priorDataForInception = null; priorDataForQuarter = null; priorDataInceptionPnl = null; priorDataQuarterlyPnl = null; } return(Utils.Wrap(true, sorted, HttpStatusCode.OK, "Performance calculated successfully")); }
public void pnl(int reqId, double dailyPnL, double unrealizedPnL, double realizedPnL) { DailyPnL.RaiseEvent(this, new DailyPnLEventArgs(reqId, dailyPnL, unrealizedPnL, realizedPnL)); }