Skip to content

Options Pricing API Reference

financelib.quant.options.black_scholes(S: float, K: float, T: float, r: float, sigma: float, option_type: str = 'call') -> float

Calculate European option price using Black-Scholes formula.

Parameters:

Name Type Description Default
S float

Current stock price.

required
K float

Strike price.

required
T float

Time to expiration in years.

required
r float

Risk-free interest rate (annualized).

required
sigma float

Volatility (annualized).

required
option_type str

'call' or 'put'.

'call'

Returns:

Type Description
float

Option price.

Example

black_scholes(S=100, K=100, T=1, r=0.05, sigma=0.2) 10.4506...

Source code in financelib/quant/options.py
def black_scholes(
    S: float,
    K: float,
    T: float,
    r: float,
    sigma: float,
    option_type: str = "call",
) -> float:
    """Calculate European option price using Black-Scholes formula.

    Args:
        S: Current stock price.
        K: Strike price.
        T: Time to expiration in years.
        r: Risk-free interest rate (annualized).
        sigma: Volatility (annualized).
        option_type: 'call' or 'put'.

    Returns:
        Option price.

    Example:
        >>> black_scholes(S=100, K=100, T=1, r=0.05, sigma=0.2)
        10.4506...
    """
    if T <= 0 or sigma <= 0:
        intrinsic = max(S - K, 0) if option_type == "call" else max(K - S, 0)
        return intrinsic

    d1 = (log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * sqrt(T))
    d2 = d1 - sigma * sqrt(T)

    if option_type == "call":
        return S * _norm_cdf(d1) - K * exp(-r * T) * _norm_cdf(d2)
    else:
        return K * exp(-r * T) * _norm_cdf(-d2) - S * _norm_cdf(-d1)

financelib.quant.options.greeks(S: float, K: float, T: float, r: float, sigma: float, option_type: str = 'call') -> Dict[str, float]

Calculate option Greeks (delta, gamma, theta, vega, rho).

Parameters:

Name Type Description Default
S float

Current stock price.

required
K float

Strike price.

required
T float

Time to expiration in years.

required
r float

Risk-free interest rate.

required
sigma float

Volatility.

required
option_type str

'call' or 'put'.

'call'

Returns:

Type Description
Dict[str, float]

Dictionary with delta, gamma, theta, vega, rho.

Source code in financelib/quant/options.py
def greeks(
    S: float,
    K: float,
    T: float,
    r: float,
    sigma: float,
    option_type: str = "call",
) -> Dict[str, float]:
    """Calculate option Greeks (delta, gamma, theta, vega, rho).

    Args:
        S: Current stock price.
        K: Strike price.
        T: Time to expiration in years.
        r: Risk-free interest rate.
        sigma: Volatility.
        option_type: 'call' or 'put'.

    Returns:
        Dictionary with delta, gamma, theta, vega, rho.
    """
    if T <= 0 or sigma <= 0:
        return {"delta": 0, "gamma": 0, "theta": 0, "vega": 0, "rho": 0}

    d1 = (log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * sqrt(T))
    d2 = d1 - sigma * sqrt(T)

    # Gamma and Vega are the same for calls and puts
    gamma = _norm_pdf(d1) / (S * sigma * sqrt(T))
    vega = S * _norm_pdf(d1) * sqrt(T) / 100  # Per 1% change in vol

    if option_type == "call":
        delta = _norm_cdf(d1)
        theta = (
            -S * _norm_pdf(d1) * sigma / (2 * sqrt(T))
            - r * K * exp(-r * T) * _norm_cdf(d2)
        ) / 365  # Per day
        rho = K * T * exp(-r * T) * _norm_cdf(d2) / 100
    else:
        delta = _norm_cdf(d1) - 1
        theta = (
            -S * _norm_pdf(d1) * sigma / (2 * sqrt(T))
            + r * K * exp(-r * T) * _norm_cdf(-d2)
        ) / 365
        rho = -K * T * exp(-r * T) * _norm_cdf(-d2) / 100

    return {
        "delta": round(delta, 6),
        "gamma": round(gamma, 6),
        "theta": round(theta, 6),
        "vega": round(vega, 6),
        "rho": round(rho, 6),
    }

