Skip to content

Commit a1aeafc

Browse files
authored
Add Monte Carlo simulation, Markowitz portfolio optimization, and Kalman filter (#123)
1 parent 3ddddee commit a1aeafc

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

quantitative_finance/kalman_filter.r

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
library(Metrics)
2+
set.seed(123)
3+
num_obs <- 100
4+
true_returns <- rnorm(num_obs, mean = 0.001, sd = 0.01)
5+
observed_prices <- cumprod(1 + true_returns) * 100
6+
noise <- rnorm(num_obs, mean = 0, sd = 0.1)
7+
noisy_prices <- observed_prices + noise
8+
# Kalman filter implementation
9+
kalman_filter <- function(observed_prices) {
10+
state <- c(observed_prices[1], 0)
11+
P <- matrix(c(1, 0, 0, 1), nrow = 2)
12+
Q <- matrix(c(0.0001, 0, 0, 0.0001), nrow = 2)
13+
R <- 0.1
14+
A <- matrix(c(1, 1, 0, 1), nrow = 2)
15+
H <- matrix(c(1, 0), nrow = 1)
16+
filtered_states <- matrix(0, nrow = length(observed_prices), ncol = 2)
17+
for (i in 1:length(observed_prices)) {
18+
state_pred <- A %*% state
19+
P_pred <- A %*% P %*% t(A) + Q
20+
K <- P_pred %*% t(H) %*% solve(H %*% P_pred %*% t(H) + R)
21+
state <- state_pred + K %*% (observed_prices[i] - H %*% state_pred)
22+
P <- (matrix(1, nrow = 2, ncol = 2) - K %*% H) %*% P_pred
23+
filtered_states[i, ] <- state
24+
}
25+
return(list(filtered_states = filtered_states, state_pred = state_pred, P_pred = P_pred))
26+
}
27+
result <- kalman_filter(noisy_prices)
28+
plot(observed_prices, type = "l", col = "blue", lwd = 2, main = "Kalman Filter")
29+
lines(result$filtered_states[, 1], type = "l", col = "red", lwd = 2)
30+
lines(true_returns, type = "l", col = "green", lwd = 2)
31+
legend("topright", legend = c("Observed Prices", "Filtered Prices", "True Returns"),
32+
col = c("blue", "red", "green"), lty = 1, lwd = 2)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Required libraries
2+
library(tidyquant)
3+
library(quadprog)
4+
# Set a seed for reproducibility
5+
set.seed(123)
6+
# Generate random data for three assets
7+
num_assets <- 3
8+
num_obs <- 100
9+
returns <- matrix(rnorm(num_assets * num_obs), ncol = num_assets)
10+
# Define the objective function for portfolio optimization
11+
objective_function <- function(weights, cov_matrix) {
12+
portfolio_return <- sum(weights * colMeans(returns))
13+
portfolio_volatility <- sqrt(t(weights) %*% cov_matrix %*% weights)
14+
return(c(portfolio_return, portfolio_volatility))
15+
}
16+
cov_matrix <- cov(returns)
17+
constraints <- matrix(0, nrow = 2, ncol = num_assets)
18+
constraints[1, ] <- colMeans(returns)
19+
constraints[2, ] <- 1
20+
optimal_weights <- solve.QP(Dmat = 2 * cov_matrix,
21+
dvec = rep(0, num_assets),
22+
Amat = t(constraints),
23+
bvec = c(0.05, 1),
24+
meq = 1)$solution
25+
cat("Optimal Weights:", optimal_weights, "\n")
26+
optimal_portfolio <- objective_function(optimal_weights, cov_matrix)
27+
cat("Expected Return:", optimal_portfolio[1], "\n")
28+
cat("Volatility:", optimal_portfolio[2], "\n")
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Required libraries
2+
library("quantmod")
3+
# Parameters
4+
S0 <- 100 # Initial stock price
5+
K <- 100 # Strike price
6+
r <- 0.05 # Risk-free rate
7+
sigma <- 0.2 # Volatility
8+
T <- 1 # Time to maturity (in years)
9+
n <- 252 # Number of trading days
10+
# Function to simulate stock prices using geometric Brownian motion
11+
simulate_stock_prices <- function(S0, r, sigma, T, n) {
12+
dt <- T/n
13+
t <- seq(0, T, by = dt)
14+
W <- c(0, cumsum(sqrt(dt) * rnorm(n)))
15+
S <- S0 * exp((r - 0.5 * sigma^2) * t + sigma * W)
16+
return(S)
17+
}
18+
# Function to calculate option price using Monte Carlo simulation
19+
monte_carlo_option_price <- function(S0, K, r, sigma, T, n, num_simulations) {
20+
option_prices <- numeric(num_simulations)
21+
for (i in 1:num_simulations) {
22+
ST <- simulate_stock_prices(S0, r, sigma, T, n)[n + 1] # Final stock price
23+
option_prices[i] <- pmax(ST - K, 0) # Payoff of the option
24+
}
25+
option_price <- mean(option_prices) * exp(-r * T) # Discounted expected payoff
26+
return(option_price)
27+
}
28+
# Number of Monte Carlo simulations
29+
num_simulations <- 10000
30+
option_price <- monte_carlo_option_price(S0, K, r, sigma, T, n, num_simulations)
31+
cat("Option price:", option_price, "\n")

0 commit comments

Comments
 (0)