Programmierhilfe - Lineares Regressionmodell

Allgemeine Statistik mit R, die Test-Methode ist noch nicht bekannt, ich habe noch keinen Plan!

Moderatoren: EDi, jogo

darrgans

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hallo Jörg,

bedeutet in diesem Fall negativ, dass die Zeile nicht vorkommt? Also, dass es keinen Eintrag für Trading_date - 201 Tage gibt?

Viele Grüße,
Damian
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von jogo »

Hallo Damian,

genau, deshalb bitte mal testen:

Code: Alles auswählen

index.test <- function(TTag) which(Daily_returns_for_model_calc$Date==TTag)
sapply(myInside$Trading_date, index.test)
Ein ähnliches Problem kann Dir auch auf der anderen Seite passieren.

Viele Grüße, Jörg
darrgans

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hallo Jörg,

genau das war das Problem. Ich habe die Datenreihe entsprechend angepasst (verlängert), sodass der Fehler nicht mehr vorkommt. Allerdings benutze ich die Funktion von dir um das zu prüfen.

Viele Grüße,
Damian
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von jogo »

Hallo Damian,

hier ist mein aktueller Arbeitsstand:

Code: Alles auswählen

library(readxl)
Insider_trading_data <- read_excel("Data_for_forum.xlsx", sheet = "Insider_trading_data")
Company_description <- read_excel("Data_for_forum.xlsx", sheet = "Company_description")
Stock_prices <- read_excel("Data_for_forum.xlsx", sheet = "Stock_prices")
Daily_returns_actual <- read_excel("Data_for_forum.xlsx", sheet = "Daily_returns_actual")
Stock_prices_adj <- read_excel("Data_for_forum.xlsx", sheet = "Stock_prices_adj")
Daily_returns_for_model_calc <- read_excel("Data_for_forum.xlsx", sheet = "Daily_returns_for_model_calc")

Insider_returns_actual <- read_excel("Insider_returns_actual.xlsx")

names(Company_description)[2] <- "Company" # Namensangleichung
myInside <- merge(Insider_trading_data, Company_description, sort=FALSE)

# Zeilenindizes (in Daily_returns_for_model_calc) von myInside$Trading_date
sapply(myInside$Trading_date, function(TDAY) which(Daily_returns_for_model_calc$Date==TDAY))

myworkaholic <- function(TDAY, Comp) {
  i.TDAY <- which(Daily_returns_for_model_calc$Date==TDAY)
  M <- lm(as.formula(paste0(Comp, " ~ DAX")), data=Daily_returns_for_model_calc[(i.TDAY-201):(i.TDAY-21),])
  P <- predict(M, newdata=Daily_returns_for_model_calc[(i.TDAY-20):(i.TDAY+20), c("Date", "DAX")])
  a.Tag <- which(Daily_returns_actual$Date==TDAY)
  list(M=M, P=P, Dact=unlist(Daily_returns_actual[(a.Tag+1):(a.Tag+20), Comp], use.names = FALSE)) ## ? oder (a.Tag-20):(a.Tag-1) ?
}

L <- mapply(FUN=myworkaholic, myInside$Trading_date, myInside$Company_name, SIMPLIFY = FALSE)
N <- paste(myInside$Trading_date, myInside$Company_name) ## passende Namen für die Elemente der Ergebnisliste von mapply()

Ins.pred <- data.frame(myInside[c("Company_name", "Trading_date")], t(sapply(L, '[[', "P")))
Ins.pred.VOR  <- as.matrix(Ins.pred[,  3:22])
Ins.pred.NACH <- as.matrix(Ins.pred[, 24:43])
Ins.ACT  <- as.matrix(Insider_returns_actual[, 6:25])
D.ACT <- sapply(L, '[[', "Dact")
D.ACT
Viele Grüße, Jörg
darrgans

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hallo Jörg,

