---
title: "Getting Started with EventStudy"
author: "Simon Mueller"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Introduction to EventStudy}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  eval = TRUE
)

# Vignette-only helper: render a flat tibble/data.frame as a styled HTML table.
# Uses tinytable when available (bold header, right-aligned numerics), falls back
# to knitr::kable() otherwise.  Return the table object so knitr::knit_print()
# renders it -- do NOT call print() inside.
es_tt <- function(x, caption = NULL, digits = 4, bar_cols = c("aar", "caar")) {
  if (requireNamespace("tinytable", quietly = TRUE)) {
    # Identify bar target columns: bar_cols that exist in x and are numeric
    target_cols <- intersect(bar_cols, names(x)[vapply(x, is.numeric, logical(1L))])

    # Local helper: convert a numeric vector to HTML diverging-bar cell strings
    make_bar_html <- function(vals, m, digs) {
      vapply(vals, function(val) {
        num_str <- if (is.na(val)) {
          formatC(NA_real_, digits = digs, format = "f")
        } else {
          formatC(val, digits = digs, format = "f")
        }
        if (is.na(val) || !is.finite(val) || val == 0) {
          paste0(
            '<div style="display:inline-block;position:relative;width:70px;height:0.9em;vertical-align:middle;">',
            '<div style="position:absolute;left:50%;top:0;width:1px;height:100%;background:#9ca3af;"></div>',
            '</div>',
            '<span style="font-variant-numeric:tabular-nums;">', num_str, '</span>'
          )
        } else {
          bar_pct <- round(50 * abs(val) / m, 2)
          bar_pct <- min(bar_pct, 50)
          if (val < 0) {
            bar_style <- paste0(
              'position:absolute;right:50%;top:0;height:100%;',
              'width:', bar_pct, '%;background:#dc2626;'
            )
          } else {
            bar_style <- paste0(
              'position:absolute;left:50%;top:0;height:100%;',
              'width:', bar_pct, '%;background:#16a34a;'
            )
          }
          paste0(
            '<div style="display:inline-block;position:relative;width:70px;height:0.9em;vertical-align:middle;">',
            '<div style="position:absolute;left:50%;top:0;width:1px;height:100%;background:#9ca3af;"></div>',
            '<div style="', bar_style, '"></div>',
            '</div>',
            '<span style="font-variant-numeric:tabular-nums;">', num_str, '</span>'
          )
        }
      }, character(1L))
    }

    # Replace target columns with HTML strings; track which were replaced
    x_out <- x
    for (col in target_cols) {
      m <- max(abs(x_out[[col]]), na.rm = TRUE)
      if (length(m) == 0L || is.na(m) || !is.finite(m) || m == 0) next
      x_out[[col]] <- make_bar_html(x_out[[col]], m, digits)
    }

    # Compute align on the modified frame (bar cols are now character -> "l")
    align <- ifelse(vapply(x_out, is.numeric, logical(1L)), "r", "l")
    tbl <- tinytable::tt(x_out, caption = caption, digits = digits)
    tbl <- tinytable::style_tt(tbl, i = 0L, bold = TRUE)
    for (j_idx in seq_along(align)) {
      tbl <- tinytable::style_tt(tbl, j = j_idx, align = align[[j_idx]])
    }
    tbl
  } else {
    args <- list(x = x, caption = caption)
    if (!is.null(digits)) args$digits <- digits
    do.call(knitr::kable, args)
  }
}
```

# Introduction

An event study measures the impact of an event -- a merger, earnings announcement, or macroeconomic shock -- on the value of a firm. `EventStudy` offers a modular pipeline for conducting these analyses in R: apply common return models, run diagnostic and test statistics, and extract publication-ready results, all in a workflow that composes cleanly with the tidyverse.

This vignette walks through the core flow: define a task, run the study, inspect the results, and extract or plot them. It uses the Dieselgate scandal as a running example.

# Quick Start

If you already have firm data, index data, and a request table (all defined below), the entire pipeline runs in a single call:

```{r quick-start, eval = FALSE}
# Preview of the full pipeline — data objects are loaded and unpacked step-by-step below.
library(EventStudy)

