Programmierhilfe - Lineares Regressionmodell

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

Moderatoren: EDi, jogo

darrgans

Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hallo zusammen,

ich nutze R in Rahmen meiner Masterarbeit und habe bereits ein paar Anfängererfahrungen gesammelt.
Allerdings bin ich auf eine Hürde gestoßen, die ich so - ohne Hilfe - leider nicht überwinden kann.

Ich muss etwas weiter ausholen um das - hoffentlich - verständlich zu erklären.
Ich befasse mich in meiner MA mit dem Insidertrading von DAX Vorständen und habe hierzu die entsprechenden Kauf- und Verkaufstrades gesammelt. Die Trades sind eine klassische Zeitreihe, so wie alle anderen Daten auf denen mein Modell basiert. Ich habe für die Kursdaten der jeweiligen Aktie (30 Stück analog zur Anzahl der DAX Unternehmen) sowie für ein Marktportfolio logarithmierte Tagesrenditen berechnet.
In Zuge meiner Analyse muss aus diesen Daten ein Modell entwickeln, welches "normale" Tagesrenditen (expected returns) vorhersagt. Hierzu habe ich ein passendes Modell in der Literatur identifiziert, welches im Grunde auf einer simplen lineare Regression von Tagesrenditen des Marktportfolios als unabhängige und die Tagesrenditen der jeweiligen Aktie als abhängige Variable basiert.
Nun ist es aber so, dass das ganze als Event-Study angelegt ist um den Effekt des Insidertradings zu "extrahieren", daher wird das Modell nicht einfach mit allen Daten aus der Beobachtungsperiode kreuzvalidiert, sondern basiert auf einer Schätzperiode, welche für 200 Tage vor dem Trade des jeweiligen Insiders das Modell berechnet. Dieses Modell wird dann benutzt um nach dem Trade des Insiders (welcher quasi Tag 0 ist) erwartete Tagesrenditen zu bestimmen. Jetzt ist es so, dass ich für jeden Trade das Modell neu aufsetzen müsste, was bei 30 Unternehmen (also 30 mal eine andere abhängige Variable) und ca. 50-150 Trades pro Unternehmen händisch einen unglaublichen Aufwand (von ca. 3.000 linearen Regressionen) produzieren würde.

Ich habe darüber nachgedacht, ob das Ganze mit einer If else () und lm() gelöst werden kann, aber ich stoße irgendwie an die Grenze meiner Programmierfähigkeiten. Und leider finde ich keine Lösung in Foren dazu, weil das Problem relativ spezifisch ist.
Über Hilfe wäre ich echt super, super dankbar.

Ich bedanke mich aber schon mal im Voraus für das Lesen dieses Romans. :D
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,

willkommen im Forum!
darrgans hat geschrieben: So Jul 22, 2018 8:29 pm ... Jetzt ist es so, dass ich für jeden Trade das Modell neu aufsetzen müsste, was bei 30 Unternehmen (also 30 mal eine andere abhängige Variable) und ca. 50-150 Trades pro Unternehmen händisch einen unglaublichen Aufwand (von ca. 3.000 linearen Regressionen) produzieren würde.
was hast Du denn bis jetzt für einen Trade programmiert?
Wenn das fertig ist, kann man mit den Metafunktionen von R den Rest erledigen (lapply(), replicate(), ...).

Gruß, Jörg
darrgans

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hallo Jörg,

mein Datensatz und die Funktion sehen beispielsweise so aus:

(1) So sieht der Trading Datensatz aus

Code: Alles auswählen

Trading_date    Insider              Amount       Price      Volume     Typ    Relation_to_company  Company
2018-05-18      Plattner, Hasso      1,000        95.75      97,750     Buy    Director             SAP
(2) So sieht der Datensatz mit den Tagesrenditen für die Aktie (SAP) und für das Marktportfolio (DAX)

Code: Alles auswählen

