#' Computing adaptive forecast
#'
#' The functions forAD computes the adaptive one-step ahead forecast of Giraitis, Kapetanios and Price (2013).
#'
#' @usage forAD(x, p_max = 3, T0 = 50, n_v = 100, n_AR = 400,
#'       plots = TRUE, P = 50, PL = 500, p = 1, date_1 = NULL)
#' @param x A univariate numeric time series (\code{ts}, \code{xts}, \code{zoo}) object or a numeric vector or a numeric data frame column.
#' @param p_max Maximum order of the AR model. Default is \code{3}. If set to \code{0}, no AR is estimated.
#' @param T0 Length of the training period used to select tuning parameter \eqn{\rho}. Default is \code{50}.
#' @param n_v Length of the period of forecast errors used in calculation of MSFE. Default is \code{100}.
#' @param n_AR Length of the period of forecast errors used for estimation of AR and for computing correlograms. Default is \code{400}.
#' @param plots Logical. If \code{TRUE} (default), the following plots are produced: \cr 1) Rolling MSFEs (adapt, adapt+AR(\eqn{p}), adapt\eqn{^2}, adapt\eqn{^2}+AR(\eqn{p}), \eqn{p=1,...,p_{max}}), \cr 2) Rolling tuning parameters \eqn{\rho} (adapt, adapt\eqn{^2}), \cr 3) Rolling one-step ahead forecasts (adapt, adapt+AR(\eqn{p}), adapt\eqn{^2}, adapt\eqn{^2}+AR(\eqn{p}) for selected \eqn{p}) and the data, \cr 4) Rolling forecast errors (adapt, adapt+AR(\eqn{p}), adapt\eqn{^2}, adapt\eqn{^2}+AR(\eqn{p}) for selected \eqn{p}), \cr 5) Correlograms of the forecast errors. \cr Alternatively, \code{plots} can be a logical vector specifying which plots, 1)--5), to display.
#' @param P Length of the period used in plots. Default is \code{50}.
#' @param PL Length of the longer period used in plots. Default is \code{500}.
#' @param p Selected AR order used in plots. Default is \code{1}.
#' @param date_1 The date for the one-step ahead forecast when \code{x} has dates. Default is \code{NULL}.
#' @details
#' The method implements the adaptive (one-stage adapt or two-stage adapt\eqn{^2}) one-step ahead forecasting with weights \eqn{w_{j,\rho}\propto\rho^j}{w[j,rho] \propto rho^j} for \eqn{0<\rho\leq 1} (normalized to sum up to 1) in the 1st step, combined with AR forecasting in 2nd step.
#' @return An object of class '\code{forAD}', which is a list with the following components:
#' \item{for_1}{The one-step ahead forecast for all methods (adapt, adapt+AR(\eqn{p}), adapt\eqn{^2}, adapt\eqn{^2}+AR(\eqn{p}), \eqn{p=1,...,p_{max}}).}
#' \item{rho}{The tuning parameter for adaptive methods (adapt, adapt\eqn{^2}).}
#' \item{ar_coef_se}{The estimated coefficients and their standard errors for the adapt+AR(\eqn{p}), \eqn{p=1,...,p_{max}}.}
#' \item{ar_coef_se_sq}{The estimated coefficients and their standard errors for the adapt\eqn{^2}+AR(\eqn{p}), \eqn{p=1,...,p_{max}}.}
#' \item{MSFE}{The MSFE for all methods.}
#' \item{for_in}{The rolling one-step ahead forecasts for all methods.}
#' \item{rho_in}{The rolling tuning parameters for adaptive methods.}
#' \item{MSFE_in}{The rolling MSFE for all methods.}
#' \item{err_in}{The rolling one-step ahead forecast errors for all methods.}
#' \item{data}{The original data.}
#' @note
#' Missing values are not allowed. \cr Permitted sample size: \eqn{N\geq25+2p_{max}} when \code{p_max > 0} and \eqn{N\geq21} when \code{p_max = 0}.
#' @author
#' Violetta Dalla, Liudas Giraitis and George Kapetanios
#' @references
#' Giraitis L, Kapetanios G, Price S (2013). "Adaptive Forecasting in the Presence of Recent and Ongoing Structural Change." Journal of Econometrics, 177(2), 153-170. \doi{doi:10.1016/j.jeconom.2013.04.003}. \cr
#' Giraitis L, Kapetanios G, Mansur M, Price S (2015). "Forecasting Under Structural Change." In J Beran, Y Feng, H Hebbel (eds.), Empirical Economic and Financial Research: Theory, Methods and Practice, pp. 401–419. Springer International Publishing, Cham. \doi{doi:10.1007/978-3-319-03122-4_25}.
#' @examples
#' # Sample x contains 200 independent standard normal data.
#' x <- rnorm(200)
#' print(forAD(x, plots = FALSE))
#' # Set plots to TRUE to see the plots.
#' \donttest{print(forAD(x))}
#' @importFrom stats optimize lm vcov time pnorm is.ts
#' @importFrom graphics plot lines points matplot matpoints abline legend axis axis.Date title strwidth
#' @importFrom lubridate is.Date
#' @importFrom grDevices colorRampPalette
#' @importFrom knitr kable
#' @importFrom testcorr ac.test
#' @importFrom xts is.xts
#' @importFrom zoo is.zoo
#' @export