# One-call shortcut: prepare -> fit -> calculate, in one step
est_task <- run_event_study(
  EventStudyTask$new(firm_tbl, index_tbl, request_tbl),
  ParameterSet$new(
    return_calculation      = LogReturn$new(),
    return_model            = MarketModel$new(),
    single_event_statistics = SingleEventStatisticsSet$new(),
    multi_event_statistics  = MultiEventStatisticsSet$new()
  )
)

est_task$aar_caar_tbl
```

The rest of this vignette unpacks the same pipeline step by step, so you can see -- and customize -- each stage.

# Example: Dieselgate

To demonstrate the functionality and ease of use of EventStudy, let's look at an example: an event study analysis of the Dieselgate scandal. This example demonstrates how to use the EventStudy package by conducting an event study analysis on the "Dieselgate" scandal. The scandal, which erupted in 2015, involved Volkswagen's admission that it had installed software on its diesel cars to cheat on emissions tests. This significant event had substantial effects on the stock prices of Volkswagen and other automotive companies.

The following code will guide you through the steps of performing an event study analysis, from the initial setup to the extraction of results.

## Initialization

The first step is to load necessary packages and data. This includes market data for the companies of interest and the index during the event study period.

```{r, warning=FALSE, message=FALSE}
library(EventStudy)

# Load the bundled frozen Dieselgate dataset (replaces a live network download via
# tidyquant so this vignette builds fully offline and reproducibly on CRAN/pkgdown).
data(dieselgate)

firm_tbl    <- dieselgate$firm     # symbol / date / adjusted (4 firms, DD-MM-YYYY dates)
index_tbl   <- dieselgate$index    # symbol / date / adjusted (^GDAXI)
request_tbl <- dieselgate$request  # event_id / firm_symbol / index_symbol / event_date /
                                   # group / event_window_start / event_window_end /
                                   # shift_estimation_window / estimation_window_length
```

Both, the firm data as the index data should have the following structure:

1.  **symbol**: Contains the symbol of the stock.
2.  **date**: The date of the price information.
3.  **adjusted**: The price of the stock at given date. The price column can be parametrized according to your needs when the task is defined. The default is `adjusted`.

```{r}
es_tt(head(firm_tbl))
```

## Define the Event Study

Next, we define the event study. This involves specifying the return calculation method, the market model, and the test statistics to be used. In this example, we use logarithmic returns, the market model, and the default AR and CAR T-Tests. Descriptions of the available models can be found on our website: [Expected Return Models](https://eventstudy.de/models/expected_return.html "Choosing the Right Approach: A Comprehensive Guide to Estimating Expected Returns.").

```{r}
# Parametrization of the Event Study
log_return = LogReturn$new()
market_model = MarketModel$new()
```

For single events the standard [AR and CAR T test](https://eventstudy.de/statistics/ar_car_statistics.html "A Comprehensive Guide to Analyzing Abnormal Returns in Event Studies.") are applied. For performing an Event Study on multiple events, the Cross-Sectional T Test (AAR and CAAR) is applied by default, alongside Patell Z, BMP, sign, and rank tests.

```{r}
# Define single event test statistics
# Per default AR and CAR T-Tests are applied
single_event_tests = SingleEventStatisticsSet$new()

# Per default CSEct T Test is applied (AAR & CAAR)
multiple_event_tests = MultiEventStatisticsSet$new()
```

Your Event Study is then defined in a parameter set:

```{r}
# Setup parameter set
param_set = ParameterSet$new(return_calculation      = log_return,
                             return_model            = market_model,
                             single_event_statistics = single_event_tests,
                             multi_event_statistics  = multiple_event_tests)
