#' Apply a risk or return function to a set of weights1#'2#' This function is used to calculate risk or return metrics given a matrix of3#' weights and is primarily used as a convenience function used in chart.Scatter functions4#'5#' @param R xts object of asset returns6#' @param weights a matrix of weights generated from random_portfolios or \code{optimize.portfolio}7#' @param FUN name of a function8#' @param arguments named list of arguments to FUN9#' @author Ross Bennett10#' @export11applyFUN <- function(R, weights, FUN="mean", arguments){12nargs <- arguments1314moments <- function(R){15momentargs <- list()16momentargs$mu <- matrix(as.vector(apply(R, 2, "mean")), ncol = 1)17momentargs$sigma <- cov(R)18momentargs$m3 <- PerformanceAnalytics::M3.MM(R)19momentargs$m4 <- PerformanceAnalytics::M4.MM(R)20return(momentargs)21}2223nargs <- c(nargs, moments(R))24nargs$R <- R25#nargs$invert=FALSE2627# match the FUN arg to a risk or return function28switch(FUN,29mean = {30fun = match.fun(mean)31},32sd =,33StdDev = {34fun = match.fun(StdDev)35},36mVaR =,37VaR = {38fun = match.fun(VaR)39if(is.null(nargs$portfolio_method)) nargs$portfolio_method='single'40if(is.null(nargs$invert)) nargs$invert = FALSE41},42es =,43mES =,44CVaR =,45cVaR =,46ETL=,47mETL=,48ES = {49fun = match.fun(ES)50if(is.null(nargs$portfolio_method)) nargs$portfolio_method='single'51if(is.null(nargs$invert)) nargs$invert = FALSE52},53# CSM = {54# fun = match.fun(CSM)55# if(is.null(nargs$portfolio_method)) nargs$portfolio_method='single'56# if(is.null(nargs$invert)) nargs$invert = FALSE57# },58{ # see 'S Programming p. 67 for this matching59fun <- try(match.fun(FUN))60}61) # end switch block6263if(!is.null(nrow(weights))){64# case for matrix of weights65out <- rep(0, nrow(weights))66.formals <- formals(fun)67onames <- names(.formals)68for(i in 1:nrow(weights)){69nargs$weights <- as.numeric(weights[i,])70nargs$x <- R %*% as.numeric(weights[i,])71dargs <- nargs72pm <- pmatch(names(dargs), onames, nomatch = 0L)73names(dargs[pm > 0L]) <- onames[pm]74.formals[pm] <- dargs[pm > 0L]75out[i] <- try(do.call(fun, .formals))76}77} else {78# case for single vector of weights79.formals <- formals(fun)80onames <- names(.formals)81nargs$weights <- as.numeric(weights)82nargs$x <- R %*% as.numeric(weights)83dargs <- nargs84pm <- pmatch(names(dargs), onames, nomatch = 0L)85names(dargs[pm > 0L]) <- onames[pm]86.formals[pm] <- dargs[pm > 0L]87out <- try(do.call(fun, .formals))88}89return(out)90}9192#' Apply a risk or return function to asset returns93#'94#' This function is used to calculate risk or return metrics given a matrix of95#' asset returns and will be used for a risk-reward scatter plot of the assets96#'97#' @param R xts object of asset returns98#' @param FUN name of function99#' @param arguments named list of arguments to FUN100#' @author Ross Bennett101#' @export102scatterFUN <- function(R, FUN, arguments=NULL){103if(is.null(arguments)){104nargs <- list()105} else{106nargs <- arguments107}108109# match the FUN arg to a risk or return function110switch(FUN,111mean = {112return(as.numeric(apply(R, 2, mean)))113#fun = match.fun(mean)114#nargs$x = R115},116var = {117return(as.numeric(apply(R, 2, var)))118#fun = match.fun(mean)119#nargs$x = R120},121sd =,122StdDev = {123fun = match.fun(StdDev)124},125mVaR =,126VaR = {127fun = match.fun(VaR)128if(is.null(nargs$portfolio_method)) nargs$portfolio_method='single'129if(is.null(nargs$invert)) nargs$invert = FALSE130},131es =,132mES =,133CVaR =,134cVaR =,135ETL =,136mETL =,137ES = {138fun = match.fun(ES)139if(is.null(nargs$portfolio_method)) nargs$portfolio_method='single'140if(is.null(nargs$invert)) nargs$invert = FALSE141},142# CSM = {143# fun = match.fun(CSM)144# if(is.null(nargs$portfolio_method)) nargs$portfolio_method='single'145# if(is.null(nargs$invert)) nargs$invert = FALSE146# },147{ # see 'S Programming p. 67 for this matching148fun <- try(match.fun(FUN))149}150) # end switch block151152# calculate FUN on R153out <- rep(0, ncol(R))154.formals <- formals(fun)155onames <- names(.formals)156for(i in 1:ncol(R)){157nargs$R <- R[, i]158dargs <- nargs159pm <- pmatch(names(dargs), onames, nomatch = 0L)160names(dargs[pm > 0L]) <- onames[pm]161.formals[pm] <- dargs[pm > 0L]162out[i] <- try(do.call(fun, .formals))163}164return(out)165}166167###############################################################################168# R (https://r-project.org/) Numeric Methods for Optimization of Portfolios169#170# Copyright (c) 2004-2021 Brian G. Peterson, Peter Carl, Ross Bennett, Kris Boudt171#172# This library is distributed under the terms of the GNU Public License (GPL)173# for full details see the file COPYING174#175# $Id$176#177###############################################################################178179180181