forAD <- function(x, p_max = 3, T0 = 50, n_v = 100, n_AR = 400, plots = TRUE, P = 50, PL = 500, p = 1, date_1 = NULL) {

  if (is.null(x)) stop()
  if (is.numeric(x) | is.ts(x) | is.xts(x) | is.zoo(x) | is.data.frame(x)) {}
  else{
    stop('argument "x" must be numeric vector or numeric time series (ts, xts, zoo) object or numeric data frame variable')
  }
  if (!is.numeric(p_max)) stop('argument "p_max" must be numeric')
  if (p_max != ceiling(p_max) | p_max < 0) stop('argument "p_max" must be a positive integer')
  if (!is.numeric(T0)) stop('argument "T0" must be numeric')
  if (T0 != ceiling(T0) | T0 < 0) stop('argument "T0" must be a positive integer')
  if (!is.numeric(n_v)) stop('argument "n_v" must be numeric')
  if (n_v != ceiling(n_v) | n_v < 0) stop('argument "n_v" must be a positive integer')
  if (!is.numeric(n_AR)) stop('argument "n_AR" must be numeric')
  if (n_AR != ceiling(n_AR) | n_AR < 0) stop('argument "n_AR" must be a positive integer')
  if (!is.logical(plots)) stop('argument "plots" must be logical')
  if (!length(plots) %in% c(1, 5)) stop('argument "plots" must be a logical vector of length 1 or 5')
  if (!is.numeric(P)) stop('argument "P" must be numeric')
  if (P != ceiling(P) | P < 0) stop('argument "P" must be a positive integer')
  if (!is.numeric(PL)) stop('argument "PL" must be numeric')
  if (PL != ceiling(PL) | PL < 0) stop('argument "PL" must be a positive integer')
  if (!is.numeric(p)) stop('argument "p" must be numeric')
  if (p != ceiling(p) | p < 0 | (p > p_max & p_max != 0)) stop('argument "p" must be a positive integer less or equal to "p_max"')
  if (NCOL(x) != 1) stop('argument "x" must be univariate')
  if (any(is.na(x))) stop('argument "x" must not contain missing values')
  if (p_max > 0 & length(x) < 25 + 2 * p_max) stop('Permitted sample size: N >= 25 + 2 * p_max')
  if (p_max == 0 & length(x) < 21) stop('Permitted sample size: N >= 21')
  if (!is.null(date_1)) {
    is_format_correct <- grepl("^\\d{4}-\\d{2}-\\d{2}$", date_1)
    is_real_date <- !is.na(as.Date(date_1, format = "%Y-%m-%d"))
    if (!is_format_correct || !is_real_date) {
      stop('argument "date_1" is not a valid date in "YYYY-MM-DD" format')
    }
  }

  dates <- time(x)
  x <- as.numeric(x)
  N.x <- NROW(x)
  if (is.null(date_1)) {
    date_1 <- N.x + 1
  }
  else {
    date_1 <- as.Date(date_1)
  }

  forAD.x <- forADar(x, T0 = T0, M0 = n_v, p_max = p_max, E0 = n_AR)
  N1 <- NROW(forAD.x$for.in)
  err.x <- forAD.x$err.in[11:N1]
  forADsq.x <- forADar(err.x, T0 = T0, M0 = n_v, p_max = p_max, E0 = n_AR)
  N2 <- NROW(forADsq.x$for.in)

  if (p_max != 0) {
    obs <- dates[(N.x - N2 + 1):N.x]
    for_1 <- cbind.data.frame(date_1, forAD.x$for1, t(forAD.x$for1.ar), forAD.x$for1 + forADsq.x$for1, t(forAD.x$for1.ar + forADsq.x$for1.ar))
    rho <- cbind.data.frame(date_1, forAD.x$rho, forADsq.x$rho)
    ar_coef_se <- forAD.x$ar.coef.se
    ar_coef_se_sq <- forADsq.x$ar.coef.se
    MSFE <- cbind.data.frame(date_1, forAD.x$msfe, t(forAD.x$msfe.ar), forADsq.x$msfe, t(forADsq.x$msfe.ar))
    if (p_max == 1) {
      for_in <- cbind.data.frame(obs, forAD.x$for.in[(N1 - N2 + 1):N1], forAD.x$for.ar.in[(N1 - N2 + 1):N1], forAD.x$for.in[(N1 - N2 + 1):N1] + forADsq.x$for.in, forAD.x$for.ar.in[(N1 - N2 + 1):N1] + forADsq.x$for.ar.in)
      rho_in <- cbind.data.frame(obs, forAD.x$rho.in[(N1 - N2 + 1):N1], forADsq.x$rho.in)
      MSFE_in <- cbind.data.frame(obs, forAD.x$msfe.in[(N1 - N2 + 1):N1], forAD.x$msfe.ar.in[(N1 - N2 + 1):N1], forADsq.x$msfe.in, forADsq.x$msfe.ar.in)
      err_in <- cbind.data.frame(obs, forAD.x$err.in[(N1 - N2 + 1):N1], forAD.x$err.ar.in[(N1 - N2 + 1):N1], forADsq.x$err.in, forADsq.x$err.ar.in)
    }
    if (p_max != 1) {
      for_in <- cbind.data.frame(obs, forAD.x$for.in[(N1 - N2 + 1):N1], forAD.x$for.ar.in[(N1 - N2 + 1):N1, ], forAD.x$for.in[(N1 - N2 + 1):N1] + forADsq.x$for.in, forAD.x$for.ar.in[(N1 - N2 + 1):N1, ] + forADsq.x$for.ar.in)
      rho_in <- cbind.data.frame(obs, forAD.x$rho.in[(N1 - N2 + 1):N1], forADsq.x$rho.in)
      MSFE_in <- cbind.data.frame(obs, forAD.x$msfe.in[(N1 - N2 + 1):N1], forAD.x$msfe.ar.in[(N1 - N2 + 1):N1, ], forADsq.x$msfe.in, forADsq.x$msfe.ar.in)
      err_in <- cbind.data.frame(obs, forAD.x$err.in[(N1 - N2 + 1):N1], forAD.x$err.ar.in[(N1 - N2 + 1):N1, ], forADsq.x$err.in, forADsq.x$err.ar.in)
    }
  }

  if (p_max == 0) {
    obs <- dates[(N.x - N2 + 1):N.x]
    for_1 <- cbind.data.frame(date_1, forAD.x$for1, forAD.x$for1 + forADsq.x$for1)
    rho <- cbind.data.frame(date_1, forAD.x$rho, forADsq.x$rho)
    MSFE <- cbind.data.frame(date_1, forAD.x$msfe, forADsq.x$msfe)
    for_in <- cbind.data.frame(obs, forAD.x$for.in[(N1 - N2 + 1):N1], forAD.x$for.in[(N1 - N2 + 1):N1] + forADsq.x$for.in)
    rho_in <- cbind.data.frame(obs, forAD.x$rho.in[(N1 - N2 + 1):N1], forADsq.x$rho.in)
    MSFE_in <- cbind.data.frame(obs, forAD.x$msfe.in[(N1 - N2 + 1):N1], forADsq.x$msfe.in)
    err_in <- cbind.data.frame(obs, forAD.x$err.in[(N1 - N2 + 1):N1], forADsq.x$err.in)
  }

  if (NROW(plots) == 1) {
    plotM <- plots
    plotR <- plots
    plotF <- plots
    plotE <- plots
    plotA <- plots
  }
  if (NROW(plots) == 5) {
    plotM <- plots[1]
    plotR <- plots[2]
    plotF <- plots[3]
    plotE <- plots[4]
    plotA <- plots[5]
  }

  if (p_max != 0) {
    P0 <- min(c(P, N2))
    Pmax <- min(c(PL, N2))
    A0 <- min(c(n_AR, N2))
    if (plotM == TRUE) {
      myplot.M2(MSFE, MSFE_in[(N2 - P0 + 1):N2, ], p_max, date_1)
      Sys.sleep(2)
    }
    if (plotR == TRUE) {
      myplot.R(rho, rho_in[(N2 - P0 + 1):N2, ], date_1)
      Sys.sleep(2)
    }
    if (plotF == TRUE) {
      myplot.F(x[(N.x - P0 + 1):N.x], for_1[c(1, 2)], for_in[(N2 - P0 + 1):N2, c(1, 2)], 0, 1, TRUE, date_1)
      Sys.sleep(2)
      myplot.F(x[(N.x - P0 + 1):N.x], for_1[c(1, p + 2)], for_in[(N2 - P0 + 1):N2, c(1, p + 2)], p, 1, FALSE, date_1)
      Sys.sleep(2)
      if (Pmax > P0) {
        myplot.F(x[(N.x - Pmax + 1):N.x], for_1[c(1, 2)], for_in[(N2 - Pmax + 1):N2, c(1, 2)], 0, 1, FALSE, date_1)
        Sys.sleep(2)
        myplot.F(x[(N.x - Pmax + 1):N.x], for_1[c(1, p + 2)], for_in[(N2 - Pmax + 1):N2, c(1, p + 2)], p, 1, FALSE, date_1)
        Sys.sleep(2)
      }
      myplot.F(x[(N.x - P0 + 1):N.x], for_1[c(1, p_max + 3)], for_in[(N2 - P0 + 1):N2, c(1, p_max + 3)], 0, 2, FALSE, date_1)
      Sys.sleep(2)
      myplot.F(x[(N.x - P0 + 1):N.x], for_1[c(1, p + p_max + 3)], for_in[(N2 - P0 + 1):N2, c(1, p + p_max + 3)], p, 2, FALSE, date_1)
      Sys.sleep(2)
      if (Pmax > P0) {
        myplot.F(x[(N.x - Pmax + 1):N.x], for_1[c(1, p_max + 3)], for_in[(N2 - Pmax + 1):N2, c(1, p_max + 3)], 0, 2, FALSE, date_1)
        Sys.sleep(2)
        myplot.F(x[(N.x - Pmax + 1):N.x], for_1[c(1, p + p_max + 3)], for_in[(N2 - Pmax + 1):N2, c(1, p + p_max + 3)], p, 2, FALSE, date_1)
        Sys.sleep(2)
      }
    }
    if (plotE == TRUE) {
      myplot.E1F(err_in[(N2 - P0 + 1):N2, 1:2], forADsq.x$for1, forADsq.x$for.in[(N2 - P0 + 1):N2], date_1)
      Sys.sleep(2)
      myplot.E2(err_in[(N2 - P0 + 1):N2, c(1, p + 2, p + p_max + 3)], p)
      Sys.sleep(2)
    }
    if (plotA == TRUE & NROW(err_in) >= 3) {
      ac.test(err_in[(N2 - A0 + 1):N2, 2], max.lag = min(10, A0 - 1), plot = c(TRUE, FALSE), var.name = "forecast errors (Adapt)", scale.font = 1.05)
      Sys.sleep(2)
      for (pp in 1:p_max) {
        ac.test(err_in[(N2 - A0 + 1):N2, pp + 2], max.lag = min(10, A0 - 1), plot = c(TRUE, FALSE), var.name = paste0("forecast errors (Adapt+AR(", pp, "))"), scale.font = 1.05)
        Sys.sleep(2)
      }
      ac.test(err_in[(N2 - A0 + 1):N2, p_max + 3], max.lag = min(10, A0 - 1), plot = c(TRUE, FALSE), var.name = "forecast errors (Adapt\u00B2)", scale.font = 1.05)
      Sys.sleep(2)
      for (pp in 1:p_max) {
        ac.test(err_in[(N2 - A0 + 1):N2, pp + p_max + 3], max.lag = min(10, A0 - 1), plot = c(TRUE, FALSE), var.name = paste0("forecast errors (Adapt\u00B2+AR(", pp, "))"), scale.font = 1.05)
        Sys.sleep(2)
      }
    }
  }

  if (p_max == 0) {
    P0 <- min(c(P, N2))
    Pmax <- min(c(PL, N2))
    A0 <- min(c(n_AR, N2))
    if (plotM == TRUE) {
      myplot.M1(MSFE, MSFE_in[(N2 - P0 + 1):N2, ], date_1)
      Sys.sleep(2)
    }
    if (plotR == TRUE) {
      myplot.R(rho, rho_in[(N2 - P0 + 1):N2, ], date_1)
      Sys.sleep(2)
    }
    if (plotF == TRUE) {
      myplot.F(x[(N.x - P0 + 1):N.x], for_1[c(1, 2)], for_in[(N2 - P0 + 1):N2, c(1, 2)], 0, 1, TRUE, date_1)
      Sys.sleep(2)
      if (Pmax > P0) {
        myplot.F(x[(N.x - Pmax + 1):N.x], for_1[c(1, 2)], for_in[(N2 - Pmax + 1):N2, c(1, 2)], 0, 1, FALSE, date_1)
        Sys.sleep(2)
      }
      myplot.F(x[(N.x - P0 + 1):N.x], for_1[c(1, 3)], for_in[(N2 - P0 + 1):N2, c(1, 3)], 0, 2, FALSE, date_1)
      Sys.sleep(2)
      if (Pmax > P0) {
        myplot.F(x[(N.x - Pmax + 1):N.x], for_1[c(1, 3)], for_in[(N2 - Pmax + 1):N2, c(1, 3)], 0, 2, FALSE, date_1)
        Sys.sleep(2)
      }
    }
    if (plotE == TRUE) {
      myplot.E1F(err_in[(N2 - P0 + 1):N2, 1:2], forADsq.x$for1, forADsq.x$for.in[(N2 - P0 + 1):N2], date_1)
      Sys.sleep(2)
      myplot.E2(err_in[(N2 - P0 + 1):N2, c(1, 2, 3)], 0)
      Sys.sleep(2)
    }
    if (plotA == TRUE & NROW(err_in) >= 3) {
      ac.test(err_in[(N2 - A0 + 1):N2, 2], max.lag = min(10, A0 - 1), plot = c(TRUE, FALSE), var.name = "forecast errors (Adapt)", scale.font = 1.05)
      Sys.sleep(2)
      ac.test(err_in[(N2 - A0 + 1):N2, 3], max.lag = min(10, A0 - 1), plot = c(TRUE, FALSE), var.name = "forecast errors (Adapt\u00B2)", scale.font = 1.05)
    }
  }

  if (p_max != 0) {
    out_names <-c("Obs", "Adapt", "Adapt^2")
    out_names2 <- c("Obs", "Adapt")
    for (pp in 1:p_max) {
      out_names2 <- c(out_names2, paste0("Adapt+AR(", pp, ")"))
    }
    out_names2 <- c(out_names2, "Adapt^2")
    for (pp in 1:p_max) {
      out_names2 <- c(out_names2, paste0("Adapt^2+AR(", pp, ")"))
    }
    colnames(for_1) <- out_names2
    colnames(rho) <- out_names
    colnames(MSFE) <- out_names2
    colnames(for_in) <- out_names2
    colnames(rho_in) <- out_names
    colnames(MSFE_in) <- out_names2
    colnames(err_in) <- out_names2

    forAD.out <- structure(list(for_1 = for_1, rho = rho, ar_coef_se = ar_coef_se, ar_coef_se_sq = ar_coef_se_sq, MSFE = MSFE, for_in = for_in, rho_in = rho_in, MSFE_in = MSFE_in, err_in = err_in, data = x), class = "forAD")
  }

  if (p_max == 0) {
    out_names <- c("Obs", "Adapt", "Adapt^2")
    colnames(for_1) <- out_names
    colnames(rho) <- out_names
    colnames(MSFE) <- out_names
    colnames(for_in) <- out_names
    colnames(rho_in) <- out_names
    colnames(MSFE_in) <- out_names
    colnames(err_in) <- out_names

    forAD.out <- structure(list(for_1 = for_1, rho = rho, MSFE = MSFE, for_in = for_in, rho_in = rho_in, MSFE_in = MSFE_in, err_in = err_in, data = x), class = "forAD")
  }

  return(invisible(forAD.out))
}

