このルーチンは、maxdrawdown に基づいて日中のストップロスを課しているようです。したがって、変数 limit を 2 番目の引数として集計関数に渡すことができるようにしたいと考えています。これは、ave の動作により、現在は 1 つの関数しか使用しません。
これらすべてを 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 で実装されていると思います)。
これは、複数の引数を必要とする関数で機能し、同じサイズまたは集計値のベクトルを返す関数でも機能します。
試してみて、これで問題が解決するかどうかをお知らせください。