Aktienschätzung

Modelle zur Korrelations- und Regressionsanalyse

Moderator: EDi

StatistikMensch

Re: Aktienschätzung

Beitrag von StatistikMensch »

Hallo, habe anbei einen kleinen Ausschnitt der Daten angefügt, allerdings mit simulierten Zahlen, da ich die Daten ungern hier posten würde.
Dateianhänge
Test.csv
(27.76 KiB) 103-mal heruntergeladen
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Aktienschätzung

Beitrag von jogo »

StatistikMensch hat geschrieben: Mi Aug 15, 2018 11:53 am Hallo, habe anbei einen kleinen Ausschnitt der Daten angefügt, allerdings mit simulierten Zahlen, da ich die Daten ungern hier posten würde.
prima.

Ich habe die Daten eingelesen:

Code: Alles auswählen

A <- read.table(file="http://forum.r-statistik.de/download/file.php?id=306", header=TRUE, sep=',', row.names=1)
und mir die Struktur anzeigen lassen:

Code: Alles auswählen

> str(A)
'data.frame':	403 obs. of  5 variables:
 $ AktienNummer : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Monats_id    : int  30 31 32 33 34 35 36 37 38 39 ...
 $ Aktienrendite: num  0.0104 0.1516 0.0794 0.0409 0.103 ...
 $ Marktrendite : num  0.1957 0.1216 -0.1106 0.185 0.0929 ...
 $ Zinsrate     : num  -0.001043 -0.000835 -0.000923 0.001966 0.00442 ...
meiner Meinung nach, hat das Einlesen Funktioniert.

Dann schau ich jetzt, was zu machen ist.

Gruß, Jörg
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Aktienschätzung

Beitrag von jogo »

Hallo StatistikMensch,
StatistikMensch hat geschrieben: Mi Aug 15, 2018 10:34 am ich habe mir zunächst ein Teildatensatz erstellt (3070 Beobachtungen mit 24 verschiedenen Aktien)
Als ich die o.g. Schleife für eine Aktie durchlaufen lassen habe, habe ich einen Vektor der Länge n-36 bzw- n-60 erhalten und diesen dann mit cbind(AlterDatensatz, Beta60) ergänzt.
Entsprechend sollte ich am Ende der Schleife für die Beta60 Schätzung 24*60 = 1440 NAs erhalten.
Die Schleife müsste also durch die stock_nrs gehens (for i in 1:nrow(stock_nr)) und jedes Mal bei einem Wechsel der Stock_nr erkennen, dass es sich um eine neue Aktie handelt
In den Beispieldaten ist das (stock_nr) die Spalte AktienNummer, richtig?
und entsprechend nicht die 60 vorhergehenden Werte der alten Aktie (Aktie mit vorhergehender Stock_nr) mit in die Schätzung einbeziehen, also dass sich die Schätzung für Beta[Aktie10] nur den Beobachtungen von Aktie10 bedient und die ersten 60 Beobachtungen leer lässt.
Das hört sich so an, als ob der Dataframe aufgespalten werden sollte anhand der Gruppierungsvariablen stock_nr und dann jeder Dataframe getrennt behandelt werden kann:

Code: Alles auswählen

L <- split(A, A$AktienNummer)
Was soll jetzt für jeden dieser Dataframes gemacht werden?
L[[1]] ist z.B. identisch mit dem Ergebnis von subset(A, AktienNummer==1) Sollen jetzt die Betas für eine Regression mit einem rollenden 60er-Fenster bestimmt werden?

Code: Alles auswählen

Beta60 <- function(Aktie) {
  I60 <- 1:60 ## Fenster
  Beta36i <- function(i) lm(Aktienrendite ~ Marktrendite, data=Aktie[i+I60,])$coefficients[2]
  B <- sapply(0:(nrow(Aktie)-60), Beta36i)
  names(B) <- NULL
  B
}
lapply(L, Beta60) # BetaList <- ...
Gruß, Jörg
StatistikMensch

Re: Aktienschätzung

Beitrag von StatistikMensch »

