import math

def payoff_binomial_call(Su: float, Sd: float, K: float) -> tuple[float,float]:
    """
    Calculate call option payoffs in up and down states for binomial model.
    
    Args:
        Su: Stock price in up state
        Sd: Stock price in down state  
        K: Strike price
        
    Returns:
        Tuple of (payoff_up, payoff_down) where:
        - payoff_up: Call option payoff if stock goes up
        - payoff_down: Call option payoff if stock goes down
        
    Example:
        >>> payoff_binomial_call(110.0, 90.0, 100.0)
        (10.0, 0.0)
    """
    Cu = max(Su - K, 0.0)
    Cd = max(Sd - K, 0.0)
    return Cu, Cd

def hedge_ratio_binomial(Cu: float, Cd: float, Su: float, Sd: float) -> float:
    """
    Calculate hedge ratio (delta) for binomial option model.
    
    The hedge ratio represents the number of shares of the underlying stock
    needed to replicate the option payoff in a binomial model.
    
    Args:
        Cu: Option value in up state
        Cd: Option value in down state
        Su: Stock price in up state
        Sd: Stock price in down state
        
    Returns:
        Hedge ratio (number of shares to hold)
        
    Example:
        >>> hedge_ratio_binomial(10.0, 0.0, 110.0, 90.0)
        0.5
    """
    return (Cu - Cd) / (Su - Sd)

def loan_binomial(Cu: float, Cd: float, Su: float, Sd: float, r: float) -> float:
    """
    Calculate loan amount needed for binomial replication strategy.
    
    This function computes the amount that needs to be borrowed (positive) 
    or lent (negative) to complete the replication portfolio.
    
    Args:
        Cu: Option value in up state
        Cd: Option value in down state
        Su: Stock price in up state
        Sd: Stock price in down state
        r: Risk-free rate (as decimal, e.g., 0.05 for 5%)
        
    Returns:
        Loan amount (negative means lending, positive means borrowing)
        
    Example:
        >>> loan_binomial(10.0, 0.0, 110.0, 90.0, 0.05)
        -42.857...
    """
    Δ = hedge_ratio_binomial(Cu, Cd, Su, Sd)
    return (Δ * Sd - Cd) / (1.0 + r)

def price_binomial_one_period(S0: float, Delta: float, B_hat: float, r: float, tau: float=1.0) -> float:
    """
    Price option using one-period binomial replication.
    
    This function calculates the option price using the replication portfolio
    approach: Option = Delta * Stock - Loan * (1+r)^tau
    
    Args:
        S0: Current stock price
        Delta: Hedge ratio (number of shares to hold)
        B_hat: Loan amount (negative means you lend money)
        r: Risk-free rate (as decimal, e.g., 0.05 for 5%)
        tau: Time to expiration in years (default 1.0)
        
    Returns:
        Option price
        
    Example:
        >>> price_binomial_one_period(100.0, 0.5, -42.86, 0.05, 1.0)
        5.003...
    """
    return Delta * S0 - (1.0 + r)**tau * B_hat

def price_risk_neutral_one_period(S0: float, Su: float, Sd: float,
                                  Cu: float, Cd: float,
                                  r: float, tau: float=1.0) -> float:
    """
    Price option using risk-neutral valuation in one-period binomial model.
    
    This function calculates the option price using risk-neutral probabilities.
    The risk-neutral probability is calculated as p* = (e^(r*tau) - d)/(u - d)
    where u = Su/S0 and d = Sd/S0.
    
    Args:
        S0: Current stock price
        Su: Stock price in up state
        Sd: Stock price in down state
        Cu: Option value in up state
        Cd: Option value in down state
        r: Risk-free rate (as decimal, e.g., 0.05 for 5%)
        tau: Time to expiration in years (default 1.0)
        
    Returns:
        Option price
        
    Example:
        >>> price_risk_neutral_one_period(100.0, 110.0, 90.0, 10.0, 0.0, 0.05, 1.0)
        5.003...
    """
    u, d = Su / S0, Sd / S0
    p_star = (math.exp(r * tau) - d) / (u - d)
    expected_payoff = p_star * Cu + (1 - p_star) * Cd
    return math.exp(-r * tau) * expected_payoff
