def calculate_zero_rates(evaluation_date, zero_rate, sorted_forward_rates, forward_period_days): forward_days = timedelta(days=forward_period_days) # set first zero_rate to overnight rate zero_rates = [ZeroRatePoint(date=evaluation_date, rate=zero_rate), ] for (prev_zero_pos, forward_point) in enumerate(sorted_forward_rates): prev_zero_rate = zero_rates[prev_zero_pos].rate forward_date = forward_point.forward_date forward_rate = forward_point.forward_rate zero_rate = (forward_rate * years(forward_days) + prev_zero_rate * years(forward_date - evaluation_date)) / years(forward_date + forward_days - evaluation_date) zero_rates.append(ZeroRatePoint(date=forward_date + forward_days, rate=zero_rate)) return zero_rates
def interpolate_zero_rate(evaluation_date, sorted_zero_rates): # find index of first zero_rate with forward_date >= evaluation date # return final zero_rate if no zero_rate satisfies this condition zero_rates = (i for i, zero_rate in enumerate(sorted_zero_rates) if zero_rate.date >= evaluation_date) i2 = next(zero_rates, len(sorted_zero_rates) - 1) if i2 == 0: # if looking for forward rate for today, use overnight zero rate return sorted_zero_rates[0].rate else: # else linearly interpolate between zero_rate points # other zero_rate point specified as the zero_rate point previous to the one specified by i2 i1 = i2 - 1 forward_date_1 = sorted_zero_rates[i1].date zero_rate_1 = sorted_zero_rates[i1].rate forward_date_2 = sorted_zero_rates[i2].date zero_rate_2 = sorted_zero_rates[i2].rate interpolated_zero = zero_rate_1 + years(evaluation_date - forward_date_1) * (zero_rate_2 - zero_rate_1) / years(forward_date_2 - forward_date_1) return interpolated_zero