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");
            }
        }