Re: Programmierhilfe - Lineares Regressionmodell
Verfasst: Mi Jul 25, 2018 2:12 pm
Und hier die letzten beiden Dateien.
Deutschsprachiges Forum zur Statistikumgebung R
http://www.forum.r-statistik.de/
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")
So schaut bei mir die Lösung für dieses erste Problem aus:darrgans hat geschrieben: Di Jul 24, 2018 11:31 pm Ein Beispiel für das Modell des ersten Trades aus Zeile 2 des ersten Reiters wäre statisch und nicht automatisiert codiert wie folgt:
HIer taucht das Problem mit der automatisierten Datenselektion für das Subset auf. Hier müsste R die Daten anhand folgender Regel automatisch bestimmen:Code: Alles auswählen
Adidas_20171128 <- lm( Daily_returns_for_model_calc$Adidas ~ Daily_returns_for_model_calc$DAX, Data = Daily_returns_for_model_calc, subset = ??
Nimm den Wert der Variable "Trading_date" aus dem Reiter "Insider_trading_data", suche ihn im Reiter "Daily_returns_for_model_calc" bei der Variable "Date", rechne MINUS 201 Beobachtungen und nimm dann die nächsten 180 Beobachtungen.
Das resultierende Subset würde dann aus 180 Beobachtungen bestehen und genau 21 Tage vor dem Wert der Variable "Trading_date" enden.
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")
## subset: "201 Tage vor" bis "20 Tage vor" Handelstag aus Insider_trading_data
## !! passendes Unternehmen
## Adidas_20171128 <- lm(Adidas ~ DAX, Data=Daily_returns_for_model_calc, subset = ?? )
# z.B. erste Zeile aus Insider_trading
TTag <- Insider_trading_data$Trading_date[1]
i.TTag <- which(Daily_returns_for_model_calc$Date==TTag)
# Adidas_20171128 <-
lm(Adidas ~ DAX, data=Daily_returns_for_model_calc[(i.TTag-201):(i.TTag-21),])
#BASF_20180507 <- lm(BASF ~ DAX, Data = Daily_returns_for_model_calc, subset = ?? )
Code: Alles auswählen
## subset: "201 Tage vor" bis "20 Tage vor" Handelstag aus Insider_trading_data
## !! passendes Unternehmen
## Adidas_20171128 <- lm(Adidas ~ DAX, Data=Daily_returns_for_model_calc, subset = ?? )
names(Company_description)[2] <- "Company" # Namensangleichung
myInside <- merge(Insider_trading_data, Company_description, sort=FALSE)
# z.B. erste Zeile aus Insider_trading
TTag <- myInside$Trading_date[1]
i.TTag <- which(Daily_returns_for_model_calc$Date==TTag)
Comp <- myInside$Company_name[1]
# Adidas_20171128 <-
lm(as.formula(paste0(Comp, " ~ DAX")), data=Daily_returns_for_model_calc[(i.TTag-201):(i.TTag-21),])
lm(Adidas ~ DAX, data=Daily_returns_for_model_calc[(i.TTag-201):(i.TTag-21),]) ## Vergleich
Code: Alles auswählen
names(Company_description)[2] <- "Company" # Namensangleichung
myInside <- merge(Insider_trading_data, Company_description, sort=FALSE)
myregr <- function(TTag, Comp) {
i.TTag <- which(Daily_returns_for_model_calc$Date==TTag)
lm(as.formula(paste0(Comp, " ~ DAX")), data=Daily_returns_for_model_calc[(i.TTag-201):(i.TTag-21),])
}
mapply(FUN=myregr, myInside$Trading_date, myInside$Company_name, SIMPLIFY = FALSE)
paste(myInside$Trading_date, myInside$Company_name) ## passende Namen für die Elemente der Ergebnisliste von mapply()
Code: Alles auswählen
estimation_models <- mapply(FUN=myregr, myInside$Trading_date, myInside$Company_name, SIMPLIFY = FALSE)
Code: Alles auswählen
paste(myInside$Company_name, myInside$Trading_date)
Code: Alles auswählen
rownames(estimation_models) <- paste(myInside$Company_name, myInside$Trading_date)
Code: Alles auswählen
dimnames(estimation_models) <- paste(myInside$Company_name, myInside$Trading_date)
Bedenke: das Objekt estimation_models ist eine Liste. Eine Liste hat keine Zeilen.darrgans hat geschrieben: Mi Jul 25, 2018 4:56 pm Ich habe die Modelle aus dem Code im Object "estimation_models" gespeichert:
Im Anschluss wollte ich die Spalten entsprechend benennen, den Befehl zur automatischen Namensentwicklung hast du mir ja bereits angemerkt.Code: Alles auswählen
estimation_models <- mapply(FUN=myregr, myInside$Trading_date, myInside$Company_name, SIMPLIFY = FALSE)
Ich habe daher versucht die Namen und die Modelle zu kombinieren und habe dafür folgende Funktionen verwendet:Code: Alles auswählen
paste(myInside$Company_name, myInside$Trading_date)
Code: Alles auswählen
rownames(estimation_models) <- paste(myInside$Company_name, myInside$Trading_date)
Bedenke: das Objekt estimation_models ist eine Liste. Eine Liste hat nur eine Dimension. Die Funktion dimnames<- ist zum Zuweisen von Namen bei mehrdimensionalen Objekten. Eine Liste hat nur einen Index - ist also eindimensional.Code: Alles auswählen
dimnames(estimation_models) <- paste(myInside$Company_name, myInside$Trading_date)
Richtig ist die Verwendung von names(...) <- ...Allerdings werden mir bei beiden Fehlermeldungen anzeigt, weil das Objekt "estimation_models" ein non-array ist. Eine Umwandlung in ein Dataframe geht ja aufgrund der lm()-Funktion nicht.
Hast du einen Ansatz wie ich die Namen zu den Modellen zugeordnet bekomme?
Code: Alles auswählen
L <- mapply(FUN=myregr, 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()
names(L) <- N
Code: Alles auswählen
c(length(N), length(unique(N)))
Code: Alles auswählen
cbind(N)
Code: Alles auswählen
L[[N[3]]]
Code: Alles auswählen
Subset_adi <- subset(Daily_returns_for_model_calc, data = Daily_returns_for_model_calc$Date[(i.Tag+0):(i.Tag+20),], select = "DAX")
Code: Alles auswählen
mypredict <- function(TDAY) {
i.TDAY <- which(Daily_returns_for_model_calc$Date==TDAY)
predict.lm(estimation_models, data=Daily_returns_for_model_calc[(i.Tag+0):(i.Tag+25),])
}
Code: Alles auswählen
mapply((FUN=mypredict))
Bei predict() ist der Parameter newdata= dafür zu verwenden. ... und ich würde das gleich in die Funktion myreg() reinpacken - die Funktion myreg() ist quasi das Arbeitstier:darrgans hat geschrieben: Do Jul 26, 2018 5:08 pm Ich habe inzwischen weitergearbeitet und bin auf eine Hürde gestoßen. Nun, wo ich die Modelle habe, muss ich diese ja noch zur Vorhersage von "erwarteten" Tagesrenditen nutzen. Dabei bin ich auf Probleme gestoßen. Ich brauche ja eine Liste von Werten, die ich in das jeweilige Modell eingebe, um die erwarteten Rendite aus dem Modell erhalten. Diese Werte sind die des DAXs aus dem Datensatz "Daily_returns_for_model_calc", welche 20 Tage nach dem Trading_date liegen. Ein Beispiel: Trading_date = 2017-11-28, dann brauche ich ein Subset der Werte für die DAX-Renditen aus dem Zeitraum 2017-11-29 bis 2017-12-29. Dies entspricht 20 Werkstagen (ohne Feiertage), oder auch den Zeilen 487 bis 507 aus dem Datensatz Daily_returns_for_model_calc.
Mein Code dazu, ohne Automatisierung, war wie folgt:
Allerdings gibt er mir bei dem Code immer einfach alle Werte und nicht die 20 gesuchten aus, obwohl mit i.Tag+20 und i.Tag+0 die richtigen Zeilen aus dem Datensatz bestimmt werden.Code: Alles auswählen
Subset_adi <- subset(Daily_returns_for_model_calc, data = Daily_returns_for_model_calc$Date[(i.Tag+0):(i.Tag+20),], select = "DAX")
Im nächsten Schritt würde dieses Subset ja zur Vorhersage von erwarteten Renditen gebraucht werden. Wenn das oben aufgehen würde, dann würde sich das Subset ja auch automatisch immer anpassen und die richtigen Inputs für predict.lm() Funktion liefern, oder vertue ich mich da?.
Code: Alles auswählen
myregr <- function(TTag, Comp) {
i.TTag <- which(Daily_returns_for_model_calc$Date==TTag)
M <- lm(as.formula(paste0(Comp, " ~ DAX")), data=Daily_returns_for_model_calc[(i.TTag-201):(i.TTag-21),])
P <- predict(M, newdata=Daily_returns_for_model_calc[i.TTag:(i.TTag+20), c("Date", "DAX")])
list(M=M, P=P)
}
L <- mapply(FUN=myregr, 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()
wäre mit der Modifikation des Arbeitstieres erledigt.Leider zeigt mir die predict.lm() Funktion immer den selben Fehler an, dass sie nicht mit einer Liste von Werte Arbeiten kann. Außerdem ist das Ganze natürlich nicht automatisiert, da müsste wieder eine Funktion (wie bei myregr) geschrieben und mit mapply() kombiniert werden, damit das ganze automatisiert für alle Modelle abläuft, oder?
Um solche Formfragen kümmere ich mich immer ganz zum Schluss, aber ich glaube, da lässt sich was machen.Die Modelle sind gespeichert in der Liste "estimation_models".
Zusätzlich habe ich auch das Problem, dass der Output eine bestimmte Form haben muss, damit die besser verarbeitet werden können. Am geeignetsten wäre das in etwas so:
Funktion 1 2 3 4 ... 20
ADIDAS_2017-11-29 0.02 -0.01 0.00 -0.05 ... 0.07
----
bis zur letzten Funktion.
Die Ergebnisse wären dann perfekt angeordnet um die tatsächlichen Renditen davon abzuziehen und so die Differenzen zu bestimmen, die dann getestet werden.
Ich scheitere allerdings schon am ersten Schritt. Mein Code sähe wie folgt aus und ist analog zu dem bereits vorhanden: ...
...
Ich habe nach Lösungen gegoogelt, aber leider habe ich keinen brauchbaren Ansatz gefunden. Am ehesten ist die Variante der Formatierung der Outputs noch mit einem as.data.frame() eine Möglichkeit gewesen. Aber irgendwie habe ich die Umsetzung in Kombination mit predict() und automatisierten Subset nicht hinbekommen.
Code: Alles auswählen
data.frame(N=N, t(sapply(L, `[[`, "P"))) ## oder
data.frame(myInside[c("Company_name", "Trading_date")], t(sapply(L, `[[`, "P")))