vorab sorry für die lange Antwortzeit, allerdings hat der Austausch mit meinem Professor etwas länger gedauert und irgenwie ist mir deine Antwort auch durch die Lappen gegangen. Ich habe mit ihm die inhaltlichen Sachen geklärt und eigentlich sind jetzt nur noch 3 Sachen zu erledigen.
  • 1) Tatsächliche Tagesrenditen von Erwarteten Tagesrenditen abziehen
    2) Die Abnormalen Renditen von gleichen Trading_date und Company-Einträgen verdichten
    3) Aggregation der Zeilen über unterschiedliche Zeitintervalle
Inhaltlich hat sich allerdings etwas geändert (was die Sache erleichtert). Die Tatsächlichen Renditen sind jetzt alle im Reiter "Actual_returns_for_model_calc". Diese müssen einfach entsprechend des Trading_dates einfach nur von den Erwarteten Renditen, welche im Element:

Code: Alles auswählen

erwartete_renditen <- data.frame(myInside[c("Company_name", "Trading_date")], t(sapply(model_predictions_buys, `[[`, "P")))
gespeichert sind abgezogen werden. Die Tatsächlichen Renditen sind ja alle bereits vorhanden, daher habe ich mir überlegt, dass man ja einfach einfach mir einer Function() lösen kann, die anhängig vom Trading_date die Daten in "Daily_returns_for_model_calc" subsetted und dann die Werte 41 Werte (Trading_date - 20 bis Trading_date + 20) wieder in die Spalten schreibt und in einem Element "Tatsächliche_renditen" speichert, damit wäre das Subtrahieren ziemlich leicht. In den Spalten davor sollte dann wieder das Trading_date und die Company stehen, wie bei den Erwarteten Renditen auch. Mein Ansatz ist eine Abwandlung von dem was wir bisher gemacht haben.

Code: Alles auswählen

Arbeitstier2 <- function(TDAY, Comp) {
  i.TDAY <- which(Daily_returns_for_model_calc$Date==TDAY)
  A <- subset.data.frame(Daily_returns_for_model_calc, newdata=Daily_returns_for_model_calc[(i.TDAY-20):(i.TDAY+20)])
  list(A=A)
}
 
Tatsächliche_renditen<- mapply(FUN=Arbeitstier2, myInside$Trading_date, myInside$Company_name, SIMPLIFY = FALSE)
names(Tatsächliche_renditen <- model_names_buys ## Das wurde bereits vorher verwendet für das Element mit den erwarteten Renditen, daher ist es hier im Code nicht nochmal programmiert
Tatsächliche_renditen <- data.frame(myInside[c("Company_name", "Trading_date")], t(sapply(Tatsächliche_renditen, `[[`, "P")))
View(Tatsächliche_renditen)
Das funktioniert bis auf den wichtigsten Teil, den Subset() Teil in der Arbeitstier2 Funktion eigentlich ganz gut.
Hast du eine Idee warum er es nicht so subsetted wie gewollt?

Vielen Dank für Deine Hilfe.
Viele Grüße,
Damian
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von jogo »

Hallo Damian,
darrgans hat geschrieben: Do Aug 02, 2018 1:07 pm vorab sorry für die lange Antwortzeit, allerdings hat der Austausch mit meinem Professor etwas länger gedauert und irgenwie ist mir deine Antwort auch durch die Lappen gegangen.
bitte schaue sie Dir trotzdem nochmal an ... (siehe unten)
Ich habe mit ihm die inhaltlichen Sachen geklärt und eigentlich sind jetzt nur noch 3 Sachen zu erledigen.

1) Tatsächliche Tagesrenditen von Erwarteten Tagesrenditen abziehen
2) Die Abnormalen Renditen von gleichen Trading_date und Company-Einträgen verdichten
3) Aggregation der Zeilen über unterschiedliche Zeitintervalle[/list]
wir gehen Stück für Stück vor.
Inhaltlich hat sich allerdings etwas geändert (was die Sache erleichtert). Die Tatsächlichen Renditen sind jetzt alle im Reiter "Actual_returns_for_model_calc". Diese müssen einfach entsprechend des Trading_dates einfach nur von den Erwarteten Renditen, welche im Element:

