Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions code/c17_model_comparison.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""
C17: Regenerate the model-comparison table (manuscript Table 2) from the frozen
model-selection JSONs — closing the one paper<->code gap with no active script.
================================================================================

The manuscript's model-comparison table (GARCH(1,1) vs GJR-GARCH vs GJR-GARCH-X
AIC/BIC/LogLik per asset) originates from the model-selection run archived in
`_archive/outputs/analysis_results/model_parameters/<asset>_parameters.json`.
Those JSONs are the source of record for the table; this script extracts and
tabulates them so the table is reproducible from committed artifacts like every
other table in the paper.

Parameter-count convention (matches the manuscript's ten-parameter statement):
the estimators profile the mean at the sample mean, so the GJR-GARCH-X
information criteria correspond to k = 10 (omega, alpha, gamma, beta, nu + 5
exogenous coefficients); BIC - AIC = k * (ln n - 2). LogLik is recovered from
AIC as (2k - AIC) / 2.
Comment on lines +13 to +17

Output (results/):
c17-model-comparison.csv one row per (asset, model): AIC, BIC, LogLik
"""
import csv
import json
from pathlib import Path

HERE = Path(__file__).resolve().parent
ROOT = HERE.parent
JSON_DIR = ROOT / "_archive" / "outputs" / "analysis_results" / "model_parameters"
OUT_DIR = ROOT / "results"

ASSETS = ["btc", "eth", "xrp", "bnb", "ltc", "ada"]
# model label in JSON -> (manuscript label, parameter count with mean profiled)
MODELS = {
"GARCH(1,1)": ("GARCH(1,1)", 5),
"TARCH(1,1)": ("GJR-GARCH", 6),
"TARCH-X": ("GJR-GARCH-X", 10),
}


def main():
OUT_DIR.mkdir(parents=True, exist_ok=True)
rows = []
for asset in ASSETS:
with open(JSON_DIR / f"{asset}_parameters.json") as f:
data = json.load(f)
for json_label, (paper_label, k) in MODELS.items():
block = data[json_label]
aic, bic = float(block["AIC"]), float(block["BIC"])
loglik = (2 * k - aic) / 2
Comment on lines +43 to +49
rows.append(
{
"asset": asset.upper(),
"model": paper_label,
"k_params": k,
"AIC": round(aic, 3),
"BIC": round(bic, 3),
"loglik": round(loglik, 3),
}
)
out = OUT_DIR / "c17-model-comparison.csv"
with open(out, "w", newline="") as f:
w = csv.DictWriter(f, fieldnames=list(rows[0].keys()))
w.writeheader()
w.writerows(rows)
Comment on lines +60 to +64
print(f"wrote {out} ({len(rows)} rows)")
# console preview mirroring the manuscript table layout
for asset in ASSETS:
sub = [r for r in rows if r["asset"] == asset.upper()]
best = min(sub, key=lambda r: r["AIC"])
line = " ".join(
f"{r['model']}: AIC {r['AIC']:.0f} BIC {r['BIC']:.0f} LL {r['loglik']:.0f}"
+ (" *" if r is best else "")
for r in sub
)
print(f"{asset.upper():4s} {line}")


if __name__ == "__main__":
main()
19 changes: 19 additions & 0 deletions results/c17-model-comparison.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
asset,model,k_params,AIC,BIC,loglik
BTC,"GARCH(1,1)",5,11904.019,11933.005,-5947.009
BTC,GJR-GARCH,6,11905.615,11940.398,-5946.807
BTC,GJR-GARCH-X,10,11900.352,11958.325,-5940.176
ETH,"GARCH(1,1)",5,13344.705,13373.692,-6667.353
ETH,GJR-GARCH,6,13346.557,13381.341,-6667.279
ETH,GJR-GARCH-X,10,13329.362,13387.335,-6654.681
XRP,"GARCH(1,1)",5,13324.298,13353.285,-6657.149
XRP,GJR-GARCH,6,13325.112,13359.895,-6656.556
XRP,GJR-GARCH-X,10,13324.297,13382.27,-6652.149
BNB,"GARCH(1,1)",5,11400.368,11428.829,-5695.184
BNB,GJR-GARCH,6,11400.936,11435.089,-5694.468
BNB,GJR-GARCH-X,10,11400.492,11457.413,-5690.246
LTC,"GARCH(1,1)",5,13779.841,13808.828,-6884.921
LTC,GJR-GARCH,6,13773.559,13808.343,-6880.78
LTC,GJR-GARCH-X,10,13773.224,13831.197,-6876.612
ADA,"GARCH(1,1)",5,14091.197,14120.183,-7040.598
ADA,GJR-GARCH,6,14093.131,14127.915,-7040.566
ADA,GJR-GARCH-X,10,14092.421,14150.394,-7036.21