Hallo Jörg, erstmal vielen Dank für deine Hilfe!
Genau, die Idee hast du richtig vestanden, es ist sehr sinnvoll sich die Daten mit Hilfe des split-Befehls trennen zu lassen.
Wenn ich deine Schleife laufen lasse, erhalte ich zwar die Werte für die verschiedenen Betas und genau so viele Werte wie ich haben will da ja die ersten 60 Perioden nicht berücksichtigt werden, allerdings ist der Beta-Wert zu allen Zeitpunkten und auch bei den anderen Aktien immer identisch (-0.109988).
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Aktienschätzung

Beitrag von jogo »

Hallo StatustikMensch,

wie kommst Du auf diesen identischen Wert? Den kann ich nicht nachvollziehen:

Code: Alles auswählen

> lapply(L, Beta60) # BetaList <- ...
$`1`
 [1] -0.06237181 -0.08280172 -0.09237306 -0.09781237 -0.09906914 -0.11791233 -0.04642050 -0.05399753 -0.10028732 -0.10242734 -0.14963949
[12] -0.16567869 -0.15046005 -0.14551514 -0.13747036 -0.12909480 -0.10118686 -0.09754992 -0.10026472 -0.14296135 -0.13989383 -0.11542771
[23] -0.11471793 -0.12018856 -0.10649219 -0.10276580 -0.08347167 -0.08527858 -0.08597205 -0.08953490 -0.08630268

$`2`
 [1] -0.0223564915 -0.0161859110 -0.0462005863 -0.0493605574 -0.0772666843 -0.0648207775 -0.0744596090 -0.1000985202 -0.0549998340
[10] -0.0591438625 -0.0783931180 -0.1009063801 -0.0880178605 -0.1126632212 -0.1153915972 -0.0364282225 -0.0613910207 -0.0167654327
[19] -0.0209169717 -0.0104621759 -0.0096302743 -0.0130268241  0.0004402547 -0.0088663079 -0.0048616045 -0.0012092030 -0.0087301792

$`3`
 [1] -0.0470965177  0.0442017336  0.0844805618  0.1775441831  0.2141975584  0.2170947921  0.2320014011  0.1753024708  0.1675104953
[10]  0.1321471813  0.1349785176  0.1111522138  0.1525875145  0.1524255789  0.1094343479  0.0919679829  0.0882466586  0.2379008789
[19]  0.2740973454  0.2614682650  0.2385627119  0.2449149412  0.2354662814  0.2048569249  0.0402437929  0.0441323903  0.0405675145
[28] -0.0008029885  0.0454479926 -0.0104811347 -0.0710493551 -0.0952583764 -0.1066868752 -0.1164683925 -0.1307519437 -0.1343200435
[37] -0.1581305166 -0.1474496973 -0.1722371477 -0.1582694870 -0.0896642843 -0.1001425818 -0.0872167304 -0.0702371336 -0.0776779902
[46] -0.0370712321 -0.0393145513 -0.0500969873 -0.0342781020 -0.1230425181 -0.1126578071 -0.0576439752 -0.0606070497 -0.0598472393
[55] -0.0667844767 -0.0433754669 -0.0839516335 -0.1198452688 -0.1313711351 -0.1103475180 -0.1211849761 -0.1330276606 -0.1659176368
[64] -0.1925438283 -0.2204222675

$`4`
 [1] -0.396059056 -0.308670501 -0.202513678 -0.144092075 -0.121713052 -0.101638006 -0.115322294 -0.099460965 -0.105998953 -0.160358431
[11] -0.190376463 -0.253387487 -0.240321484 -0.256775997 -0.319887046 -0.320846571 -0.263563363 -0.222853872 -0.205751925 -0.122996935
[21] -0.160915194 -0.244495072 -0.255680537 -0.254867124 -0.271064830 -0.132835719 -0.126157898 -0.152884003 -0.142983286 -0.157403244
[31] -0.176769293 -0.157686717 -0.219024637 -0.145885685 -0.144259750 -0.034774103 -0.074060864 -0.010818611 -0.027694980 -0.005207174
[41]  0.128235320  0.109457607  0.101022124 -0.015706528
Und welche Schleife meinst Du, etwas die Aufrufe von sapply() und lapply()?
ok, die kann man hidden loops nennen, aber ich habe keine explizite for-, while- oder sonstwas-Schleife.

