TeX 74.5%
Python 25.4%
1"""05_make_tables.py -- emit LaTeX table fragments for the report."""2import json, pandas as pd, numpy as np3T="results/tables"; R="paper/tables"4RES=json.load(open(f"{T}/results.json"))56def w(name, body): open(f"{R}/{name}.tex","w").write(body)78# --- Table 1: summary stats ---9s=pd.read_csv(f"{T}/t1_summary_stats.csv",index_col=0)10nice={"ai_adoption_wmean":"AI adoption (wmean)","ai_infrastructure_wmean":"AI infrastructure (wmean)",11 "ai_disruption_risk_wmean":"AI disruption risk (wmean)","fwd_ret":"Forward 12m return",12 "fwd_ret_mktadj":"Forward return, mkt-adj.","mom_12m":"Momentum (12m)","vol_12m":"Volatility (ann.)",13 "log_mktcap":"Log market cap"}14rows="".join(f"{nice.get(i,i)} & {s.loc[i,'mean']:.3f} & {s.loc[i,'std']:.3f} & {s.loc[i,'5%']:.3f} & {s.loc[i,'50%']:.3f} & {s.loc[i,'95%']:.3f} \\\\\n" for i in nice)15w("tab_summary", r"""\begin{table}[H]\centering\small16\caption{Summary statistics, firm-year panel with tradeable forward returns (N=%d firm-years, %d firms, formation years %s).}\label{tab:summ}17\begin{tabular}{lrrrrr}\toprule18Variable & Mean & SD & p5 & Median & p95 \\\midrule19%s\bottomrule20\end{tabular}\end{table}""" % (RES["n_obs"],RES["n_firms"],RES["yrs"],rows))2122# --- Table 2: portfolio sorts ---23sd=pd.read_csv(f"{T}/t2_portfolio_sorts.csv",index_col=0)24def row(key,label):25 r=sd.loc[key]26 return f"{label} & {r.Q1*100:.1f} & {r.Q2*100:.1f} & {r.Q3*100:.1f} & {r.Q4*100:.1f} & {r.Q5*100:.1f} & {r.Q5_minus_Q1*100:+.1f} & {r.t_stat:.2f} \\\\\n"27body =row("AI_ADOPT_EW","AI adoption (EW)")28body+=row("AI_ADOPT_VW","\\quad value-weighted")29body+=row("AI_INFRA_EW","AI infrastructure (EW)")30body+=row("AI_INFRA_VW","\\quad value-weighted")31body+=row("AI_RISK_EW","AI disruption risk (EW)")32body+=row("AI_RISK_VW","\\quad value-weighted")33body+="\\midrule\n"+row("AI_COMPOS_EW","AI composite (EW)")34body+=row("AI_COMPOS_VW","\\quad value-weighted")35w("tab_sorts", r"""\begin{table}[H]\centering\small36\caption{Forward 12-month returns (\%%) by AI-disclosure quintile. Q5$-$Q1 is the high-minus-low spread; \textit{t} uses Newey--West (3 lag) errors on the 15 annual spreads.}\label{tab:sorts}37\begin{tabular}{lrrrrrrr}\toprule38Signal (weighting) & Q1 & Q2 & Q3 & Q4 & Q5 & Q5$-$Q1 & \textit{t} \\\midrule39%s\bottomrule40\end{tabular}\end{table}""" % body)4142# --- Table 3: factor alphas ---43a=RES["ls_alpha"]44def arow(k,label):45 x=a[k]46 return (f"{label} & {x['mean_ls_ann']*100:+.1f} & {x['capm_alpha_m']*1200:+.1f} & {x['capm_alpha_t']:.2f} "47 f"& {x['ff6_alpha_ann']*100:+.1f} & {x['ff6_alpha_t']:.2f} \\\\\n")48body=arow("AI_ADOPT","AI adoption")+arow("AI_INFRA","AI infrastructure")+arow("AI_COMPOS","AI composite")+arow("AI_RISK","AI disruption risk")49w("tab_alpha", r"""\begin{table}[H]\centering\small50\caption{Risk-adjusted performance of the equal-weight high-minus-low (Q5$-$Q1) long-short portfolio, annually rebalanced (%d monthly observations). Alphas annualized; \textit{t} from Newey--West (3 lag) HAC errors.}\label{tab:alpha}51\begin{tabular}{lrrrrr}\toprule52& Mean LS & CAPM $\alpha$ & \textit{t} & FF6 $\alpha$ & \textit{t} \\53Signal & (\%%/yr) & (\%%/yr) & & (\%%/yr) & \\\midrule54%s\bottomrule55\end{tabular}\end{table}""" % (a["AI_ADOPT"]["n_months"], body))5657# --- Table 4: panel FE + Fama-MacBeth ---58fe=RES["panel_fe"]; fm=RES["fama_macbeth"]59def g(d,v):60 return d["coefs"].get(v)61m5=fe["M5_all"]; fmall=fm["all"]62def cell(coef,t): return f"{coef:+.4f} \\tstat{{{t:.2f}}}"63rows=[]64labels=[("z_AI_ADOPT","AI adoption ($z$)"),("z_AI_INFRA","AI infrastructure ($z$)"),65 ("z_AI_RISK","AI disruption risk ($z$)"),("z_size","Size ($z$)"),66 ("z_mom","Momentum ($z$)"),("z_vol","Volatility ($z$)")]67for v,lab in labels:68 fec=m5["coefs"].get(v); fmc=fmall.get(v)69 fecell = cell(fec["coef"],fec["t"]) if fec else "---"70 fmcell = cell(fmc["mean_coef"],fmc["t"]) if fmc else "---"71 rows.append(f"{lab} & {fecell} & {fmcell} \\\\")72body="\n".join(rows)73w("tab_panel", r"""\begin{table}[H]\centering\small74\caption{Forward-return regressions. Column (1): two-way (firm $\times$ year) fixed-effects panel, SE double-clustered by firm and year. Column (2): Fama--MacBeth, Newey--West \textit{t}. Dependent variable is the winsorized forward 12-month return; signals are within-year $z$-scores.}\label{tab:panel}75\begin{tabular}{lcc}\toprule76& (1) Two-way FE & (2) Fama--MacBeth \\\midrule77%s78\midrule79Firm FE & Yes & No \\80Year FE & Yes & (by construction) \\81N (obs / years) & %d & %d \\82\bottomrule83\end{tabular}\end{table}""" % (body, fe["M5_all"]["n"], fmall["n_years"]))8485# --- Table 5: structural break ---86br=RES["structural_break"]; sp=RES["subperiod_spread"]87def brow(k,label):88 b=br[k]; s=sp[k]89 pre=s["pre_2010_2021"]; post=s["post_2022_2024"]90 return (f"{label} & {pre[0]*100:+.1f} \\tstat{{{pre[1]:.2f}}} & {post[0]*100:+.1f} \\tstat{{{post[1]:.2f}}} "91 f"& {b['interaction']:+.4f} \\tstat{{{b['interaction_t']:.2f}}} \\\\\n")92body=brow("AI_ADOPT","AI adoption")+brow("AI_INFRA","AI infrastructure")+brow("AI_COMPOS","AI composite")93w("tab_break", r"""\begin{table}[H]\centering\small94\caption{The post-ChatGPT structural break. Columns 2--3: Q5$-$Q1 forward-return spread (\%%/yr, Newey--West \textit{t}) in each sub-period. Column 4: coefficient on AI~$z$\,$\times$\,Post-2022 from a pooled OLS (size and momentum controls, year-clustered SE).}\label{tab:break}95\begin{tabular}{lccc}\toprule96& \multicolumn{2}{c}{Q5$-$Q1 spread} & Interaction \\97\cmidrule(lr){2-3}98Signal & Pre (2010--21) & Post (2022--24) & AI$\times$Post \\\midrule99%s\bottomrule100\end{tabular}\end{table}""" % body)101102print("LaTeX table fragments written.")103