First lets load our packages
library(xts)#处理时间序列
## Warning: 程辑包'xts'是用R版本4.2.2 来建造的
## 载入需要的程辑包:zoo
## Warning: 程辑包'zoo'是用R版本4.2.3 来建造的
##
## 载入程辑包:'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(dygraphs)#绘图
## Warning: 程辑包'dygraphs'是用R版本4.2.3 来建造的
library(tibble)#数据形式
library(ggplot2)#绘图
## Warning: 程辑包'ggplot2'是用R版本4.2.3 来建造的
library(PerformanceAnalytics)#计算收益率与协方差矩阵
## Warning: 程辑包'PerformanceAnalytics'是用R版本4.2.3 来建造的
##
## 载入程辑包:'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
##
## legend
Next lets select a few stocks to build our portfolios. We will choose the following 4 stocks TH(诺斯兰德) Wc(齐鲁华信) Sz(同辉信息) HN(万通液压) Read the price data.
#读入数据
price <-read.csv("C:/Users/86133/Desktop/portfolio/data.csv")
#处理时间
t<-as.POSIXct(price[4:313,1])
#把价格由文本转化成数,并且保存成dataframe,将dataframe在转成时间序列
a1<-as.numeric(price[4:313,2])
a2<-as.numeric(price[4:313,19])
a4<-as.numeric(price[4:313,3])
a9<-as.numeric(price[4:313,20])
names<-c("TH","Wc","Sz","HN")
mydata1<-data.frame('TH'=a1,'Wc'=a2,'Sz'=a4,'HN'=a9)
price2= xts(mydata1, order.by=t)
#绘制价格走势
dygraph(price2)
Next we will calculate the daily returns for these stocks. We will use the logarithmic returns.
head(price2)
## TH Wc Sz HN
## 2022-01-04 25.47 8.26 10.03 9.48
## 2022-01-05 24.16 8.35 9.60 10.30
## 2022-01-06 24.53 8.40 8.50 9.32
## 2022-01-07 23.19 8.32 8.29 9.00
## 2022-01-10 22.30 8.40 8.76 9.03
## 2022-01-11 20.50 8.36 8.30 8.91
pr_daily <- to.daily(price2, indexAt = "lastof", OHLC = FALSE)
head(pr_daily)
## TH Wc Sz HN
## 2022-01-31 25.47 8.26 10.03 9.48
## 2022-01-31 24.16 8.35 9.60 10.30
## 2022-01-31 24.53 8.40 8.50 9.32
## 2022-01-31 23.19 8.32 8.29 9.00
## 2022-01-31 22.30 8.40 8.76 9.03
## 2022-01-31 20.50 8.36 8.30 8.91
rt_daily <- na.omit(Return.calculate(pr_daily, method = "log"))
head(rt_daily)
## TH Wc Sz HN
## 2022-01-31 -0.05280292 0.010836951 -0.04381750 0.082959579
## 2022-01-31 0.01519849 0.005970167 -0.12169693 -0.099981267
## 2022-01-31 -0.05617571 -0.009569451 -0.02501619 -0.034938051
## 2022-01-31 -0.03913447 0.009569451 0.05514594 0.003327790
## 2022-01-31 -0.08416179 -0.004773279 -0.05394039 -0.013378126
## 2022-01-31 0.02600050 -0.005998818 0.04706751 -0.004499445
dygraph(rt_daily)
Next let’s calculate the mean daily returns for each asset. Calculate the covariance matrix for all these stocks. We will annualize it by multiplying by 252.
mean_ret <- colMeans(rt_daily)
print(round(mean_ret, 4))
## TH Wc Sz HN
## -0.0023 -0.0013 -0.0043 -0.0013
cov_mat <- cov(rt_daily) * 252
print(round(cov_mat,4))
## TH Wc Sz HN
## TH 0.2788 0.0447 0.1010 0.0432
## Wc 0.0447 0.0970 0.0480 0.0389
## Sz 0.1010 0.0480 0.3079 0.0638
## HN 0.0432 0.0389 0.0638 0.0824
Simulation
er_p<-c()
sigma_p<-c()
sharpe_p<-c()
all_wts <- matrix(nrow = 1000,
ncol = 4)
for(i in 1:1000){w<-runif(4,min=0,max=1)
w<-w/sum(w)
all_wts[i,] <- w
miu<-((t(w)%*%mean_ret+1)^252)-1
std<-sqrt(t(w)%*%cov_mat%*%w)
sharpe_ration<-miu/std
sharpe_p<-append(sharpe_p,sharpe_ration,length(sharpe_p))
er_p<-append(er_p,miu,length(er_p))
sigma_p<-append(sigma_p,std,length(sigma_p))}
find the maxmium-return portfolio,min-variation portfolio and maxmium-Sharperation portfolio
#最值查找
library(tibble)
portfolio_values <- tibble(Return = er_p,
Risk = sigma_p,
SharpeRatio = sharpe_p,weights=all_wts)
min_var <- portfolio_values[which.min(portfolio_values$Risk),]
max_return<-portfolio_values[which.max(portfolio_values$Return),]
max_sr <- portfolio_values[which.max(portfolio_values$SharpeRatio),]
draw the histogram of the four portfolios we found just now
#最值权重分配直方图
p_return<-data.frame('name'=names,'weights'=as.vector(as.matrix(max_return[,4])))
p_1<-ggplot(data=p_return,aes(x=name,y=weights))+
geom_bar(stat='identity',fill='pink')+
theme_minimal() +
labs( title = "Max ruturn Portfolio Weights")+
scale_y_continuous(labels = scales::percent)
print(p_1)
p_var<-data.frame('name'=names,'weights'=as.vector(as.matrix(min_var[,4])))
p_2<-ggplot(data=p_var,aes(x=name,y=weights))+
geom_bar(stat='identity',fill='pink')+
theme_minimal() +
labs( title = "min risk Portifolio Weights")+
scale_y_continuous(labels = scales::percent)
print(p_2)
p_sr<-data.frame('name'=names,'weights'=as.vector(as.matrix(max_sr[,4])))
p_3<-ggplot(data=p_sr,aes(x=name,y=weights))+
geom_bar(stat='identity',fill='pink')+
theme_minimal() +
labs( title = "Tangency Portfolio Weights")+
scale_y_continuous(labels = scales::percent)
print(p_3)
draw the frontier and mark the four potifolios
#最小方差前沿
mydata2<-data.frame('expected'=er_p,'volatility'=sigma_p,'sharperation'=sharpe_p)
p<-ggplot(data=mydata2,aes(x=volatility,y=expected,color=sharperation))+
geom_point()+
geom_point(data=min_var,aes(x=Risk,y=Return),col="red")+
geom_point(data=max_return,aes(x=Risk,y=Return),col="red")+
geom_point(data=max_sr,aes(x=Risk,y=Return),col="red")+
labs(title="最小方差前沿",caption="投资组合")+
theme_classic()
print(p)