Python 75.9%
TeX 24%
1#!/usr/bin/env python32"""3================================================================4Auteur : Simon-Pierre Boucher5Contact : contact@spboucher.ai6Projet : Prévision de volatilité réalisée multi-actifs7 (HAR-RV vs GARCH vs Machine Learning)8Fichier : 02_build_rv.py9Description : Étape 02 — Construction des mesures de volatilité10 réalisée journalières (parallélisée par actif) et11 assemblage du panel multi-actifs.12Usage : python scripts/02_build_rv.py [--refresh] [--workers 8]13 [--only-cached]14================================================================15"""1617from __future__ import annotations1819import argparse20import logging21import sys22from concurrent.futures import ProcessPoolExecutor, as_completed23from pathlib import Path2425import pandas as pd2627sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))2829from wp12 import config # noqa: E4023031logger = logging.getLogger("02_build_rv")323334def build_one(inst: dict[str, str], refresh: bool) -> str:35 """Worker: build the daily RV file for one instrument."""36 from wp12 import data_pipeline37 from wp12.api_client import HFMarketDataClient3839 config.setup_logging(logging.WARNING)40 client = HFMarketDataClient()41 df = data_pipeline.build_instrument_rv(client, inst, refresh=refresh)42 return f"{inst['ticker']}: {len(df)} days"434445def main() -> None:46 """Build per-ticker RV files in parallel, then assemble the panel."""47 ap = argparse.ArgumentParser()48 ap.add_argument("--refresh", action="store_true", help="recompute RV files")49 ap.add_argument("--workers", type=int, default=8)50 ap.add_argument("--only-cached", action="store_true",51 help="only tickers whose 1-min bars are already cached")52 args = ap.parse_args()5354 config.setup_logging()55 logging.getLogger("urllib3").setLevel(logging.WARNING)56 univ = config.universe(include_predictors=True)57 if args.only_cached:58 raw = config.path("raw")59 univ = [i for i in univ60 if (raw / f"{i['asset']}_{i['ticker']}_1min.parquet").exists()]61 logger.info("building RV for %d instruments", len(univ))62 with ProcessPoolExecutor(max_workers=args.workers) as pool:63 futs = {pool.submit(build_one, i, args.refresh): i["ticker"] for i in univ}64 for fut in as_completed(futs):65 try:66 logger.info("done %s", fut.result())67 except Exception as exc: # noqa: BLE00168 logger.error("FAILED %s: %s", futs[fut], exc)6970 if not args.only_cached:71 from wp12 import data_pipeline72 panel = data_pipeline.build_panel()73 logger.info("panel: %d rows, %d tickers", len(panel),74 panel["ticker"].nunique())757677if __name__ == "__main__":78 main()79