示例#1
0
 def test_add(self):
     s = BusinessDate('20011110')
     e = BusinessDate('20011112')
     self.assertEqual(BusinessDate.add_days(s, e.day),
                      BusinessDate('20011122'))
     self.assertEqual(BusinessDate.add_months(s, 1),
                      BusinessDate('20011210'))
     self.assertEqual(BusinessDate.add_years(s, 1),
                      BusinessDate('20021110'))
示例#2
0
 def test_add(self):
     s = BusinessDate('20011110')
     e = BusinessDate('20011112')
     self.assertEqual(BusinessDate.add_days(s, e.day), BusinessDate('20011122'))
     self.assertEqual(BusinessDate.add_months(s, 1), BusinessDate('20011210'))
     self.assertEqual(BusinessDate.add_years(s, 1), BusinessDate('20021110'))
示例#3
0
class BusinessDateUnitTests(unittest.TestCase):
    def setUp(self):
        self.dec31 = BusinessDate(20151231)
        self.jan01 = BusinessDate(20160101)
        self.jan02 = BusinessDate(20160102)
        self.jan04 = BusinessDate(20160104)
        self.jan29 = BusinessDate(20160129)
        self.jan31 = BusinessDate(20160131)
        self.feb01 = BusinessDate(20160201)
        self.feb28 = BusinessDate(20160228)
        self.feb29 = BusinessDate(20160229)
        self.mar31 = BusinessDate(20160331)
        self.jun30 = BusinessDate(20160630)
        self.sep30 = BusinessDate(20160930)

        self.dates = [self.dec31, self.jan01, self.jan02, self.jan04, self.jan29, self.jan31,
                      self.feb01, self.feb28, self.feb29, self.mar31, self.jun30, self.sep30]

    def test_constructors(self):
        self.assertEqual(BusinessDate(date.today()), BusinessDate())
        self.assertEqual(self.jan02, BusinessDate('2016-01-02'))
        self.assertEqual(self.jan02, BusinessDate('01/02/2016'))
        self.assertEqual(self.jan02, BusinessDate('02.01.2016'))
        self.assertEqual(self.jan02, BusinessDate(42371))
        self.assertEqual(self.jan02, BusinessDate(42371.0))
        self.assertEqual(self.jan02, BusinessDate(735965))
        self.assertEqual(self.jan02, BusinessDate(735965.0))
        self.assertEqual([self.jan01, self.jan02], BusinessDate([20160101, 42371]))

    def test_to_string(self):
        self.assertEqual(self.jan02.to_string(), '20160102')
        self.assertEqual(BusinessDate(42371).to_string(), '20160102')

    def test_properties(self):
        self.assertEqual(self.jan01.day, 01)
        self.assertEqual(self.jan01.month, 01)
        self.assertEqual(self.jan01.year, 2016)

    def test_operators(self):
        self.assertEqual(self.jan01 + '2D', self.jan02 + '1D')
        self.assertEqual(self.jan01 - '1D', self.jan02 - '2D')
        self.assertEqual(self.jan02 - '1D' + '1M', self.feb01)
        self.assertRaises(TypeError, lambda: '1D' + self.jan02)
        self.assertEqual(self.jan01 - BusinessPeriod('1D'), self.jan02 - '2D')
        self.assertRaises(TypeError, lambda: BusinessPeriod('1D') + self.jan02)
        self.assertRaises(TypeError, lambda: BusinessPeriod('1D') - self.jan01)
        self.assertEqual(self.dec31.add_period(BusinessPeriod('2B', BusinessHolidays())),
                         self.dec31.add_period(BusinessPeriod('2B'), BusinessHolidays([self.jan02])))

    def test_validations(self):
        self.assertTrue(BusinessDate.is_businessdate(18991229))
        self.assertTrue(BusinessDate.is_businessdate(20160131))
        self.assertTrue(BusinessDate.is_businessdate(20160228))
        self.assertTrue(BusinessDate.is_businessdate(20160229))
        self.assertFalse(BusinessDate.is_businessdate(20160230))
        self.assertFalse(BusinessDate.is_businessdate(20160231))
        self.assertTrue(BusinessDate.is_businessdate(20150228))
        self.assertFalse(BusinessDate.is_businessdate(20150229))
        self.assertFalse(BusinessDate.is_businessdate('xyz'))
        self.assertFalse(BusinessDate.is_businessdate(-125))
        self.assertFalse(BusinessDate.is_businessdate(-20150228))

    def test_calculations(self):
        self.assertEqual(self.jan01.add_days(1), self.jan02)
        self.assertEqual(self.jan01.add_months(1), self.feb01)
        self.assertEqual(self.jan01.add_years(1).to_string(), '20170101')
        self.assertEqual(self.jan01.add_period('2D'), self.jan02 + BusinessPeriod('1D'))
        self.assertEqual(self.jan02.add_period('-2D'), self.jan01 - BusinessPeriod('1D'))
        self.assertEqual(self.jan02.add_period('-1b'), self.jan01 - BusinessPeriod('1b'))
        self.assertNotEqual(BusinessDate(20160630).add_period(BusinessPeriod('2B')),
                            BusinessDate(20160630).add_period(BusinessPeriod('2B', BusinessHolidays(['20160704']))))
        self.assertEqual(self.jan01 + '1b', self.jan02 + '1b')

    def test_cast_to(self):
        self.assertTrue(isinstance(self.jan01.to_date(), date))
        self.assertTrue(isinstance(self.jan01.to_businessdate(), BusinessDate))
        self.assertTrue(isinstance(self.jan01.to_businessperiod(), BusinessPeriod))
        self.assertTrue(isinstance(self.jan01.to_excel(), int))
        self.assertTrue(isinstance(self.jan01.to_ordinal(), int))
        self.assertTrue(isinstance(self.jan01.to_string(), str))
        self.assertTrue(isinstance(self.jan01.to_ymd(), tuple))

    def test_cast_from(self):
        for d in self.dates:
            self.assertEqual(BusinessDate.from_date(d.to_date()), d)
            self.assertEqual(BusinessDate.from_businessdate(d), d)
            self.assertEqual(BusinessDate.from_excel(d.to_excel()), d)
            self.assertEqual(BusinessDate.from_ordinal(d.to_ordinal()), d)
            self.assertEqual(BusinessDate.from_string(d.to_string()), d)
            self.assertEqual(BusinessDate.from_ymd(*d.to_ymd()), d)

    def test_day_count(self):  # The daycount methods are also tested separately
        delta = float((self.mar31.to_date() - self.jan01.to_date()).days)
        total = float(((self.jan01 + '1y').to_date() - self.jan01.to_date()).days)
        self.assertAlmostEqual(self.jan01.get_30_360(self.mar31), 90. / 360.)
        self.assertAlmostEqual(self.jan01.get_act_360(self.mar31), delta / 360.)
        self.assertAlmostEqual(self.jan01.get_act_365(self.mar31), delta / 365.)
        self.assertAlmostEqual(self.jan01.get_act_36525(self.mar31), delta / 365.25)
        self.assertAlmostEqual(self.jan01.get_act_act(self.mar31), delta / total)

    def test_business_day_adjustment(self):
        self.assertEqual(self.jan01.adjust_follow(), BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust_mod_follow(), BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust_previous(), BusinessDate(20151231))
        self.assertEqual(self.jan01.adjust_mod_previous(), BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust_start_of_month(), BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust_end_of_month(), BusinessDate(20160129))
        self.assertEqual(self.jan01.adjust_imm(), BusinessDate(20160115))
        self.assertEqual(self.jan01.adjust_cds_imm(), BusinessDate(20160120))

    def test_business_day_is(self):
        self.assertFalse(self.jan01.is_business_day())
        self.assertTrue(BusinessDate.is_leap_year(2016))
        self.assertTrue(BusinessDate.is_businessdate('20160101'))
        self.assertFalse(BusinessDate.is_businessdate('ABC'))
        self.assertFalse(BusinessDate.is_businessdate('20160230'))
        self.assertTrue(BusinessDate.is_businessdate('20160229'))
        self.assertFalse(BusinessDate.is_businessdate('20150229'))

    def test_is_business_date(self):
        d = self.dec31
        holi = BusinessHolidays()
        bdate = BusinessDate.from_ymd(2016, 1, 1)
        is_bday_empty_calendar = bdate.is_business_day(holi)
        self.assertTrue(is_bday_empty_calendar)
        is_bday_default_calendar = bdate.is_business_day()
        self.assertFalse(is_bday_default_calendar)

        target_a= BusinessDate.from_ymd(2016, 1, 4)
        a = d.add_business_days(2, holi)
        self.assertEqual(target_a, a)
        target_b = BusinessDate.from_ymd(2016, 1, 5)
        b = d.add_business_days(2) # default holidays contains the target days, i.e. the 1.1.2016
        self.assertEqual(target_b, b)