Code: Alles auswählen

erwartete_renditen <- data.frame(myInside[c("Company_name", "Trading_date")], t(sapply(model_predictions_buys, `[[`, "P")))
Wie ich sehe, hast Du wieder einige Umbenennungen vorgenommen. :?
gespeichert sind abgezogen werden. Die Tatsächlichen Renditen sind ja alle bereits vorhanden, daher habe ich mir überlegt, dass man ja einfach einfach mir einer Function() lösen kann, die anhängig vom Trading_date die Daten in "Daily_returns_for_model_calc" subsetted und dann die Werte 41 Werte (Trading_date - 20 bis Trading_date + 20) wieder in die Spalten schreibt und in einem Element "Tatsächliche_renditen" speichert, damit wäre das Subtrahieren ziemlich leicht. In den Spalten davor sollte dann wieder das Trading_date und die Company stehen, wie bei den Erwarteten Renditen auch. Mein Ansatz ist eine Abwandlung von dem was wir bisher gemacht haben.
Für Diesen Teil hatte ich schon nach dem damaligen Stand etwas entwickelt, IMHO ist die ursprüngliche Arbeitstier-Funktion auch hierfür die geeignete Stelle.
Bitte schaue Dir deshalb meinen Quelltext nochmal an.

Code: Alles auswählen

Arbeitstier2 <- function(TDAY, Comp) {
  i.TDAY <- which(Daily_returns_for_model_calc$Date==TDAY)
  A <- subset.data.frame(Daily_returns_for_model_calc, newdata=Daily_returns_for_model_calc[(i.TDAY-20):(i.TDAY+20)])
  list(A=A)
}
...
Das funktioniert bis auf den wichtigsten Teil, den Subset() Teil in der Arbeitstier2 Funktion eigentlich ganz gut.
Hast du eine Idee warum er es nicht so subsetted wie gewollt?
Du wendest die Funktion subset() falsch an.
Die Funktion subset() hat kein Argument newdata= . Bitte lies hierzu nochmal die Dokumentation von subset()
Zusätzlicher Literaturhinweis:

Code: Alles auswählen

library("fortunes")
fortune(85)
Ich habe noch einige Anmerkungen zu Deiner Funktion Arbeitstier2():
1. Die Funktion erwartet einen Parameter Comp - dieser wird in der Funktion gar nicht verwendet. Warum?
2. Natürlich kann man explizit die passende subset-Funktion aufrufen - das sieht man selten. Üblicherweise überlasse ich es R, die passende Funktion anhand der Objektklasse zu suchen, also subset() statt subset.data.frame() - aber die Geschmäcker sind verschieden.
3. Ein nochmaliges Umspeichern des Ergebnisses in eine Liste ist nicht erforderlich. Es hätte gereicht:

Code: Alles auswählen

Arbeitstier2 <- function(TDAY, Comp) {
  i.TDAY <- which(Daily_returns_for_model_calc$Date==TDAY)
  subset(...)
}
Mein Grundsatz lautet:
Möglichst die Strukturen flach halten.
Aber auch hier sind die Geschmäcker verschieden. ;)

Eigentlich könnte es so (oder so ähnlich) aussehen:

Code: Alles auswählen

names(Company_description)[2] <- "Company" # Namensangleichung
myInside <- merge(Insider_trading_data, Company_description, sort=FALSE)

# Zeilenindizes (in Daily_returns_for_model_calc) von myInside$Trading_date
sapply(myInside$Trading_date, function(TDAY) which(Daily_returns_for_model_calc$Date==TDAY))