Date              Daily_return_SAP   Daily_return_DAX
2018-01-03     0,02%                    0,05%
2018-01-04     0,50%                    0,01%
...                  ...                         ...
2018-04-20     -0,05%                   0,07% 
In beiden Datensätzen sind die Datumsangaben nur auf Werkstage beschränkt, da nur an Werkstagen gehandelt wird. Das ist im sofern wichtig als das die Berechnung wie nachfolgend erklärt anhand von Werkstagen stattfindet.

Mit Hilfe des zweiten Datensatzes muss ich das Modell zur Vorhersage der erwarteten Renditen für die Aktie SAP für den Zeitraum von 180 Tagen für dem "Trading_date" bestimmen. Genau genommen wird das "Trading_date" erst minus 20 Werkstage gerechnet und dann für 180 Werkstage vor dem "Trading_Date -20 days" bestimmt. Die 20 Tage vor dem Trade werden als Indikator für die Kursentwicklung vor dem Event (also dem Insider trade) aus Datensatz (1) verwendet. D.h. die lm()-Funktion würde wie folgt aussehen:

Code: Alles auswählen

lm(Daily_return_SAP ~ Daily_return_DAX, data = ...)
Hier wird es problematisch, weil hier R immer wieder den Datensatz (2) auf dem das Modell basiert entsprechend des Zeitraumes wie oben beschrieben mit den 180 Tagen neu einteilen muss und das halt vielfach für die verschiedenen Unternehmen und für jedes Event, also jeden Trade einzeln. Also müsste die Funktion hier wiederholend auf das "Trading_date" aus Datensatz (1) zugreifen und dann entsprechend Datensatz (2) entsprechend zeitlich unterteilen. Und für jeden einzelnen Trade mit entsprechender Bennungen, damit das Modell dem Trade zweifelsfrei zuzuordnen ist. Eine Beispielbenennung wäre: Expected_return_Name der company_Trading_date.

Das Ganze scheint mir leider sehr komplex in der Programmierung.
Hast du eventuelle einen Ansatz wie das Ganze funktionieren kann?
Zuletzt geändert von jogo am Mo Jul 23, 2018 3:16 pm, insgesamt 1-mal geändert.
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von jogo »

Hallo Damian,
darrgans hat geschrieben: Mo Jul 23, 2018 3:12 pm ... D.h. die lm()-Funktion würde wie folgt aussehen:

Code: Alles auswählen

lm(Daily_return_SAP ~ Daily_return_DAX, data = ...)
Hier wird es problematisch, weil hier R immer wieder den Datensatz (2) auf dem das Modell basiert entsprechend des Zeitraumes wie oben beschrieben mit den 180 Tagen neu einteilen muss und das halt vielfach für die verschiedenen Unternehmen und für jedes Event, also jeden Trade einzeln. Also müsste die Funktion hier wiederholend auf das "Trading_date" aus Datensatz (1) zugreifen und dann entsprechend Datensatz (2) entsprechend zeitlich unterteilen. Und für jeden einzelnen Trade mit entsprechender Bennungen, damit das Modell dem Trade zweifelsfrei zuzuordnen ist. Eine Beispielbenennung wäre: Expected_return_Name der company_Trading_date.

Das Ganze scheint mir leider sehr komplex in der Programmierung.
Hast du eventuelle einen Ansatz wie das Ganze funktionieren kann?
Bei mir sieht das im Ansatz so aus:

Code: Alles auswählen

BOD
width <- 3
I <- 1:width
lapply(0:(nrow(BOD)-width), FUN=function(i) BOD[i+I,])
Bei dem Argument FUN= kannst Du eine beliebige Funktion angeben, z.B. könntest Du innerhalb der Funktion Deine Regression durchführen lm(...)

Code: Alles auswählen

lapply(0:(nrow(BOD)-width), FUN=function(i) lm(demand ~ Time, data=BOD[i+I,]))
Gruß, Jörg
darrgans

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hallo Jörg,

danke nochmals für deine Hilfe.

