Skip to content

Factor Models API Reference

financelib.quant.factors.factor_exposure(asset_returns: pd.Series, factor_returns: pd.DataFrame) -> Dict[str, float]

Compute factor loadings (betas) via OLS regression.

Regresses asset returns on factor returns to determine sensitivity to each factor.

Parameters:

Name Type Description Default
asset_returns Series

Asset returns series.

required
factor_returns DataFrame

DataFrame of factor returns (columns = factors).

required

Returns:

Type Description
Dict[str, float]

Dictionary mapping factor names to their loadings (betas),

Dict[str, float]

plus 'alpha' (intercept) and 'r_squared'.

Example

exposures = factor_exposure(stock_returns, factor_df) print(f"Market beta: {exposures['MKT']:.2f}")

Source code in financelib/quant/factors.py
def factor_exposure(
    asset_returns: pd.Series,
    factor_returns: pd.DataFrame,
) -> Dict[str, float]:
    """Compute factor loadings (betas) via OLS regression.

    Regresses asset returns on factor returns to determine
    sensitivity to each factor.

    Args:
        asset_returns: Asset returns series.
        factor_returns: DataFrame of factor returns (columns = factors).

    Returns:
        Dictionary mapping factor names to their loadings (betas),
        plus 'alpha' (intercept) and 'r_squared'.

    Example:
        >>> exposures = factor_exposure(stock_returns, factor_df)
        >>> print(f"Market beta: {exposures['MKT']:.2f}")
    """
    aligned = pd.concat([asset_returns, factor_returns], axis=1).dropna()
    if len(aligned) < 10:
        return {"alpha": 0.0, "r_squared": 0.0}

    y = aligned.iloc[:, 0].values
    X = aligned.iloc[:, 1:].values

    # Add intercept
    X_with_const = np.column_stack([np.ones(len(X)), X])

    # OLS: beta = (X'X)^-1 X'y
    try:
        betas = np.linalg.lstsq(X_with_const, y, rcond=None)[0]
    except np.linalg.LinAlgError:
        return {"alpha": 0.0, "r_squared": 0.0}

    # R-squared
    y_pred = X_with_const @ betas
    ss_res = np.sum((y - y_pred) ** 2)
    ss_tot = np.sum((y - np.mean(y)) ** 2)
    r_squared = 1 - (ss_res / ss_tot) if ss_tot > 0 else 0.0

    result: Dict[str, float] = {"alpha": float(betas[0]), "r_squared": float(r_squared)}
    for i, col in enumerate(factor_returns.columns):
        result[col] = float(betas[i + 1])

    return result

financelib.quant.factors.fama_french_three(asset_returns: pd.Series, market_returns: pd.Series, smb: pd.Series, hml: pd.Series) -> Dict[str, float]

Run Fama-French 3-factor model regression.

R_i - R_f = alpha + beta_MKT(R_m - R_f) + beta_SMBSMB + beta_HML*HML + epsilon

Parameters:

Name Type Description Default
asset_returns Series

Asset excess returns.

required
market_returns Series

Market excess returns (R_m - R_f).

required
smb Series

Small Minus Big factor returns.

required
hml Series

High Minus Low factor returns.

required

Returns:

Type Description
Dict[str, float]

Dictionary with alpha, MKT, SMB, HML betas, and r_squared.

Source code in financelib/quant/factors.py
def fama_french_three(
    asset_returns: pd.Series,
    market_returns: pd.Series,
    smb: pd.Series,
    hml: pd.Series,
) -> Dict[str, float]:
    """Run Fama-French 3-factor model regression.

    R_i - R_f = alpha + beta_MKT*(R_m - R_f) + beta_SMB*SMB + beta_HML*HML + epsilon

    Args:
        asset_returns: Asset excess returns.
        market_returns: Market excess returns (R_m - R_f).
        smb: Small Minus Big factor returns.
        hml: High Minus Low factor returns.

    Returns:
        Dictionary with alpha, MKT, SMB, HML betas, and r_squared.
    """
    factors = pd.DataFrame({"MKT": market_returns, "SMB": smb, "HML": hml})
    return factor_exposure(asset_returns, factors)

financelib.quant.factors.fama_french_five(asset_returns: pd.Series, market_returns: pd.Series, smb: pd.Series, hml: pd.Series, rmw: pd.Series, cma: pd.Series) -> Dict[str, float]

Run Fama-French 5-factor model regression.

Extends 3-factor model with profitability (RMW) and investment (CMA).

Parameters:

Name Type Description Default
asset_returns Series

Asset excess returns.

required
market_returns Series

Market excess returns.

required
smb Series

Small Minus Big.

required
hml Series

High Minus Low.

required
rmw Series

Robust Minus Weak (profitability).

required
cma Series

Conservative Minus Aggressive (investment).

required

Returns:

Type Description
Dict[str, float]

Dictionary with alpha, factor betas, and r_squared.

Source code in financelib/quant/factors.py
def fama_french_five(
    asset_returns: pd.Series,
    market_returns: pd.Series,
    smb: pd.Series,
    hml: pd.Series,
    rmw: pd.Series,
    cma: pd.Series,
) -> Dict[str, float]:
    """Run Fama-French 5-factor model regression.

    Extends 3-factor model with profitability (RMW) and investment (CMA).

    Args:
        asset_returns: Asset excess returns.
        market_returns: Market excess returns.
        smb: Small Minus Big.
        hml: High Minus Low.
        rmw: Robust Minus Weak (profitability).
        cma: Conservative Minus Aggressive (investment).

    Returns:
        Dictionary with alpha, factor betas, and r_squared.
    """
    factors = pd.DataFrame({
        "MKT": market_returns,
        "SMB": smb,
        "HML": hml,
        "RMW": rmw,
        "CMA": cma,
    })
    return factor_exposure(asset_returns, factors)