Question 1. Single-Factor (Market) Model

The market model is estimated over \(n = 96\) months:

\[R_i - R_f = \alpha + \beta\,(R_m - R_f) + \varepsilon\]

Term Estimate Std. Error
Intercept (\(\alpha\)) 0.0017 0.0020
Market premium (\(\beta\)) 0.98 0.17

Reported: \(R^2 = 0.50\), average monthly market premium \(E[R_m - R_f] = 0.70\%\), critical \(|t| \approx 1.98\).

n1        <- 96
alpha     <- 0.0017;  se_alpha <- 0.0020
beta      <- 0.98;    se_beta  <- 0.17
R2_1      <- 0.50
mkt_prem  <- 0.0070     # E[R_m - R_f]
tcrit     <- 1.98

(a) Test \(H_0:\ \beta = 0\)

\[t_\beta = \frac{\hat\beta - 0}{SE(\hat\beta)}\]

t_beta <- beta / se_beta
t_beta
## [1] 5.764706

\(t_\beta =\) 5.7647. Since \(|t_\beta| > 1.98\), we reject \(H_0:\beta=0\). The loading is highly significant. Economically, \(\beta \approx 0.98\) means the fund moves almost one-for-one with the market; its systematic risk is close to the market’s.

(b) Test \(H_0:\ \beta = 1\)

\[t = \frac{\hat\beta - 1}{SE(\hat\beta)}\]

t_beta1 <- (beta - 1) / se_beta
t_beta1
## [1] -0.1176471

\(t =\) -0.1176. Since \(|t| < 1.98\), we fail to reject \(H_0:\beta=1\). There is no statistical evidence the fund’s systematic risk differs from the market’s — it is effectively a market-risk fund.

(c) Jensen’s alpha: test \(H_0:\ \alpha = 0\)

\[t_\alpha = \frac{\hat\alpha}{SE(\hat\alpha)}\]

t_alpha <- alpha / se_alpha
t_alpha
## [1] 0.85

\(t_\alpha =\) 0.8500. Since \(|t_\alpha| < 1.98\), we fail to reject \(H_0:\alpha=0\). The data do not statistically justify advertising “positive risk-adjusted performance.” The point estimate is positive, but it is indistinguishable from zero at the 5% level.

(d) Interpret \(R^2 = 0.50\)

50% of the fund’s return variation is systematic (explained by the market); the remaining 50% is diversifiable / idiosyncratic risk.

(e) CAPM-implied expected monthly excess return

Under CAPM, \(\alpha = 0\), so:

\[E[R_i - R_f] = \beta \cdot E[R_m - R_f]\]

capm_excess <- beta * mkt_prem
capm_excess          # in decimal
## [1] 0.00686
capm_excess * 100    # in percent
## [1] 0.686

CAPM-implied expected monthly excess return \(=\) 0.0069 \(=\) 0.6860%.


Question 2. Fama–French Three-Factor Model

Estimated over \(n = 144\) months:

\[R_i - R_f = \alpha + b\cdot MKT + s\cdot SMB + h\cdot HML + \varepsilon\]

Term Estimate Std. Error
Intercept (\(\alpha\)) 0.0029 0.0018
MKT (\(b\)) 0.97 0.08
SMB (\(s\)) 0.75 0.11
HML (\(h\)) -0.13 0.13

Reported: \(R^2 = 0.92\), Adjusted \(R^2 = 0.918\), critical \(|t| \approx 1.98\).

n2 <- 144
est <- c(alpha = 0.0029, MKT = 0.97, SMB = 0.75, HML = -0.13)
se  <- c(alpha = 0.0018, MKT = 0.08, SMB = 0.11, HML =  0.13)

(f) t-statistics and significance

\[t = \frac{\text{Estimate}}{\text{Std. Error}}\]

t_stats <- est / se
result <- data.frame(
  Term       = names(est),
  Estimate   = est,
  Std.Error  = se,
  t          = round(t_stats, 4),
  Significant = ifelse(abs(t_stats) > tcrit, "Yes", "No")
)
rownames(result) <- NULL
result