Ich muss zugeben, dass ich die BOD-Funktion nicht kenne. In der Beschreibung steht "Biochemical Oxygen Demand" und dass das Dataframen aus 6 Zeilen und 2 Spalten besteht. Die Zeilen sind Time und Demand. Ich habe aber doch mindestens zwei Demand Spalten für den DAX und für das Unternehmen, oder sehe ich das falsch? Wahrscheinlich habe ich das nicht so gut dargestellt, aber Datensatz (2) hat natürlich 31 Spalten für alle Unternehmen des DAX (30 Stück an der Zahl) und für die Performance des DAX selber. Ich hatte unglücklicherweise ein verkürztes Beispiel gewählt. Hat das Auswirkungen auf den Code? Kann das irgendwie angepasst werden, i.S.v ich gebe die Spalten an, die zur Erstellung des Datensatzes verwendet werden? Wobei die Spalte für den DAX (als unabgängige Variable der Regression) halt immer Spalte 2 wäre, weil Spalte 1 der Time Spalte entspricht und die Spalte für das Unternehmen (als abhängige Variable) von Spalte 3 bis 32 variiert.

Zusätzlich verstehe ich nicht wieso width auf 3 festgelegt wird, hängt das mit BOD zusammen? Oder ist das ein Beispiel, welches nicht auf den Datensatz angepasst ist, sodass ich das ganze auf 180 (oder 200 minus der letzten 20 Tage) anpassen müsste?
Ich habe auch eine Frage bezüglich des Speicherns der verschiedenen Regressionsmodelle. Ich brauche die Modelle damit ich die erwarteten Renditen nach den Modellen von den tätlichen Renditen abziehen und so bestimmen kann, ob dort eine Überrendite von dem Insider erzielt wurde, welche dann auch noch für unterschiedliche Zeiträume (1,10, 20, 25 Tage) kummuliert werden müssen. Die Kummulation erfolgt auf unterschiedlichen Aggregationsebenen. Beispielsweise für alle BUY Trades (Variable "Type") aus Datensatz (1) oder für alle Directoren (variable "Relation_to_company") aus Datensatz (1). Am Ende wird das Ganze dann von auf signifikanten Unterschied von 0 getestet.
Ich habe beispielsweise gute 780 BUY Transaktionen in meinem Datensatz, verteilt auf 30 Unternehmen. Ich müsste für jede BUY Transaktion die erwarteten Renditen nach meinem Modell mit den tatsächlichen abgleichen und das für die unterschiedlichen, genannten Zeiträume. Ich stelle mir das so vor, dass die Differenz zwischen erwarteter und tatsächlicher Rendite dann in einem Element für den jeweiligen Zeitraum gespeichert werden könnte, sodass ich 4 Elemente für 1, 10, 20, 25 Tage erhalte, welche jeweils 780 Zeilen für jede einzelne BUY Transaktion enthält. Die 4 Elemente könnte ich dann den statistischen Tests unterziehen.
Ich habe eigentlich eine gute Vorstellung was zu machen ist, leider scheitert das Ganze an der technischen Umsetzung, weil ich echt wenig Erfahrung mit R habe.

Vielen Dank an dieser Stelle nochmal für deine Hilfe, Zeit und Geduld mit mir.
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von jogo »

