1from __future__ import annotations23import numpy as np4import pandas as pd567def add_subgroups(meta: pd.DataFrame, universe: dict) -> pd.DataFrame:8 inst = {r["symbol"]: r for r in universe["instruments"]}9 meta = meta.copy()10 for col in ("adv_tercile", "vol_tercile", "group", "role", "asset_class"):11 meta[col] = meta["symbol"].map(lambda s: inst.get(s, {}).get(col, "unknown"))12 meta["tod"] = pd.cut(meta["m"], [0, 90, 210, 330, 400], labels=["open", "midday", "afternoon", "close"], include_lowest=True)13 meta["year"] = pd.to_datetime(meta["session_date"]).dt.year14 q = meta.groupby("session_date")["sigma"].transform("mean")15 thr = np.quantile(q, 0.9)16 meta["stress_day"] = (q >= thr)17 return meta181920def by_group(per: np.ndarray, meta: pd.DataFrame, col: str) -> pd.DataFrame:21 df = pd.DataFrame({"v": per, "g": meta[col].values})22 return df.groupby("g", observed=True)["v"].agg(["mean", "count"]).reset_index().rename(columns={"g": col})23