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?

War es hilfreich?

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 Daten
  • recentHigh die Indexzahl des letzten Hochtages
  • daysSince die Anzahl der Tage seit dem letzten Hoch
  • data 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")

enter image description here

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)))

enter image description hereSie 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.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top