0

我怎样才能把这一切写在一行中?

mydata是一个"zoo"系列,limit 是一个相同大小的数值向量

tmp <- ave(coredata(mydata), as.Date(index(mydata)),
           FUN = function(x) cummax(x)-x)
tmp <- (tmp < limit)
final <- ave(tmp, as.Date(index(mydata)),
             FUN = function(x) cumprod(x))

我尝试使用两个向量作为参数,ave(...) 但即使我将它们加入矩阵,它似乎也只接受一个。

这只是一个示例,但可以使用任何其他功能。

在这里,我需要将 的值cummax(mydata)-mydata与数字向量进行比较,一旦超过它,我将保持零直到一天结束。从cummax每天开始计算。

如果 limit 是单个数字而不是向量(具有不同的可能数字),我可以这样写:

ave(coredata(mydata), as.Date(index(mydata)),
    FUN = function(x) cumprod((cummax(x) - x) < limit))

但是我不能在那里引入一个长于x(它应该具有与每天相同的长度)的向量,而且我不知道如何将它作为另一个参数引入ave().

4

1 回答 1

1

似乎这个例程会根据 maxdrawdown 强加日内止损。因此,我假设您希望能够将变量限制作为第二个参数传递给您的聚合函数,由于 ave 的工作方式,该聚合函数目前只需要 1 个函数。

如果不是绝对必须将所有这些放在一行中,我可以分享我编写的一个函数,该函数通过“切割变量”概括聚合。这是代码:

mtapplylist2 <- function(t, IDX, DEF, MoreArgs=NULL, ...)
{
  if(mode(DEF) != "list")
  {
    cat("Definition must be list type\n");
    return(NULL);
  }

  a        <- c();
  colnames <- names(DEF);
  for ( i in 1:length(DEF) )
  {
    def  <- DEF[[i]];
    func <- def[1];
    if(mode(func) == "character") { func <- get(func); }
    cols <- def[-1];

    # build the argument to be called
    arglist      <- list();
    arglist[[1]] <- func;
    for( j in 1:length(cols) )
    {
      col <- cols[j];
      grp <- split(t[,col], IDX);
      arglist[[1+j]] <- grp;
    }
    arglist[["MoreArgs"]] <- MoreArgs;
    v <- do.call("mapply", arglist);
    # print(class(v)); print(v);
    if(class(v) == "matrix")
    {
      a <- cbind(a, as.vector(v));
    } else {
      a <- cbind(a, v);
    }
  }
  colnames(a) <- colnames;
  return(a);
}

你可以像这样使用它:

# assuming you have the data in the data.frame
df  <- data.frame(date=rep(1:10,10), ret=rnorm(100), limit=rep(c(0.25,0.50),50))

dfunc <- function(x, ...) { return(cummax(x)-x ) }
pfunc <- function(x,y, ...) { return((cummax(x)-x) < y) }

# assumes you have the function declared in the same namespace
def <- list(
 "drawdown"    = c("dfunc", "ret"),
 "hasdrawdown" = c("pfunc", "ret", "limit")
);

# from R console
> def <- list("drawdown" = c("dfunc", "ret"),"happened" = c("pfunc","ret","limit"))
> dim( mtapplylist2(df, df$date, def) )
[1] 100   2

请注意,“def”变量是一个包含以下项目的列表:

  • 计算列名
  • 向量 arg 函数名称作为字符串
  • 输入 data.frame 中作为函数输入的变量的名称

如果您查看“mtapplylist2”函数的内容,关键组件将是“split”和“mapply”。这些函数足够快(我认为 split 是用 C 实现的)。

这适用于需要多个参数的函数,也适用于返回相同大小或聚合值的向量的函数。

试试看,如果这能解决您的问题,请告诉我。

于 2010-11-01T22:34:32.140 回答