#' @export

print.forAD <- function(x, ...) {

  p_max <- (NCOL(x$for_1) - 1) / 2 - 1
  n_in <- NROW(x$for_in)

  k0 <- min(10, n_in)
  if (k0 == 10) {
    text.k <- c("k=10", "k=9", "k=8", "k=7", "k=6", "k=5", "k=4", "k=3", "k=2", "k=1", "k=0")
  }
  if (k0 < 10) {
    text.k <- "k=0"
    for (kk in 1:n_in) {
      text.k <- c(paste0("k=", kk), text.k)
    }
  }

  if (p_max != 0) {
    msg1a <- "Adaptive+AR and adaptive\u00B2+AR one-step ahead forecast output"
    msg1b <- "-----------------------------------------------------------"
    msg2a <- "Adaptive+AR and adaptive\u00B2+AR one-step ahead forecast output x[N-k+1|N-k]"
    msg2b <- "------------------------------------------------------------------------"

    text.adapt <- "Adapt"
    text.adaptsq <- "Adapt\u00B2"
    text.adaptAR <- "Adapt"
    text.adaptsqAR <- "Adapt\u00B2"
    for (pp in 1:p_max) {
      text.adaptAR <- c(text.adaptAR, paste0("Adapt+AR(", pp, ")"))
      text.adaptsqAR <- c(text.adaptsqAR, paste0("Adapt\u00B2+AR(", pp, ")"))
    }

    df_for_msfe <- cbind.data.frame(myformat(t(x$for_1[2:(p_max + 2)]), mydecimals = mydecimals(t(x$for_1[2:(p_max + 2)])), mydim = c(p_max + 1, 1)),
                                    myformat(t(x$MSFE[2:(p_max + 2)]), mydecimals = mydecimals(t(x$MSFE[2:(p_max + 2)])), mydim = c(p_max + 1, 1)),
                                    myformat(t(c(1, as.numeric(x$MSFE[3:(p_max + 2)]) / as.numeric(x$MSFE[2]))), mydecimals = mydecimals(t(c(1, as.numeric(x$MSFE[3:(p_max + 2)]) / as.numeric(x$MSFE[2])))), mydim = c(p_max + 1, 1)))
    df_for_msfe_sq <- cbind.data.frame(myformat(t(x$for_1[(p_max + 3):(2 * p_max + 3)]), mydecimals = mydecimals(t(x$for_1[(p_max + 3):(2 * p_max + 3)])), mydim = c(p_max + 1, 1)),
                                       myformat(t(x$MSFE[(p_max + 3):(2 * p_max + 3)]), mydecimals = mydecimals(t(x$MSFE[(p_max + 3):(2 * p_max + 3)])), mydim = c(p_max + 1, 1)),
                                       myformat(t(as.numeric(x$MSFE[(p_max + 3):(2 * p_max + 3)]) / as.numeric(x$MSFE[2])), mydecimals = mydecimals(t(c(1, as.numeric(x$MSFE[(p_max + 3):(2 * p_max + 3)]) / as.numeric(x$MSFE[2])))), mydim = c(p_max + 1, 1)))
    fake_line <- c("--------", "----", "-------------")
    df_for_msfe_12 <- rbind.data.frame(df_for_msfe, fake_line, df_for_msfe_sq)
    colnames(df_for_msfe_12) <- c("Forecast", "MSFE", "Relative MSFE")
    rownames(df_for_msfe_12) <- c(text.adaptAR, "------------", text.adaptsqAR)

    text.AR <- NULL
    for (pp in 1:p_max) {
      text.AR <- c(text.AR, c(paste0("AR(", pp, ")"), ""))
    }
    text.const.ar <- "const"
    for (pp in 1:p_max) {
      text.const.ar <- c(text.const.ar, paste0("ar", pp))
    }

    table_ar <- x$ar_coef_se
    table_ar_fmt <- myformat(table_ar, mydecimals = mydecimals(table_ar), mydim = dim(table_ar))
    for (i in 1:p_max) {
      for (j in 1:(p_max + 1)) {
        table_ar_fmt[2 * i, j] <- paste0("(", table_ar_fmt[2 * i, j], ")")
      }
    }
    for (i in 1:p_max) {
      for (j in 1:(p_max + 1)) {
        t_ar <- table_ar[2 * i - 1, j] / table_ar[2 * i, j]
        pv_ar <- 2 * (1 - pnorm(abs(t_ar)))
        if (pv_ar < 0.01 & !is.na(pv_ar)) {
          table_ar_fmt[2 * i  - 1, j] <- paste0(table_ar_fmt[2 * i  - 1, j], "***")
        }
        if (pv_ar >= 0.01 & pv_ar < 0.05 & !is.na(pv_ar)) {
          table_ar_fmt[2 * i  - 1, j] <- paste0(table_ar_fmt[2 * i  - 1, j], "**")
        }
        if (pv_ar >= 0.05 & pv_ar < 0.1 & !is.na(pv_ar)) {
          table_ar_fmt[2 * i  - 1, j] <- paste0(table_ar_fmt[2 * i  - 1, j], "*")
        }
      }
    }
    df_ar <- cbind.data.frame(text.AR, rep(c("", "s.e."), p_max), table_ar_fmt)
    rownames(df_ar) <- NULL
    colnames(df_ar) <- c("", "", text.const.ar)

    table_ar_sq <- x$ar_coef_se_sq
    table_ar_sq_fmt <- myformat(table_ar_sq, mydecimals = mydecimals(table_ar_sq), mydim = dim(table_ar_sq))
    for (i in 1:p_max) {
      for (j in 1:(p_max + 1)) {
        table_ar_sq_fmt[2 * i, j] <- paste0("(", table_ar_sq_fmt[2 * i, j], ")")
      }
    }
    for (i in 1:p_max) {
      for (j in 1:(p_max + 1)) {
        t_ar_sq <- table_ar_sq[2 * i - 1, j] / table_ar_sq[2 * i, j]
        pv_ar_sq <- 2 * (1 - pnorm(abs(t_ar_sq)))
        if (pv_ar_sq < 0.01 & !is.na(pv_ar_sq)) {
          table_ar_sq_fmt[2 * i  - 1, j] <- paste0(table_ar_sq_fmt[2 * i  - 1, j], "***")
        }
        if (pv_ar_sq >= 0.01 & pv_ar_sq < 0.05 & !is.na(pv_ar_sq)) {
          table_ar_sq_fmt[2 * i  - 1, j] <- paste0(table_ar_sq_fmt[2 * i  - 1, j], "**")
        }
        if (pv_ar_sq >= 0.05 & pv_ar_sq < 0.1 & !is.na(pv_ar_sq)) {
          table_ar_sq_fmt[2 * i  - 1, j] <- paste0(table_ar_sq_fmt[2 * i  - 1, j], "*")
        }
      }
    }
    df_ar_sq <- cbind.data.frame(text.AR, rep(c("", "s.e."), p_max), table_ar_sq_fmt)
    rownames(df_ar_sq) <- NULL
    colnames(df_ar_sq) <- c("", "", text.const.ar)

    rmsfe_in <- t(x$MSFE_in[(NROW(x$MSFE_in) - (k0 - 1)):NROW(x$MSFE_in), 3:(p_max + 2)]) / x$MSFE_in[(NROW(x$MSFE_in) - (k0 - 1)):NROW(x$MSFE_in), 2]
    rmsfe_in <- myformat(rmsfe_in, mydecimals = mydecimals(rmsfe_in), mydim = dim(rmsfe_in))
    rmsfe_1 <- x$MSFE[3:(p_max + 2)] / as.numeric(x$MSFE[2])
    rmsfe_1 <- myformat(rmsfe_1, mydecimals = mydecimals(rmsfe_1), mydim = dim(rmsfe_1))
    df_rmsfe <- cbind(rmsfe_in, t(rmsfe_1))
    colnames(df_rmsfe) <- text.k
    row_ones <- matrix(1, nrow = 1, ncol = k0 + 1)
    colnames(row_ones) <- text.k
    df_rmsfe <- rbind(row_ones, df_rmsfe)
    rmsfe_sq_in <- t(x$MSFE_in[(NROW(x$MSFE_in) - (k0 - 1)):NROW(x$MSFE_in), (p_max + 3):(2 * p_max + 3)]) / x$MSFE_in[(NROW(x$MSFE_in) - (k0 - 1)):NROW(x$MSFE_in), 2]
    rmsfe_sq_in <- myformat(rmsfe_sq_in, mydecimals = mydecimals(rmsfe_sq_in), mydim = dim(rmsfe_sq_in))
    rmsfe_sq_1 <- x$MSFE[(p_max + 3):(2 * p_max + 3)] / as.numeric(x$MSFE[2])
    rmsfe_sq_1 <- myformat(rmsfe_sq_1, mydecimals = mydecimals(rmsfe_sq_1), mydim = dim(rmsfe_sq_1))
    df_rmsfe_sq <- cbind(rmsfe_sq_in, t(rmsfe_sq_1))
    colnames(df_rmsfe_sq) <- text.k
    fake_line <- rep("----", k0 + 1)
    df_rmsfe_12 <- rbind.data.frame(df_rmsfe, fake_line, df_rmsfe_sq)
    rownames(df_rmsfe_12) <- c(text.adaptAR, "------------", text.adaptsqAR)

    df_data <- t(c(x$data[(NROW(x$data) - (k0 - 1)):NROW(x$data)], NA))
    df_data <- myformat(df_data, mydecimals = mydecimals(df_data), mydim = dim(df_data))
    df_for <- cbind(t(x$for_in[(NROW(x$for_in) - (k0 - 1)):NROW(x$for_in), 2:(p_max + 2)]),
                    t(x$for_1[2:(p_max + 2)]))
    df_for <- myformat(df_for, mydecimals = mydecimals(df_for), mydim = dim(df_for))
    df_for_sq <- cbind(t(x$for_in[(NROW(x$for_in) - (k0 - 1)):NROW(x$for_in), (p_max + 3):(2 * p_max + 3)]),
                       t(x$for_1[(p_max + 3):(2 * p_max + 3)]))
    df_for_sq <- myformat(df_for_sq, mydecimals = mydecimals(df_for_sq), mydim = dim(df_for_sq))
    fake_line <- rep("----", , k0 + 1)
    df_for_12 <- rbind.data.frame(df_data, fake_line, df_for, fake_line, df_for_sq)
    rownames(df_for_12) <- c("Data", "-----------", text.adaptAR, "------------", text.adaptsqAR)
    colnames(df_for_12) <- text.k

    df_rho <- t(as.numeric(c(x$rho_in[(NROW(x$rho_in) - (k0 - 1)):NROW(x$rho_in), 2], x$rho[2])))
    df_rho <- myformat(df_rho, mydecimals = mydecimals(df_rho), mydim = dim(df_rho))
    df_rho_sq <- t(as.numeric(c(x$rho_in[(NROW(x$rho_in) - (k0 - 1)):NROW(x$rho_in), 3], x$rho[3])))
    df_rho_sq <- myformat(df_rho_sq, mydecimals = mydecimals(df_rho_sq), mydim = dim(df_rho_sq))
    df_rho_12 <- rbind.data.frame(df_rho, df_rho_sq)
    rownames(df_rho_12) <- c(text.adapt, text.adaptsq)
    colnames(df_rho_12) <- text.k

    cat("\n")
    cat(msg1b, "\n")
    cat(msg1a, "\n")
    cat(msg1b, "\n")
    cat("\n")
    cat("Forecasts x[N+1|N], MSFE[N+1|N], RMSFE[N+1|N]")
    print(kable(df_for_msfe_12, align = "r", format = "pipe"))
    cat("\n")
    cat("\n")
    cat("AR coefficients and standard errors (adapt+AR)")
    print(kable(df_ar, align = c("l", "l", rep("r", p_max + 1)), format = "pipe"))
    cat("\n")
    cat("AR coefficients and standard errors (adapt\u00B2+AR)")
    print(kable(df_ar_sq, align = c("l", "l", rep("r", p_max + 1)), format = "pipe"))
    cat("\n")
    cat("\n")
    cat(msg2b, "\n")
    cat(msg2a, "\n")
    cat(msg2b, "\n")
    cat("\n")
    cat("Relative mean squared forecast errors RMSFE[N-k+1|N-k]")
    print(kable(df_rmsfe_12, align = "r", format = "pipe"))
    cat("\n")
    cat("\n")
    cat("Forecasts x[N-k+1|N-k]")
    options(knitr.kable.NA = "")
    print(kable(df_for_12, align = "r", format = "pipe"), na.print = "")
    cat("\n")
    cat("\n")
    cat("Tuning parameters rho[N-k+1|N-k]")
    print(kable(df_rho_12, align = "r", format = "pipe"))
    cat("\n")
  }

  if (p_max == 0) {
    msg1a <- "Adaptive and adaptive\u00B2 one-step ahead forecast output"
    msg1b <- "-----------------------------------------------------"
    msg2a <- "Rolling adaptive and adaptive\u00B2 one-step ahead forecast output"
    msg2b <- "-------------------------------------------------------------"

    text.adapt <- "Adapt"
    text.adaptsq <- "Adapt\u00B2"

    df_for_msfe <- cbind.data.frame(myformat(x$for_1[2], mydecimals = mydecimals(x$for_1[2]), mydim = c(1, 1)),
                                    myformat(x$MSFE[2], mydecimals = mydecimals(x$MSFE[2]), mydim = c(1, 1)))
    df_for_msfe_sq <- cbind.data.frame(myformat(x$for_1[3], mydecimals = mydecimals(x$for_1[3]), mydim = c(1, 1)),
                                       myformat(x$MSFE[3], mydecimals = mydecimals(x$MSFE[3]), mydim = c(1, 1)))
    df_for_msfe_12 <- rbind.data.frame(df_for_msfe, df_for_msfe_sq)
    rownames(df_for_msfe_12) <- c(text.adapt, text.adaptsq)
    colnames(df_for_msfe_12) <- c("Forecast", "MSFE")

    df_msfe <- t(as.numeric(c(x$MSFE_in[(NROW(x$MSFE_in) - (k0 - 1)):NROW(x$MSFE_in), 2], x$MSFE[2])))
    df_msfe <- myformat(df_msfe, mydecimals = mydecimals(df_msfe), mydim = dim(df_msfe))
    df_msfe_sq <- t(as.numeric(c(x$MSFE_in[(NROW(x$MSFE_in) - (k0 - 1)):NROW(x$MSFE_in), 3], x$MSFE[3])))
    df_msfe_sq <- myformat(df_msfe_sq, mydecimals = mydecimals(df_msfe_sq), mydim = dim(df_msfe_sq))
    df_msfe_12 <- rbind.data.frame(df_msfe, df_msfe_sq)
    rownames(df_msfe_12) <- c(text.adapt, text.adaptsq)
    colnames(df_msfe_12) <- text.k

    df_data <- t(c(x$data[(NROW(x$data) - (k0 - 1)):NROW(x$data)], NA))
    df_data <- myformat(df_data, mydecimals = mydecimals(df_data), mydim = dim(df_data))
    df_for <- t(as.numeric(c(x$for_in[(NROW(x$for_in) - (k0 - 1)):NROW(x$for_in), 2], x$for_1[2])))
    df_for <- myformat(df_for, mydecimals = mydecimals(df_for), mydim = dim(df_for))
    df_for_sq <- t(as.numeric(c(x$for_in[(NROW(x$for_in) - (k0 - 1)):NROW(x$for_in), 3], x$for_1[3])))
    df_for_sq <- myformat(df_for_sq, mydecimals = mydecimals(df_for_sq), mydim = dim(df_for_sq))
    fake_line <- rep("----", k0 + 1)
    df_for_12 <- rbind.data.frame(df_data, fake_line, df_for, df_for_sq)
    rownames(df_for_12) <- c("Data", "------", text.adapt, text.adaptsq)
    colnames(df_for_12) <- text.k

    df_rho <- t(as.numeric(c(x$rho_in[(NROW(x$rho_in) - (k0 - 1)):NROW(x$rho_in), 2], x$rho[2])))
    df_rho <- myformat(df_rho, mydecimals = mydecimals(df_rho), mydim = dim(df_rho))
    df_rho_sq <- t(as.numeric(c(x$rho_in[(NROW(x$rho_in) - (k0 - 1)):NROW(x$rho_in), 3], x$rho[3])))
    df_rho_sq <- myformat(df_rho_sq, mydecimals = mydecimals(df_rho_sq), mydim = dim(df_rho_sq))
    df_rho_12 <- rbind.data.frame(df_rho, df_rho_sq)
    rownames(df_rho_12) <- c(text.adapt, text.adaptsq)
    colnames(df_rho_12) <- text.k

    cat("\n")
    cat(msg1b, "\n")
    cat(msg1a, "\n")
    cat(msg1b, "\n")
    cat("\n")
    cat("Forecasts x[N+1|N], MSFE[N+1|N]")
    print(kable(df_for_msfe_12, align = "r", format = "pipe"))
    cat("\n")
    cat("\n")
    cat(msg2b, "\n")
    cat(msg2a, "\n")
    cat(msg2b, "\n")
    cat("\n")
    cat("Mean squared forecast errors MSFE[N-k+1|N-k]")
    print(kable(df_msfe_12, align = "r", format = "pipe"))
    cat("\n")
    cat("\n")
    cat("Forecasts x[N-k+1|N-k]")
    print(kable(df_for_12, align = "r", format = "pipe"))
    cat("\n")
    cat("\n")
    cat("Tuning parameters rho[N-k+1|N-k]")
    print(kable(df_rho_12, align = "r", format = "pipe"))
    cat("\n")
  }
}

