SPB Git

spb/wp40_uqo

Public MIT
4.1 KB · 66 lines cpp
1// GARCH-family conditional variance recursions and (quasi-)log-likelihoods. FP64 reference; the Metal kernel2// implements the same recursion in FP32 (documented tolerance). Definitions (registry key garch.*):3//   GARCH(1,1):     σ²_t = ω + α ε²_{t−1} + β σ²_{t−1}4//   GJR-GARCH(1,1): σ²_t = ω + (α + γ 1{ε_{t−1}<0}) ε²_{t−1} + β σ²_{t−1}5//   EGARCH(1,1):    ln σ²_t = ω + α (|z_{t−1}| − E|z|) + γ z_{t−1} + β ln σ²_{t−1},  z = ε/σ6// ε_t = r_t − μ. Initialisation: σ²_0 = sample variance of ε (GARCH/GJR), ln σ²_0 = ln(sample variance) (EGARCH) —7// the same convention as the `arch` package default ("backcast" is NOT used; see registry for the rugarch mapping).8// Densities: Gaussian, or standardized Student-t with ν > 2 (unit variance), as in arch/rugarch.9#pragma once10#include <span>11#include <vector>12#include <string>13#include "raid/core/types.hpp"14#include "raid/core/estimate.hpp"15#include "raid/core/plan.hpp"1617namespace raid::models {1819enum class GarchModel : int { garch = 0, gjr = 1, egarch = 2 };20enum class GarchDist : int { gaussian = 0, student_t = 1 };21std::string to_string(GarchModel m);22std::string to_string(GarchDist d);2324/// Parameter layout θ (natural parameterisation): [μ, ω, α, (γ), β, (ν)] — γ only for gjr/egarch, ν only for student_t.25usize garch_n_params(GarchModel m, GarchDist d);26std::vector<std::string> garch_param_names(GarchModel m, GarchDist d);2728/// Conditional variance path σ²_t (t = 0..n−1) for returns r and parameters θ; writes to sigma2 (resized).29/// Returns false (and leaves NaNs) if the recursion produced a non-positive or non-finite variance.30bool garch_variance_path(std::span<const f64> r, std::span<const f64> theta, GarchModel m, GarchDist d, std::vector<f64>& sigma2);3132/// Negative average? NO: negative *total* log-likelihood Σ_t −log f(r_t | σ²_t). Returns +inf for invalid parameters33/// (ω ≤ 0, α < 0, β < 0, α+β ≥ 1 for GARCH; α+β+γ/2 ≥ 1 for GJR; |β| ≥ 1 for EGARCH; ν ≤ 2).34/// `nu_fixed`: if > 2 and the model is Gaussian-coded, a Student-t density with that ν is used (batched grids).35f64 garch_nll(std::span<const f64> r, std::span<const f64> theta, GarchModel m, f64 nu_fixed = 0.0);36f64 garch_nll(std::span<const f64> r, std::span<const f64> theta, GarchModel m, GarchDist d);3738/// Stationarity / positivity constraints check.39bool garch_params_valid(std::span<const f64> theta, GarchModel m, GarchDist d);4041/// Unconstrained ↔ constrained transforms used by the optimiser (ω = exp, α,β via logistic simplex, ν = 2 + exp).42std::vector<f64> garch_to_unconstrained(std::span<const f64> theta, GarchModel m, GarchDist d);43std::vector<f64> garch_from_unconstrained(std::span<const f64> u, GarchModel m, GarchDist d);4445struct GarchFitOptions {46  GarchModel model{GarchModel::garch};47  GarchDist dist{GarchDist::gaussian};48  int max_iter{500};49  f64 tol{1e-8};              // relative change in NLL50  std::string cov{"qmle"};    // "qmle" (Bollerslev–Wooldridge sandwich) | "hessian" | "opg"51  int forecast_horizon{0};    // h ≥ 1 → multi-step variance forecasts in extra["forecast_variance"]52  bool scale_returns{true};   // internally scale returns to unit variance (as arch does, 'rescale')53  bool retry_starts{true};    // on non-convergence, retry from up to two alternative starting points (documented)54  ExecutionPlan plan{};55};5657/// Fit by (quasi-)maximum likelihood on the CPU (L-BFGS-style quasi-Newton on the unconstrained parameters with58/// numerical gradients validated against finite differences in tests). Never reports a non-converged fit as ok().59Estimate garch_fit(std::span<const f64> r, const GarchFitOptions& opt = {});60/// Multi-step-ahead conditional variance forecasts from the last state (h = 1..H). For EGARCH, h > 1 uses simulation-free61/// log-normal approximation only when `exact` is false; by default h > 1 forecasts for EGARCH are produced by62/// Monte Carlo with the given seed (reported in extra). GARCH/GJR forecasts are analytical.63std::vector<f64> garch_forecast(const Estimate& fit, std::span<const f64> r, int horizon, u64 seed = 20261102, int n_sim = 20000);6465}  // namespace raid::models66
Files · v0.1.0-wp40
Menu

Theme