Hallo Damian,
darrgans hat geschrieben: Mo Jul 23, 2018 4:36 pm Ich muss zugeben, dass ich die BOD-Funktion nicht kenne. In der Beschreibung steht "Biochemical Oxygen Demand" und dass das Dataframen aus 6 Zeilen und 2 Spalten besteht. Die Zeilen sind Time und Demand.
ja, es ist ein Dataframe, den auch Du zur Verfügung hast. Bei dem, was Du bisher an Daten geliefert hast, handelt es sich eher um einen print() der Daten: daraus geht z.B. nicht hervor, welche Datentypen die einzelnen Daten haben. Um Dir die Überwindung wenigstens eines Problemes zu zeigen, benötigte ich Daten, mit denen ich auch wirklich arbeiten kann.
Ich habe aber doch mindestens zwei Demand Spalten für den DAX und für das Unternehmen, oder sehe ich das falsch? Wahrscheinlich habe ich das nicht so gut dargestellt, aber Datensatz (2) hat natürlich 31 Spalten für alle Unternehmen des DAX (30 Stück an der Zahl) und für die Performance des DAX selber.
Wenn Du das so sagst, wird es wohl so sein.
Ich habe Deine Daten nicht.
Ich hatte unglücklicherweise ein verkürztes Beispiel gewählt. Hat das Auswirkungen auf den Code?
Bezüglich des einen Problems - nämlich auf den rollenden Daten eine Regression auszuführen - kaum.
Erst habe ich mit rollapply() aus dem Paket zoo experimentiert, aber vermutlich gibt es dabei ein anderes Problem.
Kann das irgendwie angepasst werden, i.S.v ich gebe die Spalten an, die zur Erstellung des Datensatzes verwendet werden? Wobei die Spalte für den DAX (als unabgängige Variable der Regression) halt immer Spalte 2 wäre, weil Spalte 1 der Time Spalte entspricht und die Spalte für das Unternehmen (als abhängige Variable) von Spalte 3 bis 32 variiert.
Um das Problem mit den mehreren Spalten habe ich mich bis jetzt noch nicht gekümmert. Wenn ich das richtig verstanden habe möchtest Du in der Regressionsformel einige Variablen austauschen.
Kannst Du das bitte exemplarisch mit drei oder vier Variablen zeigen?
Die Lösung könnte etwa so aussehen:

Code: Alles auswählen

lapply(2:4, function(i) lm(Sepal.Length ~ ., data=iris[, c(1,i)]))
Und bevor wieder die üblichen Fragen kommen:
1. Auch der Dataframe iris gehört standardmäßig zu R
2. Der Dataframe iris hat fachlich nichts mit Deinen Daten zu tun.
3. Dieser Code soll nur eine Möglichkeit aufzeigen, wie Du das Problem der verschiedenen Variablen in der Regression bei der Programmierung angehen kannst; der Code muss noch entsprechend an Deine Situation angepasst werden. Es gibt auch noch viel radikalere Methoden, z.B. kann man sich sie Formel aus den Zeichenketten der Variablenbezeichner zusammelnbasteln (mit paste0() oder sprintf()) und dann in eine Formel umwandeln mit as.formula()
Zusätzlich verstehe ich nicht wieso width auf 3 festgelegt wird, hängt das mit BOD zusammen?
ja, bei Dir sollten dann width den Wert 180 haben, wenn ich das richtig verstanden habe. Und ja, width <- 3 hängt mit BOD zusammen, da der Dataframe BOD keine 180 Zeilen hat.
Ich habe Deine Daten nicht.
Oder ist das ein Beispiel, welches nicht auf den Datensatz angepasst ist, sodass ich das ganze auf 180 (oder 200 minus der letzten 20 Tage) anpassen müsste?
jepp
Ich habe auch eine Frage bezüglich des Speicherns der verschiedenen Regressionsmodelle. Ich brauche die Modelle ...
jedes Ergebnis einer Funktion kannst Du speichern. Die Funktion lapply() liefert üblicherweise eine Liste.

Code: Alles auswählen

L <- lapply(0:(nrow(BOD)-width), FUN=function(i) lm(demand ~ Time, data=BOD[i+I,]))
liefert z.B. eine Liste L; jedes Element der Liste ist so wie im Abschnitt Value der Dokumentation der Funktion lm() beschrieben.
Über so eine Liste kann man wieder mit lapply() oder sapply() drüberrollen und mit einer geeigneten Funktion die Elemente bearbeiten.
...
Ich habe eigentlich eine gute Vorstellung was zu machen ist, leider scheitert das Ganze an der technischen Umsetzung, weil ich echt wenig Erfahrung mit R habe.
Trotzdem wirst Du einige Teile selber programmieren müssen.
Ich wollte Dir für den Anfang zeigen, dass es eigentlich für alles eine Lösung gibt - besonders auf der Metaebene: also wenn es darum geht, die gleiche Prozedur leicht abgewandelt mehrfach zu wiederholen.
Wichtig ist vor allem, dass Du die kleinen einzelnen Teile selbst programmierst, damit Du uns genau erklären kannst, was daran abgewandelt wiederholt werden soll.
Vielen Dank an dieser Stelle nochmal für deine Hilfe, Zeit und Geduld mit mir.
:roll: ist schon in Ordnung.
Es ist nett, dass Du Dich bedankst.