forADn1 <- function(xn, t0) {
  n <- NROW(xn)
  n0 <- n - t0 + 1
  Q.rho <- function(rho) {
    k.rho <- rho ^ seq(1, n, 1)
    cumsum.k.rho <- cumsum(k.rho)
    den_xn.forin <- cumsum.k.rho[(n0 - 1):(n - 1)]
    num_xn.forin <- matrix(NA, t0, 1)
    num_xn.forin[1] <- sum(k.rho[1:(n0 - 1)] * rev(xn[1:(n0 - 1)]))
    if (t0 >= 2) {
      for (s in 2:t0) {
        num_xn.forin[s] <- rho * (xn[n0 + s - 2] + num_xn.forin[s - 1])
      }
    }
    xn.forin <- num_xn.forin / den_xn.forin
    return(mean((xn[n0:n] - xn.forin) ^ 2))
  }
  optQ.rho <- optimize(Q.rho, lower = 0.001, upper = 1)
  rho.n <- optQ.rho$minimum
  Q.n <- optQ.rho$objective
  k.rho.n <- rho.n ^ seq(1, n, 1)
  for.n <- sum(k.rho.n * rev(xn)) / sum(k.rho.n)
  return(c(for.n, rho.n, Q.n))
}

forADar <- function(x, T0, M0, p_max, E0) {
  N <- NROW(x)
  forAD.N1 <- forADn1(x, min(c(T0, N - 1)))
  for1 <- forAD.N1[1]
  rho <- forAD.N1[2]
  for.in <- matrix(NA, N - 3, 1)
  rho.in <- matrix(NA, N - 3, 1)
  for (t in 4:N) {
    forAD.t <- forADn1(x[1:(t - 1)], min(c(T0, t - 2)))
    for.in[t - 3] <- forAD.t[1]
    rho.in[t - 3] <- forAD.t[2]
  }

  err.in <- x[4:N] - for.in

  msfe <- mean(err.in[max(c(1, N - 2 - M0)):(N - 3)] ^ 2)
  msfe.in <- matrix(NA, N - 4, 1)
  for (t in 5:N) {
    msfe.in[t - 4] <- mean(err.in[max(c(1, t - 3 - M0)):(t - 4)] ^ 2)
  }

  if (p_max != 0) {
    for1.ar <- NULL
    msfe.ar <- NULL
    for.ar.in <- NULL
    err.ar.in <- NULL
    msfe.ar.in <- NULL

    ar.coef.se <- NULL
    for (pp in 1:p_max) {
      err.ar.pp <- matrix(NA, N - p_max - 4, 1)
      for (w in (p_max + 2):(N - 3)) {
        err_w <- err.in[max(c(w - E0 + 1, 1)):w]
        n_w <- NROW(err_w)
        regr.ar <- NULL
        for (ppp in 1:pp) {
          regr.ar <- cbind(regr.ar, err_w[(pp - (ppp - 1)):(n_w - 1 - (ppp - 1))])
        }
        fit.ar <- lm(err_w[(pp + 1):n_w] ~ regr.ar)
        fit.ar.coeff <- fit.ar$coefficients
        fit.ar.coeff[is.na(fit.ar.coeff)] <- 0
        err.ar.pp[w - p_max - 1] <- fit.ar.coeff[1] + t(fit.ar.coeff[2:(pp + 1)]) %*% rev(err_w[(n_w - pp + 1):n_w])
      }
      for1.ar.pp <- for1 + err.ar.pp[N - p_max - 4]
      ar.coef.pp <- fit.ar$coefficients
      ar.se.pp <- sqrt(diag(vcov(fit.ar)))
      for.ar.in.pp <- for.in[(p_max + 3):(N - 3)] + err.ar.pp[1:(N - p_max - 5)]
      err.ar.in.pp <- x[(p_max + 6):N] - for.ar.in.pp

      msfe.ar.pp <- mean(err.ar.in.pp[max(c(1, N - p_max - 4 - M0)):(N - p_max - 5)] ^ 2)
      msfe.ar.in.pp <- matrix(NA, N - p_max - 6, 1)
      for (t in (p_max + 7):N) {
        msfe.ar.in.pp[t - p_max - 6] <- mean(err.ar.in.pp[max(c(1, t - p_max - 5 - M0)):(t - p_max - 6)] ^ 2)
      }

      for1.ar <- c(for1.ar, for1.ar.pp)
      msfe.ar <- c(msfe.ar, msfe.ar.pp)
      for.ar.in <- cbind(for.ar.in, for.ar.in.pp)
      err.ar.in <- cbind(err.ar.in, err.ar.in.pp)
      msfe.ar.in <- cbind(msfe.ar.in, msfe.ar.in.pp)

      ar.coef.se <- rbind(ar.coef.se, rbind(c(ar.coef.pp, rep(NA, p_max - pp)), c(ar.se.pp, rep(NA, p_max - pp))))
    }
    colnames(ar.coef.se) <- c("const", paste0("ar", 1:p_max))
    rownames(ar.coef.se) <- rep(c("coeff.", "s.e."), p_max)
  }

  if (p_max != 0) {
    N.for.in <- NROW(for.in)
    N.rho.in <- NROW(rho.in)
    N.msfe.in <- NROW(msfe.in)
    N.err.in <- NROW(err.in)
    N.for.ar.in <- NROW(for.ar.in)
    N.msfe.ar.in <- NROW(msfe.ar.in)
    N.err.ar.in <- NROW(err.ar.in)
    N.out <- NROW(msfe.ar.in)
    return(list(for1 = for1, rho = rho, msfe = msfe, for.in = for.in[(N.for.in - N.out + 1):N.for.in], rho.in = rho.in[(N.rho.in - N.out + 1):N.rho.in], msfe.in = msfe.in[(N.msfe.in - N.out + 1):N.msfe.in], err.in = err.in[(N.err.in - N.out + 1):N.err.in],
                for1.ar = for1.ar, ar.coef.se = ar.coef.se, msfe.ar = msfe.ar, for.ar.in = for.ar.in[(N.for.ar.in - N.out + 1):N.for.ar.in, ], msfe.ar.in = msfe.ar.in[(N.msfe.ar.in - N.out + 1):N.msfe.ar.in, ], err.ar.in = err.ar.in[(N.err.ar.in - N.out + 1):N.err.ar.in, ]))
  }
  if (p_max == 0) {
    N.for.in <- NROW(for.in)
    N.rho.in <- NROW(rho.in)
    N.msfe.in <- NROW(msfe.in)
    N.err.in <- NROW(err.in)
    N.out <- NROW(msfe.in)
    return(list(for1 = for1, rho = rho, msfe = msfe, for.in = for.in[(N.for.in - N.out + 1):N.for.in], rho.in = rho.in[(N.rho.in - N.out + 1):N.rho.in], msfe.in = msfe.in[(N.msfe.in - N.out + 1):N.msfe.in], err.in = err.in[(N.err.in - N.out + 1):N.err.in]))
  }
}

