Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
from typing import Sequence
from .invest_dividend_yield_types import DividendYield
from .money_amount import Money, money ← from money.amount ^1.0.0 · built alongside by fune
def _is_int(value: object) -> bool:
return isinstance(value, int) and not isinstance(value, bool)
def _basis_points(amount: int, price: int) -> int:
"""amount x 10000 / price, half-up; both 0 or more, price > 0."""
q, r = divmod(amount * 10000, price)
return q + 1 if 2 * r >= price else q
def dividend_yield(
price: Money, trailing_dividends: Sequence[Money], forward_dividend: Money, payments_per_year: int
) -> DividendYield:
"""Trailing yield from the dividends paid in the last twelve months, and
forward yield from the latest regular dividend annualised, both over the
current price."""
currency = price.currency
if not _is_int(price.minor) or price.minor <= 0:
raise ValueError("price must be whole minor units greater than zero; received %s" % (price.minor,))
if not _is_int(payments_per_year) or payments_per_year < 1 or payments_per_year > 52:
raise ValueError("paymentsPerYear must be a whole number from 1 to 52; received %s" % (payments_per_year,))
for dividend in list(trailing_dividends) + [forward_dividend]:
if dividend.currency != currency:
raise ValueError("currency mismatch: %s and %s" % (currency, dividend.currency))
if not _is_int(dividend.minor) or dividend.minor < 0:
raise ValueError("dividends must be whole minor units, 0 or more; received %s" % (dividend.minor,))
trailing = sum(d.minor for d in trailing_dividends)
forward = forward_dividend.minor * payments_per_year
return DividendYield(
trailing_annual=money(trailing, currency),
forward_annual=money(forward, currency),
trailing_basis_points=_basis_points(trailing, price.minor),
forward_basis_points=_basis_points(forward, price.minor),
)