σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsSkills
Ctrl K
AO
+1.2k Learners
LoginJoin ↗
RoadmapsSkills
AO
+1.2k Learners
Login
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsSkills
Ctrl K
AO
+1.2k Learners
LoginJoin ↗
RoadmapsSkills
AO
+1.2k Learners
Login
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
statsmodels skill›Module 1 · Regression and its checks›Topic 1.3·~50 minIntermediate

Running and reading a factor regression

Skill positionModule 1 of 3 · Topic 3 of 10
1.3 Running and reading a factor regression
—Lab score— / 100Total XP—Streak—

From a formula to a full regression

statsmodels.formula.api.ols('excess ~ mkt_rf + smb + hml', data=table).fit() fits an ordinary least squares regression from a one-line formula: the name on the left of ~ is the thing to explain, the names on the right are the regressors, and an intercept is added for you (write - 1 to remove it). The result object holds everything: params (the coefficients), bse (their standard errors), tvalues, pvalues, rsquared, rsquared_adj, aic, resid and summary() for the printed report. Because every one of these is a pandas Series or a number, putting them side by side in a DataFrame gives a clean table, and res.predict(new_frame) applies the fitted formula to new rows with the same column names. The factor regression of a stock is the standard use: excess is the stock's return above the risk-free rate, mkt_rf the market's, smb the size factor and hml the value factor.

Two comparisons make the table useful. The CAPM uses only the market, excess ~ mkt_rf; the three-factor model adds smb and hml. Adding regressors can never lower R², so use the adjusted R², the AIC, or an F test: ff3.compare_f_test(capm) returns the F statistic, its p-value and the number of extra regressors, and a small p-value says the two extra factors add real explanatory power. A second routine point is the table itself. Month-end returns come from the last close of each calendar month (prices.groupby(prices.index.to_period('M')).last() then pct_change()), and they must be joined to the factor table on the same month: a regression on misaligned months is a regression on noise.

What the real data saysApple has 319 monthly returns between February 2000 and August 2026. The CAPM gives a market beta of 1.31 (t=11.7), an alpha of 1.5% a month and R²=0.30. With size and value added, R² rises to 0.355, the loading on value is -0.72 (t=-4.98: Apple behaves like a growth stock), the size loading is small and not significant, and the alpha is 1.7% a month. The F test of the two extra factors has a p-value of 2.7×10⁻⁶. The CAPM predicts that a month in which the market beats cash by 5% comes with an Apple excess return of 8.07%.
  • One line, one regression: the formula names the response and the regressors, and the results object holds every statistic.
  • Compare nested models with the right tool: R-squared always rises, so use adjusted R-squared, AIC or the F test.
  • Align the months first: a month-end return belongs with the factors of the same month.

Lab · what's graded

  • The monthly regression table15 pts
  • The CAPM fit10 pts
  • The three-factor fit10 pts
  • A tidy coefficient table15 pts
  • Is the bigger model worth it?15 pts
  • A prediction10 pts
  • The whole study25 pts
Explorer · lab-sx-11
▾ lab-sx-11
▾ data
…
bash · in-browser
learner@quantcraft:~/lab-sx-11$
Python not loaded yetPythonLn 1, Col 1Spaces: 4UTF-8

Reset this topic?

Everything in lab-sx-11 goes back to the starter files and the terminal is cleared. Your current solution will be lost — this can't be undone.

Will be reset
  • main.py → starter code
  • Terminal history and test output
  • Unsubmitted changes
Will be kept
  • Best lab score
  • Your XP and streak
  • Lecture progress and notes

Log in to run your code.

Every lecture is free to read. Create an account or log in to run code, run tests and submit this lab.

  • In-browser IDE with a bash terminal — nothing to install
  • Instant grading, XP and your place on the skill
Create an accountLog in
OR
Continue with GitHub