[Returnanalytics-commits] r3611 - in pkg/FactorAnalytics: R man

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sun Mar 15 17:39:29 CET 2015


Author: pragnya
Date: 2015-03-15 17:39:29 +0100 (Sun, 15 Mar 2015)
New Revision: 3611

Modified:
   pkg/FactorAnalytics/R/fitTsfm.R
   pkg/FactorAnalytics/man/fitTsfm.Rd
Log:
Removed warning about excess returns in fitTsfm

Modified: pkg/FactorAnalytics/R/fitTsfm.R
===================================================================
--- pkg/FactorAnalytics/R/fitTsfm.R	2015-03-11 01:13:15 UTC (rev 3610)
+++ pkg/FactorAnalytics/R/fitTsfm.R	2015-03-15 16:39:29 UTC (rev 3611)
@@ -1,572 +1,570 @@
-#' @title Fit a time series factor model using time series regression
-#' 
-#' @description Fits a time series (a.k.a. macroeconomic) factor model for one 
-#' or more asset returns or excess returns using time series regression. 
-#' Users can choose between ordinary least squares-OLS, discounted least 
-#' squares-DLS (or) robust regression. Several variable selection options  
-#' including Stepwise, Subsets, Lars are available as well. An object of class 
-#' \code{"tsfm"} is returned.
-#' 
-#' @details 
-#' Typically, factor models are fit using excess returns. \code{rf.name} gives 
-#' the option to supply a risk free rate variable to subtract from each asset 
-#' return and factor to compute excess returns. 
-#' 
-#' Estimation method "OLS" corresponds to ordinary least squares using 
-#' \code{\link[stats]{lm}}, "DLS" is discounted least squares (weighted least 
-#' squares with exponentially declining weights that sum to unity), and, 
-#' "Robust" is robust regression (using \code{\link[robust]{lmRob}}). 
-#' 
-#' If \code{variable.selection="none"}, uses all the factors and performs no 
-#' variable selection. Whereas, "stepwise" performs traditional stepwise 
-#' LS or Robust regression (using \code{\link[stats]{step}} or 
-#' \code{\link[robust]{step.lmRob}}), that starts from the initial set of 
-#' factors and adds/subtracts factors only if the regression fit, as measured 
-#' by the Bayesian Information Criterion (BIC) or Akaike Information Criterion 
-#' (AIC), improves. And, "subsets" enables subsets selection using 
-#' \code{\link[leaps]{regsubsets}}; chooses the best performing subset of any 
-#' given size or within a range of subset sizes. Different methods such as 
-#' exhaustive search (default), forward or backward stepwise, or sequential 
-#' replacement can be employed.See \code{\link{fitTsfm.control}} for more 
-#' details on the control arguments.
-#'  
-#' \code{variable.selection="lars"} corresponds to least angle regression 
-#' using \code{\link[lars]{lars}} with variants "lasso" (default), "lar", 
-#' "stepwise" or "forward.stagewise". Note: If \code{variable.selection="lars"}, 
-#' \code{fit.method} will be ignored.
-#' 
-#' Arguments \code{mkt.name} and \code{mkt.timing} allow for market-timing 
-#' factors to be added to any of the above methods. A wrapper function 
-#' \code{\link{fitTsfmMT}} is built based on this functionality. Please refer to 
-#' \code{fitTsfmMT} for detail.  
-#' 
-#' \subsection{Data Processing}{
-#' 
-#' Note about NAs: Before model fitting, incomplete cases are removed for 
-#' every asset (return data combined with respective factors' return data) 
-#' using \code{\link[stats]{na.omit}}. Otherwise, all observations in 
-#' \code{data} are included.
-#' 
-#' Note about \code{asset.names} and \code{factor.names}: Spaces in column 
-#' names of \code{data} will be converted to periods as \code{fitTsfm} works 
-#' with \code{xts} objects internally and colnames won't be left as they are.
-#' }
-#' 
-#' @param asset.names vector containing names of assets, whose returns or 
-#' excess returns are the dependent variable.
-#' @param factor.names vector containing names of the macroeconomic factors.
-#' @param mkt.name name of the column for market excess returns (Rm-Rf); this 
-#' is necessary to add market timing factors. Default is NULL.
-#' @param rf.name name of the column of risk free rate variable to calculate 
-#' excess returns for all assets (in \code{asset.names}) and factors (in 
-#' \code{factor.names}). Default is NULL, and no action is taken.
-#' @param data vector, matrix, data.frame, xts, timeSeries or zoo object  
-#' containing column(s) named in \code{asset.names}, \code{factor.names} and 
-#' optionally, \code{mkt.name} and \code{rf.name}.
-#' @param fit.method the estimation method, one of "OLS", "DLS" or "Robust". 
-#' See details. Default is "OLS". 
-#' @param variable.selection the variable selection method, one of "none", 
-#' "stepwise","subsets","lars". See details. Default is "none".
-#' @param mkt.timing one of "HM" or "TM". See Details. Default is NULL.
-#' \code{mkt.name} is required if any of these options are to be implemented.
-#' @param control list of control parameters. The default is constructed by 
-#' the function \code{\link{fitTsfm.control}}. See the documentation for 
-#' \code{\link{fitTsfm.control}} for details.
-#' @param ... arguments passed to \code{\link{fitTsfm.control}}
-#' 
-#' @return fitTsfm returns an object of class \code{"tsfm"} for which 
-#' \code{print}, \code{plot}, \code{predict} and \code{summary} methods exist. 
-#' 
-#' The generic accessor functions \code{coef}, \code{fitted} and 
-#' \code{residuals} extract various useful features of the fit object. 
-#' Additionally, \code{fmCov} computes the covariance matrix for asset returns 
-#' based on the fitted factor model
-#' 
-#' An object of class \code{"tsfm"} is a list containing the following 
-#' components:
-#' \item{asset.fit}{list of fitted objects for each asset. Each object is of 
-#' class \code{lm} if \code{fit.method="OLS" or "DLS"}, class \code{lmRob} if 
-#' the \code{fit.method="Robust"}, or class \code{lars} if 
-#' \code{variable.selection="lars"}.}
-#' \item{alpha}{length-N vector of estimated alphas.}
-#' \item{beta}{N x K matrix of estimated betas.}
-#' \item{r2}{length-N vector of R-squared values.}
-#' \item{resid.sd}{length-N vector of residual standard deviations.}
-#' \item{fitted}{xts data object of fitted values; iff 
-#' \code{variable.selection="lars"}}
-#' \item{call}{the matched function call.}
-#' \item{data}{xts data object containing the assets and factors.}
-#' \item{asset.names}{asset.names as input.}
-#' \item{factor.names}{factor.names as input.}
-#' \item{fit.method}{fit.method as input.}
-#' \item{variable.selection}{variable.selection as input.}
-#' Where N is the number of assets, K is the number of factors and T is the 
-#' number of time periods.
-#' 
-#' @author Eric Zivot, Sangeetha Srinivasan and Yi-An Chen.
-#' 
-#' @references 
-#' Christopherson, J. A., Carino, D. R., & Ferson, W. E. (2009). Portfolio 
-#' performance measurement and benchmarking. McGraw Hill Professional.
-#' 
-#' Efron, B., Hastie, T., Johnstone, I., & Tibshirani, R. (2004). Least angle 
-#' regression. The Annals of statistics, 32(2), 407-499. 
-#' 
-#' Hastie, T., Tibshirani, R., Friedman, J., Hastie, T., Friedman, J., & 
-#' Tibshirani, R. (2009). The elements of statistical learning (Vol. 2, No. 1). 
-#' New York: Springer.
-#' 
-#' Henriksson, R. D., & Merton, R. C. (1981). On market timing and investment 
-#' performance. II. Statistical procedures for evaluating forecasting skills. 
-#' Journal of business, 513-533.
-#' 
-#' Treynor, J., & Mazuy, K. (1966). Can mutual funds outguess the market. 
-#' Harvard business review, 44(4), 131-136.
-#' 
-#' @seealso The \code{tsfm} methods for generic functions: 
-#' \code{\link{plot.tsfm}}, \code{\link{predict.tsfm}}, 
-#' \code{\link{print.tsfm}} and \code{\link{summary.tsfm}}. 
-#' 
-#' And, the following extractor functions: \code{\link[stats]{coef}}, 
-#' \code{\link[stats]{fitted}}, \code{\link[stats]{residuals}},
-#' \code{\link{fmCov}}, \code{\link{fmSdDecomp}}, \code{\link{fmVaRDecomp}} 
-#' and \code{\link{fmEsDecomp}}.
-#' 
-#' \code{\link{paFm}} for Performance Attribution. 
-#' 
-#' @examples
-#' # load data from the database
-#' data(managers)
-#' fit <- fitTsfm(asset.names=colnames(managers[,(1:6)]),
-#'                factor.names=colnames(managers[,(7:9)]), data=managers)
-#' summary(fit)
-#' fitted(fit)
-#' # plot actual returns vs. fitted factor model returns for HAM1
-#' plot(fit, plot.single=TRUE, asset.name="HAM1", which.plot.single=1, 
-#'      loop=FALSE)
-#' # group plot; type selected from menu prompt; auto-looped for multiple plots
-#' # plot(fit)
-#' 
-#' 
-#' # example using "subsets" variable selection
-#' fit.sub <- fitTsfm(asset.names=colnames(managers[,(1:6)]),
-#'                    factor.names=colnames(managers[,(7:9)]), 
-#'                    data=managers, variable.selection="subsets", 
-#'                    method="exhaustive", nvmin=2) 
-#' 
-#' # example using "lars" variable selection and subtracting risk-free rate
-#' fit.lar <- fitTsfm(asset.names=colnames(managers[,(1:6)]),
-#'                    factor.names=colnames(managers[,(7:9)]), 
-#'                    rf.name="US.3m.TR", data=managers, 
-#'                    variable.selection="lars", lars.criterion="cv") 
-#' 
-#' @importFrom PerformanceAnalytics checkData
-#' @importFrom robust lmRob step.lmRob
-#' @importFrom leaps regsubsets
-#' @importFrom lars lars cv.lars
-#' 
-#' @export
-
-fitTsfm <- function(asset.names, factor.names, mkt.name=NULL, rf.name=NULL, 
-                    data=data, fit.method=c("OLS","DLS","Robust"), 
-                    variable.selection=c("none","stepwise","subsets","lars"), 
-                    mkt.timing=NULL, control=fitTsfm.control(...), ...) {
-  
-  # record the call as an element to be returned
-  call <- match.call()
-  
-  # set defaults and check input vailidity
-  fit.method = fit.method[1]
-  if (!(fit.method %in% c("OLS","DLS","Robust"))) {
-    stop("Invalid argument: fit.method must be 'OLS', 'DLS' or 'Robust'")
-  }
-  variable.selection = variable.selection[1]
-  if (!(variable.selection %in% c("none","stepwise","subsets","lars"))) {
-    stop("Invalid argument: variable.selection must be either 'none',
-         'stepwise','subsets' or 'lars'")
-  }
-  if (missing(factor.names) && !is.null(mkt.name)) {
-    factor.names <- NULL
-  }
-
-#   if (xor(is.null(mkt.name), is.null(mkt.timing))) {
-#     stop("Missing argument: Both mkt.name and mkt.timing are necessary to add 
-#          market timing factors")
-#   }
-  
-  # extract arguments to pass to different fit and variable selection functions
-  decay <- control$decay
-  nvmin <- control$nvmin
-  lars.criterion <- control$lars.criterion
-  m1 <- match(c("weights","model","x","y","qr"), 
-              names(control), 0L)
-  lm.args <- control[m1, drop=TRUE]
-  m2 <-  match(c("weights","model","x","y","nrep"), 
-               names(control), 0L)
-  lmRob.args <- control[m2, drop=TRUE]
-  m3 <-  match(c("scope","scale","direction","trace","steps","k"), 
-               names(control), 0L)
-  step.args <- control[m3, drop=TRUE]
-  m4 <-  match(c("weights","nvmax","force.in","force.out","method",
-                 "really.big"), names(control), 0L)
-  regsubsets.args <- control[m4, drop=TRUE]
-  m5 <-  match(c("type","normalize","eps","max.steps","trace"), 
-               names(control), 0L)
-  lars.args <- control[m5, drop=TRUE]
-  m6 <-  match(c("K","type","normalize","eps","max.steps","trace"), 
-               names(control), 0L)
-  cv.lars.args <- control[m6, drop=TRUE]
-  
-  # convert data into an xts object and hereafter work with xts objects
-  data.xts <- checkData(data)
-  # convert index to 'Date' format for uniformity 
-  time(data.xts) <- as.Date(time(data.xts))
-  
-  # extract columns to be used in the time series regression
-  dat.xts <- merge(data.xts[,asset.names], data.xts[,factor.names])
-  ### After merging xts objects, the spaces in names get converted to periods
-  
-  # convert all asset and factor returns to excess return form if specified
-  if (!is.null(rf.name)) {
-    dat.xts <- "[<-"(dat.xts,,vapply(dat.xts, function(x) x-data.xts[,rf.name], 
-                                     FUN.VALUE = numeric(nrow(dat.xts))))
-  } else {
-    warning("Excess returns were not computed.")
-  }
-  
-  # opt add mkt-timing factors: down.market=max(0,Rf-Rm), market.sqd=(Rm-Rf)^2
-  if("HM" %in% mkt.timing) {
-    down.market <- dat.xts[,mkt.name]
-    down.market[down.market < 0 ] <- 0
-    dat.xts <- merge.xts(dat.xts,down.market)
-    colnames(dat.xts)[dim(dat.xts)[2]] <- "down.market"
-    factor.names <- c(factor.names,"down.market")
-  }
-  if("TM" %in% mkt.timing) {
-    market.sqd <- data.xts[,mkt.name]^2   
-    dat.xts <- merge(dat.xts, market.sqd)
-    colnames(dat.xts)[dim(dat.xts)[2]] <- "market.sqd"
-    factor.names <- c(factor.names, "market.sqd")
-  }
-  
-  # spaces get converted to periods in colnames of xts object after merge
-  asset.names <- gsub(" ",".", asset.names, fixed=TRUE)
-  factor.names <- gsub(" ",".", factor.names, fixed=TRUE)
-  
-  # Selects regression procedure based on specified variable.selection method.
-  # Each method returns a list of fitted factor models for each asset.
-  if (variable.selection == "none") {
-    reg.list <- NoVariableSelection(dat.xts, asset.names, factor.names, 
-                                    fit.method, lm.args, lmRob.args, decay)
-  } else if (variable.selection == "stepwise") {
-    reg.list <- SelectStepwise(dat.xts, asset.names, factor.names, fit.method, 
-                               lm.args, lmRob.args, step.args, decay)
-  } else if (variable.selection == "subsets") {
-    reg.list <- SelectAllSubsets(dat.xts, asset.names, factor.names, fit.method, 
-                                 lm.args, lmRob.args, regsubsets.args, 
-                                 nvmin, decay)
-  } else if (variable.selection == "lars") {
-    result.lars <- SelectLars(dat.xts, asset.names, factor.names, lars.args, 
-                              cv.lars.args, lars.criterion)
-    input <- list(call=call, data=dat.xts, asset.names=asset.names, 
-                  factor.names=factor.names, fit.method=NULL, 
-                  variable.selection=variable.selection)
-    result <- c(result.lars, input)
-    class(result) <- "tsfm"
-    return(result)
-  } 
-  
-  # extract coefficients from fitted factor models returned above
-  coef.mat <- makePaddedDataFrame(lapply(reg.list, coef))
-  alpha <- coef.mat[, 1, drop=FALSE]
-  # to get alpha of class numeric, do: aplha <- coef.mat[,1]
-  beta <- coef.mat[, -1, drop=FALSE]
-  # reorder and expand columns of beta to match factor.names
-  tmp <- matrix(NA, length(asset.names), length(factor.names))
-  colnames(tmp) <- factor.names
-  rownames(tmp) <- asset.names
-  beta <- merge(beta, tmp, all.x=TRUE, sort=FALSE)[,factor.names, drop=FALSE]
-  rownames(beta) <- asset.names
-  # extract r2 and residual sd
-  r2 <- sapply(reg.list, function(x) summary(x)$r.squared)
-  resid.sd <- sapply(reg.list, function(x) summary(x)$sigma)
-  # create list of return values.
-  result <- list(asset.fit=reg.list, alpha=alpha, beta=beta, r2=r2, 
-                 resid.sd=resid.sd, call=call, data=dat.xts, 
-                 asset.names=asset.names, factor.names=factor.names, 
-                 fit.method=fit.method, variable.selection=variable.selection)
-  class(result) <- "tsfm"
-  return(result)
-}
-
-
-### method variable.selection = "none"
-#
-NoVariableSelection <- function(dat.xts, asset.names, factor.names, fit.method,
-                                lm.args, lmRob.args, decay){
-  # initialize list object to hold the fitted objects
-  reg.list <- list()
-  
-  # loop through and estimate model for each asset to allow unequal histories
-  for (i in asset.names) {
-    # completely remove NA cases
-    reg.xts <- na.omit(dat.xts[, c(i, factor.names)])
-    
-    # formula to pass to lm or lmRob
-    fm.formula <- as.formula(paste(i," ~ ."))
-    
-    # fit based on time series regression method chosen
-    if (fit.method == "OLS") {
-      reg.list[[i]] <- do.call(lm, c(list(fm.formula,data=reg.xts),lm.args))
-    } else if (fit.method == "DLS") {
-      lm.args$weights <- WeightsDLS(nrow(reg.xts), decay)
-      reg.list[[i]] <- do.call(lm, c(list(fm.formula,data=reg.xts),lm.args))
-    } else if (fit.method == "Robust") {
-      reg.list[[i]] <- do.call(lmRob, c(list(fm.formula,data=reg.xts), 
-                                        lmRob.args))
-    } 
-  } 
-  reg.list  
-}
-
-
-### method variable.selection = "stepwise"
-#
-SelectStepwise <- function(dat.xts, asset.names, factor.names, fit.method, 
-                           lm.args, lmRob.args, step.args, decay) {
-  # initialize list object to hold the fitted objects
-  reg.list <- list()
-  
-  # loop through and estimate model for each asset to allow unequal histories
-  for (i in asset.names) {
-    # completely remove NA cases
-    reg.xts <- na.omit(dat.xts[, c(i, factor.names)])
-    
-    # formula to pass to lm or lmRob
-    fm.formula <- as.formula(paste(i," ~ ."))
-    
-    # fit based on time series regression method chosen
-    if (fit.method == "OLS") {
-      lm.fit <- do.call(lm, c(list(fm.formula,data=reg.xts),lm.args))
-      reg.list[[i]] <- do.call(step, c(list(lm.fit),step.args))
-    } else if (fit.method == "DLS") {
-      lm.args$weights <- WeightsDLS(nrow(reg.xts), decay)
-      lm.fit <- do.call(lm, c(list(fm.formula,data=reg.xts),lm.args))
-      reg.list[[i]] <- do.call(step, c(list(lm.fit),step.args))
-    } else if (fit.method == "Robust") {
-      lmRob.fit <- do.call(lmRob, c(list(fm.formula,data=reg.xts), lmRob.args))
-      reg.list[[i]] <- do.call(step.lmRob, c(list(lmRob.fit), step.args))
-    } 
-  }
-  reg.list
-}
-
-
-### method variable.selection = "subsets"
-#
-SelectAllSubsets <- function(dat.xts, asset.names, factor.names, fit.method, 
-                             lm.args, lmRob.args, regsubsets.args, nvmin, 
-                             decay) {
-  
-  # initialize list object to hold the fitted objects
-  reg.list <- list()
-  
-  # loop through and estimate model for each asset to allow unequal histories
-  for (i in asset.names) {
-    # completely remove NA cases
-    reg.xts <- na.omit(dat.xts[, c(i, factor.names)])
-    
-    # formula to pass to lm or lmRob
-    fm.formula <- as.formula(paste(i," ~ ."))
-    
-    if (fit.method=="DLS" && !"weights" %in% names(regsubsets.args)) {
-      regsubsets.args$weights <- WeightsDLS(nrow(reg.xts), decay)
-    }
-    
-    # choose best subset of factors depending on specified subset size
-    fm.subsets <- do.call(regsubsets, c(list(fm.formula,data=reg.xts), 
-                                        regsubsets.args))
-    sum.sub <- summary(fm.subsets)
-    
-    # choose best model of a given subset size nvmax=nvmin (or) 
-    # best model amongst subset sizes in [nvmin, nvmax]
-    nvmax <- length(sum.sub$bic)
-    best.size <- which.min(sum.sub$bic[nvmin:nvmax]) + nvmin -1
-    names.sub <- names(which(sum.sub$which[best.size,-1]==TRUE))
-    bic <- min(sum.sub$bic[nvmin:nvmax])
-    
-    # completely remove NA cases for chosen subset
-    reg.xts <- na.omit(dat.xts[,c(i,names.sub)])
-    
-    # fit based on time series regression method chosen
-    if (fit.method == "OLS") {
-      reg.list[[i]] <- do.call(lm, c(list(fm.formula,data=reg.xts),lm.args))
-    } else if (fit.method == "DLS") {
-      lm.args$weights <- WeightsDLS(nrow(reg.xts), decay)
-      reg.list[[i]] <- do.call(lm, c(list(fm.formula,data=reg.xts),lm.args))
-    } else if (fit.method == "Robust") {
-      reg.list[[i]] <- do.call(lmRob, c(list(fm.formula,data=reg.xts), 
-                                        lmRob.args))
-    } 
-  }
-  reg.list
-}
-
-
-### method variable.selection = "lars"
-#
-SelectLars <- function(dat.xts, asset.names, factor.names, lars.args, 
-                       cv.lars.args, lars.criterion) {
-  # initialize list object to hold the fitted objects and, vectors and matrices
-  # for the other results
-  asset.fit <- list()
-  fitted.list <- list()
-  alpha <- rep(NA, length(asset.names))
-  beta <- matrix(NA, length(asset.names), length(factor.names))
-  r2 <- rep(NA, length(asset.names))
-  resid.sd <- rep(NA, length(asset.names))
-  names(alpha)=names(r2)=names(resid.sd)=rownames(beta)=asset.names
-  colnames(beta) <- factor.names
-  
-  # loop through and estimate model for each asset to allow unequal histories
-  for (i in asset.names) {
-    # completely remove NA cases
-    reg.xts <- na.omit(dat.xts[, c(i, factor.names)])
-    # convert to matrix
-    reg.mat <- as.matrix(reg.xts)
-    # fit lars regression model
-    lars.fit <- do.call(lars, c(list(x=reg.mat[,factor.names],y=reg.mat[,i]),
-                                lars.args))
-    lars.sum <- summary(lars.fit)
-    lars.cv <- do.call(cv.lars, c(list(x=reg.mat[,factor.names],y=reg.mat[,i], 
-                                       mode="step"),cv.lars.args))
-    # including plot.it=FALSE to cv.lars strangely gives an error: "Argument s 
-    # out of range". And, specifying index=seq(nrow(lars.fit$beta)-1) resolves 
-    # the issue, but care needs to be taken for small N
-    
-    # get the step that minimizes the "Cp" statistic or 
-    # the K-fold "cv" mean-squared prediction error
-    if (lars.criterion=="Cp") {
-      s <- which.min(lars.sum$Cp)-1 # 2nd row is "step 1"
-    } else {
-      s <- which.min(lars.cv$cv)-1
-    }
-    # get factor model coefficients & fitted values at the step obtained above
-    coef.lars <- predict(lars.fit, s=s, type="coef", mode="step")
-    fitted.lars <- predict(lars.fit, reg.mat[,factor.names], s=s, type="fit", 
-                           mode="step")
-    fitted.list[[i]] <- xts(fitted.lars$fit, index(reg.xts))
-    # extract and assign the results
-    asset.fit[[i]] = lars.fit
-    alpha[i] <- (fitted.lars$fit - 
-                   reg.xts[,factor.names]%*%coef.lars$coefficients)[1]
-    beta.names <- names(coef.lars$coefficients)
-    beta[i, beta.names] <- coef.lars$coefficients
-    r2[i] <-  lars.fit$R2[s+1]
-    resid.sd[i] <- sqrt(lars.sum$Rss[s+1]/(nrow(reg.xts)-lars.sum$Df[s+1]))
-    
-  }
-  if (length(asset.names)>1) {
-    fitted.xts <- do.call(merge, fitted.list) 
-  } else {
-    fitted.xts <- fitted.list[[1]]
-  }
-  results.lars <- list(asset.fit=asset.fit, alpha=alpha, beta=beta, r2=r2, 
-                       resid.sd=resid.sd, fitted=fitted.xts)
-  # As a special case for variable.selection="lars", fitted values are also 
-  # returned by fitTsfm. Else, step s from the best fit is needed to get 
-  # fitted values & residuals.
-}
-
-
-### calculate exponentially decaying weights for fit.method="DLS"
-## t = number of observations; d = decay factor
-#
-WeightsDLS <- function(t,d) {
-  # more weight given to more recent observations 
-  w <- d^seq((t-1),0,-1)    
-  # ensure that the weights sum to unity
-  w/sum(w)
-}
-
-### make a data frame (padded with NAs) from unequal vectors with named rows
-## l = list of unequal vectors
-#
-makePaddedDataFrame <- function(l) {
-  DF <- do.call(rbind, lapply(lapply(l, unlist), "[", 
-                              unique(unlist(c(sapply(l,names))))))
-  DF <- as.data.frame(DF)
-  names(DF) <- unique(unlist(c(sapply(l,names))))
-  # as.matrix(DF) # if matrix output needed
-  DF
-}
-
-#' @param object a fit object of class \code{tsfm} which is returned by 
-#' \code{fitTsfm}
-
-#' @rdname fitTsfm
-#' @method coef tsfm
-#' @export
-
-coef.tsfm <- function(object, ...) {
-  # cbind alpha and beta; works for all fit and var selection methods
-  coef.mat <- cbind(object$alpha, object$beta)
-  # name for alpha/intercept column
-  colnames(coef.mat)[1] <- "(Intercept)"
-  return(coef.mat)
-}
-
-#' @rdname fitTsfm
-#' @method fitted tsfm
-#' @export
-
-fitted.tsfm <- function(object, ...) {  
-  if (object$variable.selection=="lars") {
-    # generic method 'fitted' does not exist for "lars" fit objects
-    # so, use fitted values returned by 'fitTsfm'
-    fitted.xts <- object$fitted
-  } else {
-    if (length(object$asset.names)>1) {
-      # get fitted values from each linear factor model fit 
-      # and convert them into xts/zoo objects
-      fitted.list = sapply(object$asset.fit, 
-                           function(x) checkData(fitted(x,...)))
-      # this is a list of xts objects, indexed by the asset name
-      # merge the objects in the list into one xts object
-      fitted.xts <- do.call(merge, fitted.list) 
-    } else {
-      fitted.xts <- checkData(fitted(object$asset.fit[[1]],...))
-      colnames(fitted.xts) <- object$asset.names
-    }
-  }
-  time(fitted.xts) <- as.Date(time(fitted.xts))
-  return(fitted.xts)
-}
-
-
-#' @rdname fitTsfm
-#' @method residuals tsfm
-#' @export
-
-residuals.tsfm <- function(object, ...) {
-  if (object$variable.selection=="lars") {
-    # generic method 'residuals' does not exist for "lars" fit objects
-    # so, calculate them from the actual and fitted values
-    residuals.xts <- object$data[,object$asset.names] - object$fitted
-  } else {
-    if (length(object$asset.names)>1) {
-      # get residuals from each linear factor model fit 
-      # and convert them into xts/zoo objects
-      residuals.list = sapply(object$asset.fit, 
-                              function(x) checkData(residuals(x,...)))
-      # this is a list of xts objects, indexed by the asset name
-      # merge the objects in the list into one xts object
-      residuals.xts <- do.call(merge, residuals.list) 
-    } else {
-      residuals.xts <- checkData(residuals(object$asset.fit[[1]],...))
-      colnames(residuals.xts) <- object$asset.names
-    }
-  }
-  time(residuals.xts) <- as.Date(time(residuals.xts))
-  return(residuals.xts)
-}
+#' @title Fit a time series factor model using time series regression
+#' 
+#' @description Fits a time series (a.k.a. macroeconomic) factor model for one 
+#' or more asset returns or excess returns using time series regression. 
+#' Users can choose between ordinary least squares-OLS, discounted least 
+#' squares-DLS (or) robust regression. Several variable selection options  
+#' including Stepwise, Subsets, Lars are available as well. An object of class 
+#' \code{"tsfm"} is returned.
+#' 
+#' @details 
+#' Typically, factor models are fit using excess returns. \code{rf.name} gives 
+#' the option to supply a risk free rate variable to subtract from each asset 
+#' return and factor to compute excess returns. 
+#' 
+#' Estimation method "OLS" corresponds to ordinary least squares using 
+#' \code{\link[stats]{lm}}, "DLS" is discounted least squares (weighted least 
+#' squares with exponentially declining weights that sum to unity), and, 
+#' "Robust" is robust regression (using \code{\link[robust]{lmRob}}). 
+#' 
+#' If \code{variable.selection="none"}, uses all the factors and performs no 
+#' variable selection. Whereas, "stepwise" performs traditional stepwise 
+#' LS or Robust regression (using \code{\link[stats]{step}} or 
+#' \code{\link[robust]{step.lmRob}}), that starts from the initial set of 
+#' factors and adds/subtracts factors only if the regression fit, as measured 
+#' by the Bayesian Information Criterion (BIC) or Akaike Information Criterion 
+#' (AIC), improves. And, "subsets" enables subsets selection using 
+#' \code{\link[leaps]{regsubsets}}; chooses the best performing subset of any 
+#' given size or within a range of subset sizes. Different methods such as 
+#' exhaustive search (default), forward or backward stepwise, or sequential 
+#' replacement can be employed.See \code{\link{fitTsfm.control}} for more 
+#' details on the control arguments.
+#'  
+#' \code{variable.selection="lars"} corresponds to least angle regression 
+#' using \code{\link[lars]{lars}} with variants "lasso" (default), "lar", 
+#' "stepwise" or "forward.stagewise". Note: If \code{variable.selection="lars"}, 
+#' \code{fit.method} will be ignored.
+#' 
+#' Arguments \code{mkt.name} and \code{mkt.timing} allow for market-timing 
+#' factors to be added to any of the above methods. A wrapper function 
+#' \code{\link{fitTsfmMT}} is built based on this functionality. Please refer to 
+#' \code{fitTsfmMT} for detail.  
+#' 
+#' \subsection{Data Processing}{
+#' 
+#' Note about NAs: Before model fitting, incomplete cases are removed for 
+#' every asset (return data combined with respective factors' return data) 
+#' using \code{\link[stats]{na.omit}}. Otherwise, all observations in 
+#' \code{data} are included.
+#' 
+#' Note about \code{asset.names} and \code{factor.names}: Spaces in column 
+#' names of \code{data} will be converted to periods as \code{fitTsfm} works 
+#' with \code{xts} objects internally and colnames won't be left as they are.
+#' }
+#' 
+#' @param asset.names vector containing names of assets, whose returns or 
+#' excess returns are the dependent variable.
+#' @param factor.names vector containing names of the macroeconomic factors.
+#' @param mkt.name name of the column for market excess returns (Rm-Rf); this 
+#' is necessary to add market timing factors. Default is NULL.
+#' @param rf.name name of the column of risk free rate variable to calculate 
+#' excess returns for all assets (in \code{asset.names}) and factors (in 
+#' \code{factor.names}). Default is NULL, and no action is taken.
+#' @param data vector, matrix, data.frame, xts, timeSeries or zoo object  
+#' containing column(s) named in \code{asset.names}, \code{factor.names} and 
+#' optionally, \code{mkt.name} and \code{rf.name}.
+#' @param fit.method the estimation method, one of "OLS", "DLS" or "Robust". 
+#' See details. Default is "OLS". 
+#' @param variable.selection the variable selection method, one of "none", 
+#' "stepwise","subsets","lars". See details. Default is "none".
+#' @param mkt.timing one of "HM" or "TM". See Details. Default is NULL.
+#' \code{mkt.name} is required if any of these options are to be implemented.
+#' @param control list of control parameters. The default is constructed by 
+#' the function \code{\link{fitTsfm.control}}. See the documentation for 
+#' \code{\link{fitTsfm.control}} for details.
+#' @param ... arguments passed to \code{\link{fitTsfm.control}}
+#' 
+#' @return fitTsfm returns an object of class \code{"tsfm"} for which 
+#' \code{print}, \code{plot}, \code{predict} and \code{summary} methods exist. 
+#' 
+#' The generic accessor functions \code{coef}, \code{fitted} and 
+#' \code{residuals} extract various useful features of the fit object. 
+#' Additionally, \code{fmCov} computes the covariance matrix for asset returns 
+#' based on the fitted factor model
+#' 
+#' An object of class \code{"tsfm"} is a list containing the following 
+#' components:
+#' \item{asset.fit}{list of fitted objects for each asset. Each object is of 
+#' class \code{lm} if \code{fit.method="OLS" or "DLS"}, class \code{lmRob} if 
+#' the \code{fit.method="Robust"}, or class \code{lars} if 
+#' \code{variable.selection="lars"}.}
+#' \item{alpha}{length-N vector of estimated alphas.}
+#' \item{beta}{N x K matrix of estimated betas.}
+#' \item{r2}{length-N vector of R-squared values.}
+#' \item{resid.sd}{length-N vector of residual standard deviations.}
+#' \item{fitted}{xts data object of fitted values; iff 
+#' \code{variable.selection="lars"}}
+#' \item{call}{the matched function call.}
+#' \item{data}{xts data object containing the assets and factors.}
+#' \item{asset.names}{asset.names as input.}
+#' \item{factor.names}{factor.names as input.}
+#' \item{fit.method}{fit.method as input.}
+#' \item{variable.selection}{variable.selection as input.}
+#' Where N is the number of assets, K is the number of factors and T is the 
+#' number of time periods.
+#' 
+#' @author Eric Zivot, Sangeetha Srinivasan and Yi-An Chen.
+#' 
+#' @references 
+#' Christopherson, J. A., Carino, D. R., & Ferson, W. E. (2009). Portfolio 
+#' performance measurement and benchmarking. McGraw Hill Professional.
+#' 
+#' Efron, B., Hastie, T., Johnstone, I., & Tibshirani, R. (2004). Least angle 
+#' regression. The Annals of statistics, 32(2), 407-499. 
+#' 
+#' Hastie, T., Tibshirani, R., Friedman, J., Hastie, T., Friedman, J., & 
+#' Tibshirani, R. (2009). The elements of statistical learning (Vol. 2, No. 1). 
+#' New York: Springer.
+#' 
+#' Henriksson, R. D., & Merton, R. C. (1981). On market timing and investment 
+#' performance. II. Statistical procedures for evaluating forecasting skills. 
+#' Journal of business, 513-533.
+#' 
+#' Treynor, J., & Mazuy, K. (1966). Can mutual funds outguess the market. 
+#' Harvard business review, 44(4), 131-136.
+#' 
+#' @seealso The \code{tsfm} methods for generic functions: 
+#' \code{\link{plot.tsfm}}, \code{\link{predict.tsfm}}, 
+#' \code{\link{print.tsfm}} and \code{\link{summary.tsfm}}. 
+#' 
+#' And, the following extractor functions: \code{\link[stats]{coef}}, 
+#' \code{\link[stats]{fitted}}, \code{\link[stats]{residuals}},
+#' \code{\link{fmCov}}, \code{\link{fmSdDecomp}}, \code{\link{fmVaRDecomp}} 
+#' and \code{\link{fmEsDecomp}}.
+#' 
+#' \code{\link{paFm}} for Performance Attribution. 
+#' 
+#' @examples
+#' # load data from the database
+#' data(managers)
+#' fit <- fitTsfm(asset.names=colnames(managers[,(1:6)]),
+#'                factor.names=colnames(managers[,(7:9)]), data=managers)
+#' summary(fit)
+#' fitted(fit)
+#' # plot actual returns vs. fitted factor model returns for HAM1
+#' plot(fit, plot.single=TRUE, asset.name="HAM1", which.plot.single=1, 
+#'      loop=FALSE)
+#' # group plot; type selected from menu prompt; auto-looped for multiple plots
+#' # plot(fit)
+#' 
+#' 
+#' # example using "subsets" variable selection
+#' fit.sub <- fitTsfm(asset.names=colnames(managers[,(1:6)]),
+#'                    factor.names=colnames(managers[,(7:9)]), 
+#'                    data=managers, variable.selection="subsets", 
[TRUNCATED]

To get the complete diff run:
    svnlook diff /svnroot/returnanalytics -r 3611


More information about the Returnanalytics-commits mailing list