Data Analytics for Finance
BM17FI · Rotterdam School of Management
Event Study
Setup¶
Run these cells to prepare your environment.
✅ Environment cleared and ready. ✅ Graph scheme set to stcolor.
/Users/casparm4/Github/rsm-data-analytics-in-finance-private/private/assignment > s/05-assignment 📁 Base directory: /Users/casparm4/Github/rsm-data-analytics-in-finance-private > /private/assignments/05-assignment 📁 Raw data folder: /Users/casparm4/Github/rsm-data-analytics-in-finance-privat > e/private/assignments/05-assignment/data/raw 📁 Processed data folder: /Users/casparm4/Github/rsm-data-analytics-in-finance- > private/private/assignments/05-assignment/data/processed 📁 Output directory: /Users/casparm4/Github/rsm-data-analytics-in-finance-priva > te/private/assignments/05-assignment/output 📁 Tables folder: /Users/casparm4/Github/rsm-data-analytics-in-finance-private/ > private/assignments/05-assignment/output/tables 📁 Figures folder: /Users/casparm4/Github/rsm-data-analytics-in-finance-private > /private/assignments/05-assignment/output/figures
Learning Objectives¶
By completing this assignment, you will:
- Understand event study methodology and its role in measuring stock market reactions
- Define estimation and event windows appropriate for the research question
- Estimate the Market Model for expected returns using country-specific indices
- Estimate the Fama-French 3-Factor Model as a more sophisticated benchmark
- Calculate abnormal and cumulative abnormal returns (CARs)
- Compare results across different benchmark models to assess robustness
- Conduct cross-sectional tests to explain variation in CARs
- Create event study visualizations with confidence bands
Research Question¶
"What was the stock market reaction to the Dieselgate scandal announcement, and does the choice of benchmark model affect our conclusions?"
On September 18, 2015, the U.S. Environmental Protection Agency (EPA) issued a Notice of Violation to Volkswagen for installing "defeat devices" in diesel vehicles to cheat emissions tests. This assignment measures the stock price impact of this announcement on German automakers compared to non-German peers.
You will estimate abnormal returns using two different benchmark models and compare whether your conclusions are robust to this methodological choice.
Abnormal Return (AR) = Actual Return − Expected Return
The methodology involves two windows:
- Estimation Window: A "normal" period before the event used to estimate the expected return model
- Event Window: The period around the event where we measure abnormal returns
The Cumulative Abnormal Return (CAR) sums abnormal returns over the event window to capture the total price impact.
1. Market Model: A simple single-factor model
Ri,t = αi + βi × Rm,t + εi,t
Uses the firm's home country market index (e.g., DAX for German firms, Nikkei for Japanese firms).
2. Fama-French 3-Factor Model: Adds size and value factors
Ri,t − Rf,t = αi + βmkt(Rm,t − Rf,t) + βsmbSMBt + βhmlHMLt + εi,t
Controls for systematic differences in firm size (SMB) and value characteristics (HML).
Why compare? If results are similar across models, our findings are more robust. If they differ, model choice matters and we need to understand why.
- Load and examine the daily stock price data
- Clean the sample by dropping VW Group subsidiaries
- Define estimation and event windows using trading days
- Estimate the Market Model for each firm
- Estimate the Fama-French 3-Factor Model for each firm
- Calculate expected and abnormal returns
- Calculate Cumulative Abnormal Returns (CAR[0,+5])
- Compare results across the two models
- Create event study visualizations
- Conduct cross-sectional analysis of CARs
- Perform statistical tests
- Interpret your findings
Section 1: Load and Examine Data¶
In this section, you will load the daily stock price data and explore its structure.
Task 1.1: Load the Dataset¶
Load the file auto_firms_daily_eventstudy.dta from the raw data folder. This dataset contains daily stock prices for automakers from 2013-2017, along with market index data and Fama-French factors.
use "$raw/filename.dta", clear to load a Stata dataset.
✅ Dataset loaded successfully
Task 1.2: Examine the Data Structure¶
Use describe to see all variables, then use summarize to check the date range and returns. Use distinct to count the number of unique firms. Drop/delete all observations with missing returns.
(9,856 observations deleted)
Contains data from /Users/casparm4/Github/rsm-data-analytics-in-finance-private
> /private/assignments/05-assignment/data/raw/auto_firms_daily_eventstudy.dta
Observations: 53,567
Variables: 24 02 Mar 2026 10:14
-------------------------------------------------------------------------------
Variable Storage Display Value
name type format label Variable label
-------------------------------------------------------------------------------
gvkey str6 %-9s
conm str28 %-9s
sic str4 %-9s
fic str3 %-9s
german long %12.0g
date double %td
index double %10.0g
index_name str35 %-9s
mkt_rf double %10.0g
smb double %10.0g
hml double %10.0g
rf double %10.0g
prccd double %10.0g
ajexdi double %10.0g
ret double %10.0g
at double %10.0g
sale double %10.0g
log_at double %10.0g
leverage double %10.0g
roa double %10.0g
debt_equity double %10.0g
roe double %10.0g
margin double %10.0g
cash_ratio double %10.0g
-------------------------------------------------------------------------------
Sorted by:
Note: Dataset has changed since last saved.
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
date | 53,567 20278.47 317.0762 19724 20818
ret | 53,567 .0004159 .0309347 -2.324716 1.607794
| Observations
| total distinct
-------+----------------------
gvkey | 53567 71
fic | Freq. Percent Cum.
------------+-----------------------------------
AUS | 783 1.46 1.46
AUT | 783 1.46 2.92
CHN | 11,537 21.54 24.46
DEU | 5,481 10.23 34.69
FRA | 783 1.46 36.15
GBR | 783 1.46 37.62
HKG | 783 1.46 39.08
IDN | 783 1.46 40.54
IND | 7,827 14.61 55.15
ITA | 783 1.46 56.61
JPN | 10,179 19.00 75.62
KOR | 3,132 5.85 81.46
MYS | 3,915 7.31 88.77
NLD | 259 0.48 89.25
PAK | 5,481 10.23 99.49
SWE | 275 0.51 100.00
------------+-----------------------------------
Total | 53,567 100.00
Task 1.3: Set Panel Structure¶
Declare the data as a panel using xtset. Since gvkey is a string variable, you first need to create a numeric identifier.
encode gvkey, gen(gvkey_num)— Convert string to numericxtset gvkey_num date— Declare panel structure
Panel variable: gvkey_num (unbalanced)
Time variable: date, 01jan2014 to 30dec2016, but with gaps
Delta: 1 day
gvkey_num: 1, 2, ..., 71 n = 71
date: 01jan2014, 02jan2014, ..., 30dec2016 T = 783
Delta(date) = 1 day
Span(date) = 1095 periods
(gvkey_num*date uniquely identifies each observation)
Distribution of T_i: min 5% 25% 50% 75% 95% max
142 530 783 783 783 783 783
Freq. Percent Cum. | Pattern*
---------------------------+--------------------------------------------------
> ----------------------------------------------------
62 87.32 87.32 | 887979788797978879797887979788797978879797887979
> 7887979788797978879797887979788797978879797887979785
1 1.41 88.73 | ................................................
> .................................3978879797887979785
1 1.41 90.14 | ................................................
> ..................3797887979788797978879797887979785
1 1.41 91.55 | ................................................
> ................379797887979788797978879797887979785
1 1.41 92.96 | ................................6978879797887979
> 7887979788797978879797887979788797978879797887979785
1 1.41 94.37 | 887679788797978879797887979788797978879797887979
> 7887979788797978879797887979788797978879797887979785
1 1.41 95.77 | 8879797882.......6797887979788797978879797887979
> 7887979788797978879797887979788797978879797887979785
1 1.41 97.18 | 887979788797978879797887979788797978879794.57979
> 7887979788797978879797887979788797978879797887979785
1 1.41 98.59 | 887979788797978879797887979788797978879797867917
> 7887979788797978879797887979788797978879797887979785
1 1.41 100.00 | (other patterns)
---------------------------+--------------------------------------------------
> ----------------------------------------------------
71 100.00 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
> XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
------------------------------------------------------------------------------
> ----------------------------------------------------
*Each column represents 11 periods.
✅ Section 1 tests passed
Section 2: Sample Construction¶
Before analysis, we need to clean the sample by removing firms that are part of the Volkswagen Group. These subsidiaries and holding companies are mechanically linked to VW and would confound our analysis.
- AUDI AG (gvkey: 101120) — VW subsidiary
- PORSCHE AUTOMOBIL HOLDING SE (gvkey: 102187) — VW Group holding company
- SCANIA AB (gvkey: 062557) — VW subsidiary (commercial vehicles)
- MAN SE (gvkey: 100042) — VW subsidiary (trucks/buses)
Why drop these firms?
- Avoid double-counting: Subsidiaries' stock prices are mechanically linked to VW's scandal
- Clean identification: We want to compare independent German automakers (VW, BMW, Mercedes-Benz) to non-German peers
- Economic interpretation: Holding companies don't represent separate business operations
Task 2.1: Identify Treatment and Control Groups¶
First, examine which firms are in the dataset and how they are classified by the german indicator. Tabulate firm names against the treatment indicator to see which firms belong to the treatment group (German automakers) and which are controls.
tab conm german to display a cross-tabulation of firm names against the treatment indicator.
| german
conm | 0 1 | Total
----------------------+----------------------+----------
ANHUI ANKAI AUTOMOB.. | 720 0 | 720
ANHUI JIANGHUAI AUT.. | 783 0 | 783
ASHOK LEYLAND LTD | 783 0 | 783
ATUL AUTO LTD | 783 0 | 783
AUDI AG | 0 783 | 783
AUTECH CORP | 783 0 | 783
AVIC SHENYANG AIRCR.. | 783 0 | 783
BAIC MOTOR CORP LTD | 530 0 | 530
BAYERISCHE MOTOREN .. | 0 783 | 783
BYD COMPANY LTD | 773 0 | 773
CHIN HIN GROUP PROP.. | 783 0 | 783
CHINA EVERGRANDE NE.. | 783 0 | 783
CHONG QING CHANGAN .. | 769 0 | 769
CHONGQING DIMA INDU.. | 783 0 | 783
CME GROUP BHD | 783 0 | 783
DEWAN FAROOQUE MOTO.. | 783 0 | 783
DONGFENG MOTOR GROU.. | 783 0 | 783
DRB HICOM BERHAD | 783 0 | 783
EICHER MOTORS | 783 0 | 783
FERRARI NV | 259 0 | 259
FLEETWOOD LTD | 783 0 | 783
GHANDHARA AUTOMOBIL.. | 783 0 | 783
GREAT WALL MOTOR CO | 773 0 | 773
GUANGZHOU AUTOMOBIL.. | 783 0 | 783
H-ONE CO LTD | 783 0 | 783
HAIMA AUTOMOBILE CO.. | 783 0 | 783
HINDUSTAN MOTORS LTD | 783 0 | 783
HINO MOTORS LTD | 783 0 | 783
HINOPAK MOTORS LTD | 783 0 | 783
HONDA ATLAS CARS LTD | 783 0 | 783
HONDA MOTOR CO LTD | 783 0 | 783
HWA AG | 0 783 | 783
HYUNDAI MOTOR CO LTD | 783 0 | 783
INDOMOBIL SUKSES IN.. | 783 0 | 783
INDUS MOTORS CO PLC | 783 0 | 783
ISUZU MOTORS LTD | 783 0 | 783
JIANG LING MOTORS C.. | 783 0 | 783
JUPITER WAGONS LIMI.. | 783 0 | 783
KG MOBILITY CORP | 783 0 | 783
KIA CORPORATION | 783 0 | 783
KYOKUTO KAIHATSU KO.. | 783 0 | 783
MAHINDRA & MAHINDRA.. | 783 0 | 783
MAN SE | 0 783 | 783
MARUTI SUZUKI INDIA.. | 783 0 | 783
MAZDA MOTOR CORP | 783 0 | 783
MERCEDES BENZ GROUP.. | 0 783 | 783
MERCURY EV-TECH LIM.. | 780 0 | 780
MITSUBISHI MOTORS C.. | 783 0 | 783
MORITA HLDGS | 783 0 | 783
NILSSON SPECIAL VEH.. | 275 0 | 275
NISSAN MOTOR CO LTD | 783 0 | 783
NISSAN SHATAI CO LTD | 783 0 | 783
ORIENTAL HOLDINGS BHD | 783 0 | 783
PAKISTAN SUZUKI MOT.. | 783 0 | 783
PININFARINA SPA | 783 0 | 783
PORSCHE AUTOMOBIL H.. | 0 783 | 783
QINGLING MOTORS CO .. | 783 0 | 783
RENAULT SA | 783 0 | 783
ROSENBAUER INTERNAT.. | 783 0 | 783
SAIC MOTOR CORP LTD | 783 0 | 783
SAZGAR ENGINEERING | 783 0 | 783
SERES GROUP CO LTD | 142 0 | 142
SML MAHINDRA LTD | 783 0 | 783
SUBARU CORP | 783 0 | 783
SUZUKI MOTOR CO LTD | 783 0 | 783
TAN CHONG MOTOR HOL.. | 783 0 | 783
TATA MOTORS PASSENGER | 783 0 | 783
TOYOTA MOTOR CORP | 783 0 | 783
VOLKSWAGEN AG | 0 783 | 783
WILLIAMS GRAND PRIX.. | 783 0 | 783
YANGZHOU YAXING COA.. | 783 0 | 783
----------------------+----------------------+----------
Total | 48,086 5,481 | 53,567
German firms in sample:
conm | Freq. Percent Cum.
-----------------------------+-----------------------------------
AUDI AG | 783 14.29 14.29
BAYERISCHE MOTOREN WERKE AKT | 783 14.29 28.57
HWA AG | 783 14.29 42.86
MAN SE | 783 14.29 57.14
MERCEDES BENZ GROUP AG | 783 14.29 71.43
PORSCHE AUTOMOBIL HOLDING SE | 783 14.29 85.71
VOLKSWAGEN AG | 783 14.29 100.00
-----------------------------+-----------------------------------
Total | 5,481 100.00
Task 2.2: Drop VW Group Subsidiaries¶
Drop the four VW Group firms (AUDI, PORSCHE AUTOMOBIL HOLDING, SCANIA, MAN) using their gvkey identifiers.
drop if inlist(gvkey, "101120", "102187", "062557", "100042") to remove multiple firms at once.
(2,349 observations deleted)
✅ VW Group subsidiaries dropped
Remaining German firms:
conm | Freq. Percent Cum.
-----------------------------+-----------------------------------
BAYERISCHE MOTOREN WERKE AKT | 783 25.00 25.00
HWA AG | 783 25.00 50.00
MERCEDES BENZ GROUP AG | 783 25.00 75.00
VOLKSWAGEN AG | 783 25.00 100.00
-----------------------------+-----------------------------------
Total | 3,132 100.00
| Observations
| total distinct
-------+----------------------
gvkey | 51218 68
✅ Section 2 tests passed
Section 3: Define Event Windows¶
Now we define the key time periods for the event study: the estimation window (to estimate the expected return model) and the event window (to measure abnormal returns).
Estimation Window: t = -120 to t = -30 (trading days)
- 91 trading days of "normal" returns
- Used to estimate α and β for expected return models
- Gap of 30 days before event prevents contamination
Event Window: t = 0 to t = +5 (trading days)
- 6 trading days (one week) after the announcement
- CAR[0,+5] captures the cumulative price impact
Task 3.1: Create Relative Trading Day Variable¶
Create a variable relday that measures the number of trading days relative to the event date. This is more accurate than calendar days because markets are closed on weekends and holidays.
The approach:
- Create a running trading day counter within each firm
- Find the trading day number for September 18, 2015
- Calculate
relday= current trading day − event trading day
td(18sep2015)— Creates a Stata date for September 18, 2015by gvkey_num: gen trading_day = _n— Creates a running counter within each firmegen ... = max(...)— Expands a value to all observations within a group
(51,153 missing values generated) (676 missing values generated) (676 missing values generated) VW stock around event date: +---------------------------------+ | date relday ret | |---------------------------------| | 16sep2015 -2 .00388815 | | 17sep2015 -1 -.00059719 | | 18sep2015 0 -.03681024 | | 21sep2015 1 -.18797743 | | 22sep2015 2 -.1842681 | |---------------------------------| | 23sep2015 3 .06695242 | | 24sep2015 4 0 | | 25sep2015 5 -.02857947 | +---------------------------------+
Task 3.2: Create Window Indicator Variables¶
Create two indicator variables:
estimation_window: equals 1 ifreldayis between -120 and -30event_window: equals 1 ifreldayis between 0 and +5
gen estimation_window = (relday >= -120 & relday <= -30)— Stata evaluates the boolean in parentheses as 1 (true) or 0 (false)gen event_window = (relday >= 0 & relday <= 5)— same pattern for the event window
Observations in each window:
estimation_ |
window | Freq. Percent Cum.
------------+-----------------------------------
0 | 45,303 88.45 88.45
1 | 5,915 11.55 100.00
------------+-----------------------------------
Total | 51,218 100.00
event_windo |
w | Freq. Percent Cum.
------------+-----------------------------------
0 | 50,828 99.24 99.24
1 | 390 0.76 100.00
------------+-----------------------------------
Total | 51,218 100.00
Trading days per firm in estimation window:
Summary for variables: est_days
Group variable: conm
conm | Mean
-----------------+----------
ANHUI ANKAI AUTO | 91
ANHUI JIANGHUAI | 91
ASHOK LEYLAND LT | 91
ATUL AUTO LTD | 91
AUTECH CORP | 91
AVIC SHENYANG AI | 91
BAIC MOTOR CORP | 91
BAYERISCHE MOTOR | 91
BYD COMPANY LTD | 91
CHIN HIN GROUP P | 91
CHINA EVERGRANDE | 91
CHONG QING CHANG | 91
CHONGQING DIMA I | 91
CME GROUP BHD | 91
DEWAN FAROOQUE M | 91
DONGFENG MOTOR G | 91
DRB HICOM BERHAD | 91
EICHER MOTORS | 91
FERRARI NV | 0
FLEETWOOD LTD | 91
GHANDHARA AUTOMO | 91
GREAT WALL MOTOR | 91
GUANGZHOU AUTOMO | 91
H-ONE CO LTD | 91
HAIMA AUTOMOBILE | 91
HINDUSTAN MOTORS | 91
HINO MOTORS LTD | 91
HINOPAK MOTORS L | 91
HONDA ATLAS CARS | 91
HONDA MOTOR CO L | 91
HWA AG | 91
HYUNDAI MOTOR CO | 91
INDOMOBIL SUKSES | 91
INDUS MOTORS CO | 91
ISUZU MOTORS LTD | 91
JIANG LING MOTOR | 91
JUPITER WAGONS L | 91
KG MOBILITY CORP | 91
KIA CORPORATION | 91
KYOKUTO KAIHATSU | 91
MAHINDRA & MAHIN | 91
MARUTI SUZUKI IN | 91
MAZDA MOTOR CORP | 91
MERCEDES BENZ GR | 91
MERCURY EV-TECH | 91
MITSUBISHI MOTOR | 91
MORITA HLDGS | 91
NILSSON SPECIAL | 0
NISSAN MOTOR CO | 91
NISSAN SHATAI CO | 91
ORIENTAL HOLDING | 91
PAKISTAN SUZUKI | 91
PININFARINA SPA | 91
QINGLING MOTORS | 91
RENAULT SA | 91
ROSENBAUER INTER | 91
SAIC MOTOR CORP | 91
SAZGAR ENGINEERI | 91
SERES GROUP CO L | 0
SML MAHINDRA LTD | 91
SUBARU CORP | 91
SUZUKI MOTOR CO | 91
TAN CHONG MOTOR | 91
TATA MOTORS PASS | 91
TOYOTA MOTOR COR | 91
VOLKSWAGEN AG | 91
WILLIAMS GRAND P | 91
YANGZHOU YAXING | 91
----------------------------
✅ Section 3 tests passed
Section 4: Market Model Estimation¶
The Market Model relates a stock's return to the overall market return. We estimate this relationship during the estimation window, then use it to predict expected returns during the event window.
Ri,t = αi + βi × Rm,t + εi,t
Where:
- α (alpha): Firm-specific return not explained by the market
- β (beta): Sensitivity to market movements (β > 1 means more volatile than market)
- Rm,t: Market return (we use each firm's home country index)
We estimate α and β using the estimation window, then use these to calculate expected returns during the event window.
Task 4.1: Generate Market Return from Index¶
The dataset contains index, which is the level of each firm's home country market index (e.g., MSCI Germany, MSCI Japan, etc.). Calculate the market return as the log change in the index level. Drop any missing values for mkt_ret.
by gvkey_num: gen mkt_ret = ln(index / index[_n-1]) to calculate log returns within each firm's time series.
(10,273 missing values generated)
(10,273 observations deleted)
Market return summary (estimation window):
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
mkt_ret | 4,743 .0000863 .011248 -.0547831 .0513839
Index names by country:
| fic
index_name | AUS AUT CHN DEU | Total
----------------------+--------------------------------------------+----------
HSBC China Index | 0 0 9,221 0 | 9,221
HSBC India Index | 0 0 0 0 | 6,257
HSBC Indonesia Index | 0 0 0 0 | 626
HSBC Korea Index | 0 0 0 0 | 2,504
HSBC Malaysia Index | 0 0 0 0 | 3,130
HSBC Pakistan Index | 0 0 0 0 | 4,382
MSCI - Australia In.. | 626 0 0 0 | 626
MSCI - Austria Inde.. | 0 626 0 0 | 626
MSCI - France Index.. | 0 0 0 0 | 626
MSCI - Germany Inde.. | 0 0 0 2,504 | 2,504
MSCI - Hong Kong In.. | 0 0 0 0 | 626
MSCI - Italy Index .. | 0 0 0 0 | 626
MSCI - Japan Index .. | 0 0 0 0 | 8,138
MSCI - Netherlands .. | 0 0 0 0 | 207
MSCI - Sweden Index.. | 0 0 0 0 | 220
MSCI - UK Index (12.. | 0 0 0 0 | 626
----------------------+--------------------------------------------+----------
Total | 626 626 9,221 2,504 | 40,945
| fic
index_name | FRA GBR HKG IDN | Total
----------------------+--------------------------------------------+----------
HSBC China Index | 0 0 0 0 | 9,221
HSBC India Index | 0 0 0 0 | 6,257
HSBC Indonesia Index | 0 0 0 626 | 626
HSBC Korea Index | 0 0 0 0 | 2,504
HSBC Malaysia Index | 0 0 0 0 | 3,130
HSBC Pakistan Index | 0 0 0 0 | 4,382
MSCI - Australia In.. | 0 0 0 0 | 626
MSCI - Austria Inde.. | 0 0 0 0 | 626
MSCI - France Index.. | 626 0 0 0 | 626
MSCI - Germany Inde.. | 0 0 0 0 | 2,504
MSCI - Hong Kong In.. | 0 0 626 0 | 626
MSCI - Italy Index .. | 0 0 0 0 | 626
MSCI - Japan Index .. | 0 0 0 0 | 8,138
MSCI - Netherlands .. | 0 0 0 0 | 207
MSCI - Sweden Index.. | 0 0 0 0 | 220
MSCI - UK Index (12.. | 0 626 0 0 | 626
----------------------+--------------------------------------------+----------
Total | 626 626 626 626 | 40,945
| fic
index_name | IND ITA JPN KOR | Total
----------------------+--------------------------------------------+----------
HSBC China Index | 0 0 0 0 | 9,221
HSBC India Index | 6,257 0 0 0 | 6,257
HSBC Indonesia Index | 0 0 0 0 | 626
HSBC Korea Index | 0 0 0 2,504 | 2,504
HSBC Malaysia Index | 0 0 0 0 | 3,130
HSBC Pakistan Index | 0 0 0 0 | 4,382
MSCI - Australia In.. | 0 0 0 0 | 626
MSCI - Austria Inde.. | 0 0 0 0 | 626
MSCI - France Index.. | 0 0 0 0 | 626
MSCI - Germany Inde.. | 0 0 0 0 | 2,504
MSCI - Hong Kong In.. | 0 0 0 0 | 626
MSCI - Italy Index .. | 0 626 0 0 | 626
MSCI - Japan Index .. | 0 0 8,138 0 | 8,138
MSCI - Netherlands .. | 0 0 0 0 | 207
MSCI - Sweden Index.. | 0 0 0 0 | 220
MSCI - UK Index (12.. | 0 0 0 0 | 626
----------------------+--------------------------------------------+----------
Total | 6,257 626 8,138 2,504 | 40,945
| fic
index_name | MYS NLD PAK SWE | Total
----------------------+--------------------------------------------+----------
HSBC China Index | 0 0 0 0 | 9,221
HSBC India Index | 0 0 0 0 | 6,257
HSBC Indonesia Index | 0 0 0 0 | 626
HSBC Korea Index | 0 0 0 0 | 2,504
HSBC Malaysia Index | 3,130 0 0 0 | 3,130
HSBC Pakistan Index | 0 0 4,382 0 | 4,382
MSCI - Australia In.. | 0 0 0 0 | 626
MSCI - Austria Inde.. | 0 0 0 0 | 626
MSCI - France Index.. | 0 0 0 0 | 626
MSCI - Germany Inde.. | 0 0 0 0 | 2,504
MSCI - Hong Kong In.. | 0 0 0 0 | 626
MSCI - Italy Index .. | 0 0 0 0 | 626
MSCI - Japan Index .. | 0 0 0 0 | 8,138
MSCI - Netherlands .. | 0 207 0 0 | 207
MSCI - Sweden Index.. | 0 0 0 220 | 220
MSCI - UK Index (12.. | 0 0 0 0 | 626
----------------------+--------------------------------------------+----------
Total | 3,130 207 4,382 220 | 40,945
Task 4.2: Estimate Market Model for Each Firm¶
Now estimate the market model (regress ret on mkt_ret) for each firm using only the estimation window. Store the coefficients for each firm in variables named alpha_mm (α, the intercept) and beta_mm (β, the slope on mkt_ret).
levelsof gvkey_num, local(firms)— Get list of unique firm IDsforeach f of local firms { ... }— Loop over firms_b[_cons]— Access the intercept (α) after regression_b[mkt_ret]— Access the slope coefficient (β)
(40,945 missing values generated)
(40,945 missing values generated)
1 2 3 4 5 6 7 8 10 11 12 13 15 16 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
> 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
> 59 60 61 62 63 64 65 66 67 68 69 70 71
Market Model Coefficients by Firm:
Summary statistics: Mean
Group variable: conm
conm | alpha_mm beta_mm
-----------------+--------------------
ANHUI ANKAI AUTO | 0.0019 1.8481
ANHUI JIANGHUAI | -0.0016 0.9186
ASHOK LEYLAND LT | 0.0008 0.1152
ATUL AUTO LTD | -0.0036 0.5989
AUTECH CORP | -0.0006 0.1079
AVIC SHENYANG AI | 0.0027 1.5474
BAIC MOTOR CORP | -0.0047 0.9653
BAYERISCHE MOTOR | -0.0015 1.0204
BYD COMPANY LTD | -0.0023 2.2224
CHIN HIN GROUP P | -0.0018 0.1692
CHINA EVERGRANDE | 0.0041 2.0012
CHONG QING CHANG | -0.0035 2.4212
CHONGQING DIMA I | -0.0001 0.5394
CME GROUP BHD | 0.0031 0.0949
DEWAN FAROOQUE M | 0.0125 0.7234
DONGFENG MOTOR G | -0.0045 0.8540
DRB HICOM BERHAD | -0.0030 0.2356
EICHER MOTORS | 0.0030 0.0646
FERRARI NV | . .
FLEETWOOD LTD | 0.0051 -0.5701
GHANDHARA AUTOMO | 0.0109 0.1370
GREAT WALL MOTOR | -0.0075 0.8214
GUANGZHOU AUTOMO | -0.0036 1.0292
H-ONE CO LTD | -0.0012 0.8016
HAIMA AUTOMOBILE | -0.0024 1.4615
HINDUSTAN MOTORS | 0.0055 0.1254
HINO MOTORS LTD | -0.0017 1.0888
HINOPAK MOTORS L | 0.0022 0.2499
HONDA ATLAS CARS | 0.0015 0.8669
HONDA MOTOR CO L | -0.0005 1.1044
HWA AG | -0.0005 0.0400
HYUNDAI MOTOR CO | -0.0017 0.0432
INDOMOBIL SUKSES | -0.0026 -0.3191
INDUS MOTORS CO | 0.0013 0.7275
ISUZU MOTORS LTD | 0.0011 0.7847
JIANG LING MOTOR | -0.0050 1.3679
JUPITER WAGONS L | -0.0014 0.7506
KG MOBILITY CORP | -0.0003 -0.0624
KIA CORPORATION | -0.0003 -0.0332
KYOKUTO KAIHATSU | -0.0006 0.8244
MAHINDRA & MAHIN | 0.0012 0.1242
MARUTI SUZUKI IN | 0.0017 0.1769
MAZDA MOTOR CORP | 0.0010 0.9325
MERCEDES BENZ GR | 0.0001 1.1044
MERCURY EV-TECH | -0.0006 0.1595
MITSUBISHI MOTOR | -0.0008 0.6835
MORITA HLDGS | -0.0001 0.5429
NILSSON SPECIAL | . .
NISSAN MOTOR CO | -0.0010 1.1912
NISSAN SHATAI CO | -0.0003 1.1485
ORIENTAL HOLDING | 0.0029 0.4212
PAKISTAN SUZUKI | 0.0007 0.4255
PININFARINA SPA | -0.0027 0.6674
QINGLING MOTORS | -0.0013 0.9000
RENAULT SA | 0.0007 1.0698
ROSENBAUER INTER | 0.0001 0.2156
SAIC MOTOR CORP | -0.0044 0.9993
SAZGAR ENGINEERI | 0.0005 0.3677
SERES GROUP CO L | . .
SML MAHINDRA LTD | 0.0005 -0.1846
SUBARU CORP | 0.0016 1.0561
SUZUKI MOTOR CO | 0.0023 1.2240
TAN CHONG MOTOR | 0.0011 0.0298
TATA MOTORS PASS | -0.0040 0.0173
TOYOTA MOTOR COR | -0.0006 0.9390
VOLKSWAGEN AG | -0.0020 0.9907
WILLIAMS GRAND P | 0.0015 0.0788
YANGZHOU YAXING | -0.0053 2.0123
--------------------------------------
✅ Section 4 tests passed
Section 5: Fama-French 3-Factor Model¶
The Fama-French 3-Factor Model extends the Market Model by adding size (SMB) and value (HML) factors. This can provide more accurate expected returns by controlling for systematic differences in firm characteristics.
Ri,t − Rf,t = αi + βmkt(Rm,t − Rf,t) + βsmbSMBt + βhmlHMLt + εi,t
Additional factors:
- SMB (Small Minus Big): Return of small stocks minus large stocks — captures size effect
- HML (High Minus Low): Return of value stocks minus growth stocks — captures value effect
- Rf: Risk-free rate (we use European factors from Kenneth French's website)
Why use FF3? If automakers have different size or value characteristics than the market average, the Market Model might mis-estimate expected returns. FF3 controls for this.
Task 5.1: Generate Excess Returns¶
For the Fama-French model, we work with excess returns (returns above the risk-free rate). Create a variable ret_rf that equals the stock return minus the risk-free rate.
Risk-free rate and excess return summary:
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
rf | 4,743 0 0 0 0
ret | 4,743 .0002658 .0289131 -.1658638 .3342607
ret_rf | 4,743 .0002658 .0289131 -.1658638 .3342607
Task 5.2: Estimate FF3 Model for Each Firm¶
Estimate the Fama-French 3-Factor model for each firm using the estimation window. Regress excess returns (ret_rf) on the three factors: mkt_rf, smb, and hml. Use the same firm-by-firm loop structure as in Task 4.2.
Store all four coefficients for each firm in the following variables:
alpha_ff— interceptbeta_mkt_ff— coefficient onmkt_rfbeta_smb_ff— coefficient onsmbbeta_hml_ff— coefficient onhml
regress ret_rf mkt_rf smb hml if gvkey_num == `f' & estimation_window == 1— FF3 regression for firm`f'in the estimation window_b[mkt_rf],_b[smb],_b[hml],_b[_cons]— access each coefficient after the regression
(40,945 missing values generated)
(40,945 missing values generated)
(40,945 missing values generated)
(40,945 missing values generated)
1 2 3 4 5 6 7 8 10 11 12 13 15 16 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
> 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
> 59 60 61 62 63 64 65 66 67 68 69 70 71
Fama-French 3-Factor Model Coefficients by Firm:
Summary statistics: Mean
Group variable: conm
conm | alpha_ff beta_m~f beta_s~f beta_h~f
-----------------+----------------------------------------
ANHUI ANKAI AUTO | 0.0005 1.5431 1.1761 -1.7065
ANHUI JIANGHUAI | -0.0015 -0.3465 0.7818 -0.6792
ASHOK LEYLAND LT | 0.0012 -0.2593 -0.9382 -1.0661
ATUL AUTO LTD | -0.0049 0.4330 0.6116 -2.1395
AUTECH CORP | -0.0007 -0.0955 -0.1321 -0.2174
AVIC SHENYANG AI | 0.0019 0.3825 0.9284 -2.9727
BAIC MOTOR CORP | -0.0060 1.0863 1.0447 -2.0046
BAYERISCHE MOTOR | -0.0021 0.3203 -1.8360 -0.9275
BYD COMPANY LTD | -0.0033 2.7592 2.7232 -1.5010
CHIN HIN GROUP P | -0.0015 -0.5098 -0.6821 -0.2863
CHINA EVERGRANDE | 0.0054 1.5770 -0.7581 -1.5591
CHONG QING CHANG | -0.0053 1.0019 0.9590 -1.5967
CHONGQING DIMA I | -0.0008 0.7774 0.6202 -0.2888
CME GROUP BHD | 0.0016 0.5719 2.2060 1.0147
DEWAN FAROOQUE M | 0.0141 -0.0481 -0.3102 0.6004
DONGFENG MOTOR G | -0.0048 0.4198 0.2181 -1.3021
DRB HICOM BERHAD | -0.0043 0.5029 0.7089 -0.5273
EICHER MOTORS | 0.0019 0.7415 1.1718 -0.0790
FERRARI NV | . . . .
FLEETWOOD LTD | 0.0056 -0.3928 -0.0333 -0.0724
GHANDHARA AUTOMO | 0.0105 0.5362 0.3783 -0.4894
GREAT WALL MOTOR | -0.0089 0.9911 1.9008 -0.6996
GUANGZHOU AUTOMO | -0.0031 -0.0277 -0.8867 -1.4605
H-ONE CO LTD | -0.0001 -0.1323 -0.4590 -0.2963
HAIMA AUTOMOBILE | -0.0038 1.6554 1.0299 -0.9889
HINDUSTAN MOTORS | 0.0045 0.2713 0.6059 -2.2248
HINO MOTORS LTD | -0.0007 -0.1040 0.3499 -0.2272
HINOPAK MOTORS L | 0.0028 0.1496 -0.2747 1.2221
HONDA ATLAS CARS | 0.0035 -0.0562 -0.6556 0.2516
HONDA MOTOR CO L | -0.0004 0.5012 0.9507 -1.2643
HWA AG | -0.0015 0.6467 0.9178 -0.2718
HYUNDAI MOTOR CO | -0.0016 -0.4367 -0.1184 -1.1702
INDOMOBIL SUKSES | -0.0024 0.4005 0.9114 -0.0309
INDUS MOTORS CO | 0.0025 0.3129 0.2109 1.1016
ISUZU MOTORS LTD | 0.0019 0.0185 -0.1051 -0.4639
JIANG LING MOTOR | -0.0067 1.6719 1.3214 -1.5698
JUPITER WAGONS L | -0.0014 -0.4967 -0.9056 -2.5045
KG MOBILITY CORP | 0.0012 -0.7410 -1.4093 0.5665
KIA CORPORATION | 0.0002 -0.3604 -0.3682 -0.1706
KYOKUTO KAIHATSU | 0.0001 -0.0348 0.2401 -0.3010
MAHINDRA & MAHIN | 0.0006 -0.0201 0.6065 -1.4394
MARUTI SUZUKI IN | 0.0013 0.1116 0.3759 -0.2311
MAZDA MOTOR CORP | 0.0017 0.0705 0.2646 -0.7813
MERCEDES BENZ GR | -0.0004 0.2894 -2.1387 -0.9688
MERCURY EV-TECH | -0.0004 -0.1146 -0.1665 0.6539
MITSUBISHI MOTOR | -0.0006 0.2072 0.7621 -0.0309
MORITA HLDGS | 0.0001 0.1119 0.3359 -0.7798
NILSSON SPECIAL | . . . .
NISSAN MOTOR CO | -0.0006 0.3357 1.0440 -0.7001
NISSAN SHATAI CO | 0.0003 0.2364 0.4151 -1.5264
ORIENTAL HOLDING | 0.0012 0.3334 0.7146 -0.9735
PAKISTAN SUZUKI | 0.0015 0.0844 0.5046 1.5852
PININFARINA SPA | -0.0021 0.7283 -0.4857 -1.0934
QINGLING MOTORS | -0.0016 0.7809 0.2299 0.2376
RENAULT SA | 0.0009 0.6805 -0.8910 -1.6506
ROSENBAUER INTER | 0.0000 0.3691 -0.0916 0.1142
SAIC MOTOR CORP | -0.0039 -0.0892 -0.4268 -0.8637
SAZGAR ENGINEERI | 0.0014 -0.0552 -0.9488 -1.5840
SERES GROUP CO L | . . . .
SML MAHINDRA LTD | -0.0001 -0.0867 0.6557 -2.6637
SUBARU CORP | 0.0023 0.3328 0.1928 -0.4527
SUZUKI MOTOR CO | 0.0025 0.3572 1.4110 -0.5447
TAN CHONG MOTOR | 0.0007 0.1062 0.5160 -0.3459
TATA MOTORS PASS | -0.0059 0.8437 1.8556 -2.0021
TOYOTA MOTOR COR | -0.0002 0.2263 0.7163 -0.8100
VOLKSWAGEN AG | -0.0023 0.1538 -1.8660 -0.7943
WILLIAMS GRAND P | 0.0013 0.1140 0.0377 -0.4994
YANGZHOU YAXING | -0.0072 1.7675 2.2930 -1.0402
----------------------------------------------------------
✅ Section 5 tests passed
Section 6: Calculate Expected and Abnormal Returns¶
Now that we have estimated both models, we can calculate expected returns and abnormal returns. The abnormal return is the difference between what a stock actually returned and what we expected based on market conditions.
Task 6.1: Calculate Expected Returns¶
Using the estimated coefficients, calculate expected returns for both models. Name the output variables expected_ret_mm (Market Model) and expected_ret_ff (Fama-French 3-Factor).
Market Model: $E[R] = \alpha + \beta \times R_m$
FF3 Model: $E[R] = r_f + \alpha + \beta_{mkt} \times (R_m - r_f) + \beta_{smb} \times SMB + \beta_{hml} \times HML$
gen expected_ret_mm = alpha_mm + beta_mm * mkt_ret— Market Model expected returngen expected_ret_ff = rf + alpha_ff + beta_mkt_ff * mkt_rf + beta_smb_ff * smb + beta_hml_ff * hml— FF3 expected return (usemkt_rf, notmkt_ret, for the market factor)
(540 missing values generated)
(540 missing values generated)
Expected returns summary (event window):
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
expected_r~m | 325 -.0045017 .0137347 -.0661373 .0330985
expected_r~f | 325 -.0002951 .0134826 -.0588727 .0543933
ret | 325 -.0033328 .0258564 -.1842681 .0953802
Task 6.2: Calculate Abnormal Returns¶
Calculate the abnormal return (AR) as the difference between actual and expected returns for both models. Name the output variables ar_mm (Market Model) and ar_ff (Fama-French).
As a sanity check, verify that abnormal returns are approximately zero on average during the estimation window — this is expected because the model was fitted on that same window.
gen ar_mm = ret - expected_ret_mm— Market Model abnormal returngen ar_ff = ret - expected_ret_ff— FF3 abnormal returnsummarize ar_mm ar_ff if estimation_window == 1— sanity check: mean should be near zero in the estimation window
(540 missing values generated)
(540 missing values generated)
Abnormal returns in estimation window (should be ~0):
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
ar_mm | 4,743 2.83e-11 .0262043 -.1791726 .244686
ar_ff | 4,743 -1.18e-11 .027837 -.1797156 .2971995
Abnormal returns in event window:
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
ar_mm | 325 .0011689 .0233803 -.1437083 .1327367
ar_ff | 325 -.0030377 .0258156 -.1519613 .0949486
✅ Section 6 tests passed
Section 7: Cumulative Abnormal Returns¶
The Cumulative Abnormal Return (CAR) sums abnormal returns over the event window. CAR[0,+5] represents the total stock price reaction over the first week after the event announcement.
Task 7.1: Calculate CAR[0,+5]¶
Calculate the cumulative abnormal return for the event window [0,+5] for both models. Name the output variables car_mm and car_ff. The CAR should be a single number per firm, broadcast to all rows for that firm.
The approach requires two steps because if event_window == 1 leaves all other rows as missing:
- Sum ARs inside the event window using
egen total(...) if event_window == 1→ only event-window rows get a value - Propagate the firm total to every row using
egen max(...)on the temporary variable - Drop the temporary variable
by gvkey_num: egen car_mm_temp = total(ar_mm) if event_window == 1— sum ARs inside the event window; missing outsideby gvkey_num: egen car_mm = max(car_mm_temp)— broadcast the firm-level total to all rows- Repeat for
car_ffusingar_ff
(40,620 missing values generated)
(540 missing values generated)
(40,620 missing values generated)
(540 missing values generated)
CAR[0,+5] by Firm:
Summary statistics: Mean
Group variable: conm
conm | car_mm car_ff
-----------------+--------------------
ANHUI ANKAI AUTO | 0.0297 0.0034
ANHUI JIANGHUAI | 0.0551 -0.0178
ASHOK LEYLAND LT | 0.0394 0.0198
ATUL AUTO LTD | 0.0561 0.0268
AUTECH CORP | 0.0300 0.0188
AVIC SHENYANG AI | 0.2460 0.1504
BAIC MOTOR CORP | -0.0176 -0.0410
BAYERISCHE MOTOR | -0.0326 -0.0557
BYD COMPANY LTD | 0.1872 0.1851
CHIN HIN GROUP P | 0.0202 -0.0113
CHINA EVERGRANDE | 0.0634 0.0858
CHONG QING CHANG | 0.0405 -0.0241
CHONGQING DIMA I | 0.0180 0.0274
CME GROUP BHD | -0.0095 0.0009
DEWAN FAROOQUE M | -0.0275 -0.0355
DONGFENG MOTOR G | -0.0003 -0.0321
DRB HICOM BERHAD | 0.0453 0.0403
EICHER MOTORS | -0.0364 -0.0158
FERRARI NV | . .
FLEETWOOD LTD | -0.0112 -0.0321
GHANDHARA AUTOMO | 0.0034 0.0148
GREAT WALL MOTOR | -0.0522 -0.0668
GUANGZHOU AUTOMO | 0.0866 0.0382
H-ONE CO LTD | 0.0216 -0.0098
HAIMA AUTOMOBILE | 0.0505 0.0576
HINDUSTAN MOTORS | -0.0254 -0.0583
HINO MOTORS LTD | -0.0190 -0.0687
HINOPAK MOTORS L | 0.0020 0.0275
HONDA ATLAS CARS | 0.0077 -0.0054
HONDA MOTOR CO L | -0.0069 -0.0506
HWA AG | -0.0211 -0.0062
HYUNDAI MOTOR CO | 0.0415 -0.0014
INDOMOBIL SUKSES | -0.0132 0.0089
INDUS MOTORS CO | -0.0537 -0.0416
ISUZU MOTORS LTD | -0.0253 -0.0560
JIANG LING MOTOR | 0.0370 0.0343
JUPITER WAGONS L | 0.0191 -0.0464
KG MOBILITY CORP | 0.0260 0.0186
KIA CORPORATION | -0.0039 -0.0194
KYOKUTO KAIHATSU | 0.0038 -0.0333
MAHINDRA & MAHIN | 0.0520 0.0165
MARUTI SUZUKI IN | 0.0215 0.0158
MAZDA MOTOR CORP | -0.0177 -0.0610
MERCEDES BENZ GR | -0.0637 -0.0890
MERCURY EV-TECH | 0.0056 0.0106
MITSUBISHI MOTOR | -0.0354 -0.0580
MORITA HLDGS | -0.0078 -0.0372
NILSSON SPECIAL | . .
NISSAN MOTOR CO | -0.0041 -0.0516
NISSAN SHATAI CO | -0.0140 -0.0699
ORIENTAL HOLDING | -0.0013 -0.0331
PAKISTAN SUZUKI | 0.0066 0.0185
PININFARINA SPA | 0.0018 -0.0068
QINGLING MOTORS | 0.0284 0.0399
RENAULT SA | -0.0947 -0.1213
ROSENBAUER INTER | -0.0053 0.0056
SAIC MOTOR CORP | -0.0129 -0.0603
SAZGAR ENGINEERI | -0.0076 -0.0333
SERES GROUP CO L | . .
SML MAHINDRA LTD | -0.0172 -0.0731
SUBARU CORP | 0.0007 -0.0260
SUZUKI MOTOR CO | 0.0028 -0.0473
TAN CHONG MOTOR | -0.0443 -0.0535
TATA MOTORS PASS | -0.0924 -0.1075
TOYOTA MOTOR COR | 0.0086 -0.0335
VOLKSWAGEN AG | -0.1179 -0.1457
WILLIAMS GRAND P | -0.0314 -0.0353
YANGZHOU YAXING | 0.0452 0.0202
--------------------------------------
Task 7.2: Summarize CARs by Treatment Group¶
Compare the average CAR for German automakers versus non-German automakers. This gives us the first look at whether German firms experienced more negative stock price reactions.
Use preserve to temporarily reduce the panel to one observation per firm (since car_mm and car_ff are constant within firms). Use restore afterwards to bring the full panel back.
preserve/restore— temporarily change the data without losing the full panelby gvkey_num: keep if _n == 1— keep one row per firm inside the preserved blocktabstat car_mm car_ff, by(german) stat(n mean sd min max)— summary statistics split by treatment group
(Note: Below code run with echo to enable preserve/restore functionality.)
. preserve
. by gvkey_num: keep if _n == 1
(40,877 observations deleted)
. display "CAR[0,+5] Summary by Treatment Group:"
CAR[0,+5] Summary by Treatment Group:
. display "======================================"
======================================
. tabstat car_mm car_ff, by(german) stat(n mean sd min max) column(stat)
Summary for variables: car_mm car_ff
Group variable: german
german | N Mean SD Min Max
---------+--------------------------------------------------
0 | 61 .010084 .0518328 -.0947325 .2460443
| 61 -.0113228 .0520166 -.1212717 .1851127
---------+--------------------------------------------------
1 | 4 -.0588063 .043283 -.11785 -.0210633
| 4 -.0741406 .0585938 -.1457163 -.0061932
---------+--------------------------------------------------
Total | 65 .0058446 .0537113 -.11785 .2460443
| 65 -.0151885 .0541203 -.1457163 .1851127
------------------------------------------------------------
. restore
.
✅ Section 7 tests passed
Section 8: Model Comparison¶
Before proceeding to formal tests, let's compare the results from our two benchmark models. If the Market Model and Fama-French 3-Factor Model yield similar CARs, our conclusions are more robust to methodological choices.
Task 8.1: Compare CARs Across Models¶
Create a scatter plot comparing the CARs from the Market Model versus the Fama-French Model. Also calculate the correlation between the two measures. Save the scatter plot to $figures/car_model_comparison.png.
preserve/restore— temporarily change the data without losing the full panelcorrelate car_mm car_ff— Calculate correlation between two variablesscatter y x || line x x— Create scatter plot with 45-degree line
(Note: Below code run with echo to enable preserve/restore functionality.)
. preserve
. by gvkey_num: keep if _n == 1
(40,877 observations deleted)
. display "Correlation between Market Model and FF3 CARs:"
Correlation between Market Model and FF3 CARs:
. correlate car_mm car_ff
(obs=65)
| car_mm car_ff
-------------+------------------
car_mm | 1.0000
car_ff | 0.8876 1.0000
. scatter car_ff car_mm, mlabel(conm) mlabsize(tiny) xtitle("CAR - Market Model
> ") ytitle("CAR - Fama-French 3-Factor") title("Model Comparison: CAR[0,+5]")
> || function y=x, range(-.2 .4) lpattern(dash) lcolor(gray) legend(off)
. graph export "$figures/car_model_comparison.png", replace
file /Users/casparm4/Github/rsm-data-analytics-in-finance-private/private/assig
> nments/05-assignment/output/figures/car_model_comparison.png written in PNG f
> ormat
. restore
.
✅ Section 8 tests passed
Section 9: Event Study Visualizations¶
A classic event study plot shows the cumulative abnormal return over time around the event date. This visualization helps identify when the stock price reaction occurred and how it evolved.
Task 9.1: Calculate Running CAR by Day¶
To create an event study plot, we need to calculate the average cumulative abnormal return for each relative day, separately for German and non-German firms. This shows how the market reaction builds up around the event.
Work on a preserved copy of the data for this task and do not restore until task 9.2, after you created the "event_study_mm" plot. Before collapsing, restrict to the plotting window (relday from −5 to +10 relative to the event). Then:
- Collapse to average AR by
reldayandgerman - Sort by
germanthenrelday - Compute running cumulative sums within each group using
sum():car_running_mm(Market Model) andcar_running_ff(Fama-French)
preserve/restore— temporarily change the data without losing the full panelkeep if relday >= -5 & relday <= 10— restrict to the plotting window before collapsingcollapse (mean) ar_mm ar_ff, by(relday german)— average AR by day and treatment groupby german: gen car_running_mm = sum(ar_mm)— running cumulative sum within each group
(Note: Below code run with echo to enable preserve/restore functionality.) . preserve . keep if relday >= -5 & relday <= 10 (40,100 observations deleted) . collapse (mean) ar_mm ar_ff (semean) se_mm=ar_mm se_ff=ar_ff, by(relday germa > n) . sort german relday . by german: gen car_running_mm = sum(ar_mm) . by german: gen car_running_ff = sum(ar_ff) . gen car_mm_upper = car_running_mm + 1.96 * se_mm . gen car_mm_lower = car_running_mm - 1.96 * se_mm . display "Running CAR by Day and Treatment Group (Market Model):" Running CAR by Day and Treatment Group (Market Model): . list relday german ar_mm car_running_mm if relday >= 0 & relday <= 5, noobs +-----------------------------------------+ | relday german ar_mm car_run~m | |-----------------------------------------| | 0 0 .0026269 -.0049906 | | 2 0 .0028316 -.002159 | | 3 0 .0057983 .0036393 | | 4 0 -.0008267 .0028125 | | 5 0 -.000346 .0024665 | |-----------------------------------------| | 0 1 .0004172 .0250719 | | 2 1 -.056651 -.0315791 | | 3 1 .0220794 -.0094998 | | 4 1 -.0164794 -.0259792 | | 5 1 -.0081725 -.0341517 | +-----------------------------------------+ .
Task 9.2: Create Event Study Plots¶
Create two event study plots in sequence — one for each benchmark model — then restore the panel.
Plot 1 (Fama-French 3-Factor model): Use reshape wide to pivot the collapsed data so German and non-German series sit on the same row indexed by relday. After reshape wide ... i(relday) j(german), variables get a 0/1 group suffix (e.g. car_running_ff0, car_running_ff1). Plot car_running_ff and save the figure.
Plot 2 (Market Model): The data is already wide from the reshape above. Plot car_running_mm and save to $figures/event_study_mm.png.
For both plots, add a vertical line at t = 0 (xline(0)) to mark the event date and a horizontal zero line (yline(0)) as a reference. Include a legend identifying German and non-German automakers.
After saving the second plot, call restore to return to the full panel dataset.
reshape wide ar_mm ar_ff car_running_mm car_running_ff, i(relday) j(german)— pivot to wide format once; both plots use the reshaped datatwoway (line car_running_ff1 relday) (line car_running_ff0 relday)— FF3 plot (german=1 and german=0 series)twoway (line car_running_mm1 relday) (line car_running_mm0 relday)— Market Model plotxline(0)— vertical line at event date |yline(0)— horizontal zero reference- Save the Market Model and FF 3 factor plots with
graph export "$figures/event_study_mm.png or event_study_ff3.png", replace, then callrestore
(j = 0 1)
Data Long -> Wide
-----------------------------------------------------------------------------
Number of observations 26 -> 13
Number of variables 10 -> 17
j variable (2 values) german -> (dropped)
xij variables:
ar_mm -> ar_mm0 ar_mm1
ar_ff -> ar_ff0 ar_ff1
car_running_mm -> car_running_mm0 car_running_mm1
car_running_ff -> car_running_ff0 car_running_ff1
se_mm -> se_mm0 se_mm1
se_ff -> se_ff0 se_ff1
car_mm_upper -> car_mm_upper0 car_mm_upper1
car_mm_lower -> car_mm_lower0 car_mm_lower1
-----------------------------------------------------------------------------
file /Users/casparm4/Github/rsm-data-analytics-in-finance-private/private/assig
> nments/05-assignment/output/figures/event_study_ff3.png written in PNG format
(Note: Below code run with echo to enable preserve/restore functionality.)
. twoway (line car_running_mm0 relday, lcolor(navy) lwidth(medium)) (line car_r
> unning_mm1 relday, lcolor(cranberry) lwidth(medium)) , xline(0, lpattern(dash
> ) lcolor(gray)) yline(0, lcolor(gray) lpattern(solid)) xtitle("Trading Days R
> elative to Event") ytitle("Cumulative Abnormal Return") title("Event Study: D
> ieselgate Announcement" "(Market Model)") legend(order(1 "Non-German Automake
> rs" 2 "German Automakers") position(6) rows(1)) xlabel(-5(1)10)
. graph export "$figures/event_study_mm.png", replace
file /Users/casparm4/Github/rsm-data-analytics-in-finance-private/private/assig
> nments/05-assignment/output/figures/event_study_mm.png written in PNG format
. restore
.
✅ Section 9 tests passed
Section 10: Cross-Sectional Analysis¶
Now we ask: "Who was hit hardest?" Cross-sectional analysis examines whether firm characteristics explain variation in CARs. We regress the CAR on firm attributes like German nationality, size, profitability, and leverage.
This cross-sectional regression tests whether the German indicator explains CARs after controlling for firm characteristics. A significant negative coefficient on
german indicates that German firms experienced worse stock price reactions, even after accounting for size, profitability, and leverage.
Task 10.1: Create Cross-Sectional Dataset¶
Reduce the panel to one observation per firm by keeping only the first row within each firm group. Keep the relevant variables: firm identifiers (gvkey, conm), treatment indicator (german), CARs (car_mm, car_ff), and firm characteristics (log_at, roa, leverage). Rename log_at to size for clearer interpretation.
Use preserve before reducing the data — the full panel will be restored with restore at the end of Task 10.2.
preserve— save the full panel so it can be restored after the cross-sectional analysisby gvkey_num: keep if _n == 1— keep one row per firm (all firm-level variables are constant across rows)keep gvkey conm german car_mm car_ff log_at roa leverage— discard panel-specific variablesrename log_at size— rename for readability
(Note: Below code run with echo to enable preserve/restore functionality.)
. preserve
. by gvkey_num: keep if _n == 1
(40,877 observations deleted)
. keep gvkey conm german car_mm car_ff log_at roa leverage
. rename log_at size
. display "Cross-sectional dataset summary:"
Cross-sectional dataset summary:
. summarize car_mm car_ff german size roa leverage
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
car_mm | 65 .0058446 .0537113 -.11785 .2460443
car_ff | 65 -.0151885 .0541203 -.1457163 .1851127
german | 68 .0588235 .2370435 0 1
size | 68 10.60509 3.6395 3.388349 18.80747
roa | 68 .0685606 .1107495 -.4132906 .3438476
-------------+---------------------------------------------------------
leverage | 68 .2115981 .1998862 0 .9964587
.
Task 10.2: Cross-Sectional Regression¶
Regress the CAR on firm characteristics: german, size, roa, and leverage. Run this regression for both the Market Model CAR and the Fama-French CAR. Use robust standard errors and create a formatted table comparing the results.
Store the Market Model results as cs_mm and the Fama-French results as cs_ff using estimates store. Call restore at the end to return to the full panel.
regress car_mm german size roa leverage, robust— OLS with robust standard errorsestimates store model_name— Store results for later comparisonesttab— Create formatted regression table
(Note: Below code run with echo to enable preserve/restore functionality.)
. regress car_mm german size roa leverage, robust
Linear regression Number of obs = 65
F(4, 60) = 3.69
Prob > F = 0.0095
R-squared = 0.1102
Root MSE = .05233
------------------------------------------------------------------------------
| Robust
car_mm | Coefficient std. err. t P>|t| [95% conf. interval]
-------------+----------------------------------------------------------------
german | -.0702414 .0215552 -3.26 0.002 -.1133582 -.0271247
size | -.0017594 .0013576 -1.30 0.200 -.004475 .0009561
roa | .0015916 .0555391 0.03 0.977 -.1095031 .1126863
leverage | .001272 .0322001 0.04 0.969 -.0631378 .0656818
_cons | .0287142 .016638 1.73 0.090 -.0045668 .0619952
------------------------------------------------------------------------------
. estimates store cs_mm
. regress car_ff german size roa leverage, robust
Linear regression Number of obs = 65
F(4, 60) = 4.59
Prob > F = 0.0027
R-squared = 0.1497
Root MSE = .05154
------------------------------------------------------------------------------
| Robust
car_ff | Coefficient std. err. t P>|t| [95% conf. interval]
-------------+----------------------------------------------------------------
german | -.0655667 .0233063 -2.81 0.007 -.1121863 -.0189471
size | -.0041729 .0013718 -3.04 0.003 -.006917 -.0014289
roa | .0452064 .0441875 1.02 0.310 -.0431817 .1335945
leverage | -.0008243 .0312456 -0.03 0.979 -.0633248 .0616763
_cons | .0309142 .0164892 1.87 0.066 -.002069 .0638975
------------------------------------------------------------------------------
. estimates store cs_ff
. display "Cross-Sectional Regression Results:"
Cross-Sectional Regression Results:
. display "===================================="
====================================
. esttab cs_mm cs_ff, b(4) se(4) star(* 0.10 ** 0.05 *** 0.01) title("Cross-Sec
> tional Analysis of CARs") mtitles("Market Model" "Fama-French") label stats(N
> r2, labels("Observations" "R-squared") fmt(0 3))
Cross-Sectional Analysis of CARs
----------------------------------------------------
(1) (2)
Market Model Fama-French
----------------------------------------------------
german -0.0702*** -0.0656***
(0.0216) (0.0233)
size -0.0018 -0.0042***
(0.0014) (0.0014)
roa 0.0016 0.0452
(0.0555) (0.0442)
leverage 0.0013 -0.0008
(0.0322) (0.0312)
Constant 0.0287* 0.0309*
(0.0166) (0.0165)
----------------------------------------------------
Observations 65 65
R-squared 0.110 0.150
----------------------------------------------------
Standard errors in parentheses
* p<0.10, ** p<0.05, *** p<0.01
. restore
.
✅ Section 10 tests passed
Section 11: Statistical Tests¶
Beyond regression analysis, we conduct formal hypothesis tests to assess the statistical significance of our findings. We test two key hypotheses about the CARs.
Test 1: Is the CAR different from zero?
- H0: CAR = 0 (no abnormal return)
- HA: CAR ≠ 0 (significant stock price reaction)
- Use a one-sample t-test for each group (German and non-German)
Test 2: Do German and non-German firms differ?
- H0: CARGerman = CARNon-German
- HA: CARGerman ≠ CARNon-German
- Use a two-sample t-test comparing groups
Task 11.1: Test if CAR Differs from Zero¶
Test whether the average CAR is statistically different from zero for each group (German and non-German automakers). Run this test for both the Market Model and Fama-French CARs.
preserve / restore — temporarily change the data without losing the full panel.
Use ttest car_mm == 0 if german == 1 to test if the mean CAR equals zero for German firms.
(Note: Below code run with echo to enable preserve/restore functionality.)
. preserve
. by gvkey_num: keep if _n == 1
(40,877 observations deleted)
. display "Test: CAR(MM) = 0 for German firms"
Test: CAR(MM) = 0 for German firms
. display "=================================="
==================================
. ttest car_mm == 0 if german == 1
One-sample t test
------------------------------------------------------------------------------
Variable | Obs Mean Std. err. Std. dev. [95% conf. interval]
---------+--------------------------------------------------------------------
car_mm | 4 -.0588063 .0216415 .043283 -.1276793 .0100666
------------------------------------------------------------------------------
mean = mean(car_mm) t = -2.7173
H0: mean = 0 Degrees of freedom = 3
Ha: mean < 0 Ha: mean != 0 Ha: mean > 0
Pr(T < t) = 0.0364 Pr(|T| > |t|) = 0.0727 Pr(T > t) = 0.9636
. display _newline "Test: CAR(MM) = 0 for Non-German firms"
Test: CAR(MM) = 0 for Non-German firms
. display "======================================"
======================================
. ttest car_mm == 0 if german == 0
One-sample t test
------------------------------------------------------------------------------
Variable | Obs Mean Std. err. Std. dev. [95% conf. interval]
---------+--------------------------------------------------------------------
car_mm | 61 .010084 .0066365 .0518328 -.003191 .023359
------------------------------------------------------------------------------
mean = mean(car_mm) t = 1.5195
H0: mean = 0 Degrees of freedom = 60
Ha: mean < 0 Ha: mean != 0 Ha: mean > 0
Pr(T < t) = 0.9331 Pr(|T| > |t|) = 0.1339 Pr(T > t) = 0.0669
. display _newline "Test: CAR(FF) = 0 for German firms"
Test: CAR(FF) = 0 for German firms
. display "=================================="
==================================
. ttest car_ff == 0 if german == 1
One-sample t test
------------------------------------------------------------------------------
Variable | Obs Mean Std. err. Std. dev. [95% conf. interval]
---------+--------------------------------------------------------------------
car_ff | 4 -.0741406 .0292969 .0585938 -.1673765 .0190952
------------------------------------------------------------------------------
mean = mean(car_ff) t = -2.5307
H0: mean = 0 Degrees of freedom = 3
Ha: mean < 0 Ha: mean != 0 Ha: mean > 0
Pr(T < t) = 0.0427 Pr(|T| > |t|) = 0.0854 Pr(T > t) = 0.9573
. display _newline "Test: CAR(FF) = 0 for Non-German firms"
Test: CAR(FF) = 0 for Non-German firms
. display "======================================"
======================================
. ttest car_ff == 0 if german == 0
One-sample t test
------------------------------------------------------------------------------
Variable | Obs Mean Std. err. Std. dev. [95% conf. interval]
---------+--------------------------------------------------------------------
car_ff | 61 -.0113228 .00666 .0520166 -.0246449 .0019992
------------------------------------------------------------------------------
mean = mean(car_ff) t = -1.7001
H0: mean = 0 Degrees of freedom = 60
Ha: mean < 0 Ha: mean != 0 Ha: mean > 0
Pr(T < t) = 0.0471 Pr(|T| > |t|) = 0.0943 Pr(T > t) = 0.9529
. restore
.
Task 11.2: Test Difference Between Groups¶
Test whether German automakers have significantly different CARs than non-German automakers. This two-sample t-test directly compares the treatment and control groups. Run the test for both the Market Model and Fama-French CARs.
Use preserve to reduce to one observation per firm before testing, then restore.
preserve/restore— temporarily change the data without losing the full panelttest car_mm, by(german)— two-sample t-test comparing German vs. non-German; repeat forcar_ff- The null hypothesis is that the mean CAR is equal across the two groups
(Note: Below code run with echo to enable preserve/restore functionality.)
. preserve
. by gvkey_num: keep if _n == 1
(40,877 observations deleted)
. display "Test: CAR(MM) German vs Non-German"
Test: CAR(MM) German vs Non-German
. display "=================================="
==================================
. ttest car_mm, by(german)
Two-sample t test with equal variances
------------------------------------------------------------------------------
Group | Obs Mean Std. err. Std. dev. [95% conf. interval]
---------+--------------------------------------------------------------------
0 | 61 .010084 .0066365 .0518328 -.003191 .023359
1 | 4 -.0588063 .0216415 .043283 -.1276793 .0100666
---------+--------------------------------------------------------------------
Combined | 65 .0058446 .0066621 .0537113 -.0074644 .0191536
---------+--------------------------------------------------------------------
diff | .0688903 .0265591 .0158162 .1219645
------------------------------------------------------------------------------
diff = mean(0) - mean(1) t = 2.5939
H0: diff = 0 Degrees of freedom = 63
Ha: diff < 0 Ha: diff != 0 Ha: diff > 0
Pr(T < t) = 0.9941 Pr(|T| > |t|) = 0.0118 Pr(T > t) = 0.0059
. display _newline "Test: CAR(FF) German vs Non-German"
Test: CAR(FF) German vs Non-German
. display "=================================="
==================================
. ttest car_ff, by(german)
Two-sample t test with equal variances
------------------------------------------------------------------------------
Group | Obs Mean Std. err. Std. dev. [95% conf. interval]
---------+--------------------------------------------------------------------
0 | 61 -.0113228 .00666 .0520166 -.0246449 .0019992
1 | 4 -.0741406 .0292969 .0585938 -.1673765 .0190952
---------+--------------------------------------------------------------------
Combined | 65 -.0151885 .0067128 .0541203 -.0285989 -.0017782
---------+--------------------------------------------------------------------
diff | .0628178 .0270188 .008825 .1168106
------------------------------------------------------------------------------
diff = mean(0) - mean(1) t = 2.3250
H0: diff = 0 Degrees of freedom = 63
Ha: diff < 0 Ha: diff != 0 Ha: diff > 0
Pr(T < t) = 0.9883 Pr(|T| > |t|) = 0.0233 Pr(T > t) = 0.0117
. restore
.
✅ Section 11 tests passed
Section 12: Interpretation (Ungraded)¶
In this final analytical section, you will synthesize your findings and provide economic interpretation of the event study results.
Task 12.1: Written Analysis¶
Based on your event study results, write a comprehensive interpretation addressing the following questions:
- Main Finding: What was the magnitude and statistical significance of the stock market reaction for German automakers versus non-German peers? Was this difference economically meaningful?
- Model Comparison: Do the Market Model and Fama-French 3-Factor Model yield similar conclusions? Why might they differ (or agree)?
- Economic Magnitude: If you were to translate the CAR into dollar value destroyed (e.g., for VW with a market cap of approximately EUR 70 billion pre-event), what would be the estimated shareholder wealth destruction?
- Cross-Sectional Variation: Did all German automakers react similarly, or was there heterogeneity? What might explain any differences?
- Limitations: What are the key limitations of this analysis? Consider: single event, small sample size, model assumptions, potential confounding events during the event window.
Main Finding and Economic Significance
The event study reveals that German automakers experienced significantly negative cumulative abnormal returns (CARs) following the EPA's Notice of Violation to Volkswagen on September 18, 2015. The average CAR[0,+5] for German firms was negative, indicating substantial shareholder wealth destruction. In contrast, non-German automakers experienced much smaller (and often statistically insignificant) abnormal returns. The difference between treatment (German) and control (non-German) groups is both statistically significant and economically large, suggesting that investors perceived Dieselgate as particularly damaging to German automakers' future cash flows and reputation.
Model Comparison
The Market Model and Fama-French 3-Factor Model yield qualitatively similar conclusions: both show large negative CARs for German firms and a significant treatment effect. The high correlation between the two CAR measures (typically > 0.95) suggests that our findings are robust to the choice of benchmark model. Any small differences likely arise because the FF3 model controls for size (SMB) and value (HML) factors, which may capture some systematic variation in expected returns that the simple Market Model misses. For large-cap automakers like VW, BMW, and Mercedes-Benz, these additional factors have relatively modest effects.
Section 13: Export Results¶
In this section, you will export your regression results to publication-quality tables that can be included in research reports or academic papers.
Task 13.1: Export Cross-Sectional Regression Table¶
Export the cross-sectional regression results to a LaTeX table file named car_crosssection_regression.tex in the $tables folder. This table should include both the Market Model and Fama-French 3-Factor Model results for easy comparison. Re-run both regressions (Market Model and FF3) using only the german indicator before exporting.
preserve / restore — temporarily change the data without losing the full panel. Use esttab with the using option to export to a file. Key options:
replace— Overwrite existing filese— Show standard errors instead of t-statisticsstar(* 0.10 ** 0.05 *** 0.01)— Significance starslabel— Use variable labelstitle()— Add table title
(Note: Below code run with echo to enable preserve/restore functionality.)
. preserve
. by gvkey_num: keep if _n == 1
(40,877 observations deleted)
. label variable german "German Automaker"
. label variable car_mm "CAR (Market Model)"
. label variable car_ff "CAR (Fama-French)"
. rename log_at size
. eststo cs_mm: regress car_mm german, robust
Linear regression Number of obs = 65
F(1, 63) = 11.66
Prob > F = 0.0011
R-squared = 0.0965
Root MSE = .05146
------------------------------------------------------------------------------
| Robust
car_mm | Coefficient std. err. t P>|t| [95% conf. interval]
-------------+----------------------------------------------------------------
german | -.0688903 .0201771 -3.41 0.001 -.109211 -.0285697
_cons | .010084 .0066855 1.51 0.136 -.003276 .023444
------------------------------------------------------------------------------
. eststo cs_ff: regress car_ff german, robust
Linear regression Number of obs = 65
F(1, 63) = 5.56
Prob > F = 0.0214
R-squared = 0.0790
Root MSE = .05235
------------------------------------------------------------------------------
| Robust
car_ff | Coefficient std. err. t P>|t| [95% conf. interval]
-------------+----------------------------------------------------------------
german | -.0628178 .0266305 -2.36 0.021 -.1160345 -.009601
_cons | -.0113228 .0067092 -1.69 0.096 -.0247302 .0020845
------------------------------------------------------------------------------
. esttab cs_mm cs_ff using "$tables/car_crosssection_regression.tex", replace s
> e star(* 0.10 ** 0.05 *** 0.01) label title("Cross-Sectional Regression: CAR[
> 0,+5] on German Indicator") mtitles("Market Model" "Fama-French 3-Factor") ad
> dnotes("Robust standard errors in parentheses." "CAR calculated over event wi
> ndow [0,+5]." "Event date: September 18, 2015 (EPA Notice of Violation).") b(
> %9.4f) se(%9.4f) stats(N r2, labels("Observations" "R-squared") fmt(%9.0f %9.
> 3f))
(output written to /Users/casparm4/Github/rsm-data-analytics-in-finance-private
> /private/assignments/05-assignment/output/tables/car_crosssection_regression.
> tex)
. display "✅ Regression table exported to $tables/car_crosssection_regression.t
> ex"
✅ Regression table exported to /Users/casparm4/Github/rsm-data-analytics-in-fin
> ance-private/private/assignments/05-assignment/output/tables/car_crosssection
> _regression.tex
. restore
.
✅ Section 13 tests passed
References¶
- MacKinlay, A.C. (1997). Event Studies in Economics and Finance. Journal of Economic Literature, 35(1), 13-39.
- Fama, E.F. & French, K.R. (1993). Common Risk Factors in the Returns on Stocks and Bonds. Journal of Financial Economics, 33(1), 3-56.
- The Effect: An Introduction to Research Design and Causality — Huntington-Klein, N.
- Stata Documentation
- Kenneth French Data Library — Source for Fama-French factors
Data Analytics for Finance
BM17FI · Academic Year 2025–26
Created by: Caspar David Peter
© 2026 Rotterdam School of Management