2020 _Vol ,
2121)
2222from rateslib .legs import FixedLeg
23+ from rateslib .scheduling import Schedule
2324from rateslib .scheduling .frequency import _get_frequency
2425
2526if TYPE_CHECKING :
3031 DualTypes_ ,
3132 FXForwards_ ,
3233 Number ,
34+ RollDay ,
3335 Sequence ,
3436 Solver_ ,
3537 VolT_ ,
3638 _BaseLeg ,
39+ bool_ ,
3740 datetime ,
3841 datetime_ ,
3942 int_ ,
4346
4447class Bill (_BaseBondInstrument ):
4548 """
46- Create a discount security.
49+ A *bill*, or discount security, composed of a :class:`~rateslib.legs.FixedLeg` .
4750
48- Parameters
49- ----------
50- effective : datetime
51- The adjusted or unadjusted effective date.
52- termination : datetime or str
53- The adjusted or unadjusted termination date. If a string, then a tenor must be
54- given expressed in days (`"D"`), months (`"M"`) or years (`"Y"`), e.g. `"7M"`.
55- frequency : str in {"M", "B", "Q", "T", "S", "A"}, optional
56- The frequency used only by the :meth:`~rateslib.instruments.Bill.ytm` method.
57- All *Bills* have an implicit frequency of "Z" for schedule construction.
58- modifier : str, optional
59- The modification rule, in {"F", "MF", "P", "MP"}
60- calendar : calendar or str, optional
61- The holiday calendar object to use. If str, looks up named calendar from
62- static data.
63- payment_lag : int, optional
64- The number of business days to lag payments by.
65- notional : float, optional
66- The leg notional, which is applied to each period.
67- currency : str, optional
68- The currency of the leg (3-digit code).
69- convention: str, optional
70- The day count convention applied to calculations of period accrual dates.
71- See :meth:`~rateslib.scheduling.dcf`.
72- settle : int
73- The number of business days for regular settlement time, i.e, 1 is T+1.
74- calc_mode : str, optional (defaults.calc_mode["Bill"])
75- A calculation mode for dealing with bonds that are in short stub or accrual
76- periods. All modes give the same value for YTM at issue date for regular
77- bonds but differ slightly for bonds with stubs or with accrued.
78- curves : CurveType, str or list of such, optional
79- A single *Curve* or string id or a list of such.
80-
81- A list defines the following curves in the order:
82-
83- - Forecasting *Curve* for ``leg1``.
84- - Discounting :class:`~rateslib.curves.Curve` for ``leg1``.
85- spec : str, optional
86- An identifier to pre-populate many field with conventional values. See
87- :ref:`here<defaults-doc>` for more info and available values.
88- metric: str, optional
89- The pricing metric returned by the ``rate`` method of the *Instrument*.
90-
91- Examples
92- --------
93- This example is taken from the US Treasury Federal website. A copy of
94- which is available :download:`here<_static/ofcalc6decTbill.pdf>`.
95-
96- We demonstrate the use of **analogue methods** which do not need *Curves* or
97- *Solvers*,
98- :meth:`~rateslib.instruments.Bill.price`,
99- :meth:`~rateslib.instruments.Bill.simple_rate`,
100- :meth:`~rateslib.instruments.Bill.discount_rate`,
101- :meth:`~rateslib.instruments.FixedRateBond.ytm`,
102- :meth:`~rateslib.instruments.FixedRateBond.ex_div`,
103- :meth:`~rateslib.instruments.FixedRateBond.accrued`,
104- :meth:`~rateslib.instruments.FixedRateBond.repo_from_fwd`
105- :meth:`~rateslib.instruments.FixedRateBond.fwd_from_repo`
106- :meth:`~rateslib.instruments.FixedRateBond.duration`,
107- :meth:`~rateslib.instruments.FixedRateBond.convexity`.
51+ .. rubric:: Examples
10852
10953 .. ipython:: python
11054 :suppress:
11155
112- from rateslib import Bill, Solver
56+ from rateslib.instruments import Bill
57+ from datetime import datetime as dt
11358
11459 .. ipython:: python
11560
11661 bill = Bill(
117- effective=dt(2004, 1, 22),
118- termination=dt(2004, 2, 19),
119- calendar="nyc",
120- modifier="NONE",
121- currency="usd",
122- convention="Act360",
123- settle=1,
124- notional=-1e6, # negative notional receives fixed, i.e. buys a bill
125- curves="bill_curve",
126- calc_mode="us_gbb",
127- )
128- bill.ex_div(dt(2004, 1, 22))
129- bill.price(rate=0.80, settlement=dt(2004, 1, 22))
130- bill.simple_rate(price=99.937778, settlement=dt(2004, 1, 22))
131- bill.discount_rate(price=99.937778, settlement=dt(2004, 1, 22))
132- bill.ytm(price=99.937778, settlement=dt(2004, 1, 22))
133- bill.accrued(dt(2004, 1, 22))
134- bill.fwd_from_repo(
135- price=99.937778,
136- settlement=dt(2004, 1, 22),
137- forward_settlement=dt(2004, 2, 19),
138- repo_rate=0.8005,
139- convention="Act360",
62+ effective=dt(2000, 1, 1),
63+ termination="3y",
64+ spec="us_gbb",
14065 )
141- bill.repo_from_fwd(
142- price=99.937778,
143- settlement=dt(2004, 1, 22),
144- forward_settlement=dt(2004, 2, 19),
145- forward_price=100.00,
146- convention="Act360",
147- )
148- bill.duration(settlement=dt(2004, 1, 22), ytm=0.8005, metric="risk")
149- bill.duration(settlement=dt(2004, 1, 22), ytm=0.8005, metric="modified")
150- bill.convexity(settlement=dt(2004, 1, 22), ytm=0.8005)
66+ bill.cashflows()
15167
68+ .. rubric:: Pricing
15269
153- The following **digital methods** consistent with the library's ecosystem are
154- also available,
155- :meth:`~rateslib.instruments.Bill.rate`,
156- :meth:`~rateslib.instruments.FixedRateBond.npv`,
157- :meth:`~rateslib.instruments.FixedRateBond.analytic_delta`,
158- :meth:`~rateslib.instruments.FixedRateBond.cashflows`,
159- :meth:`~rateslib.instruments.FixedRateBond.delta`,
160- :meth:`~rateslib.instruments.FixedRateBond.gamma`,
70+ A *Bill* requires one *disc curve*. The following input formats are
71+ allowed:
16172
162- .. ipython :: python
73+ .. code-block :: python
16374
164- bill_curve = Curve({dt(2004, 1, 21): 1.0, dt(2004, 3, 21): 1.0}, id="bill_curve")
165- instruments = [
166- (bill, {"metric": "ytm"}),
167- ]
168- solver = Solver(
169- curves=[bill_curve],
170- instruments=instruments,
171- s=[0.8005],
172- instrument_labels=["Feb04 Tbill"],
173- id="bill_solver",
174- )
175- bill.npv(solver=solver)
176- bill.analytic_delta(curves=bill_curve)
177- bill.rate(solver=solver, metric="price")
75+ curves = curve | [curve] # a single curve is repeated for all required curves
76+ curves = {"disc_curve": disc_curve} # dict form is explicit
17877
179- The sensitivities are also available. In this case the *Solver* is calibrated
180- with *instruments* priced in yield terms so sensitivities are measured in basis
181- points (bps).
78+ .. role:: red
18279
183- .. ipython :: python
80+ .. role :: green
18481
185- bill.delta(solver=solver)
186- bill.gamma(solver=solver)
82+ Parameters
83+ ----------
84+ .
85+
86+ .. note::
87+
88+ The following define generalised **scheduling** parameters.
89+
90+ effective : datetime, :red:`required`
91+ The unadjusted effective date. If given as adjusted, unadjusted alternatives may be
92+ inferred.
93+ termination : datetime, str, :red:`required`
94+ The unadjusted termination date. If given as adjusted, unadjusted alternatives may be
95+ inferred. If given as string tenor will be calculated from ``effective``.
96+ frequency : Frequency, str, :red:`required`
97+ The frequency of the schedule.
98+ If given as string will derive a :class:`~rateslib.scheduling.Frequency` aligning with:
99+ monthly ("M"), quarterly ("Q"), semi-annually ("S"), annually("A") or zero-coupon ("Z"), or
100+ a set number of calendar or business days ("_D", "_B"), weeks ("_W"), months ("_M") or
101+ years ("_Y").
102+ Where required, the :class:`~rateslib.scheduling.RollDay` is derived as per ``roll``
103+ and business day calendar as per ``calendar``.
104+ roll : RollDay, int in [1, 31], str in {"eom", "imm", "som"}, :green:`optional`
105+ The roll day of the schedule. If not given or not available in ``frequency`` will be
106+ inferred for monthly frequency variants.
107+ eom : bool, :green:`optional`
108+ Use an end of month preference rather than regular rolls for ``roll`` inference. Set by
109+ default. Not required if ``roll`` is defined.
110+ modifier : Adjuster, str in {"NONE", "F", "MF", "P", "MP"}, :green:`optional`
111+ The :class:`~rateslib.scheduling.Adjuster` used for adjusting unadjusted schedule dates
112+ into adjusted dates. If given as string must define simple date rolling rules.
113+ calendar : calendar, str, :green:`optional`
114+ The business day calendar object to use. If string will call
115+ :meth:`~rateslib.scheduling.get_calendar`.
116+ payment_lag: Adjuster, int, :green:`optional`
117+ The :class:`~rateslib.scheduling.Adjuster` to use to map adjusted schedule dates into
118+ a payment date. If given as integer will define the number of business days to
119+ lag payments by.
120+ ex_div: Adjuster, int, :green:`optional`
121+ The :class:`~rateslib.scheduling.Adjuster` to use to map adjusted schedule dates into
122+ additional dates, which may be used, for example by fixings schedules. If given as integer
123+ will define the number of business days to lag dates by.
124+ convention: str, :green:`optional (set by 'defaults')`
125+ The day count convention applied to calculations of period accrual dates.
126+ See :meth:`~rateslib.scheduling.dcf`.
187127
188- The DataFrame of cashflows.
128+ .. note::
189129
190- .. ipython:: python
130+ The following define generalised **settlement** parameters.
191131
192- bill.cashflows(solver=solver)
132+ currency : str, :green:`optional (set by 'defaults')`
133+ The local settlement currency of the *Instrument* (3-digit code).
134+ notional : float, Dual, Dual2, Variable, :green:`optional (set by 'defaults')`
135+ The initial leg notional, defined in units of *reference currency*.
136+
137+ .. note::
138+
139+ The following are **meta parameters**.
140+
141+ curves : _BaseCurve, str, dict, _Curves, Sequence, :green:`optional`
142+ Pricing objects passed directly to the *Instrument's* methods' ``curves`` argument. See
143+ **Pricing**.
144+ calc_mode : str or BillCalcMode
145+ A calculation mode for dealing with bonds under different conventions. See notes.
146+ settle: int
147+ The number of days by which to lag 'today' to arrive at standard settlement.
148+ metric : str, :green:`optional` (set as 'price')
149+ The pricing metric returned by :meth:`~rateslib.instruments.FixedRateBond.rate`.
150+ spec: str, :green:`optional`
151+ A collective group of parameters. See
152+ :ref:`default argument specifications <defaults-arg-input>`.
193153
194154 """
195155
@@ -210,12 +170,15 @@ def __init__(
210170 effective : datetime_ = NoInput (0 ),
211171 termination : datetime | str_ = NoInput (0 ),
212172 frequency : str_ = NoInput (0 ),
173+ roll : int | RollDay | str_ = NoInput (0 ),
174+ eom : bool_ = NoInput (0 ),
213175 modifier : str_ = NoInput (0 ),
214176 calendar : CalInput = NoInput (0 ),
215177 payment_lag : int_ = NoInput (0 ),
216178 notional : DualTypes_ = NoInput (0 ),
217179 currency : str_ = NoInput (0 ),
218180 convention : str_ = NoInput (0 ),
181+ ex_div : int_ = NoInput (0 ),
219182 settle : int_ = NoInput (0 ),
220183 calc_mode : BillCalcMode | str_ = NoInput (0 ),
221184 curves : CurvesT_ = NoInput (0 ),
@@ -229,6 +192,9 @@ def __init__(
229192 modifier = modifier ,
230193 calendar = calendar ,
231194 payment_lag = payment_lag ,
195+ ex_div = ex_div ,
196+ roll = roll ,
197+ eom = eom ,
232198 notional = notional ,
233199 currency = currency ,
234200 convention = convention ,
@@ -260,6 +226,17 @@ def __init__(
260226 meta_args = ["curves" , "calc_mode" , "settle" , "metric" , "frequency" , "vol" ],
261227 )
262228 self .kwargs .meta ["calc_mode" ] = _get_bill_calc_mode (self .kwargs .meta ["calc_mode" ])
229+ if isinstance (self .kwargs .leg1 ["termination" ], str ):
230+ s_ = Schedule (
231+ effective = self .kwargs .leg1 ["effective" ],
232+ termination = self .kwargs .leg1 ["termination" ],
233+ frequency = self .kwargs .leg1 ["termination" ],
234+ modifier = self .kwargs .leg1 ["modifier" ],
235+ calendar = self .kwargs .leg1 ["calendar" ],
236+ roll = self .kwargs .leg1 ["roll" ],
237+ eom = self .kwargs .leg1 ["eom" ],
238+ )
239+ self ._kwargs .leg1 ["termination" ] = s_ .termination
263240 self ._kwargs .leg1 ["frequency" ] = "Z"
264241 self ._kwargs .meta ["frequency" ] = _drb (
265242 self .kwargs .meta ["calc_mode" ]._ytm_clone_kwargs ["frequency" ],
0 commit comments