import math


def implied_vol_quadratic_approx(
        underlying, strike, rate, maturity, option_value):
    """implied_vol_quadratic_approx
    calculates implied volatility by Corrado-Miller approximation formula.
    See Corrado, C. J., & Miller, T. W. (1996).
    A note on a simple, accurate formula
    to compute implied standard deviations.
    Journal of Banking & Finance, 20(1996), 595–603.
    https://doi.org/10.1016/0378-4266(95)00014-3

    :param float underlying:
    :param float strike:
    :param float rate:
    :param float maturity:
    :param float option_value:

    :return: approximated implied volatility.
        If `maturity` is not positive, this function returns 0.
    :rtype: float.
    """
    if maturity <= 0.0:
        return 0.0
    discount_strike = math.exp(-rate * maturity) * strike
    moneyness_delta = underlying - discount_strike
    diff = option_value - moneyness_delta / 2.0
    moneyness_delta2 = moneyness_delta ** 2
    # take lower bound
    sqrt_inner = max(diff ** 2 - moneyness_delta2 / math.pi, 0.0)
    factor1 = diff + math.sqrt(sqrt_inner)
    factor2 = (math.sqrt(2.0 * math.pi / maturity)
               / (underlying + discount_strike))
    return factor1 * factor2