Source code for py_wlc.economics.discount

""":py:mod:`~.discount` enables the calculation of Present Value."""

from ..generic import ExtendedDict, IndexSeries


[docs]class Discount(IndexSeries): """Discount rates and factors for calculating Present Value. The discount rate is assumed to be zero prior to ``year_zero``, and remain at the rate corresponding to the last year in ``self.rates`` indefinitely. Similarly, the factor is assumed to be ``1.0`` prior to the base year. The initial rate, i.e. the rate corresponding to the smallest year in the rates dictionary, is assumed to be the rate from the ``base_year`` onwards. Arguments: base_year (``int``): The base year for discounting, i.e. the year in which the factor is ``1.0``. rates (``dict`` of ``int``: ``float``, optional): The discount rates, where the key is the start year and the value is the rate to apply. Defaults to HM Treasury `Green Book`_ rates. year_zero (``int``, optional): Year zero, the year from which the applicable rate is incremented. Defaults to ``base_year``. .. _`Green Book`: https://www.gov.uk/government/publications/the-green-book-appraisal-and-evaluation-in-central-governent """ RATES = {0: 0.035, 31: 0.03, 76: 0.025, 126: 0.02, 201: 0.015, 301: 0.01} """Default HM Treasury "Green Book" discount rates.""" def __init__(self, base_year, rates=None, year_zero=None): if rates is None: rates = self.RATES self._infill_rates(rates) super().__init__(base_year, ExtendedDict(rates), initial_value=1.0, year_zero=year_zero) def __getitem__(self, year): try: return super().__getitem__(year) except KeyError: return 1.0
[docs] def rebase(self, year_zero): """Create a :py:class:`~.Discount` with new ``year_zero``. Arguments: year_zero (``int``): The new ``year_zero`` to use. Returns: :py:class:`~.Discount`: The new :py:class:`~.Discount` object. """ return Discount(self.base_year, self._rates, year_zero)
[docs] def rate(self, year): """The rate used in the specified year. Arguments: year (``int``): The year to retrieve the rate for. Returns: float: The rate used in that year. """ if year < (self.base_year - self.year_zero): return 0.0 return super().rate(year)
def _extend_values(self, year): for year_ in range(max(self._values), year): self._values[year_+1] = (self._values[year_] / (1.0 + self.rate(year_+1)))