The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
Bayesian Nonlinear Ornstein-Uhlenbeck Models with Stochastic Volatility
bayesianOU fits a Bayesian nonlinear Ornstein-Uhlenbeck
(OU) / nonlinear error-correction model with cubic drift, stochastic
volatility (SV), and Student-t innovations. Sector-specific parameters
use a non-centered hierarchical (partial-pooling)
parameterization, and sampling is done with Stan
(reduce_sum for within-chain parallelism). Model comparison
uses PSIS-LOO (Vehtari, Gelman, Gabry 2017).
# install.packages("remotes")
remotes::install_github("IsadoreNabi/bayesianOU")
# Stan backend (cmdstanr recommended):
install.packages("cmdstanr", repos = c("https://mc-stan.org/r-packages/", getOption("repos")))
cmdstanr::install_cmdstan()
# Or rstan:
install.packages("rstan")library(bayesianOU)
Y <- as.matrix(your_prices_data) # market prices by sector
X <- as.matrix(your_production_prices_data) # prices of production
TMG <- your_tmg_series # aggregate profit rate
COM <- as.matrix(your_com_data) # organic composition of capital
K <- as.matrix(your_capital_data) # total capital by sector
results <- fit_ou_nonlinear_tmg(
results_robust = list(),
Y = Y, X = X, TMG = TMG, COM = COM, CAPITAL_TOTAL = K,
fit_window = "train", # honest out-of-sample evaluation
chains = 4, iter = 4000, warmup = 2000,
verbose = TRUE
)
validate_ou_fit(results) # MCMC + LOO (incl. Pareto-k) + OOS
kappa_stability_evidence(results) # dynamic mean-reversion evidence
plot_beta_tmg(results)
plot_drift_curves(results)For each sector s, on training-standardized series, the
one-step (Euler, dt = 1) increment is
dY[t,s] = kappa_s * (theta_s - Y[t-1,s] + a3_s * (Y[t-1,s] - theta_s)^3) # cubic OU drift
+ (beta0_s + beta1 * zTMG[t]) * X[t-1,s] # TMG-modulated pass-through
+ gamma * COM_std[t-1,s] # organic composition in mean
+ eps[t,s], eps ~ Student-t(nu, 0, sigma[t,s])
log sigma^2[t,s] = h[t,s], h ~ stationary AR(1) (alpha_s, rho_s, sigma_eta_s)
kappa_s mean-reversion speed, theta_s
equilibrium level, a3_s < 0 cubic term. The implied
long-run equilibrium is Y* = theta_s + (beta/kappa_s) X,
i.e. a nonlinear error-correction toward a linear function of the prices
of production.theta_s, kappa_s, a3_s, beta0_s are built
hierarchically as intercept + slope * COM_s + sd * z,
z ~ N(0,1) (non-centered).nu > 2 (finite variance). sigma[t,s] is
the Student-t scale; the conditional standard deviation
is sigma * sqrt(nu/(nu-2)).Training/test and “out-of-sample”. A Bayesian fit on
all data is perfectly valid for inference and for
PSIS-LOO (which approximates leave-one-out predictive
performance from the full-data posterior — this is exactly what
rstanarm does, and it is not leakage). Leakage only arises
if one labels a block “out-of-sample” while it still entered the
likelihood. This package keeps the two designs coherent via
fit_window:
fit_window = "train" (default): the likelihood and
log_lik are summed only over the training
window 2:T_train; the test block is genuinely held out, so
evaluate_oos is a real out-of-sample evaluation.fit_window = "full": fit on all observations
(full-information). PSIS-LOO is then valid over all points, but
evaluate_oos becomes in-sample.Priors are configurable and neutral by default. The
key hypothesis prior is neutral: beta1 ~ Normal(0, 0.5) (no
sign baked in). The Student-t df uses a weakly-informative
nu_tilde ~ Gamma(2, 0.1) (prior mean nu ~ 22),
and SV persistence rho_s ~ Normal(0.7, 0.2). Override any
of these through the priors argument and run a sensitivity
analysis.
Leakage in preprocessing is avoided by default.
use_train_loadings = TRUE computes the common-factor
loadings from the training window only and then projects the full
series, so the orthogonalized TMG regressor does not see the future.
Stability assumption. a3_s < 0 is
enforced, so mean reversion strengthens with the deviation. This is an
assumption (global stabilization), not an estimated result; it
precludes detecting locally expansive / self-amplifying regimes.
Half-life. With the Euler dt = 1 discretization, the
discrete persistence of the linear part is 1 - kappa;
interpret half-lives as log(0.5)/log(1 - kappa), not
log(2)/kappa (these coincide only as
kappa -> 0).
PSIS-LOO caveat. The model has one latent SV state
per observation, so plain PSIS-LOO tends to be optimistic and to produce
high Pareto-k. validate_ou_fit surfaces a Pareto-k summary
and warns; for genuine forecasting assessment prefer leave-future-out
(LFO-CV).
validate_ou_fit).tests/testthat/test-recovery.R).fit_window = "train") and PSIS-LOO comparison against
baselines.@software{bayesianOU,
author = {Gómez Julián, José Mauricio},
title = {bayesianOU: Bayesian Nonlinear Ornstein-Uhlenbeck Models},
year = {2024},
note = {ORCID: 0009-0000-2412-3150},
url = {https://github.com/IsadoreNabi/bayesianOU}
}
MIT License
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.