Path: blob/master/sandbox/symposium2013/R/table.RiskStats.R
1433 views
# Additional and re-organized tables for WB presentations12table.RiskStats <-3function (R, ci = 0.95, scale = NA, Rf = 0, MAR = .1/12, p= 0.95, digits = 4)4{# @author Peter Carl5# Risk Statistics: Statistics and Stylized Facts67y = checkData(R, method = "zoo")8if(!is.null(dim(Rf)))9Rf = checkData(Rf, method = "zoo")10# Set up dimensions and labels11columns = ncol(y)12rows = nrow(y)13columnnames = colnames(y)14rownames = rownames(y)1516if(is.na(scale)) {17freq = periodicity(y)18switch(freq$scale,19minute = {stop("Data periodicity too high")},20hourly = {stop("Data periodicity too high")},21daily = {scale = 252},22weekly = {scale = 52},23monthly = {scale = 12},24quarterly = {scale = 4},25yearly = {scale = 1}26)27}2829# for each column, do the following:30for(column in 1:columns) {31x = na.omit(y[,column,drop=FALSE])32# for each column, make sure that R and Rf are for the same dates33if(!is.null(dim(Rf))){ # if Rf is a column34z = merge(x,Rf)35zz = na.omit(z)36x = zz[,1,drop=FALSE]37Rf.subset = zz[,2,drop=FALSE]38}39else { # unless Rf is a single number40Rf.subset = Rf41}4243z = c(44Return.annualized(x, scale = scale),45StdDev.annualized(x, scale = scale),46SharpeRatio.annualized(x, scale = scale, Rf = Rf),47DownsideDeviation(x,MAR=0)*sqrt(scale),# Add annualization to this function48SortinoRatio(x)*sqrt(scale), # New function adds annualization49PerformanceAnalytics:::AverageDrawdown(x),50maxDrawdown(x),51SterlingRatio(x),52VaR(x, p=p,method="historical"),53ES(x, p=p,method="historical"),54skewness(x),55kurtosis(x),56VaR(x, p=p),57ES(x, p=p),58SharpeRatio(x, p=p, Rf=Rf, FUN="ES", annualize=TRUE),59length(x)60)61znames = c(62"Annualized Return",63"Annualized Std Dev",64"Annualized Sharpe Ratio",65"Annualized Downside Deviation",66"Annualized Sortino Ratio",67"Average Drawdown",68"Maximum Drawdown",69"Sterling Ratio (10%)",70paste("Historical VaR (",base::round(p*100,1),"%)",sep=""),71paste("Historical ETL (",base::round(p*100,1),"%)",sep=""),72"Skewness",73"Excess Kurtosis",74paste("Modified VaR (",base::round(p*100,1),"%)",sep=""),75paste("Modified ETL (",base::round(p*100,1),"%)",sep=""),76paste("Annualized Modified Sharpe Ratio (ETL ", base::round(p*100,1),"%)",sep=""),77"# Obs"78)79if(column == 1) {80resultingtable = data.frame(Value = z, row.names = znames)81}82else {83nextcolumn = data.frame(Value = z, row.names = znames)84resultingtable = cbind(resultingtable, nextcolumn)85}86}87colnames(resultingtable) = columnnames88ans = base::round(resultingtable, digits)89ans90}9192table.PerfStats <-93function (R, scale = NA, Rf = 0, digits = 4)94{# @author Peter Carl95# Performance Statistics: Statistics and Stylized Facts9697y = checkData(R)98if(!is.null(dim(Rf)))99Rf = checkData(Rf)100# Set up dimensions and labels101columns = ncol(y)102rows = nrow(y)103columnnames = colnames(y)104rownames = rownames(y)105106if(is.na(scale)) {107freq = periodicity(y)108switch(freq$scale,109minute = {stop("Data periodicity too high")},110hourly = {stop("Data periodicity too high")},111daily = {scale = 252},112weekly = {scale = 52},113monthly = {scale = 12},114quarterly = {scale = 4},115yearly = {scale = 1}116)117}118119# for each column, do the following:120for(column in 1:columns) {121x = na.omit(y[,column,drop=FALSE])122# for each column, make sure that R and Rf are for the same dates123if(!is.null(dim(Rf))){ # if Rf is a column124z = merge(x,Rf)125zz = na.omit(z)126x = zz[,1,drop=FALSE]127Rf.subset = zz[,2,drop=FALSE]128}129else { # unless Rf is a single number130Rf.subset = Rf131}132133z = c(134Return.cumulative(x),135Return.annualized(x, scale = scale),136StdDev.annualized(x, scale = scale),137length(subset(x, x>0)),138length(subset(x, x<=0)),139length(subset(x, x>0))/length(x),140mean(subset(x, x>0)),141mean(subset(x, x<=0)),142mean(x),143AverageDrawdown(x),144AverageRecovery(x)145)146znames = c(147"Cumulative Return",148"Annualized Return",149"Annualized Std Dev",150"# Positive Months",151"# Negative Months",152"% Positive Months",153"Average Positive Month",154"Average Negative Month",155"Average Month",156"Average Drawdown",157"Average Months to Recovery"158)159if(column == 1) {160resultingtable = data.frame(Value = z, row.names = znames)161}162else {163nextcolumn = data.frame(Value = z, row.names = znames)164resultingtable = cbind(resultingtable, nextcolumn)165}166}167colnames(resultingtable) = columnnames168ans = base::round(resultingtable, digits)169ans170}171172table.RiskContribution <- function(R, p, ..., weights=NULL, scale=NA, geometric = TRUE) {173174R = na.omit(R)175if(is.null(weights)) {176message("no weights passed in, assuming equal weighted portfolio")177weights = rep(1/dim(R)[[2]], dim(R)[[2]])178}179if (is.na(scale)) {180freq = periodicity(R)181switch(freq$scale, minute = {182stop("Data periodicity too high")183}, hourly = {184stop("Data periodicity too high")185}, daily = {186scale = 252187}, weekly = {188scale = 52189}, monthly = {190scale = 12191}, quarterly = {192scale = 4193}, yearly = {194scale = 1195})196}197198# Returns199# ret.col = colMeans(R)*weights200ret.col = Return.annualized(R, geometric=geometric)*weights201percret.col = ret.col/sum(ret.col)202result = cbind(t(ret.col), t(percret.col))203# Standard Deviation204sd.cols = StdDev(R, weights=weights, invert=TRUE, portfolio_method="component", p=(1-1/12))205result = cbind(sd.cols$contribution*sqrt(scale), sd.cols$pct_contrib_StdDev, result)206# VaR?207var.cols = VaR(R, weights=weights, method="gaussian", portfolio_method="component", p=(1-1/12))208result = cbind(var.cols$contribution, var.cols$pct_contrib_VaR, result)209210mvar.cols = VaR(R, weights=weights, method="gaussian", portfolio_method="component", p=(1-1/12))211result = cbind(mvar.cols$contribution, mvar.cols$pct_contrib_VaR, result)212213# ES214es.cols = ES(R, weights=weights, method="gaussian", portfolio_method="component", p=(1-1/12))215result = cbind(es.cols$contribution, es.cols$pct_contrib_ES, result)216217mes.cols = ES(R, weights=weights, method="modified", portfolio_method="component", p=(1-1/12))218result = cbind(weights, mes.cols$contribution, mes.cols$pct_contrib_MES, result)219total = colSums(result)220221result = rbind(result, colSums(result))222rownames(result) = c(colnames(R),"Total")223# colnames(result) = c("Weights", "Contribution to mETL", "Percentage Contribution to mETL", "Contribution to gETL", "Percentage Contribution to gETL", "Contribution to Annualized StdDev", "Percentage Contribution to StdDev", "Contribution to Annualized E(R)", "Percentage Contribution to E(R)")224225colnames(result) = c("Weights", "Contribution to mETL", "%Contribution to mETL", "Contribution to gETL", "%Contribution to gETL", "Contribution to mVaR", "%Contribution to mVaR", "Contribution to gVaR", "%Contribution to gVaR", "Contribution to Annualized StdDev", "%Contribution to StdDev", "Contribution to Annualized E(R)", "%Contribution to E(R)")226return(result)227228}229230231