myworkaholic <- function(TDAY, Comp) {
  i.TDAY <- which(Daily_returns_for_model_calc$Date==TDAY)
  M <- lm(as.formula(paste0(Comp, " ~ DAX")), data=Daily_returns_for_model_calc[(i.TDAY-201):(i.TDAY-21),])
  P <- predict(M, newdata=Daily_returns_for_model_calc[(i.TDAY-20):(i.TDAY+20), c("Date", "DAX")])
  a.Tag <- which(Daily_returns_actual$Date==TDAY)
  list(M=M, P=P, Dact=unlist(Daily_returns_actual[(a.Tag-20):(a.Tag+20), Comp], use.names = FALSE))
}

model_predictions_buys <- mapply(FUN=myworkaholic, myInside$Trading_date, myInside$Company_name, SIMPLIFY = FALSE)
erwartete_renditen <- data.frame(myInside[c("Company_name", "Trading_date")], t(sapply(model_predictions_buys, `[[`, "P")))

as.matrix(erwartete_renditen[3:43]) - t(sapply(model_predictions_buys, '[[', "Dact"))
(Ich habe mal das Stück, in dem es um das Einlesen der Daten geht, weggelassen.)
Ich bin mir nicht sicher, ob ich bei Dact=unlist(Daily_returns_actual[(a.Tag-20):(a.Tag+20), Comp], use.names = FALSE) die Daten aus der richtigen Tabelle ziehe. Das musst Du bitte nochmal kontrollieren :!:

Viele Grüße, Jörg
darrgans

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hallo Jörg,

danke nochmal für die Hilfe. Sorry für die Umbenennungen, das liegt daran, dass ich die Arbeit auf Englisch verfassen und einreichen muss.

Ich habe die Änderungen übernommen und alles in die Arbeitstierfunktion gepackt.
Ich wollte nochmal ein paar Verständnissachen fragen. In der Funktion gibt es den Part

Code: Alles auswählen

myworkaholic <- function(TDAY, Comp) {
  i.TDAY <- which(Daily_returns_for_model_calc$Date==TDAY)
  M <- lm(as.formula(paste0(Comp, " ~ DAX")), data=Daily_returns_for_model_calc[(i.TDAY-201):(i.TDAY-21),])
  P <- predict(M, newdata=Daily_returns_for_model_calc[(i.TDAY-20):(i.TDAY+20), c("Date", "DAX")])
  a.Tag <- which(Daily_returns_actual$Date==TDAY)
  list(M=M, P=P, Dact=unlist(Daily_returns_actual[(a.Tag-20):(a.Tag+20), Comp], use.names = FALSE))
}
Der "Dact"-Teil guckt im Reiter "Daily_returns_actual" nach den Rendite -20 bis + 20 Tage um das Trading_date und speichert diese im Element "Dact", richtig?

Der Teil dazwischen ist ja identisch geblieben. Allerdings habe ich eine Frage zum letzten Teil, der Subtraktion.

Code: Alles auswählen

