QM026 Hands-on Lab: Point-in-Time Dynamic Universe Construction
QM026 · Hands-on Lab
Objective
Build a synthetic ETF inventory with staggered listing dates and changing liquidity. Compare a current-survivor backfill with a point-in-time universe, then select one representative per exposure.
Python
from dataclasses import dataclass
import pandas as pd
master = pd.DataFrame({
"ticker": ["A", "B", "C", "D"],
"exposure": ["Japan", "Japan", "Brazil", "Brazil"],
"list_date": pd.to_datetime(["2018-01-01", "2023-01-01", "2019-01-01", "2025-01-01"]),
"adv_m": [25, 40, 18, 35],
"history_days": [2000, 800, 1700, 300],
})
signal_date = pd.Timestamp("2024-12-31")
pt = master[(master.list_date <= signal_date) & (master.history_days >= 504) & (master.adv_m >= 10)]
rep = (pt.sort_values(["exposure", "adv_m", "history_days"], ascending=[True, False, False])
.groupby("exposure", as_index=False).first())
print(rep[["exposure", "ticker"]])Audit questions
- Which ticker incorrectly enters 2024 if today’s survivor list is backfilled?
- Which names are market-eligible but fail the history gate?
- If a newer wrapper becomes the liquidity leader in 2027, from what signal month should the representative switch take effect?
- Would that prospective switch justify rewriting the certified 2024 portfolio history? Why not?
Interpretation boundary
The inventory is synthetic. The exercise demonstrates point-in-time eligibility and representative selection; it does not identify an optimal universe or justify retroactively rewriting certified historical membership.