示例#4
0
class BusinessDateUnitTests(unittest.TestCase):
    def setUp(self):
        self.dec31 = BusinessDate(20151231)
        self.jan01 = BusinessDate(20160101)
        self.jan02 = BusinessDate(20160102)
        self.jan04 = BusinessDate(20160104)
        self.jan29 = BusinessDate(20160129)
        self.jan31 = BusinessDate(20160131)
        self.feb01 = BusinessDate(20160201)
        self.feb28 = BusinessDate(20160228)
        self.feb29 = BusinessDate(20160229)
        self.mar31 = BusinessDate(20160331)
        self.jun30 = BusinessDate(20160630)
        self.sep30 = BusinessDate(20160930)

        self.dates = [
            self.dec31, self.jan01, self.jan02, self.jan04, self.jan29,
            self.jan31, self.feb01, self.feb28, self.feb29, self.mar31,
            self.jun30, self.sep30
        ]

    def test_constructors(self):
        self.assertEqual(BusinessDate(date.today()), BusinessDate())
        self.assertEqual(self.jan02, BusinessDate('2016-01-02'))
        self.assertEqual(self.jan02, BusinessDate('01/02/2016'))
        self.assertEqual(self.jan02, BusinessDate('02.01.2016'))
        self.assertEqual(self.jan02, BusinessDate(42371))
        self.assertEqual(self.jan02, BusinessDate(42371.0))
        self.assertEqual(self.jan02, BusinessDate(735965))
        self.assertEqual(self.jan02, BusinessDate(735965.0))
        self.assertEqual([self.jan01, self.jan02],
                         BusinessDate([20160101, 42371]))

    def test_to_string(self):
        self.assertEqual(self.jan02.to_string(), '20160102')
        self.assertEqual(BusinessDate(42371).to_string(), '20160102')

    def test_properties(self):
        self.assertEqual(self.jan01.day, 1)
        self.assertEqual(self.jan01.month, 1)
        self.assertEqual(self.jan01.year, 2016)

    def test_operators(self):
        self.assertEqual(self.jan01 + '2D', self.jan02 + '1D')
        self.assertEqual(self.jan01 - '1D', self.jan02 - '2D')
        self.assertEqual(self.jan02 - '1D' + '1M', self.feb01)
        self.assertRaises(TypeError, lambda: '1D' + self.jan02)
        self.assertEqual(self.jan01 - BusinessPeriod('1D'), self.jan02 - '2D')
        self.assertRaises(TypeError, lambda: BusinessPeriod('1D') + self.jan02)
        self.assertRaises(TypeError, lambda: BusinessPeriod('1D') - self.jan01)
        self.assertEqual(
            self.dec31.add_period(BusinessPeriod('2B', BusinessHolidays())),
            self.dec31.add_period(BusinessPeriod('2B'),
                                  BusinessHolidays([self.jan02])))

    def test_validations(self):
        self.assertTrue(BusinessDate.is_businessdate(18991229))
        self.assertTrue(BusinessDate.is_businessdate(20160131))
        self.assertTrue(BusinessDate.is_businessdate(20160228))
        self.assertTrue(BusinessDate.is_businessdate(20160229))
        self.assertFalse(BusinessDate.is_businessdate(20160230))
        self.assertFalse(BusinessDate.is_businessdate(20160231))
        self.assertTrue(BusinessDate.is_businessdate(20150228))
        self.assertFalse(BusinessDate.is_businessdate(20150229))
        self.assertFalse(BusinessDate.is_businessdate('xyz'))
        self.assertFalse(BusinessDate.is_businessdate(-125))
        self.assertFalse(BusinessDate.is_businessdate(-20150228))

    def test_calculations(self):
        self.assertEqual(self.jan01.add_days(1), self.jan02)
        self.assertEqual(self.jan01.add_months(1), self.feb01)
        self.assertEqual(self.jan01.add_years(1).to_string(), '20170101')
        self.assertEqual(self.jan01.add_period('2D'),
                         self.jan02 + BusinessPeriod('1D'))
        self.assertEqual(self.jan02.add_period('-2D'),
                         self.jan01 - BusinessPeriod('1D'))
        self.assertEqual(self.jan02.add_period('-1b'),
                         self.jan01 - BusinessPeriod('1b'))
        self.assertNotEqual(
            BusinessDate(20160630).add_period(BusinessPeriod('2B')),
            BusinessDate(20160630).add_period(
                BusinessPeriod('2B', BusinessHolidays(['20160704']))))
        self.assertEqual(self.jan01 + '1b', self.jan02 + '1b')

        rng = list(range(1, 10))
        periods = list()
        for y in rng:
            for m in rng:
                for d in rng:
                    periods.append(
                        BusinessPeriod(
                            str(y) + 'y' + str(m) + 'm' + str(d) + 'd'))

        for d in self.dates:
            for p in periods:
                c = d + p
                self.assertEqual((c - d), BusinessPeriod(p), (c, d, c - d, p))

        d = BusinessDate(20160229)
        self.assertEqual(d + '1y' + '1m', BusinessDate(20170328))
        self.assertEqual(d + '1m' + '1y', BusinessDate(20170329))
        self.assertEqual(d + '1y1m', BusinessDate(20170329))

    def test_cast_to(self):
        self.assertTrue(isinstance(self.jan01.to_date(), date))
        self.assertTrue(isinstance(self.jan01.to_businessdate(), BusinessDate))
        self.assertTrue(
            isinstance(self.jan01.to_businessperiod(), BusinessPeriod))
        self.assertTrue(isinstance(self.jan01.to_excel(), int))
        self.assertTrue(isinstance(self.jan01.to_ordinal(), int))
        self.assertTrue(isinstance(self.jan01.to_string(), str))
        self.assertTrue(isinstance(self.jan01.to_ymd(), tuple))

    def test_cast_from(self):
        for d in self.dates:
            self.assertEqual(BusinessDate.from_date(d.to_date()), d)
            self.assertEqual(BusinessDate.from_businessdate(d), d)
            self.assertEqual(BusinessDate.from_excel(d.to_excel()), d)
            self.assertEqual(BusinessDate.from_ordinal(d.to_ordinal()), d)
            self.assertEqual(BusinessDate.from_string(d.to_string()), d)
            self.assertEqual(BusinessDate.from_ymd(*d.to_ymd()), d)

    def test_day_count(
            self):  # The daycount methods are also tested separately
        delta = float((self.mar31.to_date() - self.jan01.to_date()).days)
        total = float(
            ((self.jan01 + '1y').to_date() - self.jan01.to_date()).days)
        self.assertAlmostEqual(self.jan01.get_30_360(self.mar31), 90. / 360.)
        self.assertAlmostEqual(self.jan01.get_act_360(self.mar31),
                               delta / 360.)
        self.assertAlmostEqual(self.jan01.get_act_365(self.mar31),
                               delta / 365.)
        self.assertAlmostEqual(self.jan01.get_act_36525(self.mar31),
                               delta / 365.25)
        self.assertAlmostEqual(self.jan01.get_act_act(self.mar31),
                               delta / total)

    def test_business_day_adjustment(self):
        self.assertEqual(self.jan01.adjust_follow(), BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust_mod_follow(),
                         BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust_previous(), BusinessDate(20151231))
        self.assertEqual(self.jan01.adjust_mod_previous(),
                         BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust_start_of_month(),
                         BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust_end_of_month(),
                         BusinessDate(20160129))
        self.assertEqual(self.jan01.adjust_imm(), BusinessDate(20160115))
        self.assertEqual(self.jan01.adjust_cds_imm(), BusinessDate(20160120))

    def test_business_day_is(self):
        self.assertFalse(self.jan01.is_business_day())
        self.assertTrue(BusinessDate.is_leap_year(2016))
        self.assertTrue(BusinessDate.is_businessdate('20160101'))
        self.assertFalse(BusinessDate.is_businessdate('ABC'))
        self.assertFalse(BusinessDate.is_businessdate('20160230'))
        self.assertTrue(BusinessDate.is_businessdate('20160229'))
        self.assertFalse(BusinessDate.is_businessdate('20150229'))

    def test_is_business_date(self):
        d = self.dec31
        holi = BusinessHolidays()
        bdate = BusinessDate.from_ymd(2016, 1, 1)
        is_bday_empty_calendar = bdate.is_business_day(holi)
        self.assertTrue(is_bday_empty_calendar)
        is_bday_default_calendar = bdate.is_business_day()
        self.assertFalse(is_bday_default_calendar)

        target_a = BusinessDate.from_ymd(2016, 1, 4)
        a = d.add_business_days(2, holi)
        self.assertEqual(target_a, a)
        target_b = BusinessDate.from_ymd(2016, 1, 5)
        b = d.add_business_days(
            2)  # default holidays contains the target days, i.e. the 1.1.2016
        self.assertEqual(target_b, b)