as.matrix(erwartete_renditen[3:43]) - t(sapply(model_predictions_buys, '[[', "Dact"))
Wenn ich das richtig verstanden habe, dann werden hier die tatsächlichen Renditen (enthalten im Element "Dact" von den erwarteten Renditen (enthalten im Element "erwartete_renditen") abgezogen. Dies müsste umgekehrt sein, da die erwarteten von den tatsächlichen abgezogen werden sollen.
Daher habe ich das so umgestellt:

Code: Alles auswählen

abnormale_renditen <- t(sapply(model_predictions_buys, '[[', "Dact")) - as.matrix(expected_returns_buys[3:43]
Allerdings sind bei Ansicht vom Element "abnormale_renditen" lediglich 21 Spalten vorhanden, es müssten aber ja eigentlich 41 sein. Kann es sein, dass irgendetwas mit Element "Dact" nicht stimmt, oder ist das Umstellen, wie ich es gemacht habe nicht korrekt?

Vielen Dank für Deine tolle Unterstützung an dieser Stelle nochmals!! Du bist echt eine gigantische Hilfe.
Viele Grüße,
Damian
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von jogo »

Hallo Damian,
darrgans hat geschrieben: Do Aug 02, 2018 4:16 pm Ich wollte nochmal ein paar Verständnissachen fragen. In der Funktion gibt es den Part

Code: Alles auswählen

myworkaholic <- function(TDAY, Comp) {
  i.TDAY <- which(Daily_returns_for_model_calc$Date==TDAY)
  M <- lm(as.formula(paste0(Comp, " ~ DAX")), data=Daily_returns_for_model_calc[(i.TDAY-201):(i.TDAY-21),])
  P <- predict(M, newdata=Daily_returns_for_model_calc[(i.TDAY-20):(i.TDAY+20), c("Date", "DAX")])
  a.Tag <- which(Daily_returns_actual$Date==TDAY)
  list(M=M, P=P, Dact=unlist(Daily_returns_actual[(a.Tag-20):(a.Tag+20), Comp], use.names = FALSE))
}
Der "Dact"-Teil guckt im Reiter "Daily_returns_actual" nach den Rendite -20 bis + 20 Tage um das Trading_date und speichert diese im Element "Dact", richtig?
ja
Der Teil dazwischen ist ja identisch geblieben. Allerdings habe ich eine Frage zum letzten Teil, der Subtraktion.

Code: Alles auswählen

as.matrix(erwartete_renditen[3:43]) - t(sapply(model_predictions_buys, '[[', "Dact"))
Wenn ich das richtig verstanden habe, dann werden hier die tatsächlichen Renditen (enthalten im Element "Dact" von den erwarteten Renditen (enthalten im Element "erwartete_renditen") abgezogen. Dies müsste umgekehrt sein, da die erwarteten von den tatsächlichen abgezogen werden sollen.
ich hatte mich an Deine Beschreibung gehalten:
1) Tatsächliche Tagesrenditen von Erwarteten Tagesrenditen abziehen
Daher habe ich das so umgestellt:

Code: Alles auswählen

abnormale_renditen <- t(sapply(model_predictions_buys, '[[', "Dact")) - as.matrix(expected_returns_buys[3:43]
Allerdings sind bei Ansicht vom Element "abnormale_renditen" lediglich 21 Spalten vorhanden, es müssten aber ja eigentlich 41 sein. Kann es sein, dass irgendetwas mit Element "Dact" nicht stimmt, oder ist das Umstellen, wie ich es gemacht habe nicht korrekt?
Bei mir werden 41 Spalten angezeigt; somit weiß ich nicht, was dort schief läuft. Bitte lass Dir das Objekt abnormale_renditen einfach an der Konsole anzeigen:

Code: Alles auswählen

abnormale_renditen
und auch sicherheitshalber noch:

Code: Alles auswählen

str(abnormale_renditen)
Viele Grüße, Jörg
darrgans

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hallo Jörg,

vielen Dank fürs Feedback.
Entschuldige die fehlerhafte Beschreibung bei der Subtraktion am Anfang, ich bin schlichtweg nach den Stunden vorm Rechner schon halbgar gekocht.

Zum letzten Teil:
Mit der str() Funktion zeigt er mir folgendes an:

Code: Alles auswählen

 num [1:774, 1:41] -0.00091 -0.000307 -0.000307 -0.005356 -0.005356 ...
 - attr(*, "dimnames")=List of 2
  ..$ : chr [1:774] "2017-11-28 Adidas" "2017-11-10 Adidas" "2017-11-10 Adidas" "2017-10-11 Adidas" ...
  ..$ : NULL
wenn ich mir das mit view() anschauen will, dann zeigt er mit nur 21 Spalten an. Ist es möglich, dass das Ergebnis in ein Dataframe umgewandelt wird, so wie es hier:

Code: Alles auswählen

data.frame(myInside_buys[c("Company_name", "Trading_date")], t(sapply(model_predictions_buys, `[[`, "P")))
auch gemacht wurde?

Ich habe versucht das ganze direkt zu verknüpfen in dieser Art:

Code: Alles auswählen

Abnormale_renditen <- data.frame(myInside_buys[c("Company_name", "Trading_date")], t(sapply(model_predictions_buys, '[[', "Dact")) - as.matrix(expected_returns_buys[3:43]))
Das geht auch wohl durch, allerdings bin ich mir unsicher ob das code-technisch korrekt ist. Kannst du einen Blick darauf werfen?

Vielen Dank und viele Grüße,
Damian
Zuletzt geändert von jogo am Do Aug 02, 2018 7:49 pm, insgesamt 1-mal geändert.
Grund: Formatierung
darrgans

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hallo Jörg,

ich habe inzwischen weitergemacht und mich dem Punkt der Aggregation zu Mittelwerten für gleiche Trading_dates und Companyeinträge gewidmet. Dies sieht wie folgt aus:

Code: Alles auswählen

abnormal_returns_buys_agg <- aggregate(list(abnormal_returns_buys$X1, abnormal_returns_buys$X2, abnormal_returns_buys$X3, abnormal_returns_buys$X4,abnormal_returns_buys$X5, abnormal_returns_buys$X6, abnormal_returns_buys$X7, abnormal_returns_buys$X8,abnormal_returns_buys$X9, abnormal_returns_buys$X10, 
                                            abnormal_returns_buys$X11, abnormal_returns_buys$X12,abnormal_returns_buys$X13, abnormal_returns_buys$X14, abnormal_returns_buys$X15, abnormal_returns_buys$X16,abnormal_returns_buys$X17, abnormal_returns_buys$X18, abnormal_returns_buys$X19, abnormal_returns_buys$X20,
                                            abnormal_returns_buys$X21, abnormal_returns_buys$X22, abnormal_returns_buys$X23, abnormal_returns_buys$X24,abnormal_returns_buys$X25, abnormal_returns_buys$X26, abnormal_returns_buys$X27, abnormal_returns_buys$X28, abnormal_returns_buys$X29, abnormal_returns_buys$X30,
                                            abnormal_returns_buys$X31, abnormal_returns_buys$X32,abnormal_returns_buys$X33, abnormal_returns_buys$X34, abnormal_returns_buys$X35, abnormal_returns_buys$X36, abnormal_returns_buys$X37, abnormal_returns_buys$X38, abnormal_returns_buys$X39, abnormal_returns_buys$X40,
                                            abnormal_returns_buys$X41), by = list(abnormal_returns_buys$Company_name, abnormal_returns_buys$Trading_date), mean)
Die Benennung ist auf englisch, aber sonst ist es das Dataframe "Abnormale_renditen" auf das ich dich gebeten hatte einen Blick zu werden. :)
Die Aggragation zu Mittelwertel hat geklappt, allerdings disaggregiert R das Ganze wieder, wenn ich es in ein Dataframe umwandeln möchte. (Wollte ich nur aus ästhetischen und Übersichtlichkeitsgründen machen). Viel wichtiger ist, wenn ich jetzt eine einzelne Spalten kummulieren möchte, z.B. Spalten 3-22 und hierfür die cumsum() Funktion nützen möchte, dann gibt er mir in dem neuen Element nur die gleichen 20 Spalten wieder aus anstatt diese zu einer Spalte zu aggregieren.

Code: Alles auswählen

P-20to0 <- cumsum(abnormal_returns_buys_agg[, 3:22])


Hast du eine Idee woran das liegen kann? Die cumsum() Funktion besteht nicht wirklich aus vielen Argumenten.
Vielen Dank nochmal.
Viele Grüße,
Damian
Antworten