Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
from .math_round_div import round_div ← from math.round-div ^1.0.0 · built alongside by fune
from .money_amount import Money, money ← from money.amount ^1.0.0 · built alongside by fune
from .property_rental_yield_types import RentalYield
# Above this, amount * 10000 is no longer exact as a JavaScript number; the
# same limit applies here so every language refuses the same inputs.
_MAX_MINOR = 90_000_000_000
def rental_yield(annual_rent: Money, annual_costs: Money, property_value: Money) -> RentalYield:
"""Gross and net rental yield in basis points. Each is rounded once,
half-up, from the exact ratio, never from a rounded percentage."""
currency = property_value.currency
for other in (annual_rent, annual_costs):
if other.currency != currency:
raise ValueError("currency mismatch: %s and %s" % (other.currency, currency))
if property_value.minor <= 0:
raise ValueError("propertyValue must be greater than zero, received %r" % (property_value.minor,))
if annual_rent.minor < 0:
raise ValueError("annualRent must not be negative, received %r" % (annual_rent.minor,))
if annual_costs.minor < 0:
raise ValueError("annualCosts must not be negative, received %r" % (annual_costs.minor,))
for m in (annual_rent.minor, annual_costs.minor, property_value.minor):
if m > _MAX_MINOR:
raise ValueError("amounts must be at most %d minor units" % (_MAX_MINOR,))
net = annual_rent.minor - annual_costs.minor
return RentalYield(
gross_basis_points=round_div(annual_rent.minor * 10000, property_value.minor, "half-up"),
net_basis_points=round_div(net * 10000, property_value.minor, "half-up"),
net_income=money(net, currency),
)