Why is GARCH offering no predictive value? I am playing around with GARCH models for the first time (I have a stats background but basically no experience with GARCH), trying to forecast volatility in a financial time series.
I trained a GARCH(1,1) model on 3,000 data points and forecasted 1 period ahead 500 times (retraining to include new data point after each prediction is made). Below are my results (the points/circles is the original time series, the line is the GARCH volatility prediction for that timepoint).

Please correct me if I'm wrong, but it seems that the GARCH model offers no predictive value. The "predicted" volatility values spike up after a big price move. I feel like these results could be replicated by just taking a rolling window of realized past volatility (as the GARCH model appears lagging, not predictive).
Does this seem wrong, or is this what results usually look like? Has anyone had any success with something like this? Any advice for what I might be doing wrong?
I have tried specifying the mean model as ARMA(0,0) and ARMA(1,1), no significant difference.
EDIT: I am adding my code to better supplement my question. To be clear, my data is NOT time bars, but volume bars (price sampled every time a certain threshold of volume is traded) as they have been shown to have better statistical properties. These volume bars are sampled, on average, every 4 hours (though changes significantly based on the level of trading activity).
library(rugarch)
library(forecast)
volumebardata <- read.csv(file='MyCSVFile', header=TRUE)

returns <- function(vector){
  rets <- c()
  for (i in 2:length(vector)){
    rets <- c(rets, vector[i]/vector[i-1])
  }
  return(rets)
}

pricereturns <- (returns(volumebardata$VolumeBarClose))-1
priceretstrain <- pricereturns[1:3000]
priceretstest <- pricereturns[3001:3500]

# Specify a standard GARCH model with constant mean
garchspec <- ugarchspec(mean.model = list(armaOrder = c(0,0)),
                        variance.model = list(model = "eGARCH", 
                                              garchOrder=c(1,1),
                                              variance.targeting=FALSE), 
                        distribution.model = "std")


# Estimate the model
garchfit <- ugarchfit(data = priceretstrain, spec = garchspec)

predvol <- c()
for (i in 1:300){
  if (i > 1){
    # Specify a standard GARCH model with constant mean
    garchspec <- ugarchspec(mean.model = list(armaOrder = c(0,0)),
                            variance.model = list(model = "eGARCH", 
                                                  garchOrder=c(1,1),
                                              variance.targeting=FALSE), 
                            distribution.model = "std")
    
    # Estimate the model
    fulldata <- c(priceretstrain, priceretstest[1:(i-1)])
    garchfit <- ugarchfit(data = fulldata, spec = garchspec)
  }
  # Forecast volatility 1 period ahead  
  garchforecast <- ugarchforecast(fitORspec = garchfit, 
                                  n.ahead = 1)
  # Extract the predicted volatilities and print them
  predvol <- c(predvol, sigma(garchforecast))
}
plot(cumprod(priceretstest+1)[1:500], type='l')
par(new=TRUE)
plot(predvol[1:500], type='l')

Additionally, here is a zoomed in plot of the GARCH-predicted volatility (red line) vs. the squared returns (as proxy for "true" volatility, shown in black). You can quite clearly see the time-lag.

EDIT 2: Several commenters are pointing out that I might be measuring volatility incorrectly, therefore of course the GARCH predictions appear incorrect. However, I don't understand why the model is being defended when clearly the volatility predictions lag behind the actual rapid shifts in the time series (regardless of how you measure it), making the predictions obviously useless because I can derive the same kind of predictions with a V(t+1)=V(t) "prediction" model. Am I misusing GARCH? Or is it just not all that great of a volatility prediction model?

Your observation is correct. GARCH is an autoregressive model and its $h$-step-ahead predictions tend to lag $h$ steps behind, as is the case with most autoregressive models.
We often model time series processes as being hit by a new zero-mean stochastic shock every period. A special case that illustrates the lagging predictions best is an AR(1) with a zero intercept and a unit slope (in other words, a random walk):
$$
y_t=c+\varphi_1 y_{t-1}+\varepsilon_t
$$
where $c=0$ and $\varphi_1=1$. An optimal (under square loss) $h$-step-ahead point forecast is $\hat y_{t+h|t}=y_t$, i.e. the last observed value. Thus even if we were able to estimate $c$ and $\varphi_1$ with perfect precision, our optimal (!) forecast would seem to lag by $h$ steps.
Similar logic applies in the more general case of $c\neq 0$ and $\varphi\neq 1$, though the argument for the general case is more nuanced. GARCH being an autoregressive model suffers from the same problem. (The fact that GARCH is autoregressive in terms of conditional variance rather than conditional mean does not change the essence. See this answer for more detail.) But recall that that need not be a sign of forecast suboptimality, as even optimal forecasts may be characterized by it. This applies to GARCH to a large extent; in typical applications of GARCH models, conditional variance is often found to be quite close to a random walk.
