mean_vector <- function(vector) { sum_ <- 0 # Initialize sum variable
len <- length(vector) # Compute the length of the vector
for (i in vector) {
sum_ <- sum_ + i # Manually accumulate the sum
}
mean_value <- sum_ / len
# Compute the mean
return(mean_value) # Return the computed mean
}
vector <- rnorm(10) # Generate 10 random numbers
print(vector) # Print the vector
mean_value <- mean_vector(vector) # Compute mean using custom function print(mean_value) # Print the computed mean
std_obt <- function(vector) {
sum_ <- 0 # Initialize sum variable
len <- length(vector) # Compute the length of the vector
# Compute the sum of all elements in the vector
for (value in vector) {
sum_ <- sum_ + value
}
mean_value <- sum_ / len # Compute the mean of the vector
square_sum <- 0 # Initialize squared differences sum
# Compute the sum of squared differences from the mean
for (value in vector) {
square_sum <- square_sum + (value - mean_value)^2
}
variance <- square_sum / (len - 1) # Compute variance (unbiased estimator)
std_dev <- sqrt(variance) # Compute standard deviation
return(std_dev) # Return the computed standard deviation
}
vector <- rnorm(10) # Generate 10 random numbers
print(vector) # Print the vector
std_value <- std_obt(vector) # Compute standard deviation
print(std_value) # Print the computed standard deviation
f_am <- function(interest_rate, n, current_balance, repayment) {
for (month in 1:n) {
current_balance <- current_balance * (1 + interest_rate / 12) - repayment } return(current_balance) }
final_balance <- f_am(interest_rate = 0.05, n = 12, current_balance = 1000, repayment = 100) print(final_balance)
#The first one that i’m going to code is the iterative one
f_factorial_iterative <- function(n) {
result <- 1 # Initialize result to 1 before the loop
for (i in 1:n) {
result <- result * i # Multiply iteratively
}
return(result)
}
#i personally find the iterative easier to understand #
n <- 100 result_1 <- f_factorial_iterative(n) print(result_1)
f_factorial_recursive <- function(n) { if (n == 0) {
#in this case we use the if-else function
return(1) } else { return(n * f_factorial_recursive(n - 1))
} } #imposing that, as iterative, the function is going to recalculate itself
n<- 100 result_2<-f_factorial_recursive(n)
print(result_2)
Vector1<- rnorm(100)
print(Vector1)
#with the function rnorm, we are going to have n number as in the () normally distributed Vector2<- array(1:100) print(Vector2)
#with the function array, im going to create a vector with a lenght of (1 : n), were n rapresent the lenght
Matrix1<- matrix(rnorm(10000), nrow = 100, ncol = 100) print(Matrix1)
#with the function matrix in the first, (im going to put the total number of values), and indicate the number of column and the number of row with ncol and nrow
v_data_returns <- rnorm(12, 0.01, 0.02) # Monthly returns with mean 1% and std dev 2% print(v_data_return) # in this way i’m giong to print it
compute_prices <- function(returns, initial_price = 100) {
prices <- numeric(length(returns) + 1)
# Create a vector of length (returns + 1) and Initialize price vector
prices[1] <- initial_price # Set the initial price to 100, base level at t0
for (i in 2:length(prices)) {
prices[i] <- prices[i - 1] * (1 + returns[i - 1]) # Compute price iteratively
}
return(prices) # Return the computed price series
}
prices <- compute_prices(v_data_returns)
print(prices) # Display the price series
compute_returns <- function(prices) { returns <- diff(prices) / head(prices, -1) # Compute log-returns return(returns) # Return the computed returns }
recomputed_returns <- compute_returns(prices)
print(recomputed_returns) # Display the returns (should match
v_data_returns)
compute_total_return <- function(returns) { total_return <- prod(1 + returns) - 1
# Compute the cumulative product of (1 + returns) and subtract 1 return(total_return)
# Return the total return }
total_return <- compute_total_return(v_data_returns)
print(total_return) # print the total return at year-end
v_data_return<- rnorm(12, 0.2, 0.3)
print(v_data_return)
v_benchmark_returns <- c(0, 0, 0, 0.005, 0.005, 0.005, 0.005, 0.01, 0.01, 0.01, 0.01, 0.01)
print(v_benchmark_returns)
#at first i put the datas for the exercise as the previous exercises
compute_risk <- function(returns) {
#at first i impose the function
volatility <- sd(returns) #using sd function to calculate volatility
variance <- var(returns) #using var function to calculate variance
return(list(volatility = volatility, variance = variance))
} #using list to put the volatility and variance as a list of 2
compute_risk(v_data_return)
compute_Sharpe_Ratio <- function(returns, benchmark_returns, risk_free_rate = 0) {
#im going to impose the Sharpe ratio function , at first i am going to calculate the excess returns with the difference between returns and benchmark returns
excess_returns <- returns - benchmark_returns
mean_excess_return <- mean(excess_returns)
volatility <- sd(excess_returns)
sharpe_ratio <- (mean_excess_return - risk_free_rate) /
volatility
return(sharpe_ratio)
}
compute_Sharpe_Ratio(v_data_return, v_benchmark_returns)
#with this function we are able to compute the Sharpe Ratio for whatever vector of returns
compute_VaR <- function(returns, confidence_level = 0.95) {
mean_return <- mean(returns)
sd_return <- sd(returns)
z_score <- qnorm(confidence_level)
VaR <-(mean_return + z_score * sd_return)
return(VaR)
}
compute_VaR(v_data_return, confidence_level = 0.95)
#we could even take the sixth worst result that we have, if we are using an historical return approach instead of parametric
compute_simul_weights <- function(nb_assets, nb_simulations) {
# Create an empty matrix to store portfolio weights
weights_matrix <- matrix(0, nrow = nb_assets, ncol =
nb_simulations)
# Generate random weights for each simulation
for (i in 1:nb_simulations) {
random_weights <- runif(nb_assets) # Generate random numbers
normalized_weights <- random_weights / sum(random_weights)
# Normalize so that weights sum to 1
weights_matrix[, i] <- normalized_weights
}
return(weights_matrix)
# Return the 3 x 10000 matrix of weights
}
compute_simul_portfolios <- function(nb_assets, nb_simulations, m_data_returns) {
# Generate random portfolio weights
weights_matrix <- compute_simul_weights(nb_assets,
nb_simulations)
# Compute mean returns and covariance matrix of asset classes
mean_returns <- colMeans(m_data_returns) # Compute the expected return for each asset class covariance_matrix <- cov(m_data_returns)
# Compute covariance matrix of asset returns
#Create an empty matrix to store performance metrics (returns &
variance) performance_metrics <- matrix(0, nrow = 2, ncol =
nb_simulations)
for (i in 1:nb_simulations) {
weights <- weights_matrix[, i] # Extract weights for the current portfolio
portfolio_return <- sum(weights * mean_returns) # Compute portfolio return
portfolio_variance <- t(weights) %% covariance_matrix %% weights
# Compute portfolio variance
performance_metrics[1, i] <- portfolio_return # Store portfolio return performance_metrics[2, i] <- portfolio_variance # Store portfolio variance
}
return(list(performance_metrics = performance_metrics, weights_matrix = weights_matrix))
# Return results
}
compute_minimum_variance_portfolio <- function(covariance_matrix)
{ nb_assets <- nrow(covariance_matrix) # Get the number of asset classes
one_vector <- rep(1, nb_assets) # Create a vector of ones
inv_cov <- solve(covariance_matrix) # Compute the inverse of the covariance matrix
# Compute the minimum variance portfolio (MVP) weights
min_var_weights <- inv_cov %% one_vector / as.numeric(t(one_vector) %% inv_cov %*% one_vector)
return(as.numeric(min_var_weights)) # Convert to numeric vector and return
}
set.seed(123) # Set seed for reproducibility
# Create a 12x3 matrix of asset returns for bonds, stocks, and cash
m_data_returns <- matrix(0, ncol = 3, nrow = 12)
m_data_returns[, 1] <- rnorm(12, 0.010, 0.020) # Bonds: Mean return
1%, Std dev 2% m_data_returns[, 2] <- rnorm(12, 0.015, 0.025) #
Stocks: Mean return 1.5%, Std dev 2.5% m_data_returns[, 3] <-
rnorm(12, 0.002, 0.005) # Cash: Mean return 0.2%, Std dev 0.5%
#Define number of asset classes and number of simulations
nb_assets <- 3
nb_simulations <- 10000
simulation_results <- compute_simul_portfolios(nb_assets, nb_simulations,m_data_returns) performance_metrics <- simulation_results performance_metrics
# Extract performance metrics weights_matrix <- simulation_results$weights_matrix
# Extract simulated weights
covariance_matrix <- cov(m_data_returns)
min_var_weights <- compute_minimum_variance_portfolio(covariance_matrix)
mean_returns <- colMeans(m_data_returns) # Compute mean returns of assets min_var_return <- sum(min_var_weights * mean_returns)
# Compute expected return of MVP
min_var_risk <- sqrt(t(min_var_weights) %% covariance_matrix %% min_var_weights)
# Compute risk (std dev) of MVP
std_devs <- sqrt(performance_metrics[2, ]) # Compute standard deviations from variances mean_returns_simulated <- performance_metrics[1, ] # Extract expected returns
plot(std_devs, mean_returns_simulated,
xlab = “Standard Deviation (Risk)”, # X-axis label
ylab = “Expected Return”, # Y-axis label
main = “Mean-Variance Frontier”, # Title of the plot
pch = 1, col = rgb(0.1, 0.4, 0.3, 0.3)) # Style and transparency
points(min_var_risk, min_var_return, col = “red”, pch = 19, cex = 1.5)
# Add a red dot for MVP
text(min_var_risk, min_var_return, labels = “Min Var”, pos = 4, col = “red”)
# Label for MVP