myformat <- function(x, mydecimals, mydim) {
  if (mydecimals != 0) {
    myformat.x <- substr(as.character(x), 1, regexpr("\\.", as.character(x)) + mydecimals)
  }
  if (mydecimals == 0) {
    myformat.x <- substr(as.character(x), 1, regexpr("\\.", as.character(x)) + mydecimals - 1)
  }
  dim(myformat.x) <- mydim
  return(as.data.frame(myformat.x))
}

mydecimals <- function(x) {
  if (min(abs(x), na.rm = TRUE) >= 100) {decimals <- 0}
  if ((min(abs(x), na.rm = TRUE) < 100) & (min(abs(x), na.rm = TRUE) >= 10)) {decimals <- 1}
  if ((min(abs(x), na.rm = TRUE) < 10) & (min(abs(x), na.rm = TRUE) >= 0.01)) {decimals <- 2}
  if ((min(abs(x), na.rm = TRUE) < 0.01) & (min(abs(x), na.rm = TRUE) >= 0.001)) {decimals <- 3}
  if ((min(abs(x), na.rm = TRUE) < 0.001) & (min(abs(x), na.rm = TRUE) >= 0.0001)) {decimals <- 4}
  if (min(abs(x), na.rm = TRUE) < 0.0001) {decimals <- 5}
  return(decimals)
}

