Python 56.2%
TeX 43.7%
1"""Event window construction for event studies."""23from __future__ import annotations45import numpy as np6import pandas as pd789def create_event_windows(10 prices: pd.DataFrame,11 event_dates: list,12 window: tuple[int, int] = (-5, 5),13 label: str = "event",14) -> pd.DataFrame:15 """Create event windows around each event date.1617 Returns DataFrame with columns:18 [event_date, relative_day, market, price, return, abnormal_return]19 """20 rows = []21 idx = prices.index22 event_dates_ts = [pd.Timestamp(d) for d in event_dates]2324 for col in prices.columns:25 series = prices[col].dropna()26 if series.empty:27 continue28 returns = series.diff()29 mean_return = returns.mean()3031 for event_dt in event_dates_ts:32 loc = idx.get_indexer([event_dt], method="nearest")[0]33 if loc < 0 or loc >= len(idx):34 continue35 for rel_day in range(window[0], window[1] + 1):36 abs_idx = loc + rel_day37 if 0 <= abs_idx < len(idx):38 date = idx[abs_idx]39 price = series.iloc[abs_idx] if abs_idx < len(series) else np.nan40 ret = returns.iloc[abs_idx] if abs_idx < len(returns) else np.nan41 ar = ret - mean_return if not np.isnan(ret) else np.nan42 rows.append({43 "event_date": event_dt,44 "relative_day": rel_day,45 "market": col,46 "price": price,47 "return": ret,48 "abnormal_return": ar,49 })5051 return pd.DataFrame(rows)525354def compute_car(event_windows: pd.DataFrame) -> pd.DataFrame:55 """Compute cumulative abnormal returns from event windows."""56 result = []57 for (event_date, market), group in event_windows.groupby(["event_date", "market"]):58 group = group.sort_values("relative_day")59 group = group.copy()60 group["CAR"] = group["abnormal_return"].cumsum()61 result.append(group)62 if result:63 return pd.concat(result, ignore_index=True)64 return pd.DataFrame()65