#-------------------------------------------------# # # # Week6: Typische Eigenschaften von # # Finanzzeitreihen # # # #-------------------------------------------------# Die returns von liquide handelbaren Assets wie Aktien, Aktienindizes, Waehrungswechselkursen oder Rohstoffen wie Oel, Gold oder Silber haben einige typische, ge- meinsame Eigenschaften. Ist S_k der Preis eines Assets am Ende von Tag t_k, so ist der return ret(t_k) fuer den Tag t_k definiert durch ret(t_k) := (S_k - S_{k-1}) / S_{k-1} (1) Im folgenden sollen die statistischen Eigenschaften dieser returns fuer DAX, SPX und die General Electric Aktie etwas genauer untersucht werden. Dazu erinnern wir uns zunaechst an die Stichprobenvarianz und das Stichprobenmittel: Es sei x = (x1,x2,...,xd) ein gegebener Datenvektor. Die xi's werden dann also die ret(t_k)'s sein. Das Stichprobenmittel ist definiert durch mean(x) := 1/d * sum_{i=1}^d xi (2) und die Stichprobenvarianz var(x) ist definiert durch var(x) := 1/d * sum_{i=1}^d [ xi - mean(x) ]^2 (3) Aus der Varianz bekommt man dann die Standardabweichung einfach, indem man die Wurzel zieht, also stddev(x) := sqrt{ var(x) } (4) Wenn wir jetzt die returns einer Finanzzeitreihe betrach- ten und die Groessen (2), (3) oder (4) berechnen wollen, muessen wir zunaechst einen Zeithorizont d festlegen. Wenn wir etwa die DAX-Zeitreihe betrachten, die hat Daten von 2005 bis 2015, und wir betrachten etwa den Tag t_k = 26. Mai 2013 und wir wollen fuer diesen Tag Mittelwerte und Standard- abweichungen bestimmen, dann geben wir uns ein d vor, etwa d = 250, das entspricht dann 1 Jahr (1 Jahr hat in etwa 250 Arbeitstage oder Handelstage), und der Mittel- wert fuer den Tag t_k = 26.Mai 2013 wird dann also ge- nommen ueber die 250 Handelstage, die direkt vor diesem Tag liegen, das sind dann also in etwa die Arbeitstage vom 26.Mai 2012 bis zum 26.Mai 2013. Also, mit anderen Worten, die Sachen, die wir berechnen wollen, sind "running d-day means" und "running d-day stddev's". Der d-Tages Mittelwert zum Tag t_k ist dann also defi- niert durch mean_d(t_k) := 1/d sum_{j=0}^{d-1} ret(t_{k-j}) (5) Man findet: Stylized Fact 1) Fuer beliebige Zeithorizonte d (groe- sser als 2 oder 3 Wochen) sind die d-Tages Mittelwerte der returns nahe bei Null. Wegen Stylized Fact1 kann man die d-Tages Standard- abweichung (auch d-Tages Volatilitaet genannt) am Tag t_k definieren durch stddev_d(t_k) := sqrt{ 1/d sum_{j=0}^{d-1} ret(t_{k-j})^2 } (6) Die normierten returns (fuer den Zeithorizont d Tage) sind definiert durch normret_d(t_k) := [ ret(t_k) - mean_d(t_{k-1}) ] / stddev_d(t_{k-1}) (7) Wir koennten auf der rechten Seite von (7) auch mean und stddev bei t_k anstatt t_{k-1} benutzen, das wird naechste Woche klarer werden, warum wir das so schreiben. Wegen stylized fact1, mean_d(t_k) approx 0, koennen wir das auch so schreiben: normret_d(t_k) = ret(t_k) / stddev_d(t_{k-1}) (8) Man schaut sich dann ein Histogramm, also die Verteilung, der normierten returns an und vergleicht sie mit der Nor- malverteilung. Man stellt fest: Stylized Fact 2a) Waehlt man d sehr gross (etwa d>=250, das entspricht einem Jahr), dann ist die Verteilung der normierten returns "leptokurtisch", das heisst, sie hat einen hoeheren peak bei 0 und faellt dafuer steiler ab als die Normalverteilung. Weiterhin hat man 'heavy tails': es treten einige sehr grosse (positive und negative) normierte returns auf, die man bei der Annahme einer Normalverteilung nicht sehen wuerde. Stylized Fact 2b) Macht man das d langsam kleiner und setzt es schliesslich auf d=15 oder d=20 (3 oder 4 Wochen), naehert sich die Verteilung der normierten returns mehr und mehr einer Normalverteilung. Das Aufteten von 'heavy tails' nimmt ab. Dafuer nimmt die Variabilitaet der d-Tages Volatilitaet stddev_d(t_{k-1}) mehr und mehr zu. Diese Beobachtung ist die Grundmotivation fuer Modelle mit stochastischer oder variabler Volatilitaet. Weiterhin stellt man noch folgendes fest: Stylized Fact 3) returns an unterschiedlichen Tagen t_k und t_{k-1}, t_{k-2},... sind annaehernd unkorreliert, jedoch haben der Absolutbetrag oder das Quadrat von sol- chen returns eine deutlich positive Korrelation (etwa 10%-20%). Stylized Fact 4) "volatility clustering": returns tendie- ren dazu, cluster zu bilden: grosse und kleine returns sind nicht gleichmaessig ueber die Zeit verteilt, sondern grosse returns finden sich zu Gruppen mit grossen returns zusammen und analoges gilt fuer kleine returns. Das ist die wesentliche Motivation fuer die Modelle aus der ARCH- und GARCH-Familie. Schauen wir uns das jetzt an konkreten Zeitreihendaten an: das file DAX.txt enthaelt die taeglichen DAX-Schluss- kurse der 10 Jahre 2005 bis 2015, das sind in etwa 2500 Beobachtungstage; das file SPX.txt enthaelt die Schluss- kurse des S&P500, die 500 groessten amerikanischen Unter- nehmen, von 1950 bis 2015, das sind etwa 16500 Beobach- tungstage, und das file GE.txt enthaelt die Schlusskurse der General Electric Company von 1962 bis 2015, circa 13500 Beobachtungstage. #### Start R Session: #### # Laden Sie sich das file DAX.txt von der VL-homepage herunter und passen Sie # den Pfadnamen fuer den Speicherort des files auf Ihrem Computer entsprechend # an: read.table("..ihr Speicherort../DAX.txt",header=TRUE,sep=";") dax=read.table("C:/Users/detlef/HSRM/Vorlesungen/WS2223/Datenanalyse-mit-R/DAX.txt",header=TRUE,sep=";") # ACHTUNG: die Schraegstriche muessen / sein, nicht \ # wenn man den Pfadnamen aus Windows kopiert, bekommt man die falschen Schraegstriche # sehr komfortabel ist auch die folgende Sache: dax = read.table(file.choose(),header=TRUE,sep=";") dax head(dax) tail(dax) summary(dax) str(dax) # das ist vom Datentyp "data.frame" # loeschen wir alle Zeilen mit NAs: dax = na.omit(dax) summary(dax) dim(dax) # 2497 Tage # in R gibt es im Wesentlichen 4 verschiedene Datentypen, # Vektoren, Matrizen, Tabellen oder Dataframes, und Listen. # dax ist vom Typ dataframe # die einzelnen Spalten eines dataframes kann man in separate # Vektoren schreiben: names(dax) # 2 Spalten: dates und index S = dax$index # ist aequivalent zu S = dax[,2] S str(S) plot(S) plot(S, type="l") S[1] S[0] # Vektoren starten immer mit dem Index 1, # nicht mit 0 n = length(S) n S[n] S[n+1] # jetzt berechnen wir die returns: ret = rep(0,n) # Vektor der Laenge n mit lauter Nullen for(i in 2:n) { ret[i] = (S[i]-S[i-1])/S[i-1] } plot(ret) plot(ret, type="l") # zum Berechnen der d-day means, stddevs und normrets schreiben # wir drei Funktionen: dDayMean = function( d , ret ) { n = length(ret) result = rep(0,n) summe = 0 for(i in 1:n) { summe = summe + ret[i] if(i > d) { summe = summe - ret[i-d] result[i] = summe/d } else { result[i] = summe/i } } return(result) } # let's take a look at Stylized Fact 1: mean20 = dDayMean(20,ret) mean60 = dDayMean(60,ret) mean180 = dDayMean(180,ret) meanAll = dDayMean(n,ret) plot(mean20) points(mean60, col="red") points(mean180, col="yellow") points(meanAll, col="green") # running standard deviation: dDayStdDev = function( d , ret ) { n = length(ret) result = rep(0,n) summe = 0 for(i in 1:n) { summe = summe + ret[i]*ret[i] if(i > d) { summe = summe - ret[i-d]*ret[i-d] result[i] = summe/d } else { result[i] = summe/i } } # a theoretical 0 could numerically become slightly negative: result = abs(result) # we want to take a square root result = sqrt(result) # square root element by element return(result) } # let's check: stddev20 = dDayStdDev(20,ret) stddev60 = dDayStdDev(60,ret) stddev180 = dDayStdDev(180,ret) stddevAll = dDayStdDev(n,ret) plot(stddev20) points(stddev60, col="red") points(stddev180, col="yellow") points(stddevAll, col="green") # apparently: volatility is not constant # Jetzt die sehr wichtige Groesse # normalized returns dDayNormRet = function( d , ret ) { stddev = dDayStdDev(d,ret) # stddev could be 0 if data are constant: stddev = pmax(stddev,0.00000001) # "parallel max": maximum element by element result = ret/stddev # division element by element return(result) } # let's have a look: normret15 = dDayNormRet(15,ret) normret60 = dDayNormRet(60,ret) normret250 = dDayNormRet(250,ret) normretAll = ret/stddevAll[n] par( mfrow = c(2,2) ) #set up 2 time 2 plot array #that is, 4 pictures at once hist(normretAll, breaks=50, xlim=c(-5,5), ylim=c(0,0.8), prob=TRUE) curve(dnorm(x), from=-5, to=5, add=TRUE, col="red") hist(normret250, breaks=50, xlim=c(-5,5), ylim=c(0,0.8), prob=TRUE) curve(dnorm(x), from=-5, to=5, add=TRUE, col="red") hist(normret60, breaks=50, xlim=c(-5,5), ylim=c(0,0.8), prob=TRUE) curve(dnorm(x), from=-5, to=5, add=TRUE, col="red") hist(normret15, breaks=40, xlim=c(-5,5), ylim=c(0,0.8), prob=TRUE) curve(dnorm(x), from=-5, to=5, add=TRUE, col="red") # thus: if returns are normalized with more recent volatility # data, then normalized returns are more Gaussian: # # Grosse Ausreisser, 'heavy tails', kommen weniger haeufig vor, # da bei der Normierung durch eine groessere Zahl, das aktuelle # Volatilitaetsniveau nur der letzten 2 oder 3 Wochen und nicht # der letzten 10 Jahre, geteilt wird.