Gruß, Jörg
darrgans

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hallo Jörg,

ich habe es mir mal einfach gemacht und eine reduzierte Datei angehängt. Das sollte Klarheit verschaffen, leider war die komplette Datei zu groß, daher habe ich die Daten exemplarisch für 3 der 30 Unternehmen reduziert. Im Original sind im ersten Reiter 990 Trades vorhanden, in der reduzierten 7 Trades. Die Anpassungen in Sachen Umfang der Daten und Länge der Zeitreihen sollte ich aber später hinbekommen, sobald der Ansatz der Lösung für mich erkennbar ist.

Die Datei besteht aus 6 Reitern:
  • 1- "Insider_trading_data" enthält die Insidertransaktionen und die Variablen wie eingangs beschrieben.
    2- "Company_describtion" erklärt die kompletten Namen zur Variable "Company" aus Reiter 1.
    3- "Stock prices" enthält die Kurse der DAX Unternehmen.
    4- "Daily_returns" enthält die logarithmierten Tagesrenditen zu den Kursen aus Reiter 3.
    5 - "Stock_prices_adj" enthält bereinigte Kursdaten der DAX Unternehmen.
    6 - "Daily_returns_for_model_calc" enthält die logarithmierten Tagesrenditen aus Reiter 5.
Ein Beispiel für das Modell des ersten Trades aus Zeile 2 des ersten Reiters wäre statisch und nicht automatisiert codiert wie folgt:

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 = ?? 
HIer taucht das Problem mit der automatisierten Datenselektion für das Subset auf. Hier müsste R die Daten anhand folgender Regel automatisch bestimmen:
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.

Das nächste Problem ist allerdings, dass die Trades ja unterschiedlichen Unternehmen (Erkennbar an der Variable "Company" aus dem ersten Reiter) zu zuordnen sind. Im obigen Code ist das statisch auf Adidas gesetzt, weil der erste Trade zum Unternehmen Adidas gehört. In Zeile 4 von Reiter 1 ist z.B. ein Trade der Firma BASF (Company Variable = BAS). Dort wäre das Modell dann:

