R for Finance Exercises: 25 Practice Problems
Twenty-five practice problems for finance work in R: returns, volatility, portfolios, Sharpe, VaR, CAPM, factor models. Hidden solutions.
By Selva Prabhakaran · Published May 11, 2026 · Last updated May 11, 2026
library(dplyr)
library(tibble)
library(ggplot2)
library(quantmod)
library(slider)
library(zoo)
Exercise 1: Simple returns
Difficulty: Beginner.
Show solution
p <- c(100, 102, 99, 105, 108)
diff(p) / head(p, -1)
Exercise 2: Log returns
Difficulty: Beginner.
Show solution
p <- c(100, 102, 99, 105, 108)
diff(log(p))
Exercise 3: Cumulative return
Difficulty: Intermediate.
Show solution
r <- c(0.02, -0.03, 0.06, 0.03)
prod(1 + r) - 1
Exercise 4: Annualized return
Difficulty: Intermediate.
Show solution
r <- runif(252, -0.02, 0.02)
prod(1 + r)^(252/length(r)) - 1
Exercise 5: Daily volatility
Difficulty: Intermediate.
Show solution
r <- rnorm(252, 0, 0.01)
sd(r)
Exercise 6: Annualized vol from daily
Difficulty: Intermediate.
Show solution
r <- rnorm(252, 0, 0.01)
sd(r) * sqrt(252)
Exercise 7: Sharpe ratio
Difficulty: Intermediate. Excess return / std.
Show solution
r <- rnorm(252, 0.0005, 0.01) # daily
rf <- 0.04 / 252
(mean(r) - rf) / sd(r) * sqrt(252)
Exercise 8: Maximum drawdown
Difficulty: Advanced.
Show solution
set.seed(1)
prices <- cumprod(1 + rnorm(252, 0.0005, 0.01)) * 100
peak <- cummax(prices)
dd <- prices / peak - 1
min(dd)
Exercise 9: Portfolio return (2 assets)
Difficulty: Intermediate.
Show solution
w <- c(0.6, 0.4)
r <- c(0.08, 0.05)
sum(w * r)
Exercise 10: Portfolio variance
Difficulty: Advanced.
Show solution
w <- c(0.6, 0.4)
S <- matrix(c(0.04, 0.01, 0.01, 0.025), 2, 2)
t(w) %*% S %*% w
Exercise 11: Covariance matrix
Difficulty: Intermediate.
Show solution
set.seed(1)
r <- matrix(rnorm(252*3, 0, 0.01), ncol = 3)
cov(r) * 252
Exercise 12: Correlation matrix
Difficulty: Beginner.
Show solution
set.seed(1)
r <- matrix(rnorm(252*3, 0, 0.01), ncol = 3)
cor(r)
Exercise 13: Historical VaR 5%
Difficulty: Advanced.
Show solution
set.seed(1)
r <- rnorm(1000, 0, 0.01)
quantile(r, 0.05)
Exercise 14: Parametric VaR
Difficulty: Advanced.
Show solution
mu <- 0; sigma <- 0.01
qnorm(0.05, mu, sigma)
Exercise 15: Conditional VaR (Expected Shortfall)
Difficulty: Advanced.
Show solution
set.seed(1)
r <- rnorm(1000, 0, 0.01)
v <- quantile(r, 0.05)
mean(r[r <= v])
Exercise 16: Beta vs market (CAPM)
Difficulty: Advanced.
Show solution
set.seed(1)
mkt <- rnorm(252, 0, 0.012)
asset <- 1.3 * mkt + rnorm(252, 0, 0.005)
coef(lm(asset ~ mkt))["mkt"]
Exercise 17: Rolling mean return
Difficulty: Advanced.
Show solution
set.seed(1)
r <- rnorm(252, 0.0005, 0.01)
roll <- zoo::rollmean(r, k = 20, fill = NA, align = "right")
tail(roll, 5)
Exercise 18: Compounding 10 years at 7%
Difficulty: Beginner.
Show solution
100 * (1 + 0.07)^10
Exercise 19: Time-weighted return
Difficulty: Advanced.
Show solution
sub_returns <- c(0.05, -0.02, 0.03)
prod(1 + sub_returns) - 1
Exercise 20: Equal-weight portfolio backtest
Difficulty: Advanced.
Show solution
set.seed(1)
r <- matrix(rnorm(252 * 3, 0.0003, 0.01), ncol = 3)
portfolio <- rowMeans(r)
cumprod(1 + portfolio)[252]
Exercise 21: Plot returns
Difficulty: Intermediate.
Show solution
set.seed(1)
r <- rnorm(252, 0.0005, 0.01)
plot(cumprod(1 + r), type = "l", main = "Equity curve")
Exercise 22: Correlation of two assets over rolling window
Difficulty: Advanced.
Show solution
set.seed(1)
a <- rnorm(252, 0, 0.01); b <- rnorm(252, 0, 0.01)
slider::slide2_dbl(a, b, ~ cor(.x, .y), .before = 59, .complete = TRUE) |> tail()
Exercise 23: Black-Scholes call price (formula)
Difficulty: Advanced.
Show solution
bs_call <- function(S, K, r, T, sigma) {
d1 <- (log(S/K) + (r + 0.5*sigma^2)*T) / (sigma*sqrt(T))
d2 <- d1 - sigma*sqrt(T)
S*pnorm(d1) - K*exp(-r*T)*pnorm(d2)
}
bs_call(S = 100, K = 100, r = 0.05, T = 1, sigma = 0.2)
Exercise 24: Monte Carlo portfolio simulation
Difficulty: Advanced.
Show solution
set.seed(1)
final <- replicate(5000, prod(1 + rnorm(252, 0.0005, 0.01)))
quantile(final, c(0.05, 0.95))
Exercise 25: Read Yahoo prices with quantmod (concept)
Difficulty: Intermediate.
Show solution
# quantmod::getSymbols("AAPL", src = "yahoo", from = "2024-01-01")
# Returns an xts object named AAPL with OHLC columns
What to do next
- Time-Series-Exercises (shipped), broader TS drills.
- ARIMA-Exercises (shipped), forecasting.