Я хотел бы сделать «версию ggplot» базовой функциональности charts.PerformanceSummary
, которая доступна в пакете PerformanceAnalytics
, так как я думаю, что ggplot обычно красивее и теоретически более мощный с точки зрения редактирования образ. У меня достаточно близкие, но у меня есть несколько вопросов, на которые мне хотелось бы помочь. А именно:ggplot version of charts.PerformanceSummary
- уменьшая объем пространства, что легенда берет вверх, это становится ужасающим/некрасиво, имея более чем 10 строк на нем ... (только цвет линии и название достаточно)
- Увеличение размер арифметики Daily_Returns в соответствии с диаграммой charts.PerformanceSummary в
PerformanceAnalytics
- Есть опция, которая указывает, какой актив показывать в ежедневной строке возврата в факеле Daily_Returns, а не всегда использовать первый столбец, который является чем то, что происходит в
charts.PerformanceSummary
Если есть более эффективные способы сделать это потенциально, используя gridExtra
, а не грани ... Я не против людей, показывающих мне, как это будет выглядеть лучше ...
Проблема здесь в эстетике и потенциальной легкости манипуляции, я думаю, поскольку у PerformanceAnalytics уже есть хороший рабочий пример, я просто хочу сделать его более красивым/более профессиональным ...
В дополнение к этому для бонусных очков я хотел бы иметь возможность показывать статистику производительности с ним где-то на или ниже или сбоку графика для каждого актива ... не слишком уверен, где лучше всего показывать или отображать эту информацию.
Кроме того, я не против людей, предлагающих части, которые очищают мой код, если у них есть предложения для этого.
Вот мой воспроизводимый пример ...
Сначала приготовьте Возвращаемые данные:
require(xts)
X.stock.rtns <- xts(rnorm(1000,0.00001,0.0003), Sys.Date()-(1000:1))
Y.stock.rtns <- xts(rnorm(1000,0.00003,0.0004), Sys.Date()-(1000:1))
Z.stock.rtns <- xts(rnorm(1000,0.00005,0.0005), Sys.Date()-(1000:1))
rtn.obj <- merge(X.stock.rtns , Y.stock.rtns, Z.stock.rtns)
colnames(rtn.obj) <- c("x.stock.rtns","y.stock.rtns","z.stock.rtns")
Я хотел бы повторить изображение из результата:
require(PerformanceAnalytics)
charts.PerformanceSummary(rtn.obj, geometric=TRUE)
Это моя попытка до сих пор ...
gg.charts.PerformanceSummary <- function(rtn.obj, geometric=TRUE, main="",plot=TRUE){
# load libraries
suppressPackageStartupMessages(require(ggplot2))
suppressPackageStartupMessages(require(scales))
suppressPackageStartupMessages(require(reshape))
suppressPackageStartupMessages(require(PerformanceAnalytics))
# create function to clean returns if having NAs in data
clean.rtn.xts <- function(univ.rtn.xts.obj,na.replace=0){
univ.rtn.xts.obj[is.na(univ.rtn.xts.obj)]<- na.replace
univ.rtn.xts.obj
}
# Create cumulative return function
cum.rtn <- function(clean.xts.obj, g=TRUE){
x <- clean.xts.obj
if(g==TRUE){y <- cumprod(x+1)-1} else {y <- cumsum(x)}
y
}
# Create function to calculate drawdowns
dd.xts <- function(clean.xts.obj, g=TRUE){
x <- clean.xts.obj
if(g==TRUE){y <- Drawdowns(x)} else {y <- Drawdowns(x,geometric=FALSE)}
y
}
# create a function to create a dataframe to be usable in ggplot to replicate charts.PerformanceSummary
cps.df <- function(xts.obj,geometric){
x <- clean.rtn.xts(xts.obj)
series.name <- colnames(xts.obj)[1]
tmp <- cum.rtn(x,geometric)
tmp$rtn <- x
tmp$dd <- dd.xts(x,geometric)
colnames(tmp) <- c("Cumulative_Return","Daily_Return","Drawdown")
tmp.df <- as.data.frame(coredata(tmp))
tmp.df$Date <- as.POSIXct(index(tmp))
tmp.df.long <- melt(tmp.df,id.var="Date")
tmp.df.long$asset <- rep(series.name,nrow(tmp.df.long))
tmp.df.long
}
# A conditional statement altering the plot according to the number of assets
if(ncol(rtn.obj)==1){
# using the cps.df function
df <- cps.df(rtn.obj,geometric)
# adding in a title string if need be
if(main==""){
title.string <- paste0(df$asset[1]," Performance")
} else {
title.string <- main
}
# generating the ggplot output with all the added extras....
gg.xts <- ggplot(df, aes_string(x="Date",y="value",group="variable"))+
facet_grid(variable ~ ., scales="free", space="free")+
geom_line(data=subset(df,variable=="Cumulative_Return"))+
geom_bar(data=subset(df,variable=="Daily_Return"),stat="identity")+
geom_line(data=subset(df,variable=="Drawdown"))+
ylab("")+
geom_abline(intercept=0,slope=0,alpha=0.3)+
ggtitle(title.string)+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
scale_x_datetime(breaks = date_breaks("6 months"), labels = date_format("%d/%m/%Y"))
} else {
# a few extra bits to deal with the added rtn columns
no.of.assets <- ncol(rtn.obj)
asset.names <- colnames(rtn.obj)
df <- do.call(rbind,lapply(1:no.of.assets, function(x){cps.df(rtn.obj[,x],geometric)}))
df$asset <- ordered(df$asset, levels=asset.names)
if(main==""){
title.string <- paste0(df$asset[1]," Performance")
} else {
title.string <- main
}
if(no.of.assets>5){legend.rows <- 5} else {legend.rows <- no.of.assets}
gg.xts <- ggplot(df, aes_string(x="Date", y="value",group="asset"))+
facet_grid(variable~.,scales="free",space="free")+
geom_line(data=subset(df,variable=="Cumulative_Return"),aes(colour=factor(asset)))+
geom_bar(data=subset(df,variable=="Daily_Return"),stat="identity",aes(fill=factor(asset),colour=factor(asset)),position="dodge")+
geom_line(data=subset(df,variable=="Drawdown"),aes(colour=factor(asset)))+
ylab("")+
geom_abline(intercept=0,slope=0,alpha=0.3)+
ggtitle(title.string)+
theme(legend.title=element_blank(), legend.position=c(0,1), legend.justification=c(0,1),
axis.text.x = element_text(angle = 45, hjust = 1))+
guides(col=guide_legend(nrow=legend.rows))+
scale_x_datetime(breaks = date_breaks("6 months"), labels = date_format("%d/%m/%Y"))
}
assign("gg.xts", gg.xts,envir=.GlobalEnv)
if(plot==TRUE){
plot(gg.xts)
} else {}
}
# seeing the ggplot equivalent....
gg.charts.PerformanceSummary(rtn.obj, geometric=TRUE)
Я использовал это в качестве упражнения, чтобы узнать ggplot2. Управление легендами было кошмаром, со временем произошло много изменений. Ключевое слово: show_guide = FALSE. Получение легенды для отображения формы и цвета было жестким. Я сделал это таким образом, который отличается от того, что предлагает руководство. В предлагаемом руководстве выдается предупреждение.(Я прокомментировал код выше, чтобы вы могли экспериментировать и видеть, есть ли у вас предупреждения). Существует способ получить ярлыки с несколькими словами, без подчеркивания или точек, но я бросил попытку, прежде чем сойти с ума. Я удалил дни с временной оси. Комментарии приветствуются! – PatrickT
Мне бы хотелось, чтобы надписи «Drawdown», «Return», «Index» были напечатаны черным по белому, а не серым. И мне, вероятно, хотелось бы, чтобы цвет фона был немного светлее. Я думаю. Но сейчас я остановлю этот маленький проект. Возможно, кто-то еще может сделать еще один шаг. – PatrickT
У меня есть 2 обновления, которые показывают, как настроить текстовые метки, цвета фона и сетки. Одна вещь, которую я замечаю, состоит в том, что легенда, вероятно, была бы красивее без серого цвета фона. Я собираюсь угадать, что это можно исправить добавлением color = "white" в параметр legend.background = element_rect() внутри темы. Но это всего лишь предположение ... – PatrickT