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
15 changes: 2 additions & 13 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ ignore = [

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["E402", "N801"]
"typing.py" = ["E501"]
"typing.py" = ["E501", "E402"]
"python/tests/*" = ["F401", "B", "N", "S", "ANN", "D"]
"rust/*" = ["D"]

Expand All @@ -149,9 +149,7 @@ max-complexity = 14
files = ["python/"]
exclude = [
"python/tests",
"/instruments/components/bonds",
"/instruments/fx_options",
# "/instruments/components/protocols",
# "/instruments/bonds/bond_future.py",
]
strict = true
#packages = [
Expand All @@ -163,12 +161,3 @@ omit = [
"/typing.py",
# "python/tests/*"
]

[tool.isort]
profile = "black"
line_length = 100
src_paths = ["python"]

[tool.black]
line-length = 100
target-version = ['py310']
2 changes: 1 addition & 1 deletion python/rateslib/curves/curves.py
Original file line number Diff line number Diff line change
Expand Up @@ -2982,7 +2982,7 @@ def _try_index_value(
return _index_value_from_mixed_series_and_curve(
index_lag=index_lag,
index_method=index_method,
index_fixings=fixings_series[1], # type: ignore[arg-type]
index_fixings=fixings_series[1],
index_date=index_date,
index_curve=index_curve,
)
Expand Down
7 changes: 6 additions & 1 deletion python/rateslib/curves/rs.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@
from rateslib.scheduling.convention import _get_convention

if TYPE_CHECKING:
from rateslib.typing import CalInput, CurveInterpolator, DualTypes, Number
from rateslib.typing import ( # pragma: no cover
CalInput,
CurveInterpolator,
DualTypes,
Number,
)


class CurveRs:
Expand Down
54 changes: 29 additions & 25 deletions python/rateslib/instruments/bonds/bill.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import TYPE_CHECKING

from rateslib import defaults
from rateslib.curves._parsers import _validate_obj_not_no_input
from rateslib.dual import Variable, gradient
from rateslib.dual.utils import _dual_float, _to_number
from rateslib.enums.generics import NoInput, _drb
Expand All @@ -15,7 +16,7 @@
from rateslib.instruments.protocols.kwargs import _convert_to_schedule_kwargs, _KWArgs
from rateslib.instruments.protocols.pricing import (
_Curves,
_maybe_get_curve_or_dict_maybe_from_solver,
_maybe_get_curve_maybe_from_solver,
_Vol,
)
from rateslib.legs import FixedLeg
Expand All @@ -24,12 +25,12 @@
if TYPE_CHECKING:
from rateslib.typing import ( # pragma: no cover
CalInput,
CurveOption_,
Curves_,
CurvesT_,
DualTypes,
DualTypes_,
FXForwards_,
Number,
Sequence,
Solver_,
VolT_,
_BaseLeg,
Expand Down Expand Up @@ -200,7 +201,7 @@ def leg1(self) -> FixedLeg:
return self._leg1

@property
def legs(self) -> list[_BaseLeg]:
def legs(self) -> Sequence[_BaseLeg]:
"""A list of the *Legs* of the *Instrument*."""
return self._legs

Expand All @@ -217,7 +218,7 @@ def __init__(
convention: str_ = NoInput(0),
settle: int_ = NoInput(0),
calc_mode: BillCalcMode | str_ = NoInput(0),
curves: Curves_ = NoInput(0),
curves: CurvesT_ = NoInput(0),
spec: str_ = NoInput(0),
metric: str = "price",
):
Expand Down Expand Up @@ -271,7 +272,7 @@ def __init__(
def _parse_vol(self, vol: VolT_) -> _Vol:
return _Vol()

def _parse_curves(self, curves: CurveOption_) -> _Curves:
def _parse_curves(self, curves: CurvesT_) -> _Curves:
"""
A Bill has one curve requirements: a disc_curve.

Expand All @@ -298,23 +299,25 @@ def _parse_curves(self, curves: CurveOption_) -> _Curves:
raise ValueError(
f"{type(self).__name__} requires only 1 curve types. Got {len(curves)}."
)
elif isinstance(curves, _Curves):
return curves
else: # `curves` is just a single input which is copied across all curves
return _Curves(
disc_curve=curves,
disc_curve=curves, # type: ignore[arg-type]
)

def rate(
self,
*,
curves: Curves_ = NoInput(0),
curves: CurvesT_ = NoInput(0),
solver: Solver_ = NoInput(0),
fx: FXForwards_ = NoInput(0),
vol: VolT_ = NoInput(0),
base: str_ = NoInput(0),
settlement: datetime_ = NoInput(0),
forward: datetime_ = NoInput(0),
metric: str_ = NoInput(0),
) -> DualTypes_:
) -> DualTypes:
"""
Return various pricing metrics of the security calculated from
:class:`~rateslib.curves.Curve` s.
Expand Down Expand Up @@ -345,17 +348,20 @@ def rate(
-------
float, Dual, Dual2
"""
disc_curve_ = _maybe_get_curve_or_dict_maybe_from_solver(
solver=solver,
name="disc_curve",
curves=self._parse_curves(curves),
curves_meta=self.kwargs.meta["curves"],
disc_curve_ = _validate_obj_not_no_input(
_maybe_get_curve_maybe_from_solver(
solver=solver,
name="disc_curve",
curves=self._parse_curves(curves),
curves_meta=self.kwargs.meta["curves"],
),
"disc_curve",
)
settlement_ = self._maybe_get_settlement(settlement=settlement, disc_curve=disc_curve_)

# scale price to par 100 and make a fwd adjustment according to curve
price = (
self.npv(curves=curves, solver=solver, fx=fx, base=base, local=False)
self.npv(curves=curves, solver=solver, local=False) # type: ignore[operator]
* 100
/ (-self.leg1.settlement_params.notional * disc_curve_[settlement_])
)
Expand Down Expand Up @@ -387,7 +393,7 @@ def simple_rate(self, price: DualTypes, settlement: datetime) -> DualTypes:
"""
acc_frac = self.kwargs.meta["calc_mode"]._settle_accrual(self, settlement, 0)
dcf = (1 - acc_frac) * self.leg1._regular_periods[0].period_params.dcf
return ((100 / price - 1) / dcf) * 100
return ((100 / price - 1) / dcf) * 100 # type: ignore[no-any-return]

def discount_rate(self, price: DualTypes, settlement: datetime) -> DualTypes:
"""
Expand All @@ -407,7 +413,7 @@ def discount_rate(self, price: DualTypes, settlement: datetime) -> DualTypes:
acc_frac = self.kwargs.meta["calc_mode"]._settle_accrual(self, settlement, 0)
dcf = (1 - acc_frac) * self.leg1._regular_periods[0].period_params.dcf
rate = ((1 - price / 100) / dcf) * 100
return rate
return rate # type: ignore[no-any-return]

def price(
self,
Expand Down Expand Up @@ -444,14 +450,14 @@ def price(
def _price_discount(self, rate: DualTypes, settlement: datetime) -> DualTypes:
acc_frac = self.kwargs.meta["calc_mode"]._settle_accrual(self, settlement, 0)
dcf = (1 - acc_frac) * self.leg1._regular_periods[0].period_params.dcf
return 100 - rate * dcf
return 100 - rate * dcf # type: ignore[no-any-return]

def _price_simple(self, rate: DualTypes, settlement: datetime) -> DualTypes:
acc_frac = self.kwargs.meta["calc_mode"]._settle_accrual(self, settlement, 0)
dcf = (1 - acc_frac) * self.leg1._regular_periods[0].period_params.dcf
return 100 / (1 + rate * dcf / 100)
return 100 / (1 + rate * dcf / 100) # type: ignore[no-any-return]

def ytm(
def ytm( # type: ignore[override]
self,
price: DualTypes,
settlement: datetime,
Expand Down Expand Up @@ -492,11 +498,11 @@ def ytm(
while quasi_ustart > settlement:
quasi_ustart = frequency.uprevious(quasi_ustart)

equiv_bond = FixedRateBond(
equiv_bond = FixedRateBond( # type: ignore[abstract]
effective=quasi_ustart,
termination=self.leg1.schedule.utermination,
fixed_rate=0.0,
**calc_mode_._ytm_clone_kwargs,
**calc_mode_._ytm_clone_kwargs, # type: ignore[arg-type]
)
return equiv_bond.ytm(price, settlement)

Expand Down Expand Up @@ -527,9 +533,7 @@ def duration(self, ytm: DualTypes, settlement: datetime, metric: str = "risk") -
# TODO: this is not AD safe: returns only float
ytm_: float = _dual_float(ytm)
if metric == "duration":
price_: Dual | Dual2 = _to_number( # type: ignore[assignment]
self.price(Variable(ytm_, ["y"]), settlement, dirty=True)
)
price_ = _to_number(self.price(Variable(ytm_, ["y"]), settlement, dirty=True))
freq = _get_frequency(
self.kwargs.meta["frequency"],
self.leg1.schedule.utermination.day,
Expand Down
Loading
Loading