我想请求您帮助解决一个看似非常奇怪的问题。也就是说,我试图在金融时间序列中(以及它发生时)找到负回报的最长连续子序列,但我可以设法只编程具有相同符号的返回的最长连续子序列。我正在处理以下类型的财务数据:
LgReturn
1991-08-13 0.005180647
1991-08-14 0.008555806
1991-08-15 0.004878436
1991-08-16 -0.004723199
我的方法如下:首先使用符号获得仅1s的序列(正返回和-1s(负返回)并使用rle 获取所有长度的列表
z <- sign(NASDAQLgRetOpen[,1])
rle(z)
命令rle(z)产生以下输出:
Run Length Encoding
lengths: int [1:2731] 3 3 2 1 4 6 1 1 2 3 ...
values : num [1:2731] 1 -1 1 -1 1 -1 1 -1 1 -
然后我使用以下代码找到最长的子序列:
pad <- rev(sort(rle(z)$lengths[rle(z)$values[rle(z)$lengths]==-1]))
和以下代码提取我在时间序列中出现的位置
vsota <- sum(rle(z)$lengths[1:(which(unlist(rle(z)$lengths)==pad[1]))])
这给了我时间序列中的行,所以我使用了
serija <- NASDAQLgRetOpen[(vsota+1-pad[1]):vsota,1]
plot(cumprod(1+serija), type="l")
问题是我得到了一个情节,清楚地显示了一个增加的序列,所以我找到了最长的正序子。真正奇怪的是,无论我在行
中选择1还是-1,我都得到正的子序列 pad <- rev(sort(rle(z)$lengths[rle(z)$values[rle(z)$lengths]==-1]))
我错过了什么?伙计们,帮助我,因为这真的令人困惑。提前感谢您的建议。
...找到了解决这个问题的简单方法:反转符号并应用log,使得负回报变为0并且回归变为NaN - 然后rle总是返回最长的负设置序列,因为Nan被解释为长度为1。以下代码有效;假设您要分析的数据位于数据表的第i列:
fall <- function(data,i){
sg <- log(-sign(data[,i]))
zacetek <- sum(rle(sg)$lengths[1:(which(rle(sg)$lengths==max(rle(sg)$lengths))-1)[1]])
podatki <- data[(zacetek+1):(zacetek+max(rle(sg)$lengths)),1]
plot(cumprod(1+podatki), type="l")
}
既然已经解决了这个问题,我会问我的数据分析更重要的是:我收集了27个财务数据集,为了提高我的编码技能,我想开始使用lapply函数而不是for循环或相似的东西。 问题如下:如何在列表中的所有27个元素上应用上层函数。我已使用此代码制作所有对象的列表
sz <-c()
for (i in 1:length(files)){
sz <- rbind(sz,gsub(" ","", paste(unlist(strsplit(files[[i]],
".txt")),"LgRetOpen","")))
}
sz <- list(sz)
生成以下结果的(第一行):
[,1]
[1,] "AUDUSDLgRetOpen"
[2,] "BVSPUSDIBOVLgRetOpen"
[3,] "DAXLgRetOpen"
[4,] "DJIALgRetOpen"
我想要应用函数的数据是否存储为sz列表中的名称,但是没有连字符,即我想应用于AUDUSDLgRetOpen [,1],或者更好地说调用函数下降(AUDUSDLgRetOpen, 1)等等列表中的每个元素。我该怎么做呢?我尝试过像
这样的东西padci <- lapply(sz, function(x,i) fall(x,1))
但这当然不起作用,因为我必须调用data.frames AUDUSDLgRetOpen等等而不是字符&#34; AUDUSDLgRetOpen&#34;。怎么解决这个问题?
答案 0 :(得分:6)
我认为您使用rle
进入了正确的轨道,但您需要查看运行的值以确保其为负。 (当然,您需要确保您的数据按日期排序rle
才能生效。)
set.seed(17)
dd<-data.frame(
date=seq(as.Date("1991-01-01"), as.Date("1991-02-28"), by="1 day"),
lgreturn=rnorm(59, 0, 100)
)
run<-rle(dd$lgreturn<0)
maxrun <- which.min(run$lengths * run$values*-1)
datestart <- sum(run$lengths[1:(maxrun-1)])+1
dateend <- datestart+run$lengths[maxrun]-1
然后datestart
和dateend
将包含运行开始和结束的行的索引。这是结果图......
plot(lgreturn~date, dd)
abline(h=0, lty=2, col="red")
abline(v=dd$date[c(datestart, dateend)], lty=2)