First lets load our packages
Next lets select a few stocks to build our portfolios.
We will choose the following 4 stocks 430198.BJ(微创光电) 430300.BJ(辰光医疗) 430476.BJ(海能技术) 430478.BJ(峆一药业) Read the price data.
##选取投资组合对象
#430139.BJ(微创光电) 430198.BJ(辰光医疗) 430425.BJ(海能技术) 430300.BJ(峆一药业)
##读取数据
price <-read.csv("D:/zhangxy/data_work1.csv")
#修改数据格式
price[,1] = as.POSIXct(price[,1])
price = xts(price[,-1], order.by=price[,1])
##绘制走势图
names(price)<-c("WC","CG","HN","QY")
dygraph(price)
#plot(price)
##获取月汇报
#过滤数据
#pr_monthly <- to.monthly(price, indexAt = "lastof", OHLC = FALSE)
#head(pr_monthly)
#计算回报
#rt_monthly <- na.omit(Return.calculate(pr_monthly, method = "log"))
head(price)
## WC CG HN QY
## 2022-01-04 9.70 8.86 10.05 21.99
## 2022-01-05 9.77 8.88 9.90 21.51
## 2022-01-06 9.66 8.91 9.91 21.51
## 2022-01-07 9.53 8.67 10.04 21.99
## 2022-01-10 9.50 8.70 10.01 21.99
## 2022-01-11 9.44 8.61 10.05 22.00
pr_daily <- to.daily(price, indexAt = "lastof", OHLC = FALSE)
head(pr_daily)
## WC CG HN QY
## 2022-01-31 9.70 8.86 10.05 21.99
## 2022-01-31 9.77 8.88 9.90 21.51
## 2022-01-31 9.66 8.91 9.91 21.51
## 2022-01-31 9.53 8.67 10.04 21.99
## 2022-01-31 9.50 8.70 10.01 21.99
## 2022-01-31 9.44 8.61 10.05 22.00
#计算回报
rt_daily <- na.omit(Return.calculate(pr_daily, method = "log"))
head(rt_daily)
## WC CG HN QY
## 2022-01-31 0.007190581 0.002254792 -0.015037877 -0.0220698613
## 2022-01-31 -0.011322818 0.003372684 0.001009591 0.0000000000
## 2022-01-31 -0.013548931 -0.027305451 0.013032766 0.0220698613
## 2022-01-31 -0.003152919 0.003454235 -0.002992521 0.0000000000
## 2022-01-31 -0.006335818 -0.010398707 0.003988041 0.0004546488
## 2022-01-31 0.006335818 0.021827403 0.000000000 0.0095001845
dygraph(rt_daily)
mean_ret <- colMeans(rt_daily)
print(round(mean_ret, 4))
## WC CG HN QY
## -0.0024 -0.0013 0.0010 -0.0006
cov_mat <- cov(rt_daily) * 252
print(round(cov_mat,4))
## WC CG HN QY
## WC 0.0667 0.0228 0.0133 0.0172
## CG 0.0228 0.0950 0.0177 0.0347
## HN 0.0133 0.0177 0.1250 0.0119
## QY 0.0172 0.0347 0.0119 1.3291
tick <- c("WC","CG","HN","QY")
wts <- runif(n = length(tick))
wts <- wts/sum(wts)
print(wts)
## [1] 0.3683467 0.2166561 0.1613975 0.2535998
port_returns <- (sum(wts * mean_ret) + 1)^252 - 1
port_risk <- sqrt(t(wts) %*% (cov_mat %*% wts))
sharpe_ratio <- port_returns/port_risk
num_port <- 1000
# Creating a matrix to store the weights
all_wts <- matrix(nrow = num_port,
ncol = length(tick))
# Creating an empty vector to store
# Portfolio returns
port_returns <- vector('numeric', length = num_port)
# Creating an empty vector to store
# Portfolio Standard deviation
port_risk <- vector('numeric', length = num_port)
# Creating an empty vector to store
# Portfolio Sharpe Ratio
sharpe_ratio <- vector('numeric', length = num_port)
for (i in seq_along(port_returns)) {
wts <- runif(length(tick))
wts <- wts/sum(wts)
# Storing weight in the matrix
all_wts[i,] <- wts
# Portfolio returns
port_ret <- sum(wts * mean_ret)
port_ret <- ((port_ret + 1)^252) - 1
# Storing Portfolio Returns values
port_returns[i] <- port_ret
# Creating and storing portfolio risk
port_sd <- sqrt(t(wts) %*% (cov_mat %*% wts))
port_risk[i] <- port_sd
# Creating and storing Portfolio Sharpe Ratios
# Assuming 0% Risk free rate
sr <- port_ret/port_sd
sharpe_ratio[i] <- sr
}
# Storing the values in the table
portfolio_values <- tibble(Return = port_returns,
Risk = port_risk,
SharpeRatio = sharpe_ratio)
# Converting matrix to a tibble and changing column names
all_wts <- tk_tbl(all_wts)
## Warning in tk_tbl.data.frame(as.data.frame(data), preserve_index, rename_index,
## : Warning: No index to preserve. Object otherwise converted to tibble
## successfully.
colnames(all_wts) <- colnames(pr_daily)
# Combing all the values together
portfolio_values <- tk_tbl(cbind(all_wts, portfolio_values))
## Warning in tk_tbl.data.frame(cbind(all_wts, portfolio_values)): Warning: No
## index to preserve. Object otherwise converted to tibble successfully.
min_var <- portfolio_values[which.min(portfolio_values$Risk),]
max_sr <- portfolio_values[which.max(portfolio_values$SharpeRatio),]
p <- min_var %>%
gather(WC:QY, key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Minimum Variance Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p)
p <- max_sr %>%
gather(WC:QY, key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Tangency Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p)
p <- portfolio_values %>%
ggplot(aes(x = Risk, y = Return, color = SharpeRatio)) +
geom_point() +
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk,
y = Return), data = min_var, color = 'red') +
geom_point(aes(x = Risk,
y = Return), data = max_sr, color = 'red') #+
#annotate('text', x = 3.2, y = 550, label = "Tangency Portfolio") +
#annotate('text', x = 1.3, y = 40, label = "Min Var portfolio") #+
#annotate(geom = 'segment', x = 0.2, xend = 0.185, y = 0.03,
# yend = 0.11, color = 'red', arrow = arrow(type = "open")) +
#annotate(geom = 'segment', x = 0.285, xend = 0.26, y = 0.34,
# yend = 0.31, color = 'red', arrow = arrow(type = "open"))
ggplotly(p)