Modifying tsCV function I tried to modify the tsCV function to seperate between xreg_subset and xreg_future as Im going to  use forecasted data for validate and test samples:

y <- ts(rnorm(500))
xreg1_subset <- matrix(rnorm(1000),ncol=2)
xreg2_future <- matrix(rnorm(1000),ncol=2)
 far2 <- function(x, h, xreg, newxreg) {
   forecast(Arima(x, order=c(1,0,1), xreg=xreg), xreg=newxreg)
 }
tsCV <- function(y, far2, h=1, window=50, xreg=xreg, initial=0, ...) {
   y <- as.ts(y)
   n <- length(y)
   e <- ts(matrix(NA_real_, nrow = n, ncol = h))
   if(initial >= n) stop("initial period too long")
   tsp(e) <- tsp(y)
   if (!is.null(xreg)) {
     # Make xreg a ts object to allow easy subsetting later
     xreg <- ts(as.matrix(xreg))
     if(NROW(xreg) != length(y))
       stop("xreg must be of the same size as y")
     # Pad xreg with NAs
     xreg <- ts(rbind(xreg, matrix(NA, nrow=h, ncol=NCOL(xreg))),
                start = start(y),
                frequency = frequency(y))
   }
   if (is.null(window))
     indx <- seq(1+initial, n - 1L)
   else
     indx <- seq(window+initial, n - 1L, by = 1L)
   for (i in indx) {
     y_subset <- subset(
       y,
       start = ifelse(is.null(window), 1L,
                      ifelse(i - window >= 0L, i - window + 1L, stop("small window"))),
       end = i)
     if (is.null(xreg)) {
       fc <- try(suppressWarnings(
         forecastfunction(y_subset, h = h, ...)
       ), silent = TRUE)
     }
     else {
       xreg_subset <- subset(
         xreg1_subset,
         start = ifelse(is.null(window), 1L,
                        ifelse(i - window >= 0L, i - window + 1L, stop("small window"))),
         end = i)
       xreg_future <- subset(
         xreg2_future,
         start = i+1,
         end = i+h)
       fc <- try(suppressWarnings(
         forecastfunction(y_subset, h = h, xreg = xreg_subset, newxreg=xreg_future)
       ), silent = TRUE)
     }
     if (!is.element("try-error", class(fc))) {
       e[i, ] <- y[i + (1:h)] - fc$mean
     }
   }
   if (h == 1) {
     return(e[, 1L])
   } else {
     colnames(e) <- paste("h=", 1:h, sep = "")
     return(e)
   }
 }


But the "e" can not be generated, Im not sure where Im making mistake, I hope someone can help me about it.

# Version of tsCV with different forecast xreg from actual xreg

mytsCV <- function(y, forecastfunction, h=1, window=NULL, xreg_actual=NULL, xreg_forecast=NULL, initial=0, ...) {
  y <- as.ts(y)
  n <- length(y)
  e <- ts(matrix(NA_real_, nrow = n, ncol = h))
  if(initial >= n) 
    stop("initial period too long")
  tsp(e) <- tsp(y)
  if (!is.null(xreg_actual)) {
    # Make xreg a ts object to allow easy subsetting later
    xreg_actual <- ts(as.matrix(xreg_actual))
    xreg_forecast <- ts(as.matrix(xreg_forecast))
    if(NROW(xreg_actual) != length(y))
      stop("xreg must be of the same size as y")
    xreg_actual <- ts(rbind(xreg_actual, matrix(NA, nrow = h, ncol = NCOL(xreg_actual))),
        start = start(y), frequency = frequency(y))
    xreg_forecast <- ts(rbind(xreg_forecast, matrix(NA, nrow = h, ncol = NCOL(xreg_forecast))),
                      start = start(y), frequency = frequency(y))
  }
  if (is.null(window))
    indx <- seq(1+initial, n - 1L)
  else
    indx <- seq(window+initial, n - 1L, by = 1L)
  for (i in indx) {
    y_subset <- subset(
      y,
      start = ifelse(is.null(window), 1L,
                     ifelse(i - window >= 0L, i - window + 1L, stop("small window"))),
      end = i)
    if (is.null(xreg_actual)) {
      fc <- try(suppressWarnings(
        forecastfunction(y_subset, h = h, ...)
      ), silent = TRUE)
    }
    else {
      xreg_subset <- subset(
        xreg_actual,
        start = ifelse(is.null(window), 1L,
                       ifelse(i - window >= 0L, i - window + 1L, stop("small window"))),
        end = i)
      xreg_future <- subset(
        xreg_forecast,
        start = i+1,
        end = i+h)
      fc <- try(suppressWarnings(
        forecastfunction(y_subset, h = h, xreg = xreg_subset, newxreg=xreg_future)
      ), silent = TRUE)
    }
    if (!is.element("try-error", class(fc))) {
      e[i, ] <- y[i + seq(h)] - fc$mean[seq(h)]
    }
  }
  if (h == 1) {
    return(e[, 1L])
  } else {
    colnames(e) <- paste("h=", 1:h, sep = "")
    return(e)
  }
}

# Load forecast package
library(forecast)
#> Registered S3 method overwritten by 'quantmod':
#>   method            from
#>   as.zoo.data.frame zoo

# Generate synthetic data
y <- ts(rnorm(500))
xreg_actual <- matrix(rnorm(1000),ncol=2)
xreg_forecast <- matrix(rnorm(1000),ncol=2)

# Forecasting function
far2_xreg <- function(x, h, xreg, newxreg) {
  forecast(Arima(x, order=c(1,0,1), xreg=xreg), xreg=newxreg)
}

# Use actual xreg for training and test periods
e1 <- forecast::tsCV(y, far2_xreg, h=3, xreg=xreg_actual)
# Use actual xreg for training and forecast xreg for test period.
e2 <- mytsCV(y, far2_xreg, h=3, xreg_actual=xreg_actual, xreg_forecast=xreg_forecast)

Created on 2021-10-10 by the reprex package (v2.0.1)
