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))

引数として 2 つのベクトルを使用しようとしましたave(...) が、それらを行列に結合しても 1 つだけを受け入れるようです。

これは単なる例ですが、他の関数を使用することもできます。

ここでは、 の値を数値ベクトルと比較する必要があり、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 に基づいて日中のストップロスを課しているようです。したがって、変数 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 で実装されていると思います)。

これは、複数の引数を必要とする関数で機能し、同じサイズまたは集計値のベクトルを返す関数でも機能します。

試してみて、これで問題が解決するかどうかをお知らせください。

于 2010-11-01T22:34:32.140 に答える