Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ dev = [
"mypy>=1.13,<1.20",
"pandas-stubs>2.0,<3.0",
# doc building
"sphinx>=9.1,<9.2",
"sphinx>=8.1,<9.0",
"sphinx-automodapi>=0.16.0,<1.0",
"sphinxcontrib-googleanalytics>=0.4,<1.0",
"sphinx-tabs>=3.4,<4.0",
Expand Down
2 changes: 1 addition & 1 deletion python/rateslib/data/fixings.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@
LegFixings,
PeriodFixings,
Result,
StubInference,
_BaseCurve_,
bool_,
datetime_,
int_,
str_,
StubInference,
)


Expand Down
2 changes: 1 addition & 1 deletion python/rateslib/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from rateslib._spec_loader import INSTRUMENT_SPECS
from rateslib.enums.generics import NoInput, _drb
from rateslib.enums.parameters import FloatFixingMethod
from rateslib.rs import Adjuster, Convention, NamedCal, StubInference
from rateslib.rs import Adjuster, Convention, NamedCal

PlotOutput = tuple[plt.Figure, plt.Axes, list[plt.Line2D]] # type: ignore[name-defined]

Expand Down
5 changes: 2 additions & 3 deletions python/rateslib/instruments/cds.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ class CDS(_BaseInstrument):
leg2_payment_lag: Adjuster, int, :green:`optional (inherited from leg1)`
leg2_payment_lag_exchange: Adjuster, int, :green:`optional (inherited from leg1)`
leg2_ex_div: Adjuster, int, :green:`optional (inherited from leg1)`
leg2_convention: str, :green:`optional (inherited from leg1)`

.. note::