myplot.M1 <- function(MSFE, MSFE_in, date_1) {
  xaxis.in <- MSFE_in[ , 1]
  xaxis.out <- date_1
  xaxis <- c(xaxis.in, xaxis.out)
  values <- unlist(c(MSFE[2:3], MSFE_in[ , 2:3]))
  legend.text <- "Adapt"
  plot(xaxis.in, MSFE_in[ , 2], type = "o", lty = 1, pch = 1, cex = 0.5, col = "blue", xlab = "", ylab = "", xlim = c(min(xaxis), max(xaxis)), xaxt = 'n', ylim = c(min(values), max(values) + 0.25 * (max(values) - min(values))))
  points(xaxis.out, MSFE[2], col = "blue", pch = 16, cex = 0.5, lty = 0)
  legend("top", legend = legend.text, lty = 1, pch = 1,  pt.cex = 0.5, col = "blue", x.intersp = 0.5)
  if (is.numeric(xaxis)) axis(side = 1, at = unique(floor(pretty(xaxis))), labels = T)
  if (is.Date(xaxis)) axis.Date(side = 1, at = unique(pretty(xaxis)), labels = T)
  title(expression(bold("Selection of the best forecasting method \n") * phantom("")), col.main = "grey50", cex.main = 1.3)
  title(expression(phantom("") * bold("Mean squared forecast errors (MSFE)")), col.main = "black", cex.main = 1.1)
  Sys.sleep(2)
  legend.text <- c("Adapt   ", "Adapt\u00B2")
  plot(xaxis.in, MSFE_in[ , 2], type = "o", lty = 1, pch = 1, cex = 0.5, col = "blue", xlab = "", ylab = "", xlim = c(min(xaxis), max(xaxis)), xaxt = 'n', ylim = c(min(values), max(values) + 0.25 * (max(values) - min(values))))
  lines(xaxis.in, MSFE_in[ , 3], type = "o", lty = 1, pch = 1, cex = 0.5, col = "red")
  points(xaxis.out, MSFE[2], col = "blue", pch = 16, cex = 0.5, lty = 0)
  points(xaxis.out, MSFE[3], col = "red", pch = 16, cex = 0.5, lty = 0)
  legend("top", legend = legend.text, lty = 1, pch = 1,  pt.cex = 0.5, ncol = 2, col = c("blue", "red"), x.intersp = 0.5, text.width = strwidth(legend.text))
  if (is.numeric(xaxis)) axis(side = 1, at = unique(floor(pretty(xaxis))), labels = T)
  if (is.Date(xaxis)) axis.Date(side = 1, at = unique(pretty(xaxis)), labels = T)
  title(expression(bold("\n") * phantom("")), col.main = "grey50", cex.main = 1.3)
  title(expression(phantom("") * bold("Mean squared forecast errors (MSFE) (comparison)")), col.main = "black", cex.main = 1.1)
}

