0

我想计算投资组合中每只股票的风险贡献。

portfolioComponentReturns <- na.omit(Return.calculate(monthly_return, method = "log"))

covariance_matrix <- cov(portfolioComponentReturns)

# Square root of transpose of the weights cross prod covariance matrix returns 
# cross prod weights gives portfolio standard deviation.
sd_portfolio <- sqrt(t(w) %*% covariance_matrix %*% w)

# Marginal contribution of each asset. 
marginal_contribution <- w %*% covariance_matrix / sd_portfolio[1, 1]

# Component contributions to risk are the weighted marginal contributions
component_contribution <- marginal_contribution * w 

# This should equal total portfolio vol, or the object `sd_portfolio`
components_summed <- rowSums(component_contribution)

# To get the percentage contribution, divide component contribution by total sd.
component_percentages <- component_contribution / sd_portfolio[1, 1]

percentage_tibble_by_hand <- 
  tibble(symbols, w, as.vector(component_percentages)) %>% 
  rename(asset = symbols, 'portfolio weight' = w, 'risk contribution' = `as.vector(component_percentages)`)

percentage_tibble_by_hand

然而,我从第一行就有以下问题:

> portfolioComponentReturns <- na.omit(Return.calculate(monthly_return, method = "log"))
Warning message:
In log(pr) : NaNs produced
> 
> covariance_matrix <- cov(portfolioComponentReturns)
> 
> # Square root of transpose of the weights cross prod covariance matrix returns 
> # cross prod weights gives portfolio standard deviation.
> sd_portfolio <- sqrt(t(w) %*% covariance_matrix %*% w)
Error in t(w) %*% covariance_matrix : non-conformable arguments

数据

数据文件在这里

为了得到monthly_return

library (dplyr)
library (lubridate)
   
df <- read.xlsx ("Data.xlsx", sheet = "Sector-STOXX600", startRow = 2, colNames = TRUE, detectDates = TRUE, skipEmptyRows = FALSE)
df [2:19] <- data.matrix (df [2:19])

# changing nas with the preceding value
nas <- which(apply(df[, -1], 1, FUN=function(x) any(is.na(x))))
ver <- c(nas, nas - 1, nas + 1)
ver <- ver[order(ver)]
df[nas, -1] <- (df[nas-1,-1] + df[nas+1,-1])/2
df[ver,]

percent_change2 <- function(x)last(x)/first(x) - 1
monthly_return <- df %>% 
  group_by(gr = floor_date(Date, unit = "month")) %>%
  summarize_at(vars(-Date, -gr), percent_change2) %>%
  ungroup()

# Generamos el xts, indicando la columna con la info de tiempo
monthly_return <- xts(monthly_return[,-1], order.by=monthly_return$gr) 
4

0 回答 0