Expand Down Expand Up @@ -265,7 +264,7 @@ def __init__(
leg2_calendar: CalInput = NoInput(1),
leg2_payment_lag: int_ = NoInput(1),
leg2_payment_lag_exchange: int_ = NoInput(1),
leg2_convention: str_ = NoInput(1),
# leg2_convention: str_ = NoInput(1),
leg2_ex_div: int_ = NoInput(1),
# settlement
notional: float_ = NoInput(0),
Expand Down Expand Up @@ -313,7 +312,7 @@ def __init__(
leg2_ex_div=leg2_ex_div,
leg2_notional=leg2_notional,
leg2_amortization=leg2_amortization,
leg2_convention=leg2_convention,
# leg2_convention=leg2_convention,
# rate and credit
premium_accrued=premium_accrued,
fixed_rate=fixed_rate,
Expand Down
116 changes: 71 additions & 45 deletions python/rateslib/legs/credit.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,31 @@

class CreditPremiumLeg(_BaseLeg, _WithExDiv):
"""
Define a *Leg* containing :class:`~rateslib.periods.CreditPremiumPeriod`.
A *Leg* containing :class:`~rateslib.periods.CreditPremiumPeriod`.

.. rubric:: Examples

.. ipython:: python
:suppress:

from rateslib import Schedule
from rateslib.legs import CreditPremiumLeg
from datetime import datetime as dt

.. ipython:: python

cpl = CreditPremiumLeg(
schedule=Schedule(
effective=dt(2000, 3, 20),
termination=dt(2001, 3, 20),
frequency="Q",
modifier="FEX",
),
convention="Act360",
fixed_rate=1.0,
notional=10e6,
)
cpl.cashflows()

.. role:: red

Expand Down Expand Up @@ -87,15 +111,6 @@ class CreditPremiumLeg(_BaseLeg, _WithExDiv):
premium_accrued: bool, :green:`optional (set by 'defaults')`
Whether an accrued premium is paid on the event of mid-period credit default.


Notes
-----
TODO

Examples
--------
See :ref:`Leg Examples<legs-doc>`

"""

@property
Expand All @@ -111,6 +126,8 @@ def periods(self) -> list[CreditPremiumPeriod]:

@property
def fixed_rate(self) -> DualTypes_:
"""The fixed rate parameter of each composited
:class:`~rateslib.periods.CreditPremiumPeriod`."""
return self._fixed_rate

@fixed_rate.setter
Expand All @@ -121,10 +138,14 @@ def fixed_rate(self, value: DualTypes_) -> None:

@property
def schedule(self) -> Schedule:
"""The :class:`~rateslib.scheduling.Schedule` object of *Leg*."""
return self._schedule

@property
def amortization(self) -> Amortization:
"""
The :class:`~rateslib.legs.Amortization` object associated with the schedule.
"""
return self._amortization

def accrued(self, settlement: datetime) -> DualTypes:
Expand Down Expand Up @@ -225,50 +246,51 @@ def spread(

class CreditProtectionLeg(_BaseLeg):
"""
Create a credit protection leg composed of :class:`~rateslib.periods.CreditProtectionPeriod` s.
A *Leg* containing :class:`~rateslib.periods.CreditProtectionPeriod`.

Parameters
----------
args : tuple
Required positional args to :class:`BaseLeg`.
kwargs : dict
Required keyword arguments to :class:`BaseLeg`.
.. rubric:: Examples

Notes
-----
The NPV of a credit protection leg is the sum of the period NPVs.
.. ipython:: python
:suppress:

.. math::
from rateslib import dt, CreditProtectionLeg, Schedule

P = \\sum_{i=1}^n P_i
.. ipython:: python

The analytic delta is the sum of the period analytic deltas.
cpl = CreditProtectionLeg(
schedule=Schedule(
effective=dt(2000, 3, 20),
termination=dt(2001, 3, 30),
frequency="Z",
),
notional=10e6,
)
cpl.cashflows()

.. math::
.. role:: red

A = -\\frac{\\partial P}{\\partial S} = \\sum_{i=1}^n -\\frac{\\partial P_i}{\\partial S}
.. role:: green

Examples
--------
Parameters
----------
schedule: Schedule, :red:`required`
The :class:`~rateslib.scheduling.Schedule` object which structures contiguous *Periods*.
The schedule object also contains data for payment dates, payment dates for notional
exchanges and ex-dividend dates for each period.

.. ipython:: python
:suppress:
.. note::

from rateslib.curves import Curve
from rateslib.scheduling import Schedule
from rateslib.legs import CreditProtectionLeg
from datetime import datetime as dt
The following define generalised **settlement** parameters.

.. ipython:: python
currency : str, :green:`optional (set by 'defaults')`
The local settlement currency of the leg (3-digit code).
notional : float, Dual, Dual2, Variable, :green:`optional (set by 'defaults')`
The initial leg notional, defined in units of *reference currency*.
amortization: float, Dual, Dual2, Variable, str, Amortization, :green:`optional (set as zero)`
Set a non-constant notional per *Period*. If a scalar value, adjusts the ``notional`` of
each successive period by that same value. Should have
sign equal to that of notional if the notional is to reduce towards zero.

disc_curve = Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.98})
hazard_curve = Curve({dt(2022, 1, 1): 1.0, dt(2023, 1, 1): 0.995})
protection_leg = CreditProtectionLeg(
schedule=Schedule(dt(2022, 1, 1), "9M", "Z"),
notional=1000000,
)
protection_leg.cashflows(rate_curve=hazard_curve, disc_curve=disc_curve)
protection_leg.npv(rate_curve=hazard_curve, disc_curve=disc_curve)
""" # noqa: E501

@property
Expand All @@ -284,10 +306,14 @@ def periods(self) -> list[CreditProtectionPeriod]:

@property
def schedule(self) -> Schedule:
"""The :class:`~rateslib.scheduling.Schedule` object of *Leg*."""
return self._schedule

@property
def amortization(self) -> Amortization:
"""
The :class:`~rateslib.legs.Amortization` object associated with the schedule.
"""
return self._amortization

def __init__(
Expand All @@ -299,15 +325,15 @@ def __init__(
amortization: DualTypes_ | list[DualTypes] | Amortization | str = NoInput(0),
currency: str_ = NoInput(0),
# period
convention: str_ = NoInput(0),
# convention: str_ = NoInput(0),
) -> None:
self._schedule = schedule
self._notional: DualTypes = _drb(defaults.notional, notional)
self._amortization: Amortization = _get_amortization(
amortization, self._notional, self.schedule.n_periods
)
self._currency: str = _drb(defaults.base_currency, currency).lower()
self._convention: str = _drb(defaults.convention, convention)
# self._convention: str = _drb(defaults.convention, convention)

self._regular_periods = tuple(
[
Expand All @@ -321,7 +347,7 @@ def __init__(
start=self.schedule.aschedule[i],
end=self.schedule.aschedule[i + 1],
frequency=self.schedule.frequency_obj,
convention=self._convention,
# convention=self._convention,
termination=self.schedule.aschedule[-1],
stub=self.schedule._stubs[i],
roll=NoInput(0), # defined by Frequency
Expand Down
3 changes: 1 addition & 2 deletions python/rateslib/legs/float.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import rateslib.errors as err
from rateslib import defaults
from rateslib.data.fixings import _leg_fixings_to_list, _get_float_fixing_method
from rateslib.data.fixings import _get_float_fixing_method, _leg_fixings_to_list
from rateslib.dual import ift_1dim
from rateslib.enums.generics import NoInput, _drb
from rateslib.enums.parameters import FloatFixingMethod, LegMtm, SpreadCompoundMethod, _get_leg_mtm
Expand All @@ -31,7 +31,6 @@
from rateslib.periods.parameters.rate import _init_float_rate_series
from rateslib.scheduling.schedule import Schedule


if TYPE_CHECKING:
from rateslib.typing import ( # pragma: no cover
CurveOption_,
Expand Down
14 changes: 9 additions & 5 deletions python/rateslib/periods/credit.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from rateslib.periods.protocols import _BasePeriod
from rateslib.periods.protocols.npv import _screen_ex_div_and_forward
from rateslib.periods.utils import _maybe_local, _try_validate_base_curve, _validate_credit_curves
from rateslib.scheduling import Frequency, get_calendar
from rateslib.scheduling import Convention, Frequency, get_calendar
from rateslib.scheduling.adjuster import _get_adjuster
from rateslib.scheduling.convention import _get_convention
from rateslib.scheduling.frequency import _get_frequency
Expand Down Expand Up @@ -129,6 +129,9 @@ class CreditPremiumPeriod(_BasePeriod):
stub: bool, str, :green:`optional (set as False)`
Whether the *Period* is defined as a stub according to some external
:class:`~rateslib.scheduling.Schedule`.
roll: RollDay, int, str, :green:`optional (set by 'frequency')`
The rollday associated with any monthly :class:`~rateslib.scheduling.Frequency`, if
not directly associated with that object.
adjuster: Adjuster, :green:`optional`
The date :class:`~rateslib.scheduling.Adjuster` applied to unadjusted dates in the
external :class:`~rateslib.scheduling.Schedule` to arrive at adjusted accrual dates.
Expand Down Expand Up @@ -431,15 +434,16 @@ class CreditProtectionPeriod(_BasePeriod):
The identified end date of the *Period*.
frequency: Frequency, str, :red:`required`
The :class:`~rateslib.scheduling.Frequency` associated with the *Period*.
convention: Convention, str, :green:`optional` (set by 'defaults')
The day count :class:`~rateslib.scheduling.Convention` associated with the *Period*.
termination: datetime, :green:`optional`
The termination date of an external :class:`~rateslib.scheduling.Schedule`.
calendar: Calendar, :green:`optional`
The calendar associated with the *Period*.
stub: bool, str, :green:`optional (set as False)`
Whether the *Period* is defined as a stub according to some external
:class:`~rateslib.scheduling.Schedule`.
roll: RollDay, int, str, :green:`optional (set by 'frequency')`
The rollday associated with any monthly :class:`~rateslib.scheduling.Frequency`, if
not directly associated with that object.
adjuster: Adjuster, :green:`optional`
The date :class:`~rateslib.scheduling.Adjuster` applied to unadjusted dates in the
external :class:`~rateslib.scheduling.Schedule` to arrive at adjusted accrual dates.
Expand Down Expand Up @@ -468,7 +472,7 @@ def __init__(
start: datetime,
end: datetime,
frequency: Frequency | str,
convention: str_ = NoInput(0),
# convention: str_ = NoInput(0),
termination: datetime_ = NoInput(0),
stub: bool = False,
roll: RollDay | int | str_ = NoInput(0),
Expand All @@ -492,7 +496,7 @@ def __init__(
_calendar=get_calendar(calendar),
_adjuster=NoInput(0) if isinstance(adjuster, NoInput) else _get_adjuster(adjuster),
_stub=stub,
_convention=_get_convention(_drb(defaults.convention, convention)),
_convention=Convention.One, # _get_convention(_drb(defaults.convention, convention)),
_termination=termination,
)

Expand Down
3 changes: 3 additions & 0 deletions python/rateslib/periods/fixed_period.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ class FixedPeriod(_BasePeriodStatic):
stub: bool, str, :green:`optional (set as False)`
Whether the *Period* is defined as a stub according to some external
:class:`~rateslib.scheduling.Schedule`.
roll: RollDay, int, str, :green:`optional (set by 'frequency')`
The rollday associated with any monthly :class:`~rateslib.scheduling.Frequency`, if
not directly associated with that object.
adjuster: Adjuster, :green:`optional`
The date :class:`~rateslib.scheduling.Adjuster` applied to unadjusted dates in the
external :class:`~rateslib.scheduling.Schedule` to arrive at adjusted accrual dates.
Expand Down
5 changes: 4 additions & 1 deletion python/rateslib/periods/float_period.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ class FloatPeriod(_BasePeriodStatic):
stub: bool, str, :green:`optional (set as False)`
Whether the *Period* is defined as a stub according to some external
:class:`~rateslib.scheduling.Schedule`.
roll: RollDay, int, str, :green:`optional (set by 'frequency')`
The rollday associated with any monthly :class:`~rateslib.scheduling.Frequency`, if
not directly associated with that object.
adjuster: Adjuster, :green:`optional`
The date :class:`~rateslib.scheduling.Adjuster` applied to unadjusted dates in the
external :class:`~rateslib.scheduling.Schedule` to arrive at adjusted accrual dates.
Expand Down Expand Up @@ -764,7 +767,7 @@ def __init__(
# meta-args:
metric: str_ = NoInput(0),
) -> None:
self._rate_metric = _drb("compounding", metric).lower()
self._rate_metric: str = _drb("compounding", metric).lower()
self._schedule = schedule
self._settlement_params = _init_SettlementParams_with_fx_pair(
_currency=_drb(defaults.base_currency, currency).lower(),
Expand Down
2 changes: 1 addition & 1 deletion python/rateslib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@
from rateslib.periods.parameters import _SettlementParams as _SettlementParams
from rateslib.periods.protocols import _BasePeriod as _BasePeriod
from rateslib.rs import Adjuster as Adjuster
from rateslib.rs import StubInference as StubInference
from rateslib.rs import (
Cal,
FlatBackwardInterpolator,
Expand All @@ -114,6 +113,7 @@
NullInterpolator,
UnionCal,
)
from rateslib.rs import StubInference as StubInference

CurveInterpolator: TypeAlias = "FlatBackwardInterpolator | FlatForwardInterpolator | LinearInterpolator | LogLinearInterpolator | LinearZeroRateInterpolator | NullInterpolator"

Expand Down
Loading
Loading