如何解决如何使用 R 中的每日收益计算追踪 12 个月滑动窗口的滚动偏度?
我有股票的每日回报,其中一列包含日期,格式为 dd-mm-yy。我想使用 R 根据其过去 12 个月的每日回报来计算一个月的偏度。 The Data looks like this
例如: 如果有两家公司从 01/01/2001 到 31/12/2003 的每日收益,那么我想找出每家公司从 2002 年 1 月开始的偏度。
- 2002 年 1 月的偏度:基于过去 12 个月的每日回报 即 2001 年 1 月 1 日至 2001 年 12 月 31 日。
- 2002 年 2 月的偏度:基于过去 12 个月的每日回报 即 2001 年 2 月 1 日至 2001 年 1 月 31 日。
以滚动方式每月以此类推,其中滑动窗口宽度为 12 个月。
注意:有一个问题,因为最近12个月的天数不会是365。因为股票收益只针对交易日(不包括周六、周日和任何假期)。每个月的交易日本质上都是动态的。我想要一些东西从日期中提取月份并计算过去的 12 个月。也许类似于基于月份的分组并聚合尾随的 12 个组。
set.seed(1)
df<-data.frame(Date=seq(as.Date("2001-01-01"),as.Date("2003-12-31"),by="days"),Company1=rnorm(1095,1),Company2=rnorm(1095,1))
输入数据:
Date Company1 Company2
1 2001-01-01 0.046787710 0.21631639
2 2001-01-02 1.007350200 0.88959702
3 2001-01-03 -0.585340438 -1.10898367
4 2001-01-04 2.359564501 -0.62665947
5 2001-01-05 -0.258663440 1.80257433
6 2001-01-06 0.289608127 -3.08371338
7 2001-01-07 0.269705937 0.13092761
8 2001-01-08 -2.076263400 0.36424857
9 2001-01-09 0.752956413 -0.01024824
10 2001-01-10 -0.297581215 0.62589751
11 2001-01-11 0.439587229 -0.48158102
12 2001-01-12 -0.700782594 0.13597666
13 2001-01-13 -0.083560736 0.03184570
14 2001-01-14 0.883048949 0.17284243
15 2001-01-15 0.201498921 -0.64059292
16 2001-01-16 0.591389036 -1.19668946
17 2001-01-17 0.774895061 -0.66963705
18 2001-01-18 1.663075216 0.32016246
19 2001-01-19 -0.713455482 -1.42976017
20 2001-01-20 1.809244713 1.85308653
21 2001-01-21 0.358761796 -0.87284478
22 2001-01-22 -0.192799009 -0.14865949
23 2001-01-23 -0.126879244 -1.44882295
24 2001-01-24 -0.888239162 1.17851064
25 2001-01-25 1.139707845 0.22734274
26 2001-01-26 0.236909406 -1.12476606
27 2001-01-27 0.281275148 0.14908310
28 2001-01-28 -0.404590422 -0.78850844
29 2001-01-29 0.573109940 1.32003315
30 2001-01-30 -2.014078486 -0.36894095
31 2001-01-31 -1.438956369 1.06879518
32 2001-02-01 2.067691040 -0.74283474
33 2001-02-02 0.195995947 1.39753672
34 2001-02-03 -0.582291845 0.21987888
35 2001-02-04 -0.462393447 -1.14957969
36 2001-02-05 0.145901137 0.57741057
37 2001-02-06 -0.358606042 -1.06126753
38 2001-02-07 -1.184867338 -0.85388016
39 2001-02-08 -1.331819366 -0.06583488
40 2001-02-09 -0.284243432 1.24550387
41 2001-02-10 1.625322326 -0.34987800
42 2001-02-11 -1.115882265 0.54337237
43 2001-02-12 0.379784066 0.57215836
44 2001-02-13 -0.643792275 -0.59830689
45 2001-02-14 0.271188752 1.29537846
46 2001-02-15 -0.171287972 0.55311033
47 2001-02-16 -0.847849267 -1.35727918
48 2001-02-17 1.935119202 0.68036412
49 2001-02-18 0.171950923 1.02874683
50 2001-02-19 -1.458405950 0.32483905
51 2001-02-20 1.042342330 -1.61234419
52 2001-02-21 0.206411454 -0.08980562
53 2001-02-22 0.116044124 -0.75188707
54 2001-02-23 -0.080576867 -0.27822619
55 2001-02-24 -0.217406783 -0.48112626
56 2001-02-25 -0.042067201 -0.50870525
57 2001-02-26 -0.034464590 0.46473191
58 2001-02-27 0.277544111 -0.98551626
59 2001-02-28 -0.535228414 1.78895267
偏度函数:
skewness<-function(x)
{
m3<-mean((x-mean(x))^3)
skewness<-m3/(sd(x)^3)
skewness
}
输出类似:
Month Company1 Company2
Jan2002 Skewness(Jan2001:Dec2001) Skewness(Jan2001:Dec2001)
Feb2002 Skewness(Feb2001:Jan2002) Skewness(Feb2001:Jan2002)
Mar2002 Skewness(Mar2001:Feb2002) Skewness(Mar2001:Feb2002)
解决方法
您可以使用任何函数作为 slide_*
包中 slider
函数的参数。以下代码计算您提供的示例数据集的 365 天滚动偏度。
library(dplyr) # for group_by and pipe
library(tidyr) # for pivot_*
library(slider) # for rolling window functions
library(moments) # for skewness function
df<-data.frame(Date=seq(as.Date("2001-01-01"),as.Date("2003-12-31"),by="days"),Company1=rnorm(1095,1),Company2=rnorm(1095,1))
df %>%
pivot_longer(-Date,names_to="Company",values_to="X") %>%
group_by(Company) %>%
arrange(Date) %>%
mutate(
rollskew = slide_dbl(X,moments::skewness,.before=365,.complete=TRUE)
) %>%
ungroup() %>%
pivot_wider(names_from = Company,values_from = c(X,rollskew)) %>%
tail(12)
会输出
# A tibble: 12 x 5
Date X_Company1 X_Company2 rollskew_Company1 rollskew_Company2
<date> <dbl> <dbl> <dbl> <dbl>
1 2003-12-20 0.599 0.663 0.211 -0.153
2 2003-12-21 1.13 0.457 0.204 -0.163
3 2003-12-22 -0.802 -1.14 0.210 -0.159
4 2003-12-23 1.78 1.45 0.205 -0.165
5 2003-12-24 0.916 -0.879 0.205 -0.141
6 2003-12-25 -1.60 -0.259 0.208 -0.136
7 2003-12-26 -1.12 0.914 0.208 -0.144
8 2003-12-27 -0.404 -0.319 0.212 -0.147
9 2003-12-28 0.461 -1.51 0.208 -0.147
10 2003-12-29 -0.436 1.68 0.207 -0.140
11 2003-12-30 -1.74 0.657 0.203 -0.148
12 2003-12-31 -0.119 0.228 0.209 -0.156
,
首先将偏度定义为类似于偏度,但对于由数据框或矩阵的 ix 给定的行子集,数据。然后计算 ym,年和月作为 yearmon 向量,每行 df 一个元素,并计算除前 12 个作为 ymu 的唯一元素。请注意, yearmon 元素以年和一年的分数来衡量,因此如果 y 是 yearmon 对象,则 y-1 是一年前。
接下来计算一个列表,rowList,这样第 i 个分量是那些行的行号向量,这些行应该用于计算从 ymu[i] 开始的窗口的偏度。这取决于 df 但在问题中显示的 df 的情况下,它等于 list(1:365,32:396,...,700:1064)。最后创建一个数据框,其中包含计算偏度的一年期间之后的年/月、用于计算偏度的 df 行数和偏度值。
library(zoo)
Skewness <- function(data,ix) apply(data[ix,],2,skewness)
ym <- as.yearmon(df$Date)
ymu <- tail(unique(ym),-12)
rowList <- lapply(ymu,function(x) which(ym >= x-1 & ym < x))
out <- data.frame(YearMonth = ymu,n = lengths(rowList),t(sapply(rowList,Skewness,data = df[-1])))
head(out)
## YearMonth n Company1 Company2
## 1 Jan 2002 365 -0.054235132 0.09753488
## 2 Feb 2002 365 -0.021812097 0.11415098
## 3 Mar 2002 365 -0.008200845 0.11443663
## 4 Apr 2002 365 -0.087797237 0.09002947
## 5 May 2002 365 -0.090151360 0.07812791
## 6 Jun 2002 365 0.024598986 -0.01895502
检查
为了仔细检查,我们注意到输出的第一行给出了问题中 df[-1] 每一列的前 365 行的偏度,因此我们有以下与输出匹配的内容上面的 2002 年 1 月行。
Skewness(df[-1],1:365)
## Company1 Company2
## -0.05423513 0.09753488
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。