Code: Alles auswählen

 BASF_20180507<- lm( Daily_returns_for_model_calc$BASF~ Daily_returns_for_model_calc$DAX, Data = Daily_returns_for_model_calc, subset = ?? 
Die abhängige Variable der Regression ändert sich bei den unterschiedlichen Trades und müsste anhand der Variable "Company" flexibilisiert werden. Die unabhängige Variable der Regression ist hingegen kann statisch auf den DAX festgelegt werden, die ändert sich nicht. Falls es das codieren vereinfacht, können die Abkürzungen der Company Variable aus Reiter 1 von mir händisch umbenannt werden in die Langform (also aus ADI wird das ADIDAS, aus BAS wird BASF usw.) diese wären dann mit den Werten der Variablen aus Reiter 6 identisch und der Reiter 2 "Company_describtion" überflüssig. Die Benennung der Modelle (Bsp: Adidas_20171128) ist eine Mischung aus Name des Unternehmens und dem Trading_date.

Wenn das automatisiert ablaufen würde, dann würde ich im Resultat 990 (analog zur Anzahl der Trades im ersten Reiter des originalen Datensatzes) Modelle zur vorhersage von erwarteten Renditen um das Trading_date des jeweiligen Trades erhalten. Die erwarteten Renditen nach den Modellen werden von den tatsächlichen Renditen des vierten Reiters abgezogen und über verschiedene Zeiträume (1, 10, 20, 25 Tage) kummuliert. Die kummulierten Differenzen würden dann jeweils mittels statistischer Tests auf signifikante Abweichungen von 0 getestet werden um Ableitungen über das Trading Verhalten von Insidern im DAX zu machen.

Ich fühle mich innerlich dazu verpflichtet Dir zu danken. Die Mühe macht sich gewiss nicht jeder und daher auch an dieser Stelle nochmal vielen Dank für Deine Unterstützung.

Viele Grüße,
Damian
Dateianhänge
Data_for_forum.xlsx
Datenprobe
(180.51 KiB) 49-mal heruntergeladen
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von jogo »

Hallo Damian,
darrgans hat geschrieben: Di Jul 24, 2018 11:31 pm ich habe es mir mal einfach gemacht und eine reduzierte Datei angehängt. Das sollte Klarheit verschaffen, leider war die komplette Datei zu groß, daher habe ich die Daten exemplarisch für 3 der 30 Unternehmen reduziert. Im Original sind im ersten Reiter 990 Trades vorhanden, in der reduzierten 7 Trades. Die Anpassungen in Sachen Umfang der Daten und Länge der Zeitreihen sollte ich aber später hinbekommen, sobald der Ansatz der Lösung für mich erkennbar ist.
kannst Du mir bitte noch zeigen (also den entsprechenden Code), wie Du diese Excel-Datei einliest?

Gruß, Jörg
darrgans

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hallo Jörg,

beim Einlesen über die Oberfläche muss die Datei in 6 Dateien (entsprechend der 6 Reiter) aufgesplitet werden.
Die 6 Dateien findest du angehängt.

Der Code sieht wie folgt aus:

Code: Alles auswählen

 library(readxl)
> Insider_trading_data <- read_excel("D:/1. Archiv/Master/Master/Studienverlauf/Masterthesis/Data set/Forum/Insider_trading_data.xlsx")

Code: Alles auswählen

Company_description <- read_excel("D:/1. Archiv/Master/Master/Studienverlauf/Masterthesis/Data set/Forum/Company_description.xlsx")

Code: Alles auswählen

Stock_prices <- read_excel("D:/1. Archiv/Master/Master/Studienverlauf/Masterthesis/Data set/Forum/Stock_prices.xlsx")

Code: Alles auswählen

Daily_returns_actual <- read_excel("D:/1. Archiv/Master/Master/Studienverlauf/Masterthesis/Data set/Forum/Daily_returns_actual.xlsx")

Code: Alles auswählen

Stock_prices_adj <- read_excel("D:/1. Archiv/Master/Master/Studienverlauf/Masterthesis/Data set/Forum/Stock_prices_adj.xlsx")

Code: Alles auswählen

Daily_returns_for_model_calc <- read_excel("D:/1. Archiv/Master/Master/Studienverlauf/Masterthesis/Data set/Forum/Daily_returns_for_model_calc.xlsx")

So sieht der Code bei mir aus. Bei dir - aber das weist du besser als ich - muss der Pfad angepasst werden.
Vielen Dank nochmal für deine Hilfe.
Grüße,
Damian
Dateianhänge
Daily_returns_actual.xlsx
Reiter 4
(49.67 KiB) 47-mal heruntergeladen
Company_description.xlsx
Reiter 2
(9.13 KiB) 53-mal heruntergeladen
darrgans

Re: Programmierhilfe - Lineares Regressionmodell

Beitrag von darrgans »

Hier noch 2 weitere Dateien, da nur zwei der sechs Dateien angezeigt werden.
Dateianhänge
Insider_trading_data.xlsx
Reiter 1
(9.25 KiB) 50-mal heruntergeladen
Daily_returns_for_model_calc.xlsx
Reiter 6
(53.65 KiB) 51-mal heruntergeladen
Antworten