예제 #1
0
    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()
예제 #2
0
    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
예제 #3
0
파일: test.py 프로젝트: pbmst/businessdate
class BusinessHolidayUnitTests(unittest.TestCase):
    def setUp(self):
        self.bd = BusinessDate(19730226)
        self.list = [str(i) + '0301' for i in range(1973, 2016)]

    def test_holiday(self):
        h = BusinessHolidays(self.list)
        for l in self.list:
            self.assertTrue(BusinessDate(l) in h)
        self.assertNotEqual(self.bd.add_period('3b', h), self.bd.add_period('3b'))
예제 #4
0
class BusinessHolidayUnitTests(unittest.TestCase):
    def setUp(self):
        self.bd = BusinessDate(19730226)
        self.list = [str(i) + '0301' for i in range(1973, 2016)]

    def test_holiday(self):
        h = BusinessHolidays(self.list)
        for l in self.list:
            self.assertTrue(BusinessDate(l) in h)
        self.assertNotEqual(self.bd.add_period('3b', h),
                            self.bd.add_period('3b'))
예제 #5
0
파일: test.py 프로젝트: pbmst/businessdate
 def test_wrapper_methods(self):
     p = BusinessPeriod(years=1, months=1, days=1)
     self.assertEqual(p.add_years(p.years).add_months(p.months).add_days(p.days),
                      BusinessPeriod(years=2, months=2, days=2))
     self.assertEqual(p * 2, BusinessPeriod(years=4, months=4, days=4))
     self.assertEqual(BusinessDate.add_period(BusinessDate('20160110'), BusinessPeriod(days=-1)),
                      BusinessDate('20160109'))
예제 #6
0
 def test_wrapper_methods(self):
     p = BusinessPeriod(years=1, months=1, days=1)
     self.assertEqual(
         p.add_years(p.years).add_months(p.months).add_days(p.days),
         BusinessPeriod(years=2, months=2, days=2))
     self.assertEqual(p * 2, BusinessPeriod(years=4, months=4, days=4))
     self.assertEqual(
         BusinessDate.add_period(BusinessDate('20160110'),
                                 BusinessPeriod(days=-1)),
         BusinessDate('20160109'))
예제 #7
0
    def __init__(self, object_name_str=''):
        """
        list of the cash flows in this leg,
        reconstructed in _rebuild_object with every change of an object attribute
        """
        super(CashFlowLeg, self).__init__(object_name_str)
        # cash flow list property (new for CashFlowList)
        self._cashflow_list_ = CashFlowList()

        # index property (same for CashFlow)
        self._rate_index_ = CashRateIndex()

        # payoff properties (new for CashFlowLeg)
        self._pay_rec_ = "Pay" if self._notional_ >= 0. else "Rec"

        # schedule properties (same for CashFlow)
        self._start_date_ = BusinessDate()

        # self.SetDate  replaced by ResetOffset
        self._end_date_ = BusinessDate.add_period(self._start_date_,
                                                  self.rate_index.tenor)
        # self._pay_date_  replaced by PayOffset

        # roll properties (new for CashFlowLeg)
        self._rolling_date_ = self._end_date_
        self._rolling_frequency_ = self.rate_index.tenor
        self._rolling_method_ = ModFollow()
        self._rolling_calendar_ = TAR()

        self._reset_offset_ = self.rate_index._spot_
        self._reset_method_ = self._rolling_method_
        self._reset_calendar_ = self._rolling_calendar_

        self._pay_offset_ = BusinessPeriod(businessdays=0)
        self._pay_method_ = self._rolling_method_
        self._pay_calendar_ = self._rolling_calendar_

        # payoff properties (same for CashFlow)
        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._accrued_day_count_ = Act360()
        # self.YearFraction  calculated in CashFlow

        self._rebuild_object()
예제 #8
0
파일: test.py 프로젝트: pbmst/businessdate
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)
예제 #9
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)
예제 #10
0
 def __init__(self, object_name_str=''):
     super(Payment, self).__init__(object_name_str)
     self._pay_date_ = BusinessDate.add_period(self.origin, '3M')