Hier nochmal der Code in einem Stück, damit es jeder nachvollziehen kann:

Code: Alles auswählen

A <- read.table(file="http://forum.r-statistik.de/download/file.php?id=306", header=TRUE, sep=',', row.names=1)
L <- split(A, A$AktienNummer)
Beta60 <- function(Aktie) {
  I60 <- 1:60 ## Fenster
  Beta36i <- function(i) lm(Aktienrendite ~ Marktrendite, data=Aktie[i+I60,])$coefficients[2]
  B <- sapply(0:(nrow(Aktie)-60), Beta36i)
  names(B) <- NULL
  B
}
lapply(L, Beta60) # BetaList <- ...
Gruß, Jörg
StatistikMensch

Re: Aktienschätzung

Beitrag von StatistikMensch »

Also habe den Code noch einmal durchlaufen lassen und es hat funktioniert, wo der der Fehler vorhin war, weiß ich nicht wirklich, komme auf die gleichen Zahlen wie du, nochmals vielen Dank!
Das letzte Problem wäre noch die Einbettung in den Datensatz. Als ich das Beta nur für eine Aktie berechnet habe konnte ich einfach die ersten 60 Beobachtungen des Original-Datensatzes wegstreichen und mit cbind() die Betas anheften:

Code: Alles auswählen

Aktienfit<-subset(Test, Test$Monats_id>60)
BetaTest<-cbind(Aktienfit, BetaEst)
BetaEst wenn

Code: Alles auswählen

BetaEst<-lapply(L, Beta60) # BetaList <- ...
.
Wie kann ich diese Liste (BetaEst) nun an den Test-Datensatz hängen mit der Berücksichtigung, dass die ersten 60Beta-Werte immer NAs sind? cbind() scheint dafür nicht mehr zu funktionieren, da immer unterschiedliche Längen vorliegen?
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Aktienschätzung

Beitrag von jogo »

StatistikMensch hat geschrieben: Do Aug 16, 2018 6:02 pm Also habe den Code noch einmal durchlaufen lassen und es hat funktioniert, wo der der Fehler vorhin war, weiß ich nicht wirklich, komme auf die gleichen Zahlen wie du, nochmals vielen Dank!
Das letzte Problem wäre noch die Einbettung in den Datensatz. Als ich das Beta nur für eine Aktie berechnet habe konnte ich einfach die ersten 60 Beobachtungen des Original-Datensatzes wegstreichen und mit cbind() die Betas anheften: ...
Das würde ich anders machen: ich würde die Betas mit NAs auffüllen. Es ist ja auch eine Definitionsfrage, welches beta man welcher Beobachtung zuordnet. In der Finanzmathematik ist es oft so, wie Du es beschreibst.
Das Komplettiern des Vektors ist am besten in der Funktion Beta60() aufgehoben. Dort kann man für den Dataframe Aktie eine neue Spalte erzeugen und den Dataframe als Wert zurückliefern.
Wie kann ich diese Liste (BetaEst) nun an den Test-Datensatz hängen mit der Berücksichtigung, dass die ersten 60Beta-Werte immer NAs sind? cbind() scheint dafür nicht mehr zu funktionieren, da immer unterschiedliche Längen vorliegen?
mit c() ... ich bastel gleich was. ... und es müssen 59 NAs sein.
...

Code: Alles auswählen

A <- read.table(file="http://forum.r-statistik.de/download/file.php?id=306", header=TRUE, sep=',', row.names=1)
L <- split(A, A$AktienNummer)

Betas <- function(Aktie) {
  n <- 60
  Fenster <- 1:n
  Betai <- function(i) lm(Aktienrendite ~ Marktrendite, data=Aktie[i+Fenster,])$coefficients[2]
  Aktie$Beta <- c(rep(NA, n-1), sapply(0:(nrow(Aktie)-n), Betai))
  Aktie
}
Lneu <- lapply(L, Betas) 
Lneu[[1]] ## Kontrolle für die erste AktienNummer
... übrigens ist die data.table-Variante meiner Meinung nach noch etwas eleganter:

Code: Alles auswählen

