似乎这个例程会根据 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 实现的)。
这适用于需要多个参数的函数,也适用于返回相同大小或聚合值的向量的函数。
试试看,如果这能解决您的问题,请告诉我。