Struct PyDiscountCurve
pub struct PyDiscountCurve {
pub(crate) inner: Arc<Curve>,
pub(crate) provenance: Option<Arc<CurveProvenance>>,
pub(crate) refit: Option<Arc<CurveRefit>>,
}Expand description
A discount curve.
Fields§
§inner: Arc<Curve>§provenance: Option<Arc<CurveProvenance>>The ladder this curve was calibrated from, where it came from a calibration.
Carried on the curve rather than passed to MarketContext.with_*, for the
reason the core carries it on PinnedCurve: what is pinned decides
whether a ladder comes with it. A curve built by hand has none and says
so; the one Calibration.curve() hands back has its own, and pinning it
needs no extra argument and admits no mismatched pair.
refit: Option<Arc<CurveRefit>>What the curve was calibrated from, carried into a market beside the ladder so a quote scenario can solve it again.
Implementations§
§impl PyDiscountCurve
impl PyDiscountCurve
pub(crate) fn from_curve(curve: CoreCurve) -> Self
pub(crate) fn from_curve(curve: CoreCurve) -> Self
A curve with no ladder behind it — what a fit produces.
A fitted curve carries no provenance because it has none to carry: a
smoother has no rung that reprices, so there is no ladder and no
∂z/∂q a par-basis measure could read. That is a fact about the fit,
not an omission, and it is why this is a separate constructor rather
than an Option threaded through the calibrated one.
pub(crate) fn reference_date(&self) -> NaiveDate
pub(crate) fn reference_date(&self) -> NaiveDate
The date this curve is a curve as of — what a market checks a pin against.
pub(crate) fn curve(&self) -> &Arc<CoreCurve>
pub(crate) fn curve(&self) -> &Arc<CoreCurve>
The stored curve, for a sibling module that needs to query it.
pub(crate) fn pinned(&self) -> PyResult<PinnedCurve>
pub(crate) fn pinned(&self) -> PyResult<PinnedCurve>
This curve on its way into a market as a rate curve, with whatever ladder it carries.
A spread read back from curve("repo(KEY)") is refused: it is a
spread over a base, pinned with with_repo_spread, and as a rate
curve it would discount off the spread alone. The ladder never fails
here: a DiscountCurve’s ladder arrives from one place, Calibration,
where the curve and the ladder are two halves of one solve and cannot
disagree in length.
§impl PyDiscountCurve
impl PyDiscountCurve
pub(crate) fn new(
reference: NaiveDate,
pillars: Vec<(NaiveDate, f64)>,
interpolation: InterpolationArg,
tension: Option<f64>,
end_slopes: Option<(f64, f64)>,
long_interpolation: Option<InterpolationArg>,
changeover: Option<NaiveDate>,
rate_day_count: Named<DayCountFraction>,
) -> PyResult<Self>
pub(crate) fn new( reference: NaiveDate, pillars: Vec<(NaiveDate, f64)>, interpolation: InterpolationArg, tension: Option<f64>, end_slopes: Option<(f64, f64)>, long_interpolation: Option<InterpolationArg>, changeover: Option<NaiveDate>, rate_day_count: Named<DayCountFraction>, ) -> PyResult<Self>
Builds a curve from (date, discount_factor) pillars.
Dates are datetime.date — the type system refuses a malformed date
before this code runs, so there is no date validation to do here.
pub(crate) fn rate_day_count(&self) -> &'static str
pub(crate) fn rate_day_count(&self) -> &'static str
The day count this curve forms a rate under.
Not what it discounts on. The pillars are dated discount factors, so
the curve is a function of dates and this moves no factor it returns —
it is read where zero_rate and forward_rate divide a log factor
into a rate, and nowhere else.
pub(crate) fn long_interpolation(&self) -> Option<(&'static str, NaiveDate)>
pub(crate) fn long_interpolation(&self) -> Option<(&'static str, NaiveDate)>
The second scheme and the pillar it takes over at, when this curve reads under two.
pub(crate) fn flat(
reference: NaiveDate,
rate: f64,
day_count: Named<DayCountFraction>,
) -> PyResult<Self>
pub(crate) fn flat( reference: NaiveDate, rate: f64, day_count: Named<DayCountFraction>, ) -> PyResult<Self>
The scheme this curve reads under, by its canonical name.
One continuously compounded zero rate on day_count, anchored at
reference: the discount factor to a date is exp(-rate × t) with
t measured on the day count from the reference. The first curve a
notebook wants, and what every test’s flat_curve helper computed by
hand; the sibling of SpreadCurve.flat and SurvivalCurve.flat_hazard.
pub(crate) fn from_zero_rates(
reference: NaiveDate,
nodes: Vec<(NaiveDate, f64)>,
day_count: Named<DayCountFraction>,
) -> PyResult<Self>
pub(crate) fn from_zero_rates( reference: NaiveDate, nodes: Vec<(NaiveDate, f64)>, day_count: Named<DayCountFraction>, ) -> PyResult<Self>
Continuously compounded zero rates on day_count, read linearly in the
zero rate between nodes.
A node on reference states the rate the first segment starts from.
pub(crate) fn with_zero_spread(
&self,
spread: f64,
day_count: Named<DayCountFraction>,
) -> PyResult<Self>
pub(crate) fn with_zero_spread( &self, spread: f64, day_count: Named<DayCountFraction>, ) -> PyResult<Self>
This curve under a flat continuously compounded zero spread on
day_count, measured from its reference: each discount factor times
exp(−spread · τ).
pub(crate) fn with_spread(&self, spread: &PyDiscountCurve) -> PyResult<Self>
pub(crate) fn with_spread(&self, spread: &PyDiscountCurve) -> PyResult<Self>
This curve’s discount factors times spread’s, which must share its
reference date. A zero-rate curve as spread adds its zero rates, on
that curve’s day count, to this curve’s.
pub(crate) fn rebased(&self, reference: NaiveDate) -> PyResult<Self>
pub(crate) fn rebased(&self, reference: NaiveDate) -> PyResult<Self>
This curve read forward from reference: its discount factor over its
own there. A date before this
curve’s own reference is refused.
pub(crate) fn fx_implied(
base: &PyDiscountCurve,
pair: &str,
spot: f64,
spot_date: NaiveDate,
forwards: Vec<(NaiveDate, f64)>,
) -> PyResult<Self>
pub(crate) fn fx_implied( base: &PyDiscountCurve, pair: &str, spot: f64, spot_date: NaiveDate, forwards: Vec<(NaiveDate, f64)>, ) -> PyResult<Self>
A curve implied by FX forwards over base by covered interest parity:
for pair quoted as quote units per one base, the quote currency’s
discount factor is (spot / F(t)) · DF_base(t) / DF_base(spot_date),
F interpolating the forwards outrights from the spot. The spot is
the curve’s one risk parameter; the outrights pin its shape.
pub(crate) fn step_forward(
reference: NaiveDate,
knots: Vec<(NaiveDate, String)>,
discount_factors: Vec<f64>,
) -> PyResult<Self>
pub(crate) fn step_forward( reference: NaiveDate, knots: Vec<(NaiveDate, String)>, discount_factors: Vec<f64>, ) -> PyResult<Self>
A step curve: log-linear between pillars that carry an identity — a central-bank meeting, a turn of period, or none — so risk read back from it is keyed by the event rather than by a date.
knots are (date, tag) pairs, the tag "meeting:FED" (any bank
code), "turn" or "anon" — what knot_tags() reads back — and
discount_factors one per knot. dates.meeting_dates and
dates.turn_dates give the dates a knot lands on.
The tag of each pillar of a step curve, in date order — "meeting:FED",
"turn" or "anon" — or None for a curve whose pillars carry no
identity.
pub(crate) fn __repr__(&self) -> String
pub(crate) fn interpolation(&self) -> &'static str
pub(crate) fn interpolation(&self) -> &'static str
The scheme the curve reads between its pillars, by its spelling.
pub(crate) fn discount(&self, at: NaiveDate) -> PyResult<f64>
pub(crate) fn discount(&self, at: NaiveDate) -> PyResult<f64>
The discount factor to a date.
Past the last pillar the curve carries on at its last segment’s forward
rate — a flat-forward extrapolation, taken silently rather than refused.
A date before the reference date raises ValueError.
pub(crate) fn zero_rate(&self, at: NaiveDate) -> PyResult<f64>
pub(crate) fn zero_rate(&self, at: NaiveDate) -> PyResult<f64>
The continuously-compounded zero rate to at, under the curve’s
rate_day_count — ACT/365 fixed unless it was built with another.
A property of the curve, on the measure it was told rates are
quoted in. It is not the rate any index quotes: see Index.forecast,
which is simple, on the index’s own day count, over the index’s own
window.
pub(crate) fn forward_rate(
&self,
start: NaiveDate,
end: NaiveDate,
) -> PyResult<f64>
pub(crate) fn forward_rate( &self, start: NaiveDate, end: NaiveDate, ) -> PyResult<f64>
The continuously-compounded forward rate between start and end, on
ACT/365.
As with zero_rate, a reading of the curve rather than of an index. A
caller who wants the rate a coupon fixes on wants Index.forecast; for an
ACT/360 index the two differ, which a test asserts.
pub(crate) fn parameter_count(&self) -> usize
pub(crate) fn parameter_count(&self) -> usize
How many free parameters the curve has.
pub(crate) fn natural(&self) -> PyResult<Vec<f64>>
pub(crate) fn natural(&self) -> PyResult<Vec<f64>>
The fitted form’s natural parameters, as Rust’s natural() reads
them: [β0, β1, β2, λ] for a Nelson-Siegel curve, [β0, β1, β2, β3, λ1, λ2] for a Svensson one, the decays squashed back to their
natural scale. What curves.fit_bond_curve solved, read back without
re-deriving it from the zero rates.
Raises ValueError on any other curve: a piecewise curve has
pillars, an exponential-splines fit has basis weights, and neither is
a natural parameter vector.
Trait Implementations§
§impl Clone for PyDiscountCurve
impl Clone for PyDiscountCurve
§fn clone(&self) -> PyDiscountCurve
fn clone(&self) -> PyDiscountCurve
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl DerefToPyAny for PyDiscountCurve
§impl IntoPy<Py<PyAny>> for PyDiscountCurve
impl IntoPy<Py<PyAny>> for PyDiscountCurve
§impl PyClass for PyDiscountCurve
impl PyClass for PyDiscountCurve
§impl PyClassImpl for PyDiscountCurve
impl PyClassImpl for PyDiscountCurve
§const IS_BASETYPE: bool = false
const IS_BASETYPE: bool = false
§const IS_SUBCLASS: bool = false
const IS_SUBCLASS: bool = false
§const IS_MAPPING: bool = false
const IS_MAPPING: bool = false
§const IS_SEQUENCE: bool = false
const IS_SEQUENCE: bool = false
§type ThreadChecker = SendablePyClass<PyDiscountCurve>
type ThreadChecker = SendablePyClass<PyDiscountCurve>
§type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::ImmutableChild
type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::ImmutableChild
§type BaseNativeType = PyAny
type BaseNativeType = PyAny
PyAny by default, and when you declare
#[pyclass(extends=PyDict)], it’s PyDict.fn items_iter() -> PyClassItemsIter
fn lazy_type_object() -> &'static LazyTypeObject<Self>
fn dict_offset() -> Option<isize>
fn weaklist_offset() -> Option<isize>
§impl PyClassNewTextSignature<PyDiscountCurve> for PyClassImplCollector<PyDiscountCurve>
impl PyClassNewTextSignature<PyDiscountCurve> for PyClassImplCollector<PyDiscountCurve>
fn new_text_signature(self) -> Option<&'static str>
§impl<'a, 'py> PyFunctionArgument<'a, 'py> for &'a PyDiscountCurve
impl<'a, 'py> PyFunctionArgument<'a, 'py> for &'a PyDiscountCurve
§impl PyMethods<PyDiscountCurve> for PyClassImplCollector<PyDiscountCurve>
impl PyMethods<PyDiscountCurve> for PyClassImplCollector<PyDiscountCurve>
fn py_methods(self) -> &'static PyClassItems
§impl PyTypeInfo for PyDiscountCurve
impl PyTypeInfo for PyDiscountCurve
§fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject
fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject
§fn type_object_bound(py: Python<'_>) -> Bound<'_, PyType>
fn type_object_bound(py: Python<'_>) -> Bound<'_, PyType>
§fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool
fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool
object is an instance of this type or a subclass of this type.§fn is_exact_type_of_bound(object: &Bound<'_, PyAny>) -> bool
fn is_exact_type_of_bound(object: &Bound<'_, PyAny>) -> bool
object is an instance of this type.