public static double tradeVolLinearInterp(Date valuationDate, double tradeOpenVol, double tradeCloseVol, Date startDate, Date maturityDate, int numOfSmoothingDays, DayCountMode dayCountMode, ICalendar calendar) { Date smoothingEndDate; double T, t; switch (dayCountMode) { case DayCountMode.CalendarDay: smoothingEndDate = startDate.AddDays(numOfSmoothingDays); if (smoothingEndDate > maturityDate) { smoothingEndDate = maturityDate; } T = smoothingEndDate - startDate; t = valuationDate - startDate; break; default: smoothingEndDate = calendar.AddBizDays(startDate, numOfSmoothingDays); if (smoothingEndDate > maturityDate) { smoothingEndDate = maturityDate; } Date valuationTradingDate = calendar.IsBizDay(valuationDate) ? valuationDate : calendar.PrevBizDay(valuationDate); T = calendar.BizDaysBetweenDatesExcluStartDay(startDate, smoothingEndDate).Count; t = calendar.BizDaysBetweenDatesExcluStartDay(startDate, valuationTradingDate).Count; break; } if (valuationDate >= smoothingEndDate) { return(tradeCloseVol); } if (valuationDate < smoothingEndDate & valuationDate >= startDate) { double slope = (tradeCloseVol - tradeOpenVol) / T; return(tradeOpenVol + slope * t); } else { throw new PricingBaseException("AnalyticalOptionTradeVolInterp error: valuationDate < startDate"); } }
private void TradeVolLinearInterpSlopeCalc(double tradeOpenVol, double tradeCloseVol, DayCountMode dayCountMode = DayCountMode.TradingDay) { var startDate = new Date(2018, 3, 21); var maturityDate = new Date(2018, 5, 21); var valuationDate = new Date[] { new Date(2018, 3, 22), new Date(2018, 3, 23), new Date(2018, 3, 26) }; var numOfSmoothingDays = 30; var calendar = CalendarImpl.Get("chn"); double vol1 = AnalyticalOptionTradeVolInterp.tradeVolLinearInterp(valuationDate[0], tradeOpenVol, tradeCloseVol, startDate, maturityDate, numOfSmoothingDays, dayCountMode, calendar); double vol2 = AnalyticalOptionTradeVolInterp.tradeVolLinearInterp(valuationDate[1], tradeOpenVol, tradeCloseVol, startDate, maturityDate, numOfSmoothingDays, dayCountMode, calendar); double vol3 = AnalyticalOptionTradeVolInterp.tradeVolLinearInterp(valuationDate[2], tradeOpenVol, tradeCloseVol, startDate, maturityDate, numOfSmoothingDays, dayCountMode, calendar); Assert.AreEqual(vol2 - vol1, vol3 - vol2, 1e-10); }
private void TradeVolLinearInterpCalc(double expectedValue, Date valuationDate, double tradeOpenVol, double tradeCloseVol, DayCountMode dayCountMode) { var startDate = new Date(2018, 3, 21); var maturityDate = new Date(2018, 5, 21); var numOfSmoothingDays = 30; var calendar = CalendarImpl.Get("chn"); double vol = AnalyticalOptionTradeVolInterp.tradeVolLinearInterp(valuationDate, tradeOpenVol, tradeCloseVol, startDate, maturityDate, numOfSmoothingDays, dayCountMode, calendar); Assert.AreEqual(expectedValue, vol, 1e-10); }