###############################################################################1# R (https://r-project.org/) Numeric Methods for Optimization of Portfolios2#3# Copyright (c) 2004-2023 Yifu Kang, Doug Martin, Xinran Zhao4#5# This library is distributed under the terms of the GNU Public License (GPL)6# for full details see the file COPYING7#8# $Id$9#10###############################################################################1112#' @title Compute returns mean vector and covariance matrix with custom.covRob.MM13#'14#' @description15#' custom.covRob.MM uses the RobStatTM package function covRobMM to compute a robust16#' mean vector and robust covariance matrix for a portfolio's asset returns17#'18#' @param R xts object of asset returns19#' @param ... parameters for covRob.MM20#'21#' @references For parameter details, see covRobMM in the RobStatTM Reference22#' Manual at \url{https://CRAN.R-project.org/package=RobStatTM}23#'24#' @return a list containing covariance matrix sigma and mean vector mu25#' @author Yifu Kang, Xinran Zhao26#' @export27#'28custom.covRob.MM <- function(R, ...){29out <- list()30if(hasArg(tol)) tol = match.call(expand.dots = TRUE)$tol else tol = 1e-431if(hasArg(maxit)) maxit = match.call(expand.dots = TRUE)$maxit else maxit = 503233robustCov <- RobStatTM::covRobMM(X = R, tolpar = tol, maxit = maxit)3435out$sigma <- robustCov$cov36out$mu <- robustCov$center37return(out)38}3940#' @title Compute returns mean vector and covariance matrix with custom.covRob.Rocke41#'42#' @description43#' custom.covRob.Rocke uses the RobStatTM package function covRobRocke to compute a robust44#' mean vector and robust covariance matrix for a portfolio's asset returns45#'46#' @param R xts object of asset returns47#' @param ... parameters for covRob.Rocke48#'49#' @details For parameter details, see covRobRocke in the RobStatTM Reference50#' Manual at \url{https://CRAN.R-project.org/package=RobStatTM}51#'52#' @return a list containing covariance matrix sigma and mean vector mu53#' @author Yifu Kang54#' @export55#'56custom.covRob.Rocke <- function(R, ...){57out <- list()58if(hasArg(tol)) tol = match.call(expand.dots = TRUE)$tol else tol = 1e-459if(hasArg(maxit)) maxit = match.call(expand.dots = TRUE)$maxit else maxit = 5060if(hasArg(initial)) initial = match.call(expand.dots = TRUE)$initial else initial = 'K'61if(hasArg(maxsteps)) maxsteps = match.call(expand.dots = TRUE)$maxsteps else maxsteps = 562if(hasArg(propmin)) propmin = match.call(expand.dots = TRUE)$propmin else propmin = 263if(hasArg(qs)) qs = match.call(expand.dots = TRUE)$qs else qs = 506465robustCov <- RobStatTM::covRobRocke(X = R, initial = initial, maxsteps = maxsteps, propmin = propmin,66qs = qs, tol = tol, maxit = maxit)6768out$sigma <- robustCov$cov69out$mu <- robustCov$center70return(out)71}7273#' @title Compute returns mean vector and covariance matrix with custom.covRob.Mcd74#'75#' @description76#' custom.covRob.Mcd uses the robustbase package function covMcd to compute a robust77#' mean vector and robust covariance matrix for a portfolio's asset returns78#'79#' @param R xts object of asset returns80#' @param ... parameters for covRob.Mcd81#'82#' @details For parameter details, see covMcd in the robustbase Reference83#' Manual at \url{https://CRAN.R-project.org/package=robustbase}84#'85#' @return a list containing covariance matrix sigma and mean vector mu86#' @export87custom.covRob.Mcd <- function(R, ...){8889if(hasArg(control)) control = match.call(expand.dots = TRUE)$control else control = MycovRobMcd()90if(hasArg(alpha)) alpha = match.call(expand.dots = TRUE)$alpha else alpha = control$alpha91if(hasArg(nsamp)) nsamp = match.call(expand.dots = TRUE)$nsamp else nsamp = control$nsamp92if(hasArg(nmini)) nmini = match.call(expand.dots = TRUE)$nmini else nmini = control$nmini93if(hasArg(kmini)) kmini = match.call(expand.dots = TRUE)$kmini else kmini = control$kmini94if(hasArg(scalefn)) scalefn = match.call(expand.dots = TRUE)$scalefn else scalefn = control$scalefn95if(hasArg(maxcsteps)) maxcsteps = match.call(expand.dots = TRUE)$maxcsteps else maxcsteps = control$maxcsteps96if(hasArg(initHsets)) initHsets = match.call(expand.dots = TRUE)$initHsets else initHsets = control$initHsets97if(hasArg(seed)) seed = match.call(expand.dots = TRUE)$seed else seed = control$seed98if(hasArg(tolSolve)) tolSolve = match.call(expand.dots = TRUE)$tolSolve else tolSolve = control$tolSolve99if(hasArg(wgtFUN)) wgtFUN = match.call(expand.dots = TRUE)$wgtFUN else wgtFUN = control$wgtFUN100if(hasArg(use.correction)) use.correction = match.call(expand.dots = TRUE)$use.correction else use.correction = control$use.correction101102103robustMCD <- robustbase::covMcd(x = R, alpha = alpha,104nsamp = nsamp, nmini = nmini,105kmini = kmini, seed = seed,106tolSolve = tolSolve, scalefn = scalefn,107maxcsteps = maxcsteps,108initHsets = initHsets,109wgtFUN = wgtFUN, use.correction = use.correction)110111return(list(mu = robustMCD$center, sigma = robustMCD$cov))112}113114#' @title115#' Control settings for custom.covRob.Mcd116#'117#' @description118#' Auxiliary function for passing the estimation options as parameters119#' to the estimation function MCD.robust.moment120#'121#' @param alpha numeric parameter controlling the size of the subsets over122#' which the determinant is minimized. Allowed values are between123#' 0.5 and 1 and the default is 0.5.124#' @param nsamp number of subsets used for initial estimates or "best", "exact",125#' or "deterministic". Default is nsamp = 500. For nsamp = "best"126#' exhaustive enumeration is done, as long as the number of trials127#' does not exceed 100'000, which is the value of nlarge. For "exact",128#' exhaustive enumeration will be attempted however many samples are needed.129#' In this case a warning message may be displayed saying that130#' the computation can take a very long time.131#' For "deterministic", the deterministic MCD is computed;132#' as proposed by Hubert et al. (2012) it starts from the h most133#' central observations of six (deterministic) estimators.134#' @param nmini,kmini for n >= 2*n0, n0 := nmini, the algorithm splits the data135#' into maximally kmini (by default 5) subsets, of size approximately,136#' but at least nmini. When nmini*kmini < n, the initial search137#' uses only a subsample of size nmini*kmini. The original algorithm138#' had nmini = 300 and kmini = 5 hard coded.139#' @param scalefn function to compute a robust scale estimate or character string140#' specifying a rule determining such a function for the deterministic MCD.141#' The default is "hrv2012". Another option value is "v2014".142#' @param maxcsteps maximal number of concentration steps in the deterministic MCD143#' @param seed initial seed for random generator144#' @param tolSolve numeric tolerance to be used for inversion of the covariance matrix145#' @param wgtFUN a character string or function, specifying how the weights for146#' the reweighting step should be computed. Default is "01.originalz".147#' @param beta a quantile, experimentally used for some of the prespecified wgtFUNs. For our148#' MCD method, the default is 0.975.149#' @param use.correction whether to use finite sample correction factors; defaults to TRUE.150#' @return a list of passed parameters151#' @export152#'153154MycovRobMcd <- function(alpha = 1/2,155nsamp = 500, nmini = 300, kmini = 5,156scalefn = "hrv2012", maxcsteps = 200,157seed = NULL, tolSolve = 1e-14,158wgtFUN = "01.original", beta,159use.correction = TRUE160){161if(missing(beta) || !is.numeric(beta))162beta <- 0.975163164return(list(alpha = alpha, nsamp = nsamp, nmini = as.integer(nmini), kmini = as.integer(kmini),165seed = as.integer(seed),166tolSolve = tolSolve, scalefn = scalefn, maxcsteps = as.integer(maxcsteps),167wgtFUN = wgtFUN, beta = beta,168use.correction = use.correction))169}170171#' @title Compute returns mean vector and covariance matrix with custom.covRob.TSGS172#'173#' @description174#' This is a function uses the TSGS function from GSE package to compute175#' the Two-Step Generalized S-Estimate, a robust estimate of location176#' and scatter for data with cell-wise and case-wise contamination.177#'178#' @param R xts object of asset returns179#' @param ... parameters for covRob.TSGS180#'181#' @return a list contains mean and covariance matrix of the stock return matrix182#' @export183#'184#' @references Claudio Agostinelli, Andy Leung, "Robust estimation of multivariate185#' location and scatter in the presence of cellwise and casewise contamination",186#' 2014.187188custom.covRob.TSGS <- function(R, ...){189if(hasArg(control)) control = match.call(expand.dots = TRUE)$control else control = MycovRobTSGS()190if(hasArg(filter)) filter = match.call(expand.dots = TRUE)$filter else filter = control$filter191if(hasArg(partial.impute)) partial.impute = match.call(expand.dots = TRUE)$partial.impute else partial.impute = control$partial.impute192if(hasArg(tol)) tol = match.call(expand.dots = TRUE)$tol else tol = control$tol193if(hasArg(maxiter)) maxiter = match.call(expand.dots = TRUE)$maxiter else maxiter = control$maxiter194if(hasArg(loss)) loss = match.call(expand.dots = TRUE)$loss else loss = control$loss195if(hasArg(init)) init = match.call(expand.dots = TRUE)$init else init = control$init196197tsgsRob <- GSE::TSGS(x = R, filter = filter,198partial.impute = partial.impute, tol = tol,199maxiter = maxiter, method = loss,200init = init)201202return(list(mu = tsgsRob@mu, sigma = tsgsRob@S))203204}205206#' @title207#' Control settings for custom.covRob.TSGS208#'209#' @description210#' Auxiliary function for passing the estimation options as parameters211#' to the estimation function custom.TSGS212#'213#' @param filter the filter to be used in the first step. Available choices are214#' "UBF-DDC","UBF","DDC","UF". The default one is "UBF-DDC".215#' @param partial.impute whether partial imputation is used prior to estimation.216#' The default is FALSE.217#' @param tol tolerance for the convergence criterion. Default is 1e-4.218#' @param maxiter maximum number of iterations. Default is 150.219#' @param loss loss function to use, "bisquare" or "rocke". Default is "bisquare"220#' @param init type of initial estimator. Options include "emve", "qc", "huber","imputed","emve_c"221#'222#' @return a list of passed parameters223#' @export224#'225226MycovRobTSGS <- function(filter = c("UBF-DDC","UBF","DDC","UF"),227partial.impute = FALSE, tol = 1e-4, maxiter = 150,228loss = c("bisquare","rocke"),229init = c("emve","qc","huber","imputed","emve_c")){230231filter <- match.arg(filter)232loss <- match.arg(loss)233init <- match.arg(init)234235return(list(filter = filter, partial.impute = partial.impute,236tol = tol, maxiter = as.integer(maxiter),237loss = loss,init))238}239240