Significant at 5%: MKT and SMB. The intercept and HML are not significant.

(g) Investment style (size & value/growth tilt)

  • SMB \(= 0.75 > 0\), significant \(\Rightarrow\) strong small-cap tilt.
  • HML \(= -0.13\), \(t = -1.00\), not significant \(\Rightarrow\) no reliable value/growth tilt (at most a faint growth lean, statistically neutral).

Style: a small-cap fund with no statistically significant value-or-growth tilt.

(h) Interpret the intercept

t_stats["alpha"]
##    alpha 
## 1.611111

\(\alpha = 0.0029\) (\(\approx 0.29\%\)/month, \(\approx 3.5\%\)/year), \(t =\) 1.6111 \(< 1.98\), so it is not significant. The manager’s risk-adjusted alpha is indistinguishable from zero — the data do not support genuine value-add beyond the factor exposures.

(i) \(R^2\) rise from 0.75 to 0.92 and the role of Adjusted \(R^2\)

Adding SMB and HML explains substantially more return variation (here driven mainly by the significant SMB loading). We compare models with adjusted \(R^2\) because plain \(R^2\) never decreases when predictors are added — it can rise on pure noise. Adjusted \(R^2\) penalizes the number of regressors:

\[R^2_{adj} = 1 - (1 - R^2)\,\frac{n - 1}{n - p - 1}\]

adjR2 <- function(R2, n, p) 1 - (1 - R2) * (n - 1) / (n - p - 1)
# Three-factor model: p = 3 predictors
adjR2(0.92, n2, 3)
## [1] 0.9182857

The computed adjusted \(R^2 \approx\) 0.9183 confirms the genuine improvement (matching the reported 0.918) — the added factors improve fit beyond what extra variables would contribute by chance.


Question 3. Logistic Regression for Market Direction

\[\text{logit}\,P(\text{Up}) = \beta_0 + \beta_1 r_{t-1} + \beta_2 \Delta VIX_{t-1}\]

Coefficients: \(\beta_0 = -0.02,\ \beta_1 = 5.4,\ \beta_2 = -0.38\). Inputs: \(r_{t-1} = 0.010,\ \Delta VIX = 1.5\).

b0 <- -0.02; b1 <- 5.4; b2 <- -0.38
r_lag <- 0.010; dVIX <- 1.5

(j) Predicted probability and class

\[\text{logit} = \beta_0 + \beta_1 r_{t-1} + \beta_2 \Delta VIX, \qquad P(\text{Up}) = \frac{1}{1 + e^{-\text{logit}}}\]

logit_val <- b0 + b1 * r_lag + b2 * dVIX
logit_val
## [1] -0.536
p_up <- 1 / (1 + exp(-logit_val))
p_up
## [1] 0.3691186
class_pred <- ifelse(p_up >= 0.5, "Up", "Down")
class_pred
## [1] "Down"

\(\text{logit} =\) -0.5360, so \(P(\text{Up}) =\) 0.3691. Since \(0.3691 < 0.5\), the predicted class is Down.

(k) Economic interpretation of \(\beta_1\) and \(\beta_2\)

  • \(\beta_1 = +5.4\): momentum — a higher prior-day return raises the probability of an up day.
  • \(\beta_2 = -0.38\): rising VIX (fear/volatility) lowers the probability of an up day; a falling VIX favors up moves.

(l) Confusion-matrix metrics

TP <- 67; FN <- 33   # Actual Up = 100
FP <- 44; TN <- 56   # Actual Down = 100
N  <- TP + FN + FP + TN

accuracy    <- (TP + TN) / N
sensitivity <- TP / (TP + FN)   # TPR for "Up"
specificity <- TN / (TN + FP)
precision   <- TP / (TP + FP)   # Predicted Up = 111

data.frame(
  Metric = c("Accuracy", "Sensitivity (TPR, Up)", "Specificity", "Precision (Up)"),
  Value  = round(c(accuracy, sensitivity, specificity, precision), 4)
)