示例#5
0
class CashFlow(PayOffInterface, Product):
    """ representation of a single cash flow with all the necessary dates and the index for calculation of the rate """
    @property
    def rate_index(self):
        """ float rate index of cash flow """
        return self._rate_index_

    @property
    def start_date(self):
        """ start date of accrual period """
        return self._start_date_

    @property
    def end_date(self):
        """ end date of accrual period """
        return self._end_date_

    @property
    def reset_date(self):
        """ reset date , i.e. fixing date, of cash flow index """
        return self._reset_date_

    @property
    def pay_date(self):
        """ cash flow pay date """
        return self._pay_date_

    @property
    def year_fraction(self):
        """ year fraction of accrual period """
        return self._year_fraction_

    @property
    def is_pay(self):
        """ True if leg pays, False if leg receives """
        return self._notional_ < 0.

    @property
    def is_rec(self):
        """ False if leg pays, True if leg receives """
        return not self.is_pay

    @property
    def is_fix(self):
        """ True if CashFlow has non zero ConstantRate """
        return True if self._constant_rate_ else False

    @property
    def is_float(self):
        """ True if CashFlow has zero ConstantRate """
        return not self.is_fix

    def __init__(self, object_name_str=''):
        super(CashFlow, self).__init__(object_name_str)

        # index property
        self._rate_index_ = CashRateIndex()

        # rate calc properties
        self._start_date_ = BusinessDate()
        self._end_date_ = BusinessDate.add_period(self._start_date_,
                                                  self._rate_index_.tenor)

        self._accrued_day_count_ = Act360()
        self._year_fraction_ = self._accrued_day_count_.get_year_fraction(
            self._start_date_, self._end_date_)

        self._reset_date_ = self._start_date_ - self._rate_index_._spot_
        self._pay_date_ = BusinessDate.add_period(self._end_date_,
                                                  self._rate_index_._spot_)

        # payoff properties
        self._spread_ = 0.00
        self._constant_rate_ = 0.0
        self._amount_ = 0.00
        self._multiplier_ = 1.00
        self._cap_ = NO_CAP_VALUE
        self._floor_ = NO_FLOOR_VALUE

        self._rebuild_object()

    def _rebuild_object(self):
        # check which dates etc are not modified members -> rebuild them
        if '_reset_date_' not in self._modified_members:
            self._reset_date_ = self._start_date_ - self._rate_index_._spot_

        if '_end_date_' not in self._modified_members:
            if '_year_fraction_' in self._modified_members:
                yf = self._year_fraction_
                e = self._start_date_.add_days(int(yf * 365.25))
                my_yf = self._accrued_day_count_.get_year_fraction(
                    self._start_date_, e)
                while yf < my_yf:
                    e -= '1d'
                    my_yf = self._accrued_day_count_.get_year_fraction(
                        self._start_date_, e)
                while yf > my_yf:
                    e += '1d'
                    my_yf = self._accrued_day_count_.get_year_fraction(
                        self._start_date_, e)
                self._end_date_ = e
            else:
                self._end_date_ = BusinessDate.add_period(
                    self._start_date_, self._rate_index_.tenor)
                self._end_date_ = self._rate_index_._rolling_method_.adjust(
                    self._end_date_)

        if '_pay_date_' not in self._modified_members:
            self._pay_date_ = BusinessDate.add_period(self._end_date_,
                                                      self._rate_index_._spot_)
            self._pay_date_ = self._rate_index_._rolling_method_.adjust(
                self._pay_date_)

        if '_year_fraction_' not in self._modified_members:
            self._year_fraction_ = self._accrued_day_count_.get_year_fraction(
                self._start_date_, self._end_date_)

        # validate
        if '_year_fraction_' in self._modified_members and '_end_date_' in self._modified_members:
            yf = self._accrued_day_count_.get_year_fraction(
                self._start_date_, self._end_date_)
            # if not float_equal(yf, self._year_fraction_, 0.00000001):
            if not abs(yf - self._year_fraction_) < 0.00000001:
                s = self.__class__.__name__
                # raise ValueError('If %s.YearFraction and %s.EndDate is given they must meet.' % (s, s))

        if self._end_date_ < self._start_date_:
            s = self.__class__.__name__, self._end_date_, self.__class__.__name__, self._start_date_
            raise ValueError(
                '%s.EndDate (%s) must scheduled after %s.StartDate (%s).' % s)

        if self._year_fraction_ > 0 and self._pay_date_ <= self._reset_date_:
            s = self.__class__.__name__, self._pay_date_, self.__class__.__name__, self._reset_date_
            raise ValueError(
                '%s.PayDate (%s) must scheduled after %s.SetDate (%s).' % s)

        return self

    def get_expected_payoff(self,
                            value_date=BusinessDate(),
                            index_model_dict={}):
        """ calculates expected payoff at paydate

        :param BusinessDate value_date:
        :param IndexModel index_model_dict:
        :return: float, the pv of the cash flow
        """
        idx_model = index_model_dict.get(self._rate_index_.object_name,
                                         self._rate_index_.index_model)
        rate = 0.0
        is_fix_rate = True
        is_fixed_cash_flow = False
        fwd = None
        fixing_value = None
        time = None
        vol = None
        effective_floor_strike = None
        effective_cap_strike = None
        pay_rec = 1.0 if self.is_rec else -1.0
        payoff = 0.0
        rate_ccy = self.currency

        if self._pay_date_ > value_date:
            if self._constant_rate_:
                rate += self._constant_rate_
            else:
                is_fix_rate = False  # fixme: be consistent, use is_fixed_flow?
                rate_ccy = self._rate_index_.currency

                if self._rate_index_.has_fixing(self._reset_date_):
                    is_fixed_cash_flow = True
                    fixing_value = self._rate_index_.get_fixing(
                        self._reset_date_)
                    rate = fixing_value
                else:
                    fwd = idx_model.get_value(self._rate_index_,
                                              self._reset_date_,
                                              self._pay_date_)
                    rate = fwd

                if self._floor_ != NO_FLOOR_VALUE:
                    effective_floor_strike = (
                        self._floor_ - self._spread_) / self._multiplier_
                    if not is_fixed_cash_flow:
                        value, vol, time, fwd = idx_model.get_option_payoff_value(
                            self._rate_index_, Put(), effective_floor_strike,
                            self._reset_date_)
                    else:
                        value = max(effective_floor_strike - rate, 0)
                    rate += value

                if self._cap_ != NO_CAP_VALUE:
                    effective_cap_strike = (self._cap_ -
                                            self._spread_) / self._multiplier_
                    if not is_fixed_cash_flow:
                        value, vol, time, fwd = idx_model.get_option_payoff_value(
                            self._rate_index_, Call(), effective_cap_strike,
                            self._reset_date_)
                    else:
                        value = max(rate - effective_cap_strike, 0)
                    rate -= value

                rate *= self._multiplier_
                rate += self._spread_

            fx_index = self._get_fx_index(self.currency)
            fx = fx_index.get_value(value_date) if fx_index else 1.0

            payoff = fx * rate * self._year_fraction_ * self._notional_ + self._amount_

        Record(pay_rec="REC" if pay_rec == 1.0 else "PAY",
               year_fraction=self.year_fraction,
               cf_name=self.object_name,
               notional=self._notional_,
               currency=self.currency,
               rate_ccy=rate_ccy,
               is_fix_rate=is_fix_rate,
               forward=fwd,
               is_fixed_cash_flow=is_fixed_cash_flow,
               fixing_value=fixing_value,
               vol=vol,
               expiry_time=time,
               spread=self._spread_,
               reset_date=self._reset_date_,
               start_date=self._start_date_,
               end_date=self._end_date_,
               pay_date=self._pay_date_,
               constant_rate=self._constant_rate_,
               amount=self._amount_,
               effective_floor_strike=effective_floor_strike,
               effective_cap_strike=effective_cap_strike,
               index=self._rate_index_.object_name,
               expected_payoff=payoff,
               floor=None if self._floor_ == NO_FLOOR_VALUE else self._floor_,
               cap=None if self._cap_ == NO_CAP_VALUE else self._cap_)  # pylint: disable=unexpected-keyword-arg

        return payoff

    @Record.Prefix()
    def get_present_value(self,
                          value_date=BusinessDate(),
                          index_model_dict={}):
        """
        :param BusinessDate value_date:
        :param IndexModel index_model_dict:
        :return: float, the pv of the cash flow
        """
        payoff = self.get_expected_payoff(value_date, index_model_dict)
        df_index = self._get_discount_index(self.currency)

        pv_let = self._get_discounted_value(value_date, payoff, df_index)
        return pv_let