毎日のreturnsのxtsがあり、それを毎月の返品に変換したいと思います。
毎日のpricesをピリオドリターンに変換するスレッドのトンを見つけることができますが、毎日returnsを変換する必要があります。
うまく機能する this スレッドのアドバイスに従っていると、戻り値は幾何学的ではなく、算術的であることがわかりました。
したがって、cumprod(x + 1)^(365/12)-1のようなものが必要です。
ただし、sum(cx)をそれで置き換えることはできません。
これが現状の私のコードです。
# Generate data like the type I'm working with
testdata <- cbind(rnorm(100,0.0001,0.01),rnorm(100,0.0001,0.01))
testdata <- as.xts(testdata, order.by = seq(Sys.Date()-99,Sys.Date(),1))
myFun <- function(x) {
# need coredata, so c.xts will not be dispatched
cx <- coredata(x)
Return = sum(cx)
}
MonthlyReturns <- NULL
for (i in 1:ncol(testdata)){
MonthlyReturns <- cbind(MonthlyReturns,period.apply(testdata[,i], endpoints(testdata[,i], "months"),
myFun))
}
助けてくれてありがとう!
編集-出力は入力と同じ形式である必要があります-毎日ではなく毎月の収益の表。 xtsまたはdataframe/matrixのいずれか。
編集-収益マトリックスの起源に興味がある人のために、私は here のようにPerformance AnalyticsパッケージのReturn.annualized
関数を使用しています。 (実際、私はReturn.cumulative
を使用して、はるかに高速に変更しています)。つまり、価格マトリックスがあり、そこから月次収益を簡単に計算できますが、日次収益マトリックスには他の計算からの追加の列があるため、日次価格ではなく、日次収益を変換する必要があります。
return
がどのように計算されるのかはわかりませんが、正しい方向に進むための方法を次に示します。
_library(data.table)
library(lubridate)
dat <- as.data.table(testdata)
> str(dat)
Classes ‘data.table’ and 'data.frame': 100 obs. of 3 variables:
$ index: Date, format: "2020-01-01" "2020-01-02" ...
$ V1 : num 0.00213 -0.00974 0.00751 -0.01194 0.0011 ...
$ V2 : num 0.008688 0.019436 0.002724 0.000132 -0.010013 ...
- attr(*, ".internal.selfref")=<externalptr>
> dat[, .(mean(V1), mean(V2)), by = round_date(x = index, unit = 'month')]
round_date V1 V2
1: 2020-01-01 0.0013998013 0.001087134
2: 2020-02-01 0.0026295444 0.003307676
3: 2020-03-01 0.0008552149 -0.001801693
4: 2020-04-01 0.0004444565 -0.002700886
_
lubridate
パッケージの_round_date
_を使用して、各index
日付を最も近い月に丸めています。 return
を取得するロジックがないため、mean
を概念実証として使用していますが、必要に応じて列を作成できます。 .(mean(V1), new_col = V1*V2/log(V1))
。
注意:_round_date
_は「最も近い」月に丸めます。これは、月の15日を過ぎている場合、次の例に示すように翌月に丸められることを意味します。
_> Sys.time()
[1] "2020-04-09 12:19:51 EDT"
> round_date(x = Sys.time(), unit = 'month')
[1] "2020-04-01 EDT"
# Adding 7 days to get past the month mid
> Sys.time() + days(7)
[1] "2020-04-16 12:20:11 EDT"
> round_date(x = Sys.time() + days(7), unit = 'month')
[1] "2020-05-01 EDT"
_
「最も近い月」ではなく月に関心がある場合は、by
引数を変更できます。
_> dat[, .(mean(V1), mean(V2)), by = .(year(index), month(index))]
year month V1 V2
1: 2020 1 0.0024584093 0.002001868
2: 2020 2 0.0011554594 0.002243072
3: 2020 3 0.0006240678 -0.003083204
4: 2020 4 0.0009490493 -0.003752814
_
by
引数にyear(index)
を入れたのは、同じ月を別の年に持つ可能性があり、それらを組み合わせたくない可能性が高いためです。
これがお役に立てば幸いです!