3 Random Walk

Zunächst wollen wir uns mit dem einfachsten Modell für Log-Returns von Aktienkursen beschäftigen - dem Random Walk.

3.1 Daten beziehen

Im ersten Schritt laden wir uns Zeitreihen von Aktienkursen herunter. Hierbei verwenden wir das Paket tidyverse, mit dem wir unter anderem Daten über yahoo-Finance beziehen können. Hierfür müssen wir die Ticker der Unternehmen von Interesse von yahoo finance vorab herausfinden. Damit ist es sehr leicht Daten zu beziehen.

Wir wollen uns jedoch nun auf die Kurse zum Ende jedes Handelstages beschränken und für die zugehörigen Log-Returns ein Modell schätzen. Beispielsweise für die Apple-Aktie über den Verlauf der letzten 10 Jahre.

3.2 Modell schätzen

Im folgenden schätzen wir für die Log-Returns der Apple-Aktie. Hierbei verwenden wir wieder die ‘fun_fun’-Funktion. Beispielsweise können wir eine Normalverteilung folgendermaßen schätzen,

#Funktion, welche die angegebene Verteilung schätzt, ll, aic, hmi, pp- und qq-plot ausgibt
library(rugarch)

fun_fun <- function(x, distr = 'norm'){

  distr_set <- c('norm', 'snorm', 'std', 'sstd', 'ged', 'sged')
  
  if(!(any(distr == distr_set))){
    stop(paste('Bitte verwenden Sie eine dieser Verteilungen: norm, snorm, std, sstd, ged, sged'))
  }
  
  
  fit <- fitdist(distribution = distr, x)
  
  
  if(distr == 'norm'){
    
    ll <- sum(log(ddist(distribution = distr, x, mu = fit$pars[1], sigma = fit$pars[2])))
    aic <- -2*ll + 2 * length(fit$pars)
    hmi <- 2 * integrate(function(p1, m, s, data){abs(p1 - pdist(distribution = distr, quantile(data, p1), mu = m, sigma = s))},
                         lower = 0, upper = 1, m = fit$pars[1], s = fit$pars[2], data = x, subdivisions = 1000)$value
    
    p_theor <- pdist(distribution = distr, sort(x), mu = fit$pars[1], sigma = fit$pars[2])
    p_emp <- rank(sort(x))/length(x)
    
    pp_plot <- plot_ly() %>%
      add_markers(x = p_theor, y = p_emp, name = 'pp-plot', marker = list(color = 'grey', symbol = 'x')) %>%
      add_lines(x = c(0, 1), y = c(0, 1), line = list(color = 'black'), showlegend = FALSE) %>%
      layout(
        xaxis = list(title = 'Theoretische Verteilung'),
        yaxis = list(title = 'Empirische Verteilung')
      )
    
    q_theor <- qdist(distribution = distr, rank(sort(x))/(length(x) + 1), mu = fit$pars[1], sigma = fit$pars[2])
    q_emp <- quantile(x, rank(sort(x))/(length(x) + 1))
  
    qq_plot <- plot_ly() %>%
      add_markers(x = q_theor, y = q_emp, name = 'qq-plot', marker = list(color = 'skyblue', symbol = 'x')) %>%
      add_lines(x = c(min(x), max(x)), y = c(min(x), max(x)), line = list(color = 'black'), showlegend = FALSE) %>%
      layout(
        xaxis = list(title = 'Theoretische Verteilung'),
        yaxis = list(title = 'Empirische Verteilung')
      )
    
    p <- subplot(pp_plot, qq_plot, margin = 0.05, titleX = TRUE, titleY = TRUE, which_layout = 1)
    
    list_out <- list(ll = ll, aic = aic, hmi = hmi, p = p, params = fit$pars)
    
  }
  
  if(any(distr == c('std', 'ged'))){
    
    ll <- sum(log(ddist(distribution = distr, x, mu = fit$pars[1], sigma = fit$pars[2], shape = fit$pars[3])))
    aic <- -2*ll + 2 * length(fit$pars)
    hmi <- 2 * integrate(function(p1, m, s, nu, data){abs(p1 - pdist(distribution = distr, quantile(data, p1), mu = m, sigma = s, shape = nu))},
                         lower = 0, upper = 1, m = fit$pars[1], s = fit$pars[2], nu = fit$pars[3], data = x, subdivisions = 1000)$value
    
    p_theor <- pdist(distribution = distr, sort(x), mu = fit$pars[1], sigma = fit$pars[2], shape = fit$pars[3])
    p_emp <- rank(sort(x))/length(x)
    
    pp_plot <- plot_ly() %>%
      add_markers(x = p_theor, y = p_emp, name = 'pp-plot', marker = list(color = 'grey', symbol = 'x')) %>%
      add_lines(x = c(0, 1), y = c(0, 1), line = list(color = 'black'), showlegend = FALSE) %>%
      layout(
        xaxis = list(title = 'Theoretische Verteilung'),
        yaxis = list(title = 'Empirische Verteilung')
      )
    
    q_theor <- qdist(distribution = distr, rank(sort(x))/(length(x) + 1), mu = fit$pars[1], sigma = fit$pars[2], shape = fit$pars[3])
    q_emp <- quantile(x, rank(sort(x))/(length(x) + 1))
    
    qq_plot <- plot_ly() %>%
      add_markers(x = q_theor, y = q_emp, name = 'qq-plot', marker = list(color = 'skyblue', symbol = 'x')) %>%
      add_lines(x = c(min(x), max(x)), y = c(min(x), max(x)), line = list(color = 'black'), showlegend = FALSE) %>%
      layout(
        xaxis = list(title = 'Theoretische Verteilung'),
        yaxis = list(title = 'Empirische Verteilung')
      )
    
    p <- subplot(pp_plot, qq_plot, margin = 0.05, titleX = TRUE, titleY = TRUE, which_layout = 1)
    
    list_out <- list(ll = ll, aic = aic, hmi = hmi, p = p, params = fit$pars)
    
  }
  
  if(any(distr == c('snorm', 'sstd', 'sged'))){
    
    ll <- sum(log(ddist(distribution = distr, x, mu = fit$pars[1], sigma = fit$pars[2], skew = fit$pars[3], shape = fit$pars[4])))
    aic <- -2*ll + 2 * length(fit$pars)
    hmi <- 2 * integrate(function(p1, m, s, skew, nu, data){abs(p1 - pdist(distribution = distr, quantile(data, p1), mu = m, sigma = s, skew = skew, shape = nu))},
                         lower = 0, upper = 1, m = fit$pars[1], s = fit$pars[2], skew = fit$pars[3], nu = fit$pars[4], data = x, subdivisions = 1000)$value
    
    p_theor <- pdist(distribution = distr, sort(x), mu = fit$pars[1], sigma = fit$pars[2], skew = fit$pars[3], shape = fit$pars[4])
    p_emp <- rank(sort(x))/length(x)
    
    pp_plot <- plot_ly() %>%
      add_markers(x = p_theor, y = p_emp, name = 'pp-plot', marker = list(color = 'grey', symbol = 'x')) %>%
      add_lines(x = c(0, 1), y = c(0, 1), line = list(color = 'black'), showlegend = FALSE) %>%
      layout(
        xaxis = list(title = 'Theoretische Verteilung'),
        yaxis = list(title = 'Empirische Verteilung')
      )
    
    q_theor <- qdist(distribution = distr, rank(sort(x))/(length(x) + 1), mu = fit$pars[1], sigma = fit$pars[2], skew = fit$pars[3], shape = fit$pars[4])
    q_emp <- quantile(x, rank(sort(x))/(length(x) + 1))
    
    qq_plot <- plot_ly() %>%
      add_markers(x = q_theor, y = q_emp, name = 'qq-plot', marker = list(color = 'skyblue', symbol = 'x')) %>%
      add_lines(x = c(min(x), max(x)), y = c(min(x), max(x)), line = list(color = 'black'), showlegend = FALSE) %>%
      layout(
        xaxis = list(title = 'Theoretische Verteilung'),
        yaxis = list(title = 'Empirische Verteilung')
      )
    
    p <- subplot(pp_plot, qq_plot, margin = 0.05, titleX = TRUE, titleY = TRUE, which_layout = 1)
    
    list_out <- list(ll = ll, aic = aic, hmi = hmi, p = p, params = fit$pars)
    
  }
  
return(list_out)
  
}
## $ll
## [1] 6882.14
## 
## $aic
## [1] -13760.28
## 
## $hmi
## [1] 0.06486762
## 
## $p
## 
## $params
##           mu        sigma 
## 0.0008568798 0.0163519700

