So berechnen die Perioden seit 200 proioden Hoch einer Aktie
-
28-10-2019 - |
Frage
Ich möchte die Anzahl der Zeiträume berechnen, die seit dem 200 -Perioden -Hoch einer univariaten Zeitreihe verstrichen sind. Zum Beispiel ist hier der Schlusskurs von Spion:
require(quantmod)
getSymbols("SPY",from='01-01-1900')
Data <- Cl(SPY)
Jetzt kann ich die 200-Perioden-Höhen dieser Serie verwenden Lag
Funktion in Quantmod:
periodHigh <- function(x,n) {
Lags <- Lag(x,1:n)
High <- x == apply(Lags,1,max)
x[High]
}
periodHigh(Data, 200)
Aber jetzt stecke ich fest. Wie fusioniere ich das wieder mit der Originalserie (Data
) und berechnen Sie für jeden Punkt in der Serie, wie viele Perioden seit dem vorherigen n-period hohen Zeitraum verstrichen sind?
Lösung 3
Ich habe den Code aus den vorherigen Antworten so bearbeitet, dass es sich um Funktionen handelt, die die gleichen Eingaben (eine univariate Zeitreihe) annehmen und den gleichen Ausgang zurückgeben (ein Vektor von Tagen seit dem letzten N-Day-Hoch):
daysSinceHigh1 <- function(x,n) {
as.vector(n-rollapply(x, n, which.max))
}
daysSinceHigh2 <- function(x, n){
apply(embed(x, n), 1, which.max)-1
}
Die zweite Funktion scheint die schnellste zu sein, liefern jedoch leicht unterschiedliche Ergebnisse:
> 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"
Bei näherer Betrachtung scheint es, dass in der 1. Funktion einige seltsame Randfälle vorhanden sind:
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
Daher scheint die zweite Funktion (basierend auf Andries Code) besser zu sein.
Andere Tipps
Diese kleine Funktion gibt eine Liste zurück mit:
high
die Indexzahl der hohen DatenrecentHigh
die Indexzahl des letzten HochtagesdaysSince
die Anzahl der Tage seit dem letzten Hochdata
Ein XTS -Objekt nur mit hohen Tagen. Nützlich für die Planung.
Der Code:
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, ])
}
Die Ergebnisse:
daysSinceHigh(Data, 200)$daysSince
[1] 90
plot(Data)
points(daysSinceHigh(Data, 200)$data, col="red")
Die Antwort auf Ihre überarbeitete Frage:
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)))
Also für die XTS -Serie:
plot( rollapply(coredata(Data), 200, function(x) 200-which.max(x)))
Sie können offensichtlich nichts zu den ersten 200 Daten zurückführen, es sei denn, Sie wenden eine lockerere Definition von Rolling Maximum an. (In einer anderen SO -Sitzung mit "schäbigen" Daten zeigte ich, wie man die "nachfolgenden" Perioden einbettet: Datenumwandlung in r Ich weiß jedoch nicht, ob Sie Matrizen konstruieren möchten, die 200 -mal so groß sind wie Ihre Eingabedaten.)