financelib.quant.options.implied_volatility(market_price: float, S: float, K: float, T: float, r: float, option_type: str = 'call', tol: float = 1e-06, max_iter: int = 100) -> float

Calculate implied volatility using Newton-Raphson method.

Parameters:

Name Type Description Default
market_price float

Observed market price of the option.

required
S float

Current stock price.

required
K float

Strike price.

required
T float

Time to expiration in years.

required
r float

Risk-free interest rate.

required
option_type str

'call' or 'put'.

'call'
tol float

Convergence tolerance.

1e-06
max_iter int

Maximum iterations.

100

Returns:

Type Description
float

Implied volatility as a decimal.

Source code in financelib/quant/options.py
def implied_volatility(
    market_price: float,
    S: float,
    K: float,
    T: float,
    r: float,
    option_type: str = "call",
    tol: float = 1e-6,
    max_iter: int = 100,
) -> float:
    """Calculate implied volatility using Newton-Raphson method.

    Args:
        market_price: Observed market price of the option.
        S: Current stock price.
        K: Strike price.
        T: Time to expiration in years.
        r: Risk-free interest rate.
        option_type: 'call' or 'put'.
        tol: Convergence tolerance.
        max_iter: Maximum iterations.

    Returns:
        Implied volatility as a decimal.
    """
    sigma = 0.3  # Initial guess

    for _ in range(max_iter):
        price = black_scholes(S, K, T, r, sigma, option_type)
        diff = price - market_price

        if abs(diff) < tol:
            return sigma

        d1 = (log(S / K) + (r + 0.5 * sigma**2) * T) / (sigma * sqrt(T))
        vega = S * _norm_pdf(d1) * sqrt(T)

        if vega < 1e-12:
            break

        sigma -= diff / vega
        sigma = max(sigma, 0.001)

    return sigma

financelib.quant.options.binomial_tree(S: float, K: float, T: float, r: float, sigma: float, n_steps: int = 100, option_type: str = 'call', american: bool = False) -> float

Price an option using the Cox-Ross-Rubinstein binomial tree.

Supports both European and American options.

Parameters:

Name Type Description Default
S float

Current stock price.

required
K float

Strike price.

required
T float

Time to expiration in years.

required
r float

Risk-free interest rate.

required
sigma float

Volatility.

required
n_steps int

Number of time steps in the tree.

100
option_type str

'call' or 'put'.

'call'
american bool

If True, price an American option (early exercise).

False

Returns:

Type Description
float

Option price.

Source code in financelib/quant/options.py
def binomial_tree(
    S: float,
    K: float,
    T: float,
    r: float,
    sigma: float,
    n_steps: int = 100,
    option_type: str = "call",
    american: bool = False,
) -> float:
    """Price an option using the Cox-Ross-Rubinstein binomial tree.

    Supports both European and American options.

    Args:
        S: Current stock price.
        K: Strike price.
        T: Time to expiration in years.
        r: Risk-free interest rate.
        sigma: Volatility.
        n_steps: Number of time steps in the tree.
        option_type: 'call' or 'put'.
        american: If True, price an American option (early exercise).

    Returns:
        Option price.
    """
    dt = T / n_steps
    u = exp(sigma * sqrt(dt))
    d = 1 / u
    p = (exp(r * dt) - d) / (u - d)
    disc = exp(-r * dt)

    # Terminal payoffs
    prices = np.array([S * u**j * d**(n_steps - j) for j in range(n_steps + 1)])

    if option_type == "call":
        values = np.maximum(prices - K, 0)
    else:
        values = np.maximum(K - prices, 0)

    # Backward induction
    for i in range(n_steps - 1, -1, -1):
        prices = np.array([S * u**j * d**(i - j) for j in range(i + 1)])
        values = disc * (p * values[1:i + 2] + (1 - p) * values[0:i + 1])

        if american:
            if option_type == "call":
                exercise = np.maximum(prices - K, 0)
            else:
                exercise = np.maximum(K - prices, 0)
            values = np.maximum(values, exercise)

    return float(values[0])