金融系列连续下跌最多

时间:2014-05-21 22:28:57

标签: r finance

我想请求您帮助解决一个看似非常奇怪的问题。也就是说,我试图在金融时间序列中(以及它发生时)找到负回报的最长连续子序列,但我可以设法只编程具有相同符号的返回的最长连续子序列。我正在处理以下类型的财务数据:

               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;。怎么解决这个问题?

1 个答案:

答案 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

然后datestartdateend将包含运行开始和结束的行的索引。这是结果图......

plot(lgreturn~date, dd)
abline(h=0, lty=2, col="red")
abline(v=dd$date[c(datestart, dateend)], lty=2)

longest negative streak