예제 #11
0
class BusinessDateUnitTests(unittest.TestCase):
    def setUp(self):
        self.jan29_15 = BusinessDate(20150129)
        self.feb28_15 = BusinessDate(20150228)
        self.dec31_15 = 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.jan29_15, self.feb28_15, self.dec31_15, self.jan01,
            self.jan02, self.jan04, self.jan29, self.jan31, self.feb01,
            self.feb28, self.feb29, self.mar31, self.jun30, self.sep30
        ]

    def test_base_date(self):
        BusinessDate.BASE_DATE = '20160606'
        self.assertEqual(BusinessDate(), BusinessDate('20160606'))
        BusinessDate.BASE_DATE = None
        self.assertEqual(BusinessDate(), BusinessDate(date.today()))
        BusinessDate.BASE_DATE = date.today()

    def test_parse(self):
        self.assertRaises(ValueError, BusinessDate._parse_date_string,
                          'sdfasd')
        self.assertRaises(ValueError, BusinessDate, 'rtzwrwetzwe')

    def test_constructors(self):
        self.assertEqual(BusinessDate(date.today()), BusinessDate())
        self.assertEqual(BusinessDate(date.today() + timedelta(2)),
                         BusinessDate(timedelta(2)))
        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.jan01, self.jan02],
                         BusinessDate([20160101, 42371]))

    def test_to_string(self):
        self.assertEqual(self.jan02, BusinessDate(str(self.jan02)))
        self.assertEqual(str(self.jan02), '20160102')
        self.assertEqual(repr(self.jan02), "BusinessDate(20160102)")
        self.assertEqual(str(BusinessDate(42371)), '20160102')
        self.assertEqual(self.jan02, eval(repr(self.jan02)))

    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_15.add_period(BusinessPeriod('2B'), BusinessHolidays()),
            self.dec31_15.add_period(BusinessPeriod('2B'),
                                     BusinessHolidays([self.jan02])))

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

        self.assertEqual(d + ['1y', '1m'],
                         [BusinessDate(20170228),
                          BusinessDate(20160329)])
        self.assertEqual(d - ['-1y', '-1m'],
                         [BusinessDate(20170228),
                          BusinessDate(20160329)])

    def test_validations(self):
        # self.assertTrue(BusinessDate.is_businessdate(18991229))
        self.assertTrue(BusinessDate.is_businessdate(19000102))
        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))

        self.assertEqual(365, BusinessDate(20150101).days_in_year())
        self.assertEqual(366, BusinessDate(20160101).days_in_year())
        self.assertEqual(366, BusinessDate(20000101).days_in_year())

        self.assertEqual(31, BusinessDate(20150101).days_in_month())
        self.assertEqual(31, BusinessDate(20160101).days_in_month())
        self.assertEqual(31, BusinessDate(20000101).days_in_month())

        self.assertEqual(28, BusinessDate(20150201).days_in_month())
        self.assertEqual(29, BusinessDate(20160201).days_in_month())
        self.assertEqual(29, BusinessDate(20000201).days_in_month())

        self.assertEqual(BusinessDate(20150131),
                         BusinessDate(20150101).end_of_month())
        self.assertEqual(BusinessDate(20160229),
                         BusinessDate(20160201).end_of_month())
        self.assertEqual(BusinessDate(20000331),
                         BusinessDate(20000311).end_of_month())

        self.assertEqual(BusinessDate(20150331),
                         BusinessDate(20150101).end_of_quarter())
        self.assertEqual(BusinessDate(20160331),
                         BusinessDate(20160201).end_of_quarter())
        self.assertEqual(BusinessDate(20000331),
                         BusinessDate(20000311).end_of_quarter())

        self.assertTrue(BusinessDate(19000102).is_business_day())
        self.assertFalse(BusinessDate(20160101).is_business_day())
        self.assertFalse(BusinessDate(20160131).is_business_day())
        self.assertFalse(BusinessDate(20160228).is_business_day())
        self.assertTrue(BusinessDate(20160324).is_business_day())
        self.assertFalse(BusinessDate(20160325).is_business_day())
        self.assertFalse(BusinessDate(20160326).is_business_day())
        self.assertFalse(BusinessDate(20160327).is_business_day())
        self.assertFalse(BusinessDate(20160328).is_business_day())
        self.assertTrue(BusinessDate(20160329).is_business_day())
        self.assertTrue(BusinessDate(20160330).is_business_day())
        self.assertFalse(BusinessDate(20160501).is_business_day())

    def test_calculations(self):
        self.assertEqual(self.jan01._add_days(1), self.jan02)
        self.assertEqual(self.jan01._add_ymd(0, 1, 0), self.feb01)
        self.assertEqual(str(self.jan01._add_ymd(1, 0, 0)), '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.assertNotEqual(
            BusinessDate(20160630).add_period(BusinessPeriod('2B')),
            BusinessDate(20160630).add_period(
                BusinessPeriod('2B'),
                BusinessHolidays(BusinessDate(['20160704']))))
        n = 111
        a, b = BusinessDate(), BusinessDate() + BusinessPeriod(days=n)
        self.assertEqual(n, a._diff_in_days(b))
        self.assertEqual(-n, b._diff_in_days(a))

        a, b = BusinessDate(20150630), BusinessDate(20150630) + BusinessPeriod(
            years=1, months=27, days=46)
        self.assertEqual(1234, a._diff_in_days(b))
        self.assertEqual(-1234, b._diff_in_days(a))

        self.assertRaises(TypeError, BusinessDate().__add__, 'rtzwrwetzwe')
        self.assertRaises(TypeError, BusinessDate().__sub__, 'rtzwrwetzwe')
        self.assertEqual(self.jan01 + '1b', self.jan02 + '1b')

        d, p = BusinessDate('20160229'), BusinessPeriod('1Y1M1D')
        self.assertEqual((d + p - d), p, (d + p - d, d, p, d + p))
        d, p = BusinessDate('20150129'), BusinessPeriod('1Y2M1D')
        self.assertEqual((d + p - d), p, (d + p - d, d, p, d + p))
        d, p = BusinessDate('20150129'), BusinessPeriod('1Y1M1D')
        self.assertEqual((d + p - d), p, (d + p - d, d, p, d + p))
        # non idepotent pairs
        d, p = BusinessDate('20150129'), BusinessPeriod('1M29D')
        # self.assertEqual((d + p - d), p, (d + p - d, d, p, d + p))
        d, p = BusinessDate('20160129'), BusinessPeriod('1M29D')
        # self.assertEqual((d + p - d), p, (d + p - d, d, p, d + p))

    def test_more_calculations(self):

        periods = list()
        for y in range(5):
            for m in range(13):
                for d in list(range(5)) + list(range(25, 33)) + list(
                        range(58, 66)):
                    periods.append(
                        BusinessPeriod(
                            str(y) + 'y' + str(m) + 'm' + str(d) + 'd'))

        for d in self.dates:
            for p in periods:
                dp = d + p
                q = dp - d
                dq = d + q
                if d.day < 28 and p.days < 28:
                    self.assertEqual(q, p, (q, d, p, dp))

                # only idempotent pairs work always (e.g. above)
                self.assertEqual(dq, dp, (dq, d, p, dp, q))
                self.assertEqual((dq - d), q, (dq - d, d, q, dq))

        a = BusinessDate('20150228')
        for y in range(3):
            for m in range(0, 7, 5):
                for d in range(0, 13, 5):
                    b = a + BusinessPeriod(years=y, months=m, days=d)
                    self.assertEqual(-b._diff_in_days(a), a._diff_in_days(b))

    def test_cast_to(self):
        self.assertTrue(isinstance(self.jan01.to_date(), date))
        self.assertTrue(isinstance(self.jan01, BusinessDate))
        self.assertTrue(isinstance(self.jan01 - BusinessDate(),
                                   BusinessPeriod))
        self.assertTrue(isinstance(self.jan01.to_float(), float))
        # removed ordinal support
        # self.assertTrue(isinstance(self.jan01.to_ordinal(), int))
        self.assertTrue(isinstance(str(self.jan01), str))
        self.assertTrue(isinstance(self.jan01.to_ymd(), tuple))

    def test_cast_from(self):
        for d in self.dates:
            self.assertEqual(BusinessDate(d.to_date()), d)
            self.assertEqual(d.__copy__(), d)
            self.assertEqual(BusinessDate(d.to_float()), d)
            self.assertEqual(BusinessDate(str(d)), d)
            self.assertEqual(BusinessDate(*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(_silent(self.jan01.get_day_count, self.mar31),
                               delta / 365.25)
        self.assertAlmostEqual(
            self.jan01.get_day_count(self.mar31, 'ACT_36525'), delta / 365.25)
        self.assertAlmostEqual(self.jan01.get_day_count(self.mar31, '30_360'),
                               90. / 360.)
        self.assertAlmostEqual(self.jan01.get_day_count(self.mar31, 'ACT_ACT'),
                               delta / total)
        self.assertAlmostEqual(self.jan01.get_day_count(self.mar31, 'ACTACT'),
                               delta / total)

        self.assertAlmostEqual(
            self.jan01.get_year_fraction(self.mar31, '30_360'), 90. / 360.)
        self.assertAlmostEqual(self.jan01.get_day_count(self.mar31, '30e_360'),
                               0.24722222)
        self.assertAlmostEqual(
            self.jan01.get_day_count(self.mar31, '30e_360_i'), 0.247222222)
        self.assertAlmostEqual(self.jan01.get_day_count(self.mar31, 'act_360'),
                               delta / 360.)
        self.assertAlmostEqual(self.jan01.get_day_count(self.mar31, 'act_365'),
                               delta / 365.)
        self.assertAlmostEqual(
            self.jan01.get_day_count(self.mar31, 'act_36525'), delta / 365.25)
        self.assertAlmostEqual(self.jan01.get_day_count(self.mar31, 'act_act'),
                               delta / total)

        self.assertAlmostEqual(self.jan01.get_30_360(self.mar31),
                               self.jan01.get_day_count(self.mar31, '30360'))
        self.assertAlmostEqual(self.jan01.get_30e_360(self.mar31),
                               self.jan01.get_day_count(self.mar31, '30e_360'))
        self.assertAlmostEqual(
            self.jan01.get_30e_360_i(self.mar31),
            self.jan01.get_day_count(self.mar31, '30e_360_i'))
        self.assertAlmostEqual(self.jan01.get_act_360(self.mar31),
                               self.jan01.get_day_count(self.mar31, 'act_360'))
        self.assertAlmostEqual(
            self.jan01.get_act_36525(self.mar31),
            self.jan01.get_day_count(self.mar31, 'act_36525'))
        self.assertAlmostEqual(self.jan01.get_act_act(self.mar31),
                               self.jan01.get_day_count(self.mar31, 'act_act'))

    def test_business_day_adjustment(self):
        self.assertEqual(_silent(self.jan01.adjust), BusinessDate(20160101))
        self.assertEqual(_silent(self.jan01.adjust, ''),
                         BusinessDate(20160101))
        self.assertEqual(self.jan01.adjust('NO'), BusinessDate(20160101))
        self.assertEqual(self.jan01.adjust_no(), BusinessDate(20160101))
        # self.assertEqual(no(self.jan01.to_date(), BusinessDate.DEFAULT_HOLIDAYS), BusinessDate(20160101).to_date())

        self.assertEqual(self.jan01.adjust('FOLLOW'), BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust('FLW'), BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust_follow(), BusinessDate(20160104))
        # self.assertEqual(follow(self.jan01.to_date(), BusinessDate.DEFAULT_HOLIDAYS), BusinessDate(20160104).to_date())

        self.assertEqual(self.jan01.adjust('mod_follow'),
                         BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust('modflw'), BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust_mod_follow(),
                         BusinessDate(20160104))
        # self.assertEqual(modfollow(self.jan01.to_date(), BusinessDate.DEFAULT_HOLIDAYS),
        #                 BusinessDate(20160104).to_date())

        self.assertEqual(self.jan01.adjust('previous'), BusinessDate(20151231))
        self.assertEqual(self.jan01.adjust('prev'), BusinessDate(20151231))
        self.assertEqual(self.jan01.adjust('prv'), BusinessDate(20151231))
        self.assertEqual(self.jan01.adjust_previous(), BusinessDate(20151231))
        # self.assertEqual(previous(self.jan01.to_date(), BusinessDate.DEFAULT_HOLIDAYS),
        #                 BusinessDate(20151231).to_date())

        self.assertEqual(self.jan01.adjust('mod_previous'),
                         BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust('modprev'), BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust('modprv'), BusinessDate(20160104))
        # self.assertEqual(modprevious(self.jan01.to_date(), BusinessDate.DEFAULT_HOLIDAYS),
        #                 BusinessDate(20160104).to_date())

        self.assertEqual(self.jan01.adjust('start_of_month'),
                         BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust('som'), BusinessDate(20160104))
        self.assertEqual(self.jan01.adjust_start_of_month(),
                         BusinessDate(20160104))
        # self.assertEqual(modprevious(self.jan01.to_date(), BusinessDate.DEFAULT_HOLIDAYS),
        #                 BusinessDate(20160104).to_date())

        self.assertEqual(self.jan01.adjust('end_of_month'),
                         BusinessDate(20160129))
        self.assertEqual(self.jan01.adjust('eom'), BusinessDate(20160129))
        self.assertEqual(self.jan01.adjust_end_of_month(),
                         BusinessDate(20160129))
        # self.assertEqual(modprevious(self.jan01.to_date(), BusinessDate.DEFAULT_HOLIDAYS),
        #                 BusinessDate(20160104).to_date())

        self.assertEqual(self.jan01.adjust('imm'), BusinessDate(20160315))
        self.assertEqual(self.jan01.adjust_imm(), BusinessDate(20160315))
        self.assertEqual(
            BusinessDate(20160601).adjust('imm'), BusinessDate(20160616))
        self.assertEqual(
            BusinessDate(20160601).adjust_imm(), BusinessDate(20160616))
        # self.assertEqual(imm(self.jan01.to_date(), BusinessDate.DEFAULT_HOLIDAYS), BusinessDate(20160315).to_date())

        self.assertEqual(self.jan01.adjust('cds_imm'), BusinessDate(20160320))
        self.assertEqual(self.jan01.adjust('cds'), BusinessDate(20160320))
        self.assertEqual(self.jan01.adjust_cds_imm(), BusinessDate(20160320))

    def test_business_day_is(self):
        self.assertFalse(self.jan01.is_business_day())
        self.assertTrue(BusinessDate(2016, 1, 1).is_leap_year())
        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_15
        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)

    def test_from_businesperiod_str(self):
        self.assertEqual(BusinessDate() + '1B', BusinessDate('1B'))
        self.assertEqual(BusinessDate() + '1w', BusinessDate('1w'))
        self.assertEqual(BusinessDate().adjust('mod_follow'),
                         BusinessDate('MODFLW'))
        self.assertEqual(BusinessDate().adjust('mod_follow'),
                         BusinessDate('0BMODFLW'))
        self.assertEqual(
            BusinessDate('20171231').adjust('mod_follow'),
            BusinessDate('0BMODFLW20171231'))
        self.assertEqual(
            BusinessDate('20171231').adjust('mod_follow') + '3D',
            BusinessDate('0B3DMODFOLLOW20171231'))
        self.assertRaises(ValueError, BusinessDate, '0X3D')
        self.assertEqual((BusinessDate('20171231').adjust('mod_follow') +
                          '3D').adjust('mod_follow'),
                         BusinessDate('0B3D0BMODFOLLOW20171231'))
        self.assertEqual(
            BusinessDate('20171231') + '1w', BusinessDate('1w20171231'))
        self.assertEqual((BusinessDate('20171231').adjust('previous') +
                          '3D').adjust('previous'),
                         BusinessDate('0B3D0BPREV20171231'))
        self.assertEqual((BusinessDate('20171231').adjust('previous') +
                          '3D').adjust('previous'),
                         BusinessDate('0B3D0BPREVIOUS20171231'))
        self.assertEqual((BusinessDate('20171231').adjust('mod_follow') +
                          '3D').adjust('mod_follow'),
                         BusinessDate('0B3D0BMODFOLLOW20171231'))
        self.assertEqual((BusinessDate('20171231').adjust('mod_follow') +
                          '3D').adjust('mod_follow'),
                         BusinessDate('0B3D0BMODFLW20171231'))