def make_rate_helper(market, quote, reference_date=None): """ Wrapper for deposit and swaps rate helpers makers TODO: class method of RateHelper? """ rate_type, tenor, quote_value = quote if rate_type == 'SWAP': libor_index = market._floating_rate_index spread = SimpleQuote(0) fwdStart = Period(0, Days) helper = SwapRateHelper.from_tenor( quote_value, Period(tenor), market._floating_rate_index.fixing_calendar, Period(market._params.fixed_leg_period).frequency, BusinessDayConvention.from_name( market._params.fixed_leg_convention), DayCounter.from_name(market._params.fixed_leg_daycount), libor_index, spread, fwdStart) elif rate_type == 'DEP': end_of_month = True helper = DepositRateHelper( quote_value, Period(tenor), market._params.settlement_days, market._floating_rate_index.fixing_calendar, market._floating_rate_index.business_day_convention, end_of_month, DayCounter.from_name(market._deposit_daycount)) elif rate_type == 'ED': if reference_date is None: raise Exception("Reference date needed with ED Futures data") forward_date = next_imm_date(reference_date, tenor) helper = FuturesRateHelper( price=SimpleQuote(quote_value), imm_date=qldate_from_pydate(forward_date), length_in_months=3, calendar=market._floating_rate_index.fixing_calendar, convention=market._floating_rate_index.business_day_convention, end_of_month=True, day_counter=DayCounter.from_name( market._params.floating_leg_daycount)) elif rate_type.startswith('ER'): # TODO For Euribor futures, we found it useful to supply the `imm_date` # parameter directly, instead of as a number of periods from the # evaluation date, as for ED futures. To achieve this, we pass the # `imm_date` in the `tenor` field of the quote. helper = FuturesRateHelper( price=SimpleQuote(quote_value), imm_date=tenor, length_in_months=3, calendar=market._floating_rate_index.fixing_calendar, convention=market._floating_rate_index.business_day_convention, end_of_month=True, day_counter=DayCounter.from_name( market._params.floating_leg_daycount)) else: raise Exception("Rate type %s not supported" % rate_type) return helper
def create_fixed_float_swap(self, settlement_date, length, fixed_rate, floating_spread, **kwargs): """ Create a fixed-for-float swap given: - settlement date - length in years - additional arguments to modify market default parameters """ _params = self._params._replace(**kwargs) index = IborIndex.from_name(self._market, self._forecast_term_structure, **kwargs) swap_type = Payer nominal = 100.0 fixed_convention = \ BusinessDayConvention.from_name(_params.fixed_leg_convention) floating_convention = \ BusinessDayConvention.from_name(_params.floating_leg_convention) fixed_frequency = \ Period(_params.fixed_leg_period) floating_frequency = Period(_params.floating_leg_period) fixed_daycount = DayCounter.from_name(_params.fixed_leg_daycount) float_daycount = DayCounter.from_name(_params.floating_leg_daycount) calendar = calendar_from_name(_params.calendar) maturity = calendar.advance(settlement_date, length, Years, convention=floating_convention) fixed_schedule = Schedule.from_rule(settlement_date, maturity, fixed_frequency, calendar, fixed_convention, fixed_convention, Rule.Forward, False) float_schedule = Schedule.from_rule(settlement_date, maturity, floating_frequency, calendar, floating_convention, floating_convention, Rule.Forward, False) swap = VanillaSwap(swap_type, nominal, fixed_schedule, fixed_rate, fixed_daycount, float_schedule, index, floating_spread, float_daycount, fixed_convention) engine = DiscountingSwapEngine(self._discount_term_structure, False, settlement_date=settlement_date, npv_date=settlement_date) swap.set_pricing_engine(engine) return swap
def create_fixed_float_swap(self, settlement_date, length, fixed_rate, floating_spread, **kwargs): """ Create a fixed-for-float swap given: - settlement date - length in years - additional arguments to modify market default parameters """ _params = self._params._replace(**kwargs) index = IborIndex.from_name(self._market, self._forecast_term_structure, **kwargs) swap_type = Payer nominal = 100.0 fixed_convention = \ BusinessDayConvention.from_name(_params.fixed_leg_convention) floating_convention = \ BusinessDayConvention.from_name(_params.floating_leg_convention) fixed_frequency = \ code_to_frequency(_params.fixed_leg_period) floating_frequency = code_to_frequency(_params.floating_leg_period) fixed_daycount = DayCounter.from_name(_params.fixed_leg_daycount) float_daycount = DayCounter.from_name(_params.floating_leg_daycount) calendar = calendar_from_name(_params.calendar) maturity = calendar.advance(settlement_date, length, Years, convention=floating_convention) fixed_schedule = Schedule(settlement_date, maturity, Period(fixed_frequency), calendar, fixed_convention, fixed_convention, Forward, False) float_schedule = Schedule(settlement_date, maturity, Period(floating_frequency), calendar, floating_convention, floating_convention, Forward, False) swap = VanillaSwap(swap_type, nominal, fixed_schedule, fixed_rate, fixed_daycount, float_schedule, index, floating_spread, float_daycount, fixed_convention) engine = DiscountingSwapEngine(self._discount_term_structure, False, settlementDate=settlement_date, npvDate=settlement_date) swap.set_pricing_engine(engine) return swap
def make_eurobond_helper(market, clean_price, coupons, tenor, issue_date, maturity): """ Wrapper for bond helpers. FIXME: This convenience method has some conventions specifically hardcoded for Eurobonds. These should be moved to the market. """ # Create schedule based on market and bond parameters. index = market._floating_rate_index schedule = Schedule.from_rule( issue_date, maturity, Period(tenor), index.fixing_calendar, index.business_day_convention, index.business_day_convention, Rule.Backward, # Date generation rule index.end_of_month, ) daycounter = DayCounter.from_name("Actual/Actual (Bond)") helper = FixedRateBondHelper( SimpleQuote(clean_price), market._params.settlement_days, 100.0, schedule, coupons, daycounter, Following, # Payment convention 100.0, issue_date) return helper
def test_create_fixed_rate_bond_helper(self): issue_date = Date(20, 3, 2014) maturity = Date(20, 3, 2019) schedule = Schedule( issue_date, maturity, Period(Annual), TARGET(), ModifiedFollowing, ModifiedFollowing, Rule.Backward, False ) clean_price = 71.23 settlement_days = 3 rates = [0.035] daycounter = DayCounter.from_name("Actual/Actual (Bond)") helper = FixedRateBondHelper( SimpleQuote(clean_price), settlement_days, 100.0, schedule, rates, daycounter, Following, 100.0, issue_date) self.assertEqual(helper.quote.value, clean_price)
def test_create_fixed_rate_bond_helper(self): issue_date = Date(20, 3, 2014) maturity = Date(20, 3, 2019) schedule = Schedule( issue_date, maturity, Period(Annual), TARGET(), ModifiedFollowing, ModifiedFollowing, Backward, False ) clean_price = 71.23 settlement_days = 3 rates = [0.035] daycounter = DayCounter.from_name("Actual/Actual (Bond)") helper = FixedRateBondHelper( SimpleQuote(clean_price), settlement_days, 100.0, schedule, rates, daycounter, Following, 100.0, issue_date) self.assertEqual(helper.quote, clean_price)
def bootstrap_term_structure(self, interpolator=LogLinear): tolerance = 1.0e-15 settings = Settings() calendar = JointCalendar(UnitedStates(), UnitedKingdom()) # must be a business day eval_date = self._eval_date settings.evaluation_date = eval_date settlement_days = self._params.settlement_days settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date) ts = PiecewiseYieldCurve[BootstrapTrait.Discount, interpolator].from_reference_date( settlement_date, self._rate_helpers, DayCounter.from_name( self._termstructure_daycount), accuracy=tolerance) self._term_structure = ts self._discount_term_structure = YieldTermStructure() self._discount_term_structure.link_to(ts) self._forecast_term_structure = YieldTermStructure() self._forecast_term_structure.link_to(ts) return ts
def bootstrap_term_structure(self, interpolator=Interpolator.LogLinear): tolerance = 1.0e-15 settings = Settings() calendar = JointCalendar(UnitedStates(), UnitedKingdom()) # must be a business day eval_date = self._eval_date settings.evaluation_date = eval_date settlement_days = self._params.settlement_days settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date) ts = PiecewiseYieldCurve.from_reference_date( BootstrapTrait.Discount, interpolator, settlement_date, self._rate_helpers, DayCounter.from_name(self._termstructure_daycount), tolerance, ) self._term_structure = ts self._discount_term_structure = YieldTermStructure() self._discount_term_structure.link_to(ts) self._forecast_term_structure = YieldTermStructure() self._forecast_term_structure.link_to(ts) return ts
def bootstrap_term_structure(self, interpolator='loglinear'): tolerance = 1.0e-15 settings = Settings() calendar = JointCalendar(UnitedStates(), UnitedKingdom()) # must be a business day eval_date = self._eval_date settings.evaluation_date = eval_date settlement_days = self._params.settlement_days settlement_date = calendar.advance(eval_date, settlement_days, Days) # must be a business day settlement_date = calendar.adjust(settlement_date) ts = PiecewiseYieldCurve( 'discount', interpolator, settlement_date, self._rate_helpers, DayCounter.from_name(self._termstructure_daycount), tolerance) self._term_structure = ts self._discount_term_structure = YieldTermStructure(relinkable=True) self._discount_term_structure.link_to(ts) self._forecast_term_structure = YieldTermStructure(relinkable=True) self._forecast_term_structure.link_to(ts) return ts
def make_eurobond_helper( market, clean_price, coupons, tenor, issue_date, maturity): """ Wrapper for bond helpers. FIXME: This convenience method has some conventions specifically hardcoded for Eurobonds. These should be moved to the market. """ # Create schedule based on market and bond parameters. index = market._floating_rate_index schedule = Schedule( issue_date, maturity, Period(tenor), index.fixing_calendar, index.business_day_convention, index.business_day_convention, Backward, # Date generation rule index.end_of_month, ) daycounter = DayCounter.from_name("Actual/Actual (Bond)") helper = FixedRateBondHelper( SimpleQuote(clean_price), market._params.settlement_days, 100.0, schedule, coupons, daycounter, Following, # Payment convention 100.0, issue_date) return helper
def make_rate_helper(market, quote, reference_date=None): """ Wrapper for deposit and swaps rate helpers makers TODO: class method of RateHelper? """ rate_type, tenor, quote_value = quote if rate_type == 'SWAP': libor_index = market._floating_rate_index spread = SimpleQuote(0) fwdStart = Period(0, Days) helper = SwapRateHelper.from_tenor( quote_value, Period(tenor), market._floating_rate_index.fixing_calendar, code_to_frequency(market._params.fixed_leg_period), BusinessDayConvention.from_name( market._params.fixed_leg_convention), DayCounter.from_name(market._params.fixed_leg_daycount), libor_index, spread, fwdStart) elif rate_type == 'DEP': end_of_month = True helper = DepositRateHelper( quote_value, Period(tenor), market._params.settlement_days, market._floating_rate_index.fixing_calendar, market._floating_rate_index.business_day_convention, end_of_month, DayCounter.from_name(market._deposit_daycount)) elif rate_type == 'ED': if reference_date is None: raise Exception("Reference date needed with ED Futures data") forward_date = next_imm_date(reference_date, tenor) helper = FuturesRateHelper( rate =SimpleQuote(quote_value), imm_date = qldate_from_pydate(forward_date), length_in_months = 3, calendar = market._floating_rate_index.fixing_calendar, convention = market._floating_rate_index.business_day_convention, end_of_month = True, day_counter = DayCounter.from_name( market._params.floating_leg_daycount)) elif rate_type.startswith('ER'): # TODO For Euribor futures, we found it useful to supply the `imm_date` # parameter directly, instead of as a number of periods from the # evaluation date, as for ED futures. To achieve this, we pass the # `imm_date` in the `tenor` field of the quote. helper = FuturesRateHelper( rate=SimpleQuote(quote_value), imm_date=tenor, length_in_months=3, calendar=market._floating_rate_index.fixing_calendar, convention=market._floating_rate_index.business_day_convention, end_of_month=True, day_counter=DayCounter.from_name( market._params.floating_leg_daycount)) else: raise Exception("Rate type %s not supported" % rate_type) return helper