def test_FinScheduleAlignmentLeapYearNotEOM(): """ Effective date on leap year. Not EOM. """ eomFlag = False valuation_date = Date(26, 2, 2006) effDate = valuation_date.add_tenor("2D") freq_type = FrequencyTypes.SEMI_ANNUAL bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD calendar_type = CalendarTypes.UNITED_STATES adjust_termination_date = True matDate1 = effDate.add_tenor("4Y") matDate2 = effDate.add_tenor("50Y") # print(matDate1, matDate2) sched1 = Schedule(effDate, matDate1, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, adjust_termination_date, eomFlag) sched2 = Schedule(effDate, matDate2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, adjust_termination_date, eomFlag) # print(sched1._adjusted_dates) # print(sched2._adjusted_dates[:len(sched1._adjusted_dates)]) compare = (sched1._adjusted_dates[-1] == sched2._adjusted_dates[ len(sched1._adjusted_dates) - 1]) assert (compare == True)
def test_FinScheduleAlignmentEff31(): """ EOM schedule so all unadjusted dates fall on month end.""" eomFlag = True valuation_date = Date(29, 7, 2006) effDate = valuation_date.add_tenor("2D") freq_type = FrequencyTypes.SEMI_ANNUAL bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD calendar_type = CalendarTypes.UNITED_STATES adjust_termination_date = True matDate1 = effDate.add_tenor("4Y") matDate2 = effDate.add_tenor("50Y") # print(matDate1, matDate2) sched1 = Schedule(effDate, matDate1, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, adjust_termination_date, eomFlag) sched2 = Schedule(effDate, matDate2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, adjust_termination_date, eomFlag) # print(sched1._adjusted_dates) # print(sched2._adjusted_dates[:len(sched1._adjusted_dates)]) compare = (sched1._adjusted_dates[-1] == sched2._adjusted_dates[ len(sched1._adjusted_dates) - 1]) assert (compare == True)
def test_backward_front_stub(): # BACKWARD SHORT STUB AT FRONT d1 = Date(20, 8, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.QUARTERLY calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) adjusted_dates = schedule._adjusted_dates assert len(adjusted_dates) == 9 check_frequency(schedule, start=1) # BACKWARD SUPER SHORT STUB AT FRONT d1 = Date(19, 9, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.QUARTERLY calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) adjusted_dates = schedule._adjusted_dates assert len(adjusted_dates) == 9 check_frequency(schedule, start=1)
def test_forward_frequencies(): # FORWARD SCHEDULES TESTING DIFFERENT FREQUENCIES calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.FORWARD d1 = Date(20, 6, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.ANNUAL schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) adjusted_dates = schedule._adjusted_dates assert len(adjusted_dates) == 3 check_frequency(schedule) freq_type = FrequencyTypes.SEMI_ANNUAL schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type) adjusted_dates = schedule._adjusted_dates assert len(adjusted_dates) == 5 check_frequency(schedule) freq_type = FrequencyTypes.MONTHLY schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) adjusted_dates = schedule._adjusted_dates assert len(adjusted_dates) == 25 check_frequency(schedule)
def test_FinDateAdjust(): start_date = Date(28, 2, 2008) end_date = Date(28, 2, 2011) freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.NONE bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD testCases.header("NO ADJUSTMENTS", "DATE") schedule = Schedule(start_date, end_date, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type) for dt in schedule._adjusted_dates: testCases.print("Date:", dt) testCases.banner("") testCases.header("NO WEEKENDS AND FOLLOWING", "DATE") freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD schedule = Schedule(start_date, end_date, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type) for dt in schedule._adjusted_dates: testCases.print("Date:", dt) testCases.banner("") testCases.header("NO WEEKENDS AND MODIFIED FOLLOWING", "DATE") freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD schedule = Schedule(start_date, end_date, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type) for dt in schedule._adjusted_dates: testCases.print("Date:", dt) testCases.banner("") testCases.header("NO WEEKENDS AND US HOLIDAYS AND MODIFIED FOLLOWING", "DATE") freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.UNITED_STATES bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD start_date = Date(4, 7, 2008) end_date = Date(4, 7, 2011) schedule = Schedule(start_date, end_date, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type) for dt in schedule._adjusted_dates: testCases.print("Date:", dt)
def test_FinScheduleAlignment(eomFlag): valuation_date = Date(29, 3, 2005) effDate = valuation_date.add_tenor("2d") freq_type = FrequencyTypes.SEMI_ANNUAL bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD calendar_type = CalendarTypes.UNITED_STATES adjust_termination_date = False matDate1 = effDate.add_tenor("4Y") matDate2 = effDate.add_tenor("50Y") # print(matDate1) # print(matDate2) myCal = Calendar(calendar_type) adjustedMatDate1 = myCal.adjust(matDate1, bus_day_adjust_type) adjustedMatDate2 = myCal.adjust(matDate2, bus_day_adjust_type) # print(adjustedMatDate1) # print(adjustedMatDate2) sched1 = Schedule(effDate, adjustedMatDate1, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, adjust_termination_date, eomFlag) # print(sched1) sched2 = Schedule(effDate, adjustedMatDate2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, adjust_termination_date, eomFlag) compare = ( sched1._adjusted_dates[-1] == sched2._adjusted_dates[len(sched1._adjusted_dates)-1]) assert(compare == eomFlag)
def test_forward_end_stub(): # FORWARD SHORT STUB AT END termination_dateAdjust = True d1 = Date(20, 8, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.FORWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) adjusted_dates = schedule._adjusted_dates assert len(adjusted_dates) == 5 check_frequency(schedule) d1 = Date(19, 9, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.QUARTERLY calendar_type = CalendarTypes.TARGET bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.FORWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type) adjusted_dates = schedule._adjusted_dates assert len(adjusted_dates) == 9 check_frequency(schedule) d1 = Date(20, 6, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD termination_dateAdjust = True schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) adjusted_dates = schedule._adjusted_dates assert len(adjusted_dates) == 5 check_frequency(schedule)
def test_date_adjust_noweekend_usholidays_modfollowing(): start_date = Date(4, 7, 2008) end_date = Date(4, 7, 2011) calendar_type = CalendarTypes.UNITED_STATES bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING schedule = Schedule(start_date, end_date, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type) assert schedule._adjusted_dates == [ Date(4, 7, 2008), Date(5, 1, 2009), Date(6, 7, 2009), Date(4, 1, 2010), Date(6, 7, 2010), Date(4, 1, 2011), Date(5, 7, 2011) ]
def test_date_adjust_noweekend_modfollowing(): start_date = Date(28, 2, 2008) end_date = Date(28, 2, 2011) calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING schedule = Schedule(start_date, end_date, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type) assert schedule._adjusted_dates == [ Date(28, 2, 2008), Date(28, 8, 2008), Date(27, 2, 2009), Date(28, 8, 2009), Date(26, 2, 2010), Date(30, 8, 2010), Date(28, 2, 2011) ]
def test_date_adjust_no_adj(): start_date = Date(28, 2, 2008) end_date = Date(28, 2, 2011) calendar_type = CalendarTypes.NONE bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING schedule = Schedule(start_date, end_date, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type) assert schedule._adjusted_dates == [ Date(28, 2, 2008), Date(28, 8, 2008), Date(28, 2, 2009), Date(28, 8, 2009), Date(28, 2, 2010), Date(28, 8, 2010), Date(28, 2, 2011) ]
def test_FinSchedule(): ########################################################################### # BACKWARD SCHEDULES TESTING DIFFERENT FREQUENCIES ########################################################################### d1 = Date(20, 6, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD termination_dateAdjust = True schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) dumpSchedule("BACKWARD SEMI-ANNUAL FREQUENCY", schedule) d1 = Date(20, 6, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.QUARTERLY calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) dumpSchedule("BACKWARD QUARTERLY FREQUENCY", schedule) d1 = Date(20, 6, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.MONTHLY calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) dumpSchedule("BACKWARD MONTHLY FREQUENCY", schedule) ########################################################################### # FORWARD SCHEDULES TESTING DIFFERENT FREQUENCIES ########################################################################### d1 = Date(20, 6, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.ANNUAL calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.FORWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) dumpSchedule("FORWARD ANNUAL", schedule) d1 = Date(20, 6, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type) dumpSchedule("FORWARD SEMI-ANNUAL", schedule) d1 = Date(20, 6, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.MONTHLY calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) dumpSchedule("FORWARD MONTHLY", schedule) ########################################################################### # BACKWARD SHORT STUB AT FRONT ########################################################################### d1 = Date(20, 8, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.QUARTERLY calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) dumpSchedule("BACKWARD GEN WITH SHORT END STUB", schedule) ########################################################################### # BACKWARD SUPER SHORT STUB AT FRONT ########################################################################### d1 = Date(19, 9, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.QUARTERLY calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) dumpSchedule("BACKWARD GEN WITH VERY SHORT END STUB", schedule) ########################################################################### # FORWARD SHORT STUB AT END ########################################################################### d1 = Date(20, 8, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.FORWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) dumpSchedule("FORWARD GEN WITH END STUB", schedule) d1 = Date(19, 9, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.QUARTERLY calendar_type = CalendarTypes.TARGET bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.FORWARD schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type) dumpSchedule("FORWARD GEN WITH VERY SHORT END STUB", schedule) d1 = Date(20, 6, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD termination_dateAdjust = True schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust) dumpSchedule("TERMINATION DATE ADJUSTED", schedule) d1 = Date(20, 6, 2018) d2 = Date(20, 6, 2020) freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD termination_dateAdjust = True eomFlag = True schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust, eomFlag) dumpSchedule("END OF MONTH - NOT EOM TERM DATE - USING MOD FOLL", schedule) d1 = Date(30, 6, 2018) d2 = Date(30, 6, 2020) freq_type = FrequencyTypes.SEMI_ANNUAL calendar_type = CalendarTypes.WEEKEND bus_day_adjust_type = BusDayAdjustTypes.MODIFIED_FOLLOWING date_gen_rule_type = DateGenRuleTypes.BACKWARD termination_dateAdjust = True eomFlag = True schedule = Schedule(d1, d2, freq_type, calendar_type, bus_day_adjust_type, date_gen_rule_type, termination_dateAdjust, eomFlag) dumpSchedule("END OF MONTH - EOM TERM DATE - USING MOD FOLL", schedule)
def test_FinIborCapFloorVolCurve(): """ Aim here is to price cap and caplets using cap and caplet vols and to demonstrate they are the same - NOT SURE THAT HULLS BOOKS FORMULA WORKS FOR OPTIONS. """ todayDate = Date(20, 6, 2019) valuation_date = todayDate maturity_date = valuation_date.add_tenor("3Y") day_count_type = DayCountTypes.THIRTY_E_360 frequency = FrequencyTypes.ANNUAL k = 0.04 capFloorType = FinCapFloorTypes.CAP capFloor = IborCapFloor(valuation_date, maturity_date, capFloorType, k, None, frequency, day_count_type) capVolDates = Schedule(valuation_date, valuation_date.add_tenor("10Y"), frequency)._generate() flat_rate = 0.04 libor_curve = DiscountCurveFlat(valuation_date, flat_rate, frequency, day_count_type) flat = False if flat is True: capVolatilities = [20.0] * 11 capVolatilities[0] = 0.0 else: capVolatilities = [0.00, 15.50, 18.25, 17.91, 17.74, 17.27, 16.79, 16.30, 16.01, 15.76, 15.54] capVolatilities = np.array(capVolatilities)/100.0 capVolatilities[0] = 0.0 volCurve = IborCapVolCurve(valuation_date, capVolDates, capVolatilities, day_count_type) # print(volCurve._capletGammas) # Value cap using a single flat cap volatility tcap = (maturity_date - valuation_date) / gDaysInYear vol = volCurve.cap_vol(maturity_date) model = Black(vol) valueCap = capFloor.value(valuation_date, libor_curve, model) # print("CAP T", tcap, "VOL:", vol, "VALUE OF CAP:", valueCap) # Value cap by breaking it down into caplets using caplet vols vCaplets = 0.0 capletStartDate = capFloor._capFloorLetDates[1] testCases.header("START", "END", "VOL", "VALUE") for capletEndDate in capFloor._capFloorLetDates[2:]: vol = volCurve.caplet_vol(capletEndDate) modelCaplet = Black(vol) vCaplet = capFloor.value_caplet_floor_let(valuation_date, capletStartDate, capletEndDate, libor_curve, modelCaplet) vCaplets += vCaplet testCases.print("%12s" % capletStartDate, "%s" % capletEndDate, "%9.5f" % (vol*100.0), "%9.5f" % vCaplet) capletStartDate = capletEndDate testCases.header("LABEL", "VALUE") testCases.print("CAPLETS->CAP: ", vCaplets)