Wir wollen jedoch eine Bandbreite verschiedenener Funktionen schätzen und anschließend die Güte der Anpassung visuell und mittels Kennzahlen überprüfen.

Table 3.1: Übersicht des Datenfits
AIC HMI
Normal -13760.28 0.0648676
Normal (schief) -13766.37 0.0646243
Student -14116.23 0.0103100
Student (schief) -14115.38 0.0106401
GED -14091.40 0.0156534
GED (schief) -14089.57 0.0162033

Gemäß dem AIC und dem HMI scheint die (symmetrische) Student t Verteilung am besten geeignet, um die Log-Returns der Apple Aktie zu modellieren. Wir können uns die Güte dieser Schätzung erneut auch visuell ansehen.

Mit diesem Modell könnten wir z.B. bestimmen, wie hoch die Wahrscheinlichkeit ist, dass die Log-Rendite bis morgen größer als 2% ist.

## [1] 0.09073137

Oder welcher Wert innerhalb eines Tages maximal mit einer Wahrscheinlichkeit von 5% unterschritten wird.

## [1] -0.02386804

Und wir können uns zukünfige Aktienkursverläufe simulieren, gehen wir hierbei vom letzten verfügbaren Kurs aus.

Immerhin liegt der tatsächliche Verlauf innerhalb der simulierten Verläufe!

Mit höherem Zeithorizont wird die Prognose volatiler, was sich in einer breiteren Vereteilung der prognostizierten Werte äußert!