Кажется, что эта процедура накладывает внутридневной стоп-лосс на основе maxdrawdown. Поэтому я предполагаю, что вы хотите иметь возможность передавать переменный предел в качестве второго аргумента своей функции агрегации, которая только в настоящее время использует только 1 функцию из-за того, как работает ave.
Если все это в одной строке не является абсолютной необходимостью, я могу использовать функцию, которую я написал, которая обобщает агрегацию через «режущие переменные». Вот код:
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 как строка
- имя переменной во входном d ata.frame, которые являются входами в функцию
Если вы посмотрите на кишки функции «mtapplylist2», ключевые компоненты будут «разделены» и «сопоставить». Эти функции достаточно быстры (я думаю, что split реализован на C).
Это работает с функциями, требующими нескольких аргументов, а также для функций, возвращающих вектор того же размера или агрегированного значения.
Попробуйте и дайте мне знать, если это решит вашу проблему.
Здравствуйте. Я попробую. благодаря – skan