Re: garchmvbootstrap.rpf
Posted: Thu Nov 20, 2025 7:22 am
I'm not sure what you are planning with that, but the squared residuals are a poor proxy for volatility.
A Forum for RATS Software and Econometrics Discussions
https://estima.com/forum/
My question is: How to judge the backtest correlation forecasts from MVGARCH models?TomDoan wrote: ↑Thu Nov 20, 2025 7:22 am I'm not sure what you are planning with that, but the squared residuals are a poor proxy for volatility.
Code: Select all
set csdlp1000_2 %allocend()-999 %allocend()+2 = dlp + dlp{1}; * sum of 2-day actual returns
set csdlp1000_3 %allocend()-999 %allocend()+3 = dlp + dlp{1} + dlp{2}; * sum of 3-day actual returns
* etcmean I can apply Christoffersen with 1000 observations, and overlapping k>=2 upto 10 period intervals?TomDoan wrote: ↑Thu Nov 13, 2025 4:30 pm Clearly any test of "independence" makes no sense when your statistics are, by construction, not independent. You can probably still apply those if you sample the statistics at intervals larger than your overlap. So you need to think about what you want to test that isn't already excluded by the use of overlapping intervals.
Code: Select all
garch(model=trimodel,p=1,q=1,rvectors=rv,hmatrices=hh,method=BFGS) / xasset1 xasset2 xasset3
forecast(model=trimodel,steps=3,results=rhat)
@mvgarchfore(steps=3) hh rv
* cumulative forecasts var/cov matrix
comp hhcumsum1 = hh(6238); * the 1-step
comp hhcumsum2 = hh(6238) + hh(6239)
comp hhcumsum3 = hh(6238) + hh(6239) + hh(6240)
*etc
The one-step returns, forecasts and analysis,TomDoan wrote: ↑Tue Nov 25, 2025 12:35 pm There are about six questions embedded in that. I would suggest that you take this, quite literally, one step at a time. Don't worry about the multiple step returns; just see if you can figure out how to handle the calculations with one-step multivariate returns. Note, for instance, that the "correlations" never actually enter into what you would be doing. The GARCH model gives you a series of covariance matrices; the distribution of portfolio returns uses the covariance matrix. There is nothing at all to be gained in converting a covariance matrix into variances and a correlation matrix.
mean I can apply Christoffersen with 1000 observations, and overlapping k>=2 upto 10 period intervals?TomDoan wrote: ↑Thu Nov 13, 2025 4:30 pm Clearly any test of "independence" makes no sense when your statistics are, by construction, not independent. You can probably still apply those if you sample the statistics at intervals larger than your overlap. So you need to think about what you want to test that isn't already excluded by the use of overlapping intervals.
I think what you are saying is
Thanks! In garchbacktest.rpfTomDoan wrote: ↑Sun Nov 30, 2025 8:56 am I added code to garchbacktest to do formal estimation of the POF measure by maximum likelihood. (The point estimates are the same, but it does a Wald test). If you apply it to overlapping samples, you would add the options LWINDOW=NEWEY,LAGS=horizon-1 to the MAXIMIZE to correct for overlapping windows.
Code: Select all
MAXIMIZE - Estimation by BFGS
Convergence in 3 Iterations. Final criterion was 0.0000006 <= 0.0000100
With Heteroscedasticity/Misspecification Adjusted Standard Errors
Usable Observations 520
Function Value -166.8352
Variable Coeff Std Error T-Stat Signif
************************************************************************************
1. ALPHAHAT 0.0980768575 0.0130388878 7.52187 0.00000000
Wald Test for alpha=0.100
Value -0.0019231 t-Statistic -0.14749
Standard Error 0.0130389 Signif Level 0.8827430Code: Select all
--- RATS MAXIMIZE Output ---
## NL10. Analytical Derivatives Can't Be Applied to Formula
The Error Occurred At Location 1204, Line 65 of ACKUPIECWALDQMLEAren't the 1's going to be almost identical to the 2's which will be almost identical to the 3's,...?ac_1 wrote: ↑Wed Nov 26, 2025 11:00 am Example: 10-day cumulative returns/10-day VaR forecasts:
Cumulative return from day 1 --> 10
Cumulative return from day 11--> 20
Cumulative return from day 21--> 30
These windows do not overlap, so the returns should be statistically independent in theory.
But, using non-overlapping returns reduces the sample. With 1000 OOS points, sampling
t = 1, 11, 21, ..., 991 i.e. every 10th forecast, starting at 1, giving 100 non-overlapping k-day realized returns to judge (one realized 10-day cumulative return per forecast).
Or do I start at 2, giving t = 2, 12, 22, .... 992. that's a different set of 100 giving 100 non-overlapping k-day realized returns to judge.
Or do I start at 10, giving t = 10, 20, 30, .... 1000. that's a different set of 100 giving 100 non-overlapping k-day realized returns to judge.
Those will lead to a different set of results.
So 10 different sets of 100 non-overlapping results - can I use these somehow?
If I run acWaldQMLE.src (more/less a wrap) just after the new code in garchbacktest.rpf
Code: Select all
procedure acWaldQMLE horizon trigger start end
*
type integer horizon
type series trigger
type integer start end
*
local integer startl endl lag
local real alphahat k_obs viol_ratio
local integer N_obs
*
option real alpha .01
option real sig_level .05
*
inquire(reglist) startl<<start endl<<end
# trigger
*
*
* --- Calculate observed statistics ---
sstats(mean) startl endl trigger>>alphahat
compute N_obs = %nobs
compute k_obs = fix(alphahat*N_obs)
compute viol_ratio = alphahat
compute pof=2*%nobs*((1-alphahat)*log((1-alphahat)/(1-alpha))+$
alphahat*log(alphahat/alpha))
cdf(title="POF measure") chisqr pof 1
compute %%cdf = %CDSTAT
compute lag = %if((horizon==1),lag=0,lag=(horizon-1))
*
* --- Maximize Bernoulli log-likelihood ---
nonlin(parmset=alphaParms) alphahat
compute alphahat=alpha
*
frml triggerF = %if(trigger,log(alphahat),log(1-alphahat))
*
if (horizon==1) {
maximize(robust,parmset=alphaParms) triggerF startl endl
} else {
maximize(robust,parmset=alphaParms,LWINDOW=NEWEY,LAGS=(horizon-1)) triggerF startl endl
summarize(title="Wald Test for alpha="+%strval(alpha,"*.###"),parmset=alphaParms) alphahat-alpha
comp %%SIGNIF = %SIGNIF
*
* --- Output Results ---
display "=========================================="
display "--- Wald Test (QMLE) ---"
display "=========================================="
display "From "+%datelabel(startl)+" to "+%datelabel(endl)
display "Horizon (h):" horizon
if (horizon==1)
display "Returns: Non-overlapping"
else
display "Returns: Overlapping"
display "HAC lag length (L):" lag
display
display "--- Sample Statistics ---"
display "Sample size (N):" N_obs
display "Observed exceedances (k):" k_obs
display "Violation ratio (k/N):" viol_ratio
display
display "--- Kupiec POF Test (LR) ---"
display "POF statistic (LR):" %%cdf
display
display "--- Wald QMLE ---"
display "Wald QMLE:" %%SIGNIF
display "=========================================="
*
end acWaldQMLE
Code: Select all
procedure acWaldQMLE trigger start end
*
type series trigger
type integer start end
*
local integer startl endl lag
local real alphahat k_obs viol_ratio pof
local integer N_obs
*
option real alpha .01
option real sig_level .05
option integer horizon 1
*
inquire(reglist) startl<<start endl<<end
# trigger
*
*
* --- Calculate observed statistics ---
sstats(mean) startl endl trigger>>alphahat
compute N_obs = %nobs
compute k_obs = fix(alphahat*N_obs)
compute viol_ratio = alphahat
compute pof=2*%nobs*((1-alphahat)*log((1-alphahat)/(1-alpha))+$
alphahat*log(alphahat/alpha))
disp 'pof statistic' pof
cdf(title="POF measure") chisqr pof 1
compute %%cdf = %CDSTAT
compute %%pval = %SIGNIF
compute lag = %if((horizon==1),lag=0,lag=(horizon-1))
*
* --- Maximize Bernoulli log-likelihood ---
nonlin(parmset=alphaParms) alphahat
compute alphahat=alpha
*
frml triggerF = %if(trigger,log(alphahat),log(1-alphahat))
if (horizon==1) {
maximize(robust,parmset=alphaParms) triggerF startl endl
} else {
maximize(robust,parmset=alphaParms,LWINDOW=NEWEY,LAGS=(horizon-1)) triggerF startl endl
}
summarize(title="Wald Test for alpha="+%strval(alpha,"*.###"),parmset=alphaParms) alphahat-alpha
comp %%SIGNIF = %SIGNIF
*
* --- Output Results ---
display "=========================================="
display "--- Wald Test (QMLE) ---"
display "=========================================="
display "From "+%datelabel(startl)+" to "+%datelabel(endl)
display "Horizon (h):" horizon
if (horizon==1)
display "Returns: Non-overlapping"
else
display "Returns: Overlapping"
display "HAC lag length (L):" lag
display
display "--- Sample Statistics ---"
display "Sample size (N):" N_obs
display "Observed exceedances (k):" k_obs
display "Violation ratio (k/N):" viol_ratio
display
display "--- Kupiec POF Test (LR) ---"
display "POF statistic (LR):" %%cdf
display "p-value (LR):" %%pval
display
display "--- Wald QMLE ---"
display "Wald QMLE:" %%SIGNIF
display "=========================================="
*
end acWaldQMLECode: Select all
all 6237
open data g10xrate.xls
data(format=xls,org=columns) / usxjpn
*
* Convert to percent daily returns
*
set x = 100.0*log(usxjpn/usxjpn{1})
*
* Tail probability to evaluate
*
compute alpha=.10
*
* Period of back test (roughly the last two years of the data, excluding
* the last period).
*
compute tstart=%allocend()-520
compute tend =%allocend()-1
*
set trigger tstart tend = 0.0
infobox(action=define,lower=tstart,upper=tend,progress) "GARCH Model Backtest"
garch(p=1,q=1,resids=u,hseries=h,print) / x
compute fullbeta=%beta,fullxx=%xx
do end=tstart,tend
garch(p=1,q=1,resids=u,hseries=h,print,$
initial=fullbeta,hessian=fullxx,iters=400) * end x
*
* Compute the one-step forecast for the variance
*
compute hhat=%beta(2)+%beta(3)*u(end)^2+%beta(4)*h(end)
*
* Compute the model's prediction for the VaR
*
compute limit=%beta(1)+%invnormal(alpha)*sqrt(hhat)
*
compute trigger(end)=(x(end+1)<limit)
infobox(current=end) "Model converged "+%converged
end do end
infobox(action=remove)
source(noecho) acWaldQMLE.src
@acWaldQMLE(alpha=0.1,sig_level=0.05,horizon=1) trigger tstart tend