Exercise n.1: Compute the Mean of a Vector

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

}

Example usage

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

Exercise n.2 : Compute STD

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

}

Example usage

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

Exercise n.3 : Compute the Remaining Balance with Amortization

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) }

Example

final_balance <- f_am(interest_rate = 0.05, n = 12, current_balance = 1000, repayment = 100) print(final_balance)

Exercise n.4: iterative and recursive factorial

#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 #

Example

n <- 100 result_1 <- f_factorial_iterative(n) print(result_1)

Recursive method

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

Example

n<- 100 result_2<-f_factorial_recursive(n)

print(result_2)

Exercise n. 5.1: Manipulating Data

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

Exercise n. 5.2:Financial data management

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

}

Example

prices <- compute_prices(v_data_returns)
print(prices) # Display the price series

Function to compute returns from prices (inverse function of compute_prices)

compute_returns <- function(prices) { returns <- diff(prices) / head(prices, -1) # Compute log-returns return(returns) # Return the computed returns }

Example

recomputed_returns <- compute_returns(prices)
print(recomputed_returns) # Display the returns (should match v_data_returns)

Function to compute the total return over the year

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 }

Example

total_return <- compute_total_return(v_data_returns)
print(total_return) # print the total return at year-end

exercise_5.3: Performance measurement

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

Exercise n. 5.4: Portfolio Optimisation

Function to Simulate Random Portfolio Weights

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

}

Function to Compute Portfolio Performance

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)

Compute portfolio return and variance for each simulation

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

}

Function to Compute the Minimum Variance Portfolio

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

}

Generate Asset Class Returns

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

Compute Simulated Portfolio Returns and Risks

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

Compute covariance matrix of asset returns

covariance_matrix <- cov(m_data_returns)

Compute the Minimum Variance Portfolio (MVP)

min_var_weights <- compute_minimum_variance_portfolio(covariance_matrix)

Compute expected return and risk of the Minimum Variance Portfolio (MVP)

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

Extract standard deviations (risk) and mean returns from simulated portfolios

std_devs <- sqrt(performance_metrics[2, ]) # Compute standard deviations from variances mean_returns_simulated <- performance_metrics[1, ] # Extract expected returns

Plot the Mean-Variance Opportunity Set

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

Highlight the Minimum Variance Portfolio (MVP)

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