myplot.M2 <- function(MSFE, MSFE_in, p_max, date_1) {
  xaxis.in <- MSFE_in[ , 1]
  xaxis.out <- date_1
  xaxis <- c(xaxis.in, xaxis.out)
  values <- unlist(c(MSFE[2:(2 * (p_max + 1) + 1)], MSFE_in[ , 2:(2 * (p_max + 1) + 1)]))
  col.ad.ar <- colorRampPalette(c("darkviolet", "plum"))
  col.adsq.ar <- colorRampPalette(c("green4", "lightgreen"))
  col.ad <- c("blue", col.ad.ar(p_max))
  col.adsq <- c("red", col.adsq.ar(p_max))
  legend.text <- "Adapt"
  plot(xaxis.in, MSFE_in[ , 2], type = "o", lty = 1, pch = 1, cex = 0.5, col = col.ad[1], xlab = "", ylab = "", xlim = c(min(xaxis), max(xaxis)), xaxt = 'n', ylim = c(min(values), max(values) + 0.5 * (max(values) - min(values))))
  points(xaxis.out, MSFE[2], col = col.ad[1], pch = 16, cex = 0.5, lty = 0)
  legend("top", legend = legend.text, lty = 1, pch = 1,  pt.cex = 0.5, col = col.ad[1], x.intersp = 0.5)
  if (is.numeric(xaxis)) axis(side = 1, at = unique(floor(pretty(xaxis))), labels = T)
  if (is.Date(xaxis)) axis.Date(side = 1, at = unique(pretty(xaxis)), labels = T)
  title(expression(bold("Selection of the best forecasting method \n") * phantom("")), col.main = "grey50", cex.main = 1.3)
  title(expression(bold("\n") * phantom("")), col.main = "grey50", cex.main = 1.3)
  title(expression(phantom("") * bold("Mean squared forecast errors (MSFE)")), col.main = "black", cex.main = 1.1)
  Sys.sleep(2)
  legend.text <- c("Adapt", "Adapt\u00B2")
  plot(xaxis.in, MSFE_in[ , 2], type = "o", lty = 1, pch = 1, cex = 0.5, col = col.ad[1], xlab = "", ylab = "", xlim = c(min(xaxis), max(xaxis)), xaxt = 'n', ylim = c(min(values), max(values) + 0.5 * (max(values) - min(values))))
  lines(xaxis.in, MSFE_in[ , p_max + 3], type = "o", lty = 1, pch = 1, cex = 0.5, col = col.adsq[1])
  points(xaxis.out, MSFE[2], col = col.ad[1], pch = 16, cex = 0.5, lty = 0)
  points(xaxis.out, MSFE[p_max + 3], col = col.adsq[1], pch = 16, cex = 0.5, lty = 0)
  legend("top", legend = legend.text, lty = 1, pch = 1,  pt.cex = 0.5, ncol = 1, col = c(col.ad[1], col.adsq[1]), x.intersp = 0.5)
  if (is.numeric(xaxis)) axis(side = 1, at = unique(floor(pretty(xaxis))), labels = T)
  if (is.Date(xaxis)) axis.Date(side = 1, at = unique(pretty(xaxis)), labels = T)
  title(expression(bold("\n") * phantom("")), col.main = "grey50", cex.main = 1.3)
  title(expression(phantom("") * bold("Mean squared forecast errors (MSFE) (comparison)")), col.main = "black", cex.main = 1.1)
  legend.text <- c("Adapt  ", "Adapt\u00B2")
  MSFE_in_plot <- cbind(MSFE_in[ , 2], MSFE_in[ , p_max + 3])
  MSFE_out_plot <- MSFE[c(2, p_max + 3)]
  col_plot <- c(col.ad[1], col.adsq[1])
  for (pp in 1:p_max) {
    Sys.sleep(2)
    legend.text <- c(legend.text, paste0("Adapt+AR(", pp, ")  "), "")
    MSFE_in_plot <- cbind(MSFE_in_plot, MSFE_in[ , (pp + 2)], matrix(NA, NROW(xaxis.in), 1))
    MSFE_out_plot <- c(MSFE_out_plot, MSFE[(pp + 2)], NA)
    col_plot <- c(col_plot, col.ad[pp + 1], NA)
    matplot(xaxis.in, MSFE_in_plot, type = "o", lty = 1, pch = 1, cex = 0.5, col = col_plot, xlab = "", ylab = "", xlim = c(min(xaxis), max(xaxis)), xaxt = 'n', ylim = c(min(values), max(values) + 0.5 * (max(values) - min(values))))
    points(rep(xaxis.out, 2 * (pp + 1)), MSFE_out_plot, col = col_plot, pch = 16, cex = 0.5)
    legend("top", legend = legend.text, lty = 1, pch = 1, pt.cex = 0.5,  ncol = pp + 1 ,col = col_plot, x.intersp = 0.5)
    if (is.numeric(xaxis)) axis(side = 1, at = unique(floor(pretty(xaxis))), labels = T)
    if (is.Date(xaxis)) axis.Date(side = 1, at = unique(pretty(xaxis)), labels = T)
    title(expression(bold("\n") * phantom("")), col.main = "grey50", cex.main = 1.3)
    title(expression(phantom("") * bold("Mean squared forecast errors (MSFE) (comparison)")), col.main = "black", cex.main = 1.1)
  }
  for (pp in 1:p_max) {
    Sys.sleep(2)
    legend.text[2 * (pp + 1)] <- paste0("Adapt\u00B2+AR(", pp, ")")
    MSFE_in_plot[ , 2 * (pp + 1)] <- MSFE_in[ , (pp + p_max + 3)]
    MSFE_out_plot[2 * (pp + 1)] <- MSFE[pp + p_max + 3]
    col_plot[2 * (pp + 1)] <- col.adsq[pp + 1]
    matplot(xaxis.in, MSFE_in_plot, type = "o", lty = 1, pch = 1, cex = 0.5, col = col_plot, xlab = "", ylab = "", xlim = c(min(xaxis), max(xaxis)), xaxt = 'n', ylim = c(min(values), max(values) + 0.5 * (max(values) - min(values))))
    points(rep(xaxis.out, 2 * (p_max + 1)), MSFE_out_plot, col = col_plot, pch = 16, cex = 0.5)
    legend("top", legend = legend.text, lty = 1, pch = 1, pt.cex = 0.5,  ncol = p_max + 1 ,col = col_plot, x.intersp = 0.5)
    if (is.numeric(xaxis)) axis(side = 1, at = unique(floor(pretty(xaxis))), labels = T)
    if (is.Date(xaxis)) axis.Date(side = 1, at = unique(pretty(xaxis)), labels = T)
    title(expression(bold("\n") * phantom("")), col.main = "grey50", cex.main = 1.3)
    title(expression(phantom("") * bold("Mean squared forecast errors (MSFE) (comparison)")), col.main = "black", cex.main = 1.1)
  }
}

myplot.R <- function(rho, rho_in, date_1) {
  xaxis.in <- rho_in[ , 1]
  xaxis.out <- date_1
  xaxis <- c(xaxis.in, xaxis.out)
  legend.text <- c("Adapt   ", "Adapt\u00B2")
  plot(xaxis.in, rho_in[ , 2], type = "o", lty = 1, pch = 1, cex = 0.5, col = "dodgerblue3", xlab = "", ylab = "", xlim = c(min(xaxis), max(xaxis)), xaxt = 'n', yaxt = 'n', ylim = c(0, 1.2))
  lines(xaxis.in, rho_in[ , 3], type = "o", lty = 1, pch = 1, cex = 0.5, col = "deeppink3")
  points(xaxis.out, rho[2], col = "dodgerblue3", pch = 16, cex = 0.5, lty = 0)
  points(xaxis.out, rho[3], col = "deeppink3", pch = 16, cex = 0.5, lty = 0)
  legend("top", legend = legend.text, lty = 1, pch = 1,  pt.cex = 0.5, ncol = 2, col = c("dodgerblue3", "deeppink3"), x.intersp = 0.5, text.width = strwidth(legend.text))
  if (is.numeric(xaxis)) axis(side = 1, at = unique(floor(pretty(xaxis))), labels = T)
  if (is.Date(xaxis)) axis.Date(side = 1, at = unique(pretty(xaxis)), labels = T)
  axis(side = 2, at = seq(0, 1, 0.2), labels = T)
  title(expression(bold("Selected tuning parameter \n") * phantom("")), col.main = "grey50", cex.main = 1.3)
  title(expression(bold("\n") * phantom("")), col.main = "grey50", cex.main = 1.3)
  title(expression(phantom("") * bold("Optimal tuning parameter (" * rho * ")")), col.main = "black", cex.main = 1.1)
}

