def test_relinkable_structures(self): discounting_term_structure = YieldTermStructure() settlement_days = 3 flat_term_structure = FlatForward(settlement_days=settlement_days, forward=0.044, calendar=NullCalendar(), daycounter=Actual360()) discounting_term_structure.link_to(flat_term_structure) evaluation_date = Settings().evaluation_date +100 self.assertEqual( flat_term_structure.discount(evaluation_date), discounting_term_structure.discount(evaluation_date) ) another_flat_term_structure = FlatForward(settlement_days=10, forward=0.067, calendar=NullCalendar(), daycounter=Actual365Fixed()) discounting_term_structure.link_to(another_flat_term_structure) self.assertEqual( another_flat_term_structure.discount(evaluation_date), discounting_term_structure.discount(evaluation_date) ) self.assertNotEqual( flat_term_structure.discount(evaluation_date), discounting_term_structure.discount(evaluation_date) )
def test_relinkable_structures(self): discounting_term_structure = YieldTermStructure(relinkable=True) settlement_days = 3 flat_term_structure = FlatForward(settlement_days=settlement_days, forward=0.044, calendar=NullCalendar(), daycounter=Actual360()) discounting_term_structure.link_to(flat_term_structure) evaluation_date = Settings().evaluation_date +100 self.assertEqual( flat_term_structure.discount(evaluation_date), discounting_term_structure.discount(evaluation_date) ) another_flat_term_structure = FlatForward(settlement_days=10, forward=0.067, calendar=NullCalendar(), daycounter=Actual365Fixed()) discounting_term_structure.link_to(another_flat_term_structure) self.assertEqual( another_flat_term_structure.discount(evaluation_date), discounting_term_structure.discount(evaluation_date) ) self.assertNotEqual( flat_term_structure.discount(evaluation_date), discounting_term_structure.discount(evaluation_date) )
class IborMarket(FixedIncomeMarket): def __init__(self, name, market, **kwargs): params = swap_params(market) params = params._replace(**kwargs) self._params = params self._name = name self._market = market # floating rate index index = IborIndex.from_name(market, **kwargs) self._floating_rate_index = index self._deposit_daycount = params.floating_leg_daycount self._termstructure_daycount = 'ACT/365' self._eval_date = None self._quotes = None self._termstructure = None self._discount_term_structure = None self._forecast_term_structure = None self._rate_helpers = [] self._quotes = [] def _set_evaluation_date(self, dt_obs): if not isinstance(dt_obs, Date): dt_obs = pydate_to_qldate(dt_obs) settings = Settings() calendar = JointCalendar(UnitedStates(), UnitedKingdom()) # must be a business day eval_date = calendar.adjust(dt_obs) settings.evaluation_date = eval_date self._eval_date = eval_date return eval_date def set_quotes(self, dt_obs, quotes): self._quotes.extend(quotes) eval_date = self._set_evaluation_date(dt_obs) for quote in quotes: # construct rate helper helper = make_rate_helper(self, quote, eval_date) self._rate_helpers.append(helper) def set_bonds(self, dt_obs, quotes): """ Supply the market with a set of bond quotes. The `quotes` parameter must be a list of quotes of the form (clean_price, coupons, tenor, issue_date, maturity). For more information about the format of the individual fields, see the documentation for :meth:`add_bond_quote`. """ self._quotes.extend(quotes) self._set_evaluation_date(dt_obs) for quote in quotes: self.add_bond_quote(*quote) def add_bond_quote(self, clean_price, coupons, tenor, issue_date, maturity): """ Add a bond quote to the market. Parameters ---------- clean_price : real Clean price of the bond. coupons : real or list(real) Interest rates paid by the bond. tenor : str Tenor of the bond. issue_date, maturity : Date instance Issue date and maturity of the bond. """ if not isinstance(coupons, (list, tuple)): coupons = [coupons] helper = make_eurobond_helper(self, clean_price, coupons, tenor, issue_date, maturity) self._rate_helpers.append(helper) @property def calendar(self): return self._params.calendar @property def settlement_days(self): return self._params.settlement_days @property def fixed_leg_period(self): return self._params.fixed_leg_period @property def fixed_leg_convention(self): return self._params.fixed_leg_convention @property def fixed_leg_daycount(self): return self._params.fixed_leg_daycount @property def termstructure_daycounter(self): return self._termstructure_daycounter @property def reference_date(self): return 0 @property def max_date(self): return 0 def __str__(self): output = \ "Ibor Market %s\n" % self._name + \ "Number of settlement days: %d\n" % self._params.settlement_days +\ "Fixed leg period: %s\n" % self._params.fixed_leg_period +\ "Fixed leg convention: %s\n" % self._params.fixed_leg_convention +\ "Fixed leg daycount: %s\n" % self._params.fixed_leg_daycount +\ "Term structure daycount: %s\n" % self._termstructure_daycount + \ "Floating rate index: %s\n" % self._floating_rate_index + \ "Deposit daycount: %s\n" % self._deposit_daycount + \ "Calendar: %s\n" % self._params.calendar return output 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 discount(self, date_maturity, extrapolate=True): return self._discount_term_structure.discount(date_maturity) 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 test_default_constructor(self): term_structure = YieldTermStructure() with self.assertRaises(ValueError): term_structure.discount(Settings().evaluation_date)
def test_default_constructor(self): term_structure = YieldTermStructure() with self.assertRaises(ValueError): term_structure.discount(Settings().evaluation_date)
class IborMarket(FixedIncomeMarket): def __init__(self, name, market, **kwargs): params = swap_params(market) params = params._replace(**kwargs) self._params = params self._name = name self._market = market # floating rate index index = IborIndex.from_name(market, **kwargs) self._floating_rate_index = index self._deposit_daycount = params.floating_leg_daycount self._termstructure_daycount = 'ACT/365' self._eval_date = None self._quotes = None self._termstructure = None self._discount_term_structure = None self._forecast_term_structure = None self._rate_helpers = [] self._quotes = [] def _set_evaluation_date(self, dt_obs): if not isinstance(dt_obs, Date): dt_obs = pydate_to_qldate(dt_obs) settings = Settings() calendar = JointCalendar(UnitedStates(), UnitedKingdom()) # must be a business day eval_date = calendar.adjust(dt_obs) settings.evaluation_date = eval_date self._eval_date = eval_date return eval_date def set_quotes(self, dt_obs, quotes): self._quotes.extend(quotes) eval_date = self._set_evaluation_date(dt_obs) for quote in quotes: # construct rate helper helper = make_rate_helper(self, quote, eval_date) self._rate_helpers.append(helper) def set_bonds(self, dt_obs, quotes): """ Supply the market with a set of bond quotes. The `quotes` parameter must be a list of quotes of the form (clean_price, coupons, tenor, issue_date, maturity). For more information about the format of the individual fields, see the documentation for :meth:`add_bond_quote`. """ self._quotes.extend(quotes) self._set_evaluation_date(dt_obs) for quote in quotes: self.add_bond_quote(*quote) def add_bond_quote(self, clean_price, coupons, tenor, issue_date, maturity): """ Add a bond quote to the market. Parameters ---------- clean_price : real Clean price of the bond. coupons : real or list(real) Interest rates paid by the bond. tenor : str Tenor of the bond. issue_date, maturity : Date instance Issue date and maturity of the bond. """ if not isinstance(coupons, (list, tuple)): coupons = [coupons] helper = make_eurobond_helper( self, clean_price, coupons, tenor, issue_date, maturity) self._rate_helpers.append(helper) @property def calendar(self): return self._params.calendar @property def settlement_days(self): return self._params.settlement_days @property def fixed_rate_frequency(self): return self._params.fixed_rate_frequency @property def fixed_rate_convention(self): return self._params.fixed_instrument_convention @property def fixed_rate_daycounter(self): return self._params.fixed_rate_daycounter @property def termstructure_daycounter(self): return self._termstructure_daycounter @property def reference_date(self): return 0 @property def max_date(self): return 0 def __str__(self): output = \ "Ibor Market %s\n" % self._name + \ "Number of settlement days: %d\n" % self._params.settlement_days +\ "Fixed rate frequency: %s\n" % self._params.fixed_rate_frequency +\ "Fixed rate convention: %s\n" % self._params.fixed_instrument_convention +\ "Fixed rate daycount: %s\n" % self._params.fixed_instrument_daycounter +\ "Term structure daycount: %s\n" % self._termstructure_daycount + \ "Floating rate index: %s\n" % self._floating_rate_index + \ "Deposit daycount: %s\n" % self._deposit_daycount + \ "Calendar: %s\n" % self._params.calendar return output 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 discount(self, date_maturity, extrapolate=True): return self._discount_term_structure.discount(date_maturity) 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
class IborMarket(FixedIncomeMarket): def __init__(self, name, market, **kwargs): params = SwapData.params(market) params = params._replace(**kwargs) self._params = params self._name = name self._market = market # floating rate index index = IborIndex.from_name(market, **kwargs) self._floating_rate_index = index self._deposit_daycount = params.floating_leg_daycount self._termstructure_daycount = 'ACT/365' self._eval_date = None self._quotes = None self._termstructure = None self._discount_term_structure = None self._forecast_term_structure = None def __str__(self): return 'Fixed Income Market: %s' % self._name def set_quotes(self, dt_obs, quotes): self._quotes = quotes if(~isinstance(dt_obs, Date)): dt_obs = pydate_to_qldate(dt_obs) settings = Settings() calendar = JointCalendar(UnitedStates(), UnitedKingdom()) # must be a business day eval_date = calendar.adjust(dt_obs) settings.evaluation_date = eval_date self._eval_date = eval_date self._rate_helpers = [] for quote in quotes: # construct rate helper helper = make_rate_helper(self, quote, eval_date) self._rate_helpers.append(helper) @property def calendar(self): return self._params.calendar @property def settlement_days(self): return self._params.settlement_days @property def fixed_rate_frequency(self): return self._params.fixed_rate_frequency @property def fixed_rate_convention(self): return self._params.fixed_instrument_convention @property def fixed_rate_daycounter(self): return self._params.fixed_rate_daycounter @property def termstructure_daycounter(self): return self._termstructure_daycounter @property def reference_date(self): return 0 @property def max_date(self): return 0 def to_str(self): str = \ "Ibor Market %s\n" % self._name + \ "Number of settlement days: %d\n" % self._params.settlement_days +\ "Fixed rate frequency: %s\n" % self._params.fixed_rate_frequency +\ "Fixed rate convention: %s\n" % self._params.fixed_instrument_convention +\ "Fixed rate daycount: %s\n" % self._params.fixed_instrument_daycounter +\ "Term structure daycount: %s\n" % self._termstructure_daycount + \ "Floating rate index: %s\n" % self._floating_rate_index + \ "Deposit daycount: %s\n" % self._deposit_daycount + \ "Calendar: %s\n" % self._params.calendar return str def bootstrap_term_structure(self): 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 = term_structure_factory( 'discount', 'loglinear', 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._forecasting_term_structure = YieldTermStructure(relinkable=True) self._forecasting_term_structure.link_to(ts) return 0 def discount(self, date_maturity, extrapolate=True): return self._discount_term_structure.discount(date_maturity) 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._forecasting_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