The problem states: - Annual T-bill rate: 5% - Annual S&P 500 risk premium over T-bills: 8% - Annual S&P 500 standard deviation: 20%
We convert to monthly using standard finance conventions: - Monthly rate = Annual rate / 12 - Monthly σ = Annual σ / √12
# ── Annual inputs ──────────────────────────────────────────────
rf_annual <- 0.05 # T-bill rate
rp_annual <- 0.08 # Risk premium (S&P 500 over T-bills)
sigma_annual <- 0.20 # S&P 500 standard deviation
# ── Convert to monthly ─────────────────────────────────────────
rf_m <- rf_annual / 12 # Monthly T-bill rate
rp_m <- rp_annual / 12 # Monthly risk premium
Er_sp_m <- rf_m + rp_m # Monthly E(r) of S&P 500
sigma_m <- sigma_annual / sqrt(12) # Monthly std dev
cat("=== Monthly Parameters ===\n")## === Monthly Parameters ===
## Monthly T-bill rate : 0.0042 (0.4167%)
## Monthly risk premium : 0.0067 (0.6667%)
## Monthly E(r) S&P 500 : 0.0108 (1.0833%)
## Monthly σ S&P 500 : 0.0577 (5.7735%)
## Monthly variance σ² : 0.003333
Task: Calculate E(r) and Var for portfolios with different weights in T-bills vs. S&P 500.
For a portfolio with weight w in the S&P 500 and (1−w) in T-bills:
\[E(r_p) = w \cdot E(r_{S\&P}) + (1-w) \cdot r_f\]
\[\sigma_p^2 = w^2 \cdot \sigma_{S\&P}^2\]
\[\sigma_p = w \cdot \sigma_{S\&P}\]
# Portfolio weights
w_bills <- c(0, 0.2, 0.4, 0.6, 0.8, 1.0)
w_index <- 1 - w_bills
# Monthly calculations
Er_p <- w_index * Er_sp_m + w_bills * rf_m
Var_p <- w_index^2 * sigma_m^2
Sig_p <- sqrt(Var_p)
prob10 <- data.frame(
W_bills = w_bills,
W_index = w_index,
E_r_pct = round(Er_p * 100, 4),
Variance = round(Var_p, 6),
Std_Dev_pct= round(Sig_p * 100, 4)
)
kable(prob10,
col.names = c("W_bills", "W_index",
"E(r) Monthly (%)", "Variance (monthly)",
"Std Dev Monthly (%)"),
caption = "Problem 10 – Monthly Portfolio Statistics") %>%
kable_styling(bootstrap_options = c("striped","hover","condensed"),
full_width = FALSE)| W_bills | W_index | E(r) Monthly (%) | Variance (monthly) | Std Dev Monthly (%) |
|---|---|---|---|---|
| 0.0 | 1.0 | 1.0833 | 0.003333 | 5.7735 |
| 0.2 | 0.8 | 0.9500 | 0.002133 | 4.6188 |
| 0.4 | 0.6 | 0.8167 | 0.001200 | 3.4641 |
| 0.6 | 0.4 | 0.6833 | 0.000533 | 2.3094 |
| 0.8 | 0.2 | 0.5500 | 0.000133 | 1.1547 |
| 1.0 | 0.0 | 0.4167 | 0.000000 | 0.0000 |
ggplot(prob10, aes(x = Std_Dev_pct, y = E_r_pct, label = paste0("w=", W_index))) +
geom_line(colour = "steelblue", linewidth = 1) +
geom_point(colour = "steelblue", size = 3) +
geom_text(vjust = -0.8, size = 3.2) +
labs(title = "Problem 10: Capital Allocation Line (Monthly)",
subtitle = "Portfolios of T-bills and S&P 500",
x = "Monthly Standard Deviation (%)",
y = "Monthly Expected Return (%)") +
theme_minimal()The utility function is:
\[U = E(r) - \frac{1}{2} A \sigma^2\]
A2 <- 2
prob11 <- prob10 %>%
mutate(Utility_A2 = round(Er_p - 0.5 * A2 * Var_p, 6))
kable(prob11 %>% select(W_bills, W_index, E_r_pct, Variance, Utility_A2),
col.names = c("W_bills","W_index","E(r) Monthly (%)","Variance","Utility (A=2)"),
caption = "Problem 11 – Monthly Utility with A = 2") %>%
kable_styling(bootstrap_options = c("striped","hover","condensed"),
full_width = FALSE) %>%
row_spec(which.max(prob11$Utility_A2), bold = TRUE, color = "white",
background = "#2c7bb6")| W_bills | W_index | E(r) Monthly (%) | Variance | Utility (A=2) |
|---|---|---|---|---|
| 0.0 | 1.0 | 1.0833 | 0.003333 | 0.007500 |
| 0.2 | 0.8 | 0.9500 | 0.002133 | 0.007367 |
| 0.4 | 0.6 | 0.8167 | 0.001200 | 0.006967 |
| 0.6 | 0.4 | 0.6833 | 0.000533 | 0.006300 |
| 0.8 | 0.2 | 0.5500 | 0.000133 | 0.005367 |
| 1.0 | 0.0 | 0.4167 | 0.000000 | 0.004167 |
ggplot(prob11, aes(x = W_index, y = Utility_A2)) +
geom_line(colour = "darkorange", linewidth = 1) +
geom_point(colour = "darkorange", size = 3) +
geom_point(data = prob11[which.max(prob11$Utility_A2),],
colour = "red", size = 5, shape = 8) +
labs(title = "Problem 11: Utility by Equity Weight (A = 2, Monthly)",
x = "Weight in S&P 500 Index (W_index)",
y = "Utility") +
theme_minimal()Conclusion (A = 2): The portfolio with the
highest utility (★) is the one at
w_index = 1. Because A = 2 represents a
relatively low risk aversion, this investor tolerates
more equity exposure and benefits from the higher expected return.
A3 <- 3
prob12 <- prob10 %>%
mutate(Utility_A3 = round(Er_p - 0.5 * A3 * Var_p, 6))
kable(prob12 %>% select(W_bills, W_index, E_r_pct, Variance, Utility_A3),
col.names = c("W_bills","W_index","E(r) Monthly (%)","Variance","Utility (A=3)"),
caption = "Problem 12 – Monthly Utility with A = 3") %>%
kable_styling(bootstrap_options = c("striped","hover","condensed"),
full_width = FALSE) %>%
row_spec(which.max(prob12$Utility_A3), bold = TRUE, color = "white",
background = "#d7191c")| W_bills | W_index | E(r) Monthly (%) | Variance | Utility (A=3) |
|---|---|---|---|---|
| 0.0 | 1.0 | 1.0833 | 0.003333 | 0.005833 |
| 0.2 | 0.8 | 0.9500 | 0.002133 | 0.006300 |
| 0.4 | 0.6 | 0.8167 | 0.001200 | 0.006367 |
| 0.6 | 0.4 | 0.6833 | 0.000533 | 0.006033 |
| 0.8 | 0.2 | 0.5500 | 0.000133 | 0.005300 |
| 1.0 | 0.0 | 0.4167 | 0.000000 | 0.004167 |
bind_rows(
prob11 %>% mutate(A = "A = 2", Utility = Utility_A2),
prob12 %>% mutate(A = "A = 3", Utility = Utility_A3)
) %>%
ggplot(aes(x = W_index, y = Utility, colour = A, group = A)) +
geom_line(linewidth = 1) +
geom_point(size = 3) +
scale_colour_manual(values = c("A = 2" = "darkorange", "A = 3" = "#d7191c")) +
labs(title = "Problems 11 & 12: Utility Comparison (Monthly)",
x = "Weight in S&P 500 Index",
y = "Utility",
colour = "Risk Aversion") +
theme_minimal()Conclusion (A = 3): The optimal equity weight decreases relative to A = 2. A higher A penalises variance more, so a more risk-averse investor prefers a lower allocation to the risky asset. The peak utility shifts to the left compared with Problem 11.
The utility formula is \(U = E(r) - \frac{1}{2}(4)\sigma^2\).
# CFA data (already monthly / annual — given as-is, no conversion stated)
inv <- 1:4
Er_cfa <- c(0.12, 0.15, 0.21, 0.24)
sigma_cfa <- c(0.30, 0.50, 0.16, 0.21)
A_cfa1 <- 4
U_cfa1 <- Er_cfa - 0.5 * A_cfa1 * sigma_cfa^2
cfa1_df <- data.frame(Investment = inv,
E_r = Er_cfa,
Sigma = sigma_cfa,
Utility = round(U_cfa1, 4))
kable(cfa1_df,
col.names = c("Investment","E(r)","σ","Utility (A=4)"),
caption = "CFA Problem 1 – Utility with A = 4") %>%
kable_styling(bootstrap_options = c("striped","hover","condensed"),
full_width = FALSE) %>%
row_spec(which.max(U_cfa1), bold = TRUE, color = "white", background = "#1a9641")| Investment | E(r) | σ | Utility (A=4) |
|---|---|---|---|
| 1 | 0.12 | 0.30 | -0.0600 |
| 2 | 0.15 | 0.50 | -0.3500 |
| 3 | 0.21 | 0.16 | 0.1588 |
| 4 | 0.24 | 0.21 | 0.1518 |
Answer: An investor with A = 4 selects Investment 3 (U = 0.1588), which offers the highest risk-adjusted utility despite not having the highest raw expected return.
A risk-neutral investor has A = 0, so utility equals expected return: \(U = E(r)\).
U_neutral <- Er_cfa # A = 0
cfa2_df <- data.frame(Investment = inv,
E_r = Er_cfa,
Sigma = sigma_cfa,
Utility_RN = round(U_neutral, 4))
kable(cfa2_df,
col.names = c("Investment","E(r)","σ","Utility (Risk-Neutral)"),
caption = "CFA Problem 2 – Risk-Neutral Investor") %>%
kable_styling(bootstrap_options = c("striped","hover","condensed"),
full_width = FALSE) %>%
row_spec(which.max(U_neutral), bold = TRUE, color = "white", background = "#fdae61")| Investment | E(r) | σ | Utility (Risk-Neutral) |
|---|---|---|---|
| 1 | 0.12 | 0.30 | 0.12 |
| 2 | 0.15 | 0.50 | 0.15 |
| 3 | 0.21 | 0.16 | 0.21 |
| 4 | 0.24 | 0.21 | 0.24 |
Answer: A risk-neutral investor selects Investment 4 because she cares only about maximising expected return, ignoring variance entirely.
The utility formula is \(U = E(r) - \frac{1}{2}A\sigma^2\).
| Option | Statement |
|---|---|
| a | Investor’s return requirement |
| b | Investor’s aversion to risk ✓ |
| c | Certainty equivalent rate of the portfolio |
| d | Preference for one unit of return per four units of risk |
Answer: (b) — A is the coefficient of risk aversion. A larger A means the investor penalises variance more heavily, reducing willingness to hold risky assets. The term \(\frac{1}{2}A\sigma^2\) is the utility penalty for bearing risk.
summary_df <- data.frame(
Problem = c("10","11","12","CFA 1","CFA 2","CFA 3"),
Key_Result = c(
"E(r) and Var scale linearly / quadratically with equity weight",
paste0("Optimal W_index = ", prob11$W_index[which.max(prob11$Utility_A2)], " (A=2)"),
paste0("Optimal W_index = ", prob12$W_index[which.max(prob12$Utility_A3)], " (A=3, more conservative)"),
"Investment 3 maximises utility (A=4)",
"Investment 4 maximises utility (risk-neutral, max E(r))",
"A = coefficient of risk aversion (answer b)"
)
)
kable(summary_df, caption = "Homework 3 – Summary of Answers") %>%
kable_styling(bootstrap_options = c("striped","hover"), full_width = TRUE)| Problem | Key_Result |
|---|---|
| 10 | E(r) and Var scale linearly / quadratically with equity weight |
| 11 | Optimal W_index = 1 (A=2) |
| 12 | Optimal W_index = 0.6 (A=3, more conservative) |
| CFA 1 | Investment 3 maximises utility (A=4) |
| CFA 2 | Investment 4 maximises utility (risk-neutral, max E(r)) |
| CFA 3 | A = coefficient of risk aversion (answer b) |