\[\text{Accuracy} = \frac{TP+TN}{N},\quad \text{Sensitivity} = \frac{TP}{TP+FN},\quad \text{Specificity} = \frac{TN}{TN+FP},\quad \text{Precision} = \frac{TP}{TP+FP}\]

(m) Naive majority-class rule

actual_up   <- TP + FN
actual_down <- FP + TN
naive_acc   <- max(actual_up, actual_down) / N
naive_acc
## [1] 0.5
beats <- accuracy > naive_acc
beats
## [1] TRUE

The classes are balanced (100/100), so the majority rule scores 0.5000. The model (0.6150) beats it. Accuracy alone is inadequate for trading because it weights every trade equally and ignores the magnitude of gains/losses and transaction costs — a few large wrong-way trades can erase many small correct ones. A more economically relevant criterion is the strategy’s risk-adjusted return (Sharpe ratio) or expected P&L per trade.


Question 4. Resampling and Regularization in a Backtest

A strategy earns mean monthly return \(0.70\%\) with SD \(5.50\%\) over \(n = 48\) months.

mean_ret <- 0.0070
sd_ret   <- 0.0550
n4       <- 48

(n) Monthly and annualized Sharpe ratio

\[SR_{monthly} = \frac{\bar r}{s}, \qquad SR_{annual} = SR_{monthly}\times\sqrt{12}\]

SR_monthly <- mean_ret / sd_ret
SR_monthly
## [1] 0.1272727
SR_annual  <- SR_monthly * sqrt(12)
SR_annual
## [1] 0.4408857

\(SR_{monthly} =\) 0.1273, annualized \(SR =\) 0.4409. The scaling factor is \(\sqrt{12}\) (assumes i.i.d. monthly returns and risk-free \(\approx 0\)).

(o) Bootstrap SE for the Sharpe ratio

Procedure:

  1. Resample the 48 monthly returns with replacement to form a bootstrap sample of size 48.
  2. Recompute the Sharpe ratio (\(\text{mean} \div \text{SD}\)) on that sample.
  3. Repeat \(B\) times (e.g., \(B = 1{,}000\) to \(10{,}000\)), storing each Sharpe.
  4. The bootstrap SE is the standard deviation of the \(B\) bootstrap Sharpe ratios.
# Illustrative bootstrap (synthetic returns matching the moments)
set.seed(1)
sim_returns <- rnorm(n4, mean = mean_ret, sd = sd_ret)
B <- 2000
boot_SR <- replicate(B, {
  s <- sample(sim_returns, size = n4, replace = TRUE)
  mean(s) / sd(s)
})
se_SR <- sd(boot_SR)
se_SR  # bootstrap standard error of the monthly Sharpe ratio
## [1] 0.16424

The ordinary i.i.d. bootstrap is inappropriate for monthly returns because they exhibit autocorrelation and volatility clustering; resampling observations independently destroys that time dependence and understates the true variability of the Sharpe ratio. Fix: the block bootstrap (moving-block / stationary bootstrap), which resamples contiguous blocks to preserve serial dependence.

(p) Which \(\lambda\) to deploy

Deploy \(\lambda = 0.065\) (7 factors) — the one-standard-error rule. It is the most parsimonious model whose CV error lies within one standard error of the minimum, sacrificing essentially no measured accuracy for a simpler, more robust model. Fewer factors means less overfitting, better out-of-sample stability, and lower turnover/transaction costs. The \(\lambda = 0.030\) (14-factor) minimum-CV solution is more likely fitting noise in the validation folds.

(q) Walk-forward evaluation, and why random k-fold is unsafe

Walk-forward (expanding or rolling window):

  1. Train on an initial in-time window (e.g., months 1–24).
  2. Select \(\lambda\) on the immediately following validation block (e.g., months 25–30) — never using future data.
  3. Test/forecast on the next out-of-sample period; record performance.
  4. Roll or expand the window forward, re-estimate, and repeat to the end of the sample.

Standard random k-fold CV is unsafe because it shuffles observations across time, placing future data into the training folds used to predict the past — look-ahead leakage. This inflates measured accuracy and breaks the autocorrelation structure of returns. A time-respecting (walk-forward) scheme keeps every training set strictly before its test set.