myplot.F <- function(x, xfor, xfor_in, p, adapt, two.titles, date_1) {
  xaxis.in <- xfor_in[ , 1]
  xaxis.out <- date_1
  xaxis <- c(xaxis.in, xaxis.out)
  values <- unlist(c(x, xfor[2], xfor_in[ , 2]))
  plot(xaxis.in, x, type = "o", lty = 2, pch = 16, cex = 0.5, col = "black", xlab = "", ylab = "", xlim = c(min(xaxis), max(xaxis)), xaxt = 'n', ylim = c(min(values), max(values) + 0.25 * (max(values)- min(values))))
  lines(xaxis.in, xfor_in[ , 2], type = "o", lty = 1, pch = 1, cex = 0.5, col = "blue")
  points(xaxis.out, xfor[2], col =  "red", pch = 16, cex = 0.5)
  if (adapt == 1 & p != 0) {
    legend.text <- c("Data   ", paste0("Adapt+AR(", p, ")"))
    legend("top", legend = legend.text, lty = c(2, 1), pch = c(16, 1),  pt.cex = c(0.5, 0.5), ncol = 2, col = c("black", "blue"), x.intersp = 0.5, text.width = strwidth(legend.text))
  }
  if (adapt == 2 & p != 0) {
    legend.text <- c("Data   ", paste0("Adapt\u00B2+AR(", p, ")"))
    legend("top", legend = legend.text, lty = c(2, 1), pch = c(16, 1),  pt.cex = c(0.5, 0.5), ncol = 2, col = c("black", "blue"), x.intersp = 0.5, text.width = strwidth(legend.text))
  }
  if (adapt == 1 & p == 0) {
    legend.text <- c("Data   ", "Adapt")
    legend("top", legend = legend.text, lty = c(2, 1), pch = c(16, 1),  pt.cex = c(0.5, 0.5), ncol = 2, col = c("black", "blue"), x.intersp = 0.5, text.width = strwidth(legend.text))
  }
  if (adapt == 2 & p == 0) {
    legend.text <- c("Data   ", "Adapt\u00B2")
    legend("top", legend = legend.text, lty = c(2, 1), pch = c(16, 1),  pt.cex = c(0.5, 0.5), ncol = 2, col = c("black", "blue"), x.intersp = 0.5, text.width = strwidth(legend.text))
  }
  if (is.numeric(xaxis)) axis(side = 1, at = unique(floor(pretty(xaxis))), labels = T)
  if (is.Date(xaxis)) axis.Date(side = 1, at = unique(pretty(xaxis)), labels = T)
  if (two.titles == TRUE) {
    title(expression(bold("Forecasting results \n") * phantom("")), col.main = "grey50", cex.main = 1.3)
    if (adapt == 1 & p != 0) {
      title(bquote(phantom("") * bold("Data and their one-step ahead forecasts (last" ~ .(paste0(NROW(x), ") (Adapt+AR(", p, "))")))), col.main = "black", cex.main = 1.1)
    }
    if (adapt == 2 & p != 0) {
      title(bquote(phantom("") * bold("Data and their one-step ahead forecasts (last" ~ .(paste0(NROW(x), ") (Adapt\u00B2+AR(", p, "))")))), col.main = "black", cex.main = 1.1)
    }
    if (adapt == 1 & p == 0) {
      title(bquote(phantom("") * bold("Data and their one-step ahead forecasts (last" ~ .(paste0(NROW(x), ") (Adapt)")))), col.main = "black", cex.main = 1.1)
    }
    if (adapt == 2 & p == 0) {
      title(bquote(phantom("") * bold("Data and their one-step ahead forecasts (last" ~ .(paste0(NROW(x), ") (Adapt\u00B2)")))), col.main = "black", cex.main = 1.1)
    }
  }
  if (two.titles == FALSE) {
    title(expression(bold("\n") * phantom("")), col.main = "grey50", cex.main = 1.3)
    if (adapt == 1 & p != 0) {
      title(bquote(phantom("") * bold("Data and their one-step ahead forecasts (last" ~ .(paste0(NROW(x), ") (Adapt+AR(", p, "))")))), col.main = "black", cex.main = 1.1)
    }
    if (adapt == 2 & p != 0) {
      title(bquote(phantom("") * bold("Data and their one-step ahead forecasts (last" ~ .(paste0(NROW(x), ") (Adapt\u00B2+AR(", p, "))")))), col.main = "black", cex.main = 1.1)
    }
    if (adapt == 1 & p == 0) {
      title(bquote(phantom("") * bold("Data and their one-step ahead forecasts (last" ~ .(paste0(NROW(x), ") (Adapt)")))), col.main = "black", cex.main = 1.1)
    }
    if (adapt == 2 & p == 0) {
      title(bquote(phantom("") * bold("Data and their one-step ahead forecasts (last" ~ .(paste0(NROW(x), ") (Adapt\u00B2)")))), col.main = "black", cex.main = 1.1)
    }

  }
}

myplot.E1F <- function(err_in, errfor, errfor_in, date_1) {
  xaxis.in <- err_in[ , 1]
  xaxis.out <- date_1
  xaxis <- c(xaxis.in, xaxis.out)
  values <- unlist(c(err_in[ , 2], errfor, errfor_in))
  plot(xaxis.in, err_in[ , 2], type = "o", lty = 2, pch = 16, cex = 0.5, col = "black", xlab = "", ylab = "", xlim = c(min(xaxis), max(xaxis)), xaxt = 'n', ylim = c(min(values), max(values) + 0.25 * (max(values)- min(values))))
  lines(xaxis.in, errfor_in, type = "o", lty = 1, pch = 1, cex = 0.5, col = "blue")
  points(xaxis.out, errfor, col = "red", pch = 16, cex = 0.5)
  legend.text <- c("Forecast errors  ", "Adapt")
  legend("top", legend = legend.text, lty = c(2, 1), pch = c(16, 1), pt.cex = 0.5, ncol = 2, col = c("black", "blue"), x.intersp = 0.5, text.width = strwidth(legend.text))
  if (is.numeric(xaxis)) axis(side = 1, at = unique(floor(pretty(xaxis))), labels = T)
  if (is.Date(xaxis)) axis.Date(side = 1, at = unique(pretty(xaxis)), labels = T)
  abline(h = 0, col = "gray75")
  title(expression(bold("Evaluation of forecasting method \n") * phantom("")), col.main = "grey50", cex.main = 1.3)
  title(expression(bold("\n") * phantom("")), col.main = "grey50", cex.main = 1.3)
  title(bquote(phantom("") * bold("Adapt forecast errors and their one-step ahead (Adapt) forecasts (last" ~ .(paste0(NROW(err_in), ")")))), col.main = "black", cex.main = 1.1)
}

myplot.E2 <- function(err_in, p) {
  xaxis.in <- err_in[ , 1]
  values <- err_in[ , 2:3]
  plot(xaxis.in, err_in[ , 2], type = "o", lty = 1, pch = 1, cex = 0.5, col = "red", xlab = "", ylab = "", xlim = c(min(xaxis.in), max(xaxis.in)), xaxt = 'n', ylim = c(min(values), max(values) + 0.25 * (max(values)- min(values))))
  if (p != 0) {
    legend("top", legend = paste0("Adapt+AR(", p, ")"), lty = 1, pch = 1,  pt.cex = 0.5, col = "red", x.intersp = 0.5)
  }
  if (p == 0) {
    legend("top", legend = "Adapt", lty = 1, pch = 1,  pt.cex = 0.5, col = "red", x.intersp = 0.5)
  }
  if (NROW(xaxis.in) > 1) {
    if (is.numeric(xaxis.in)) axis(side = 1, at = unique(floor(pretty(xaxis.in))), labels = T)
    if (is.Date(xaxis.in)) axis.Date(side = 1, at = unique(pretty(xaxis.in)), labels = T)
  }
  if (NROW(xaxis.in) == 1) {
    if (is.numeric(xaxis.in)) axis(side = 1, at = xaxis.in, labels = T)
    if (is.Date(xaxis.in)) axis.Date(side = 1, at = xaxis.in, labels = T)
  }
  abline(h = 0, col = "gray75")
  title(expression(bold("\n") * phantom("")), col.main = "grey50", cex.main = 1.3)
  if (p != 0) {
    title.text <- paste0("Forecast errors (Adapt+AR(", p, "))")
  }
  if (p == 0) {
    title.text <- "Forecast errors (Adapt)"
  }
  title(bquote(phantom("") * bold(.(title.text))), col.main = "black", cex.main = 1.1)
  Sys.sleep(2)
  plot(xaxis.in, err_in[ , 3], type = "o", lty = 1, pch = 1, cex = 0.5, col = "red", xlab = "", ylab = "", xlim = c(min(xaxis.in), max(xaxis.in)), xaxt = 'n', ylim = c(min(values), max(values) + 0.25 * (max(values)- min(values))))
  if (p != 0) {
    legend("top", legend = paste0("Adapt\u00B2+AR(", p, ")"), lty = 1, pch = 1,  pt.cex = 0.5, col = "red", x.intersp = 0.5)
  }
  if (p == 0) {
    legend("top", legend = "Adapt\u00B2", lty = 1, pch = 1,  pt.cex = 0.5, col = "red", x.intersp = 0.5)
  }
  if (NROW(xaxis.in) > 1) {
    if (is.numeric(xaxis.in)) axis(side = 1, at = unique(floor(pretty(xaxis.in))), labels = T)
    if (is.Date(xaxis.in)) axis.Date(side = 1, at = unique(pretty(xaxis.in)), labels = T)
  }
  if (NROW(xaxis.in) == 1) {
    if (is.numeric(xaxis.in)) axis(side = 1, at = xaxis.in, labels = T)
    if (is.Date(xaxis.in)) axis.Date(side = 1, at = xaxis.in, labels = T)
  }
  abline(h = 0, col = "gray75")
  title(expression(bold("\n") * phantom("")), col.main = "grey50", cex.main = 1.3)
  if (p != 0) {
    title.text <- paste0("Forecast errors (Adapt\u00B2+AR(", p, "))")
  }
  if (p == 0) {
    title.text <- "Forecast errors (Adapt\u00B2)"
  }
  title(bquote(phantom("") * bold(.(title.text))), col.main = "black", cex.main = 1.1)
}
