Functional Weave
Code in Python

banking.savings-aer@1.0.0

impl/python.py

1,064 bytes · the Python implementation · view raw

def savings_aer(gross_rate_basis_points: int, payments_per_year: int) -> int:
    """The AER of a gross rate paid ``payments_per_year`` times a year:
    (1 + i / n)^n - 1, per the UK Finance / BSA AER Practice Note formula (d),
    rounded half-up to two decimal places of a percent (a whole basis point).

    With i = b / 10000 and D = 10000 * n the exact value in basis points is
    10000 * ((D + b)^n - D^n) / D^n, computed in integers and rounded once.
    """
    b = gross_rate_basis_points
    if isinstance(b, bool) or not isinstance(b, int) or b < 0 or b > 100000:
        raise ValueError("grossRateBasisPoints must be between 0 and 100000, received %r" % (b,))
    n = payments_per_year
    if isinstance(n, bool) or not isinstance(n, int) or n < 1 or n > 365:
        raise ValueError("paymentsPerYear must be between 1 and 365, received %r" % (n,))
    d = 10000 * n
    whole = d ** n
    numerator = 10000 * ((d + b) ** n - whole)
    # Half-up for a non-negative fraction: floor((2N + M) / 2M).
    return (2 * numerator + whole) // (2 * whole)