```

## Execute the Event Study

Now, with everything set up, we can execute the event study. This involves preparing the event study, fitting the model, and calculating the statistics. In the first step the task is defined. The firm and the index data gathered before as also the request data is necessary for performing the study.

```{r}
est_task = EventStudyTask$new(firm_tbl, index_tbl, request_tbl)
```

Internally, firm and index data symbol and price column names are renamed. Afterwards a join is applied and the data is collected in a data frame with one event per row. Let's have a look at the internal data frame:

```{r}
head(est_task$data_tbl)
```

```{r}
es_tt(head(est_task$data_tbl$data[[1]]))
```

```{r}
es_tt(est_task$data_tbl$request[[1]])
```

The internal data structure is important for you if you plan to develop your own statistical or econometric model or test statistic.

```{r}
est_task = prepare_event_study(est_task, param_set)
```

```{r}
es_tt(head(est_task$data_tbl$data[[1]]))
```

```{r}
est_task = fit_model(est_task, param_set)
```

```{r}
head(est_task$data_tbl)
```

```{r}
est_task$data_tbl$model[[1]]
```

```{r}
est_task = calculate_statistics(est_task, param_set)
```

```{r}
head(est_task$data_tbl)
```

```{r}
es_tt(est_task$data_tbl$ART[[1]])
```

```{r}
es_tt(est_task$data_tbl$CART[[1]])
```

```{r}
est_task$aar_caar_tbl
```

```{r}
es_tt(est_task$aar_caar_tbl$CSectT[[1]])
```

## Visualize the Results

The `plot_event_study()` function returns a ggplot2 object; wrapping it in
`plotly::ggplotly()` converts it to an interactive widget -- hover over data
points to inspect exact values, zoom into the announcement window, or click
legend entries to toggle series.

### Cumulative Abnormal Return (CAR)

The chart below shows the cumulative abnormal return (CAR) path with confidence
band for the first event in the study (VW, September 2015 announcement).

The CAR is the running sum of abnormal returns from the start of the event
window to each day t. Abnormal returns are the firm's actual returns minus what
the market model predicted -- in other words, the return in excess of what you
would have expected given the index movement that day. At day 0 (the event
date) the cumulative sum resets conceptually: positive values above the band
reflect unexpectedly good news; negative values below the band reflect
unexpectedly bad news.

The shaded region is the confidence band. When the CAR path moves outside the
band the abnormal performance is statistically distinguishable from zero --
the market is responding to the event beyond chance variation. When the path
stays inside the band the evidence of abnormal performance is not strong enough
to rule out noise. For the VW Dieselgate event you will notice a pronounced drop
right around the announcement window: the CAR falls sharply below the lower
bound of the confidence band, confirming a statistically significant negative
market reaction to the emissions disclosure.

Use the hover tooltip to read off the exact CAR value and confidence-band limits
at any relative day. The zoom and legend-toggle controls let you focus on the
announcement window or isolate individual series.

```{r plot-car}
plotly::ggplotly(plot_event_study(est_task, type = "car"))
```

### Cumulative Average Abnormal Return (CAAR)

The next chart shows the cumulative average abnormal return (CAAR) aggregated
across all events in the study.

Where the single-event CAR reflects one firm's reaction, the CAAR averages
abnormal returns across all events at each relative day. Averaging smooths
out firm-specific noise -- idiosyncratic movements that happen to coincide with
the event window for a particular firm but are unrelated to the event itself.
When a clean CAAR signal emerges (a sustained move outside the confidence band)
it reflects a systematic market reaction shared across firms, not just one
company's idiosyncratic move. A narrow confidence band signals that the
individual event reactions were consistent with each other; a wide band suggests
heterogeneous reactions across the sample.

For the Dieselgate study the CAAR chart summarises the mean market reaction
across all four affected automotive companies, providing a portfolio-level view
of how the scandal reverberated through the sector.

```{r plot-caar}
plotly::ggplotly(plot_event_study(est_task, type = "caar"))
```

## Next Steps

This vignette covered the core market-model pipeline. To go deeper:

-   **Return models:** See `vignette("factor-models-bhar")` for multi-factor and long-horizon models
-   **Test statistics:** See `vignette("inference-robustness")` for robust inference and bootstrap
-   **Result extraction:** See `vignette("result-extraction")` for export, `tidy()`, and cross-sectional analysis
-   **AI advisor:** See `vignette("ai-advisor")` for deterministic diagnostics and LLM interpretation
-   **Full gallery:** See `vignette("gallery")` for all available vignettes by topic

# Conclusion

Event Study offers a streamlined and intuitive interface for conducting event study analysis in R, making it a valuable addition to the toolkit of any researcher or analyst in finance. Whether you're assessing the impact of corporate events on stock prices or investigating the effects of macroeconomic news, Event Study provides a flexible and efficient solution.
