在庫の200期間以降の期間を計算する方法
-
28-10-2019 - |
質問
単変量の時系列の200期間以来経過した期間数を計算したいと思います。たとえば、スパイの終値は次のとおりです。
require(quantmod)
getSymbols("SPY",from='01-01-1900')
Data <- Cl(SPY)
今、私はこのシリーズの200期の最高値を使用して見つけることができます Lag
QuantModの関数:
periodHigh <- function(x,n) {
Lags <- Lag(x,1:n)
High <- x == apply(Lags,1,max)
x[High]
}
periodHigh(Data, 200)
しかし今、私は立ち往生しています。これを元のシリーズにマージするにはどうすればよいですか(Data
)そして、シリーズの各ポイントについて、前のN期間以降にいくつの期間が経過したのですか?
解決 3
以前の回答からコードを編集し、同じ入力(単変量時系列)を取得し、同じ出力(最後のn-day High以降の日数のベクトル)を返す関数であるようにしました。
daysSinceHigh1 <- function(x,n) {
as.vector(n-rollapply(x, n, which.max))
}
daysSinceHigh2 <- function(x, n){
apply(embed(x, n), 1, which.max)-1
}
2番目の関数は最速のようですが、わずかに異なる結果を提供しています。
> getSymbols("^GSPC",from='01-01-1900')
[1] "GSPC"
> system.time(x <- daysSinceHigh1(Cl(GSPC), 200))
user system elapsed
0.42 0.00 0.42
> system.time(y <- daysSinceHigh2(Cl(GSPC), 200))
user system elapsed
0.24 0.00 0.24
> all.equal(x,y)
[1] "Mean relative difference: 0.005025126"
綿密な検査では、第1関数には奇妙なエッジケースがあるように見えます。
data <- c(1,2,3,4,5,6,7,7,6,5,6,7,8,5,4,3,2,1)
answer <- c(0,0,0,0,1,2,3,0,0,1,2,3,4,4)
x <- daysSinceHigh1(data, 5)
y <- daysSinceHigh2(data, 5)
> x
[1] 0 0 0 1 2 3 4 4 0 1 2 3 4 4
> y
[1] 0 0 0 0 1 2 3 0 0 1 2 3 4 4
> answer
[1] 0 0 0 0 1 2 3 0 0 1 2 3 4 4
> all.equal(x,answer)
[1] "Mean relative difference: 0.5714286"
> all.equal(y,answer)
[1] TRUE
したがって、2番目の関数(Andrieのコードに基づいて)が優れているようです。
他のヒント
この小さな関数は、次のリストを返します。
high
高日付のインデックス番号recentHigh
最新の最高日のインデックス番号daysSince
最後の高値からの日数data
高い日だけのXTSオブジェクト。プロットに役立ちます。
コード:
daysSinceHigh <- function(data, days){
highs <- days-1+which(apply(embed(data, days), 1, which.max)==1)
recentHigh <- max(highs)
daysSince <- nrow(data) - recentHigh
list(
highs=highs,
recentHigh = recentHigh,
daysSince = daysSince,
data=data[highs, ])
}
結果:
daysSinceHigh(Data, 200)$daysSince
[1] 90
plot(Data)
points(daysSinceHigh(Data, 200)$data, col="red")
修正された質問への答え:
require(zoo)
x <- sample(300:500, 1000, replace=TRUE)
str(rollapply(x, 200, function(x) which.max(x)))
# int [1:801] 14 13 12 11 10 9 8 7 6 5 ...
plot(x)
plot(200:1000, rollapply(x, 200, function(x) 200-which.max(x)))
XTSシリーズの場合:
plot( rollapply(coredata(Data), 200, function(x) 200-which.max(x)))
ローリングの最大の緩やかな定義を適用しない限り、明らかに最初の200日に何もマージすることはできません。 (「シフティ」データを含む別のSOセッションでは、埋め込みを使用して「後続」期間をパッドする方法を示しました。 rのデータ変換 しかし、入力データの200倍のマトリックスを構築するかどうかはわかりません。)
所属していません StackOverflow