library("data.table")
A <- fread("http://forum.r-statistik.de/download/file.php?id=306")
BetasDT <- function(Aktie) {
  n <- 60
  Fenster <- 1:n
  Betai <- function(i) lm(Aktienrendite ~ Marktrendite, data=Aktie[i+Fenster,])$coefficients[2]
  c(rep(NA, n-1), sapply(0:(nrow(Aktie)-n), Betai))
}
A[, Beta:=BetasDT(.SD), AktienNummer]
A[AktienNummer==1] ## Kontrolle
Gruß, Jörg
StatistikMensch

Re: Aktienschätzung

Beitrag von StatistikMensch »

Super vielen Dank, genau so hatte ich es mir vorgestellt. Besonders angenehm ist der data.table()-Code auch, weil man ganz einfach das Fenster wechseln kann undso auch Beta36 schätzen kann.
Ich frage mich allerdings, macht es nicht mehr Sinn n <- 1:61 zu wählen? da wir so für die Beobachtung t=60 bereits einen Wert haben, wobei ja die ersten 60 Perioden nur zur Schätzung gedacht sind?
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Aktienschätzung

Beitrag von jogo »

StatistikMensch hat geschrieben: Fr Aug 17, 2018 12:40 pm Super vielen Dank, genau so hatte ich es mir vorgestellt. Besonders angenehm ist der data.table()-Code auch, weil man ganz einfach das Fenster wechseln kann undso auch Beta36 schätzen kann.
aber auch in der Datframe-Variante habe ich die Funktion entsprechend geändert, so dass auch dort der Wechsel der Fenstergröße problemlos möglich ist.
Ich frage mich allerdings, macht es nicht mehr Sinn n <- 1:61 zu wählen? da wir so für die Beobachtung t=60 bereits einen Wert haben, wobei ja die ersten 60 Perioden nur zur Schätzung gedacht sind?
Das ist keine R-Frage. Das ist eine Frage, die fachspezifisch beantwortet werden muss. `R` ist da ziemlich indifferent und kann beides:
entweder n <- 60 oder n <- 61 - as you like it.

Gruß, Jörg
StatistikMensch

Re: Aktienschätzung

Beitrag von StatistikMensch »

Hallo zusammen,
ich melde mich nochmal mit einer Anschlussfrage zu dem vorliegeden Datensatz. Gehen wir davon aus, dass wir den vorliegenden Datensatz A haben, in welchem die Betas geschätzt sind.
Das Ziel soll nun sein, für jeden Monat ein Quintil zu erstellen, welches zum einen die Beobachtungen mit dem niedrigsten und zum anderen die Beobachtungen mit dem höchsten Beta beinhaltet. Von diesem Quintil soll der Mittelwert gebildet werden und voneinander abgezogen werden, sodass man für jeden Monat nur noch eine Beobachtung hat. Diese Beobachtung wird später als Zeitreihe überführt.
Einmal den Code für einen Zeitraum zur Illustration:

Code: Alles auswählen

A<-na.omit(A)
library(dplyr)
library(tidyverse)
A<-arrange(A, A$Monats_id)
t<-split(A, A$Monats_id)
Test<-t$`100` %>%
mutate(quantile=ntile(t$`100`$Beta, 2))
Hier habe ich ntile(2) gewählt, da ich in dem hochgeladenen Datensatz nur 4 verschiedene Aktien reingepackt hatte und entsprechend ist eine Unterteilung in Quintile nicht sinnvoll. Im Originalcode soll hier also ntile(x,5) stehen.

Code: Alles auswählen

lowBetaTest<-subset(Test, Test$quantile==1)
highBetaTest<-subset(Test, Test$quantile==2)
a100<-mean(lowBetaTest$Aktienrendite)
b100<-mean(highBetaTest$Aktienrendite)
t100<-a100-b100
t100
Dieser Code soll beispielhaft illustrieren, wie die Untersuchung für den Zeitpunkt t=100 laufen soll. Es wäre optimal am Ende einen Vector oder Data.Frame t zu haben, der alle Zeitpunkte mit einer Rendite abdeckt. Vielleicht hat ja auch hier jemand noch eine Idee. :)
Antworten