date dateUtil::dayRollAdjust(date aDate,DayRollEnum aDayRollConvention, enums::CurrencyEnum market) { long adjustedJDN; switch(aDayRollConvention){ case enums::Following: adjustedJDN = getFolloingJDN(aDate, market); break; case enums::Preceding: adjustedJDN = getPrecedingJDN(aDate, market); break; case enums::Mfollowing: adjustedJDN = getFolloingJDN(aDate, market); if (getYearMonthDay(adjustedJDN)[1]!=aDate.getMonth()) adjustedJDN = getPrecedingJDN(aDate, market); break; case enums::Mfollowingbi: adjustedJDN = getFolloingJDN(aDate, market); if (getYearMonthDay(adjustedJDN)[1]!=aDate.getMonth()|| getYearMonthDay(adjustedJDN)[2]>=15) adjustedJDN = getPrecedingJDN(aDate, market); break; case enums::EOM: break; case enums::DayRollNull: adjustedJDN = aDate.getJudianDayNumber(); break; } date adjustedDate(adjustedJDN); return adjustedDate; }
long dateUtil::getFolloingJDN(date refDate, enums::CurrencyEnum market){ //date adjustedDate = adjustInvalidateDate(refDate,true); long JDN = refDate.getJudianDayNumber(); while(!isBizDay(JDN) || isHoliday(JDN,market)){ JDN++; } return JDN; }
long dateUtil::getPrecedingJDN(date refDate, enums::MarketEnum market){ //date adjustedDate = adjustInvalidateDate(refDate,false); long JDN = refDate.getJudianDayNumber(); while(!isBizDay(JDN) || isHoliday(JDN,market)){ JDN--; } return JDN; }
date dateUtil::getBizDateOffSet(date refDate, long offset, enums::CurrencyEnum market) { long JDN = refDate.getJudianDayNumber(); bool forward = offset>=0?true:false; for (long i=0; i<abs(offset); i++){ forward?JDN++:JDN--; while(!isBizDay(JDN) || isHoliday(JDN,market)){ forward?JDN++:JDN--; } } date offsetDate(JDN); return offsetDate; }
date dateUtil::getEndDate(date startDate, int increment, enums::DayRollEnum dayRoll, enums::MarketEnum market, DateUnit dateUnit){ date endDate; switch(dateUnit){ case YEAR: endDate = date(startDate.getYear()+increment,startDate.getMonth(), startDate.getDay()); break; case MONTH: endDate = getEndDateMonthIncrement(startDate, increment); break; case WEEK: endDate = date(startDate.getJudianDayNumber()+increment*7); break; case DAY: endDate = date(startDate.getJudianDayNumber()+increment); break; case BIZDAY: endDate = getBizDateOffSet(startDate,increment, market); break; } endDate = dayRollAdjust(adjustInvalidateDate(endDate,false),dayRoll, market); return endDate; }
double dateUtil::getAccrualFactor(date startDate,date endDate, enums::DayCountEnum dayCount){ double accrualFactor; int numBizDay=0; switch(dayCount){ case enums::thirty_360US: //This day count convention is also called Bond basis. if (endDate.getDay()==31 && (startDate.getDay()==30||31)) endDate.setDay(30); if (startDate.getDay()==31) startDate.setDay(30); accrualFactor = thirty_360(startDate, endDate); break; case enums::thirthE_360: if (startDate.getDay()==31) startDate.setDay(30); if (endDate.getDay()==31) endDate.setDay(30); accrualFactor = thirty_360(startDate, endDate); break; case enums::ACT_360: //This day count is also called Money Market basis or Actual 360 //This is the most used day count convention for money market instruments (maturity below one year). accrualFactor = (endDate.getJudianDayNumber()-startDate.getJudianDayNumber())/360.0; //cout<<"inside ACT_360"<<endl; break; case enums::ACT_365: //Also called English Money Market basis. //The number 365 is used even in a leap year. accrualFactor = (endDate.getJudianDayNumber()-startDate.getJudianDayNumber())/365.0; //cout<<"inside ACT_365"<<endl; break; case enums::ACT_ACT: throw "Need reference start and end date!"; break; case enums::BUS_252: //Numerator is the number of business days (in a given calendar) from and including the start date up to and excluding the end date. numBizDay=0; for(long i = startDate.getJudianDayNumber();i<endDate.getJudianDayNumber();i++) if (isBizDay(i)) numBizDay++; accrualFactor = numBizDay/252.0; break; default: accrualFactor = (endDate.getJudianDayNumber()-startDate.getJudianDayNumber())/360.0; } return accrualFactor; }
bool dateUtil::isHoliday(date aDate, enums::CurrencyEnum market){ return isHoliday(aDate.getJudianDayNumber(),market); }
bool dateUtil::isBizDay(date date0){ return isBizDay(date0.getJudianDayNumber()); }
signed long dateUtil::getBizDaysBetween(date startDate, date endDate){ return getBizDaysBetween (startDate.getJudianDayNumber(),endDate.getJudianDayNumber()); }
long dateUtil::getDaysBetween(date startDate, date endDate){ return getDaysBetween (endDate.getJudianDayNumber(),startDate.getJudianDayNumber()); }