2020 Yıl Sonu Dolar-TL Alış Kurunun Tahmini Üzerine Karşılaştırmalı Bir Vaka Çalışması: A Comparative Case Study on Forecast of USD-TRY Exchange Rate at the End of 2020 Year

Türkiye ekonomisinde döviz kuru oynaklıkları ve şokları iç ve/veya dış sebeplerden sıklıkla yaşanan bir durumdur. Bu çalışma kapsamında T.C. Merkez Bankası Dolar-TL alış kuru veri setinde farklı yöntemler kullanılarak Dolar-TL alış kuru 2020 dönem sonu tahminleri yapılmıştır. Dolar alış kuru tahmininde kullanılan ana değişken, 40 yıllık günlük “Dolar-TL alış kuru” değeridir.

Dolar kurunu etkileyen birçok farklı değişken modele sokularak dolar alış kurunun tahmin edilmesi elbette her zaman mümkündür. Bu durumda dolar kuru ve diğer değişkenler arasındaki nedensellik (causality) ilişkisi çok iyi bir şekilde ortaya konulmasından sonra model oluşturularak dolar kuru tahmini yapılabilir. Ortaya konulan bu değişkenlerin ölçülebilir olması da gereklidir. Ancak ölçülebilir olmayan nitel bir çok faktör de dolar kurunu etkileyebilmektedir. Örneğin uluslararası ilişkiler, iç siyasi ortam, terör, küresel ekonomik durgunluk gibi pek çok faktör de modele sokulup analiz edilmesi gereklidir. Ancak bu faktörler ölçülebilir olmadığından modele sokulması oldukça zordur ve çoğu zaman dışarda bırakılmaktadır. Dışarda bırakılan bu faktörler ölçülebilir olan nicel değişkenlerden daha da önemli de olabilir. Bu durumda sadece nicel ölçülebilir olan değişkenlerin modele sokulması eksik sonuçlar ortaya koyacaktır. Diğer bir konu, değişkenler belirlense bile bu değişkenlerin kendi içerisinde ve aralarındaki geçişkenlik dikkate alınması gereklidir.

Hacim olarak oldukça güvenilir 40 yıllık günlük Dolar-TL alış kuru veri setinin kullanılması başlı başına çok değerli çıkarımlar ortaya konulmasına katkı sağlayacaktır. Çünkü, ülkemizde döviz kuru dalgalanmaları, oynaklıkları ve şokları 40 yıllık bir zaman içerisinde bir döngü olarak sürekli yaşanmıştır. Dolayısıyla, döviz kurunu etkileyen faktörler zaten mevcut olan veri setinin içerisinde dolar alış kur değerlerine yansımış olduğu ve ekonomide öncü göstergelerden biri olduğu düşünülmektedir. Aynı zamanda bu nedenle bu çalışmada sadece dolar alış kurunun kendi içinde izlediği seyir dikkate alınarak model oluşturulmuştur. Oluşturulan model farklı yöntemlerle karşılaştırmalı olarak test edilerek MAPE (Mean Absolute Percentage Error) değerleri açsısından en iyi yöntemin hangisinin olduğuna karar verilmiştir. Deneysel olarak Merkez Bankası veri tabanından 02.01.1980 tarihinden 13.01.2020 tarihine kadar (dahil) indirilmiş dolar alış kuru verisi üzerinden 31.12.2020 tarihine kadar (dahil) geçen 353 günlük bir tahmin yapılması amaçlanmıştır. Tahminler yapılırken otomatik (default) olarak veri seti kullanılan yöntem içerisinde eğitilmiştir (training). Dolar alış kurunun tahmininde kullanılan yöntem (metot)’ler şöyledir:

  1. TBATS (Exponential smoothing state space model with Box-Cox transformation, ARMA errors, Trend and Seasonal components)
  2. ARIMA (Autoregressive Integrated Moving Average)
  3. ETS (Exponential Smoothing State Space Model)
  4. Naive
  5. NNAR (Neural Network Autoregression): Otoregresyon Sinir Ağı
  6. Holt
  7. SES (Simple Exponential Smoothing)
  8. Driftli Rassal Yürüyüş Yöntemi (Random Walk Forecast with Drift)
  9. Driftsiz Rassal Yürüyüş Yöntemi (Random Walk Forecast without Drift)
  10. Theta

Yukarıdaki bahsedilen yöntemlerle dolar alış kur değerleri tahmin edildikten sonra en iyi yöntem yaygın olarak kullanılan ve en güvenilir kabul edilen hata tiplerinden MAPE (Mean Absolute Percentage Error) ‘ye göre belirlenmiştir. MAPE hata değeri en düşük olan tahmin yöntemi Dolar-TL alış kuru tahminleri açısından en iyi yöntem olarak belirlenmiştir.

Merkez Bankası online veri tabanından 02.01.1980 tarihinden 13.01.2019 tarihine kadar (bu tarih dahil) olan günlük dolar alış kuru verisi xlsx olarak indirilmiştir. Veri setindeki değişken sayısı 2, gözlem sayı ise 10092’dir.

Çalışmada aynı zamanda tanımlayıcı istatistik bağlamında maksimum ve minimum kur değerleri esas alınarak yıllık ve aylık dalga boyları hesaplanarak grafikleri çizilmiştir. Dalga boyu, ilgili döneme ait maksimum dolar alış kuru değerinin minimum dolar alış kuru değerinden farkının minimum dolar alış kuru değerine bölünerek 100 ile çarpılmasını ifade etmektedir. Dalga boyu en yalın ifadeyle aşağıdaki eşitlik yardımıyla hesaplanmıştır: Dalga Boyu= (İlgili Döneme Ait Maksimum Kur Değeri-İlgili Döneme Ait Minimum Kur Değeri) / İlgili Döneme Ait Minimum Kur Değeri) X 100. Dalga boylarının hesaplanması döviz şoklarının gerçekleştiği dönemler ile ekonomik kriz dönemlerinin belirlenmesi açısından büyük öneme sahiptir.

İlk olarak R’da analiz için gerekli aşağıdaki kütüphaneler yüklenmiştir.

lapply(c("dplyr","tibble","tidyr","ggplot2","formattable","forecast","nnfor","xts","zoo","lubridate","readxl","xlsx"), require, character.only = TRUE)

Analiz kullanılan Merkez Bankası Dolar-TL alış kuru veri setine xlsx uzantılı olarak aşağıdaki linkte yer verilmiştir.

Analizde kullanılan Merkez Bankası Dolar Alış Kuru verisinin yüklenmesi için yazılan R kod bloğu aşağıda verilmiştir.

df <-read_excel("dolar.xlsx")

Veri setinin yüklenmesinden sonra veri setinin “tibble” tablo düzenine alınması ve tarih verisinin ay ve yıla dönüştürülmesi için gerekli R kod bloğuna aşağıda yer verilmiştir.

d1<-tibble(Tarih=dmy(df$Tarih), Yıl= year(dmy(df$Tarih)), Ay=month(df$Tarih), Kur=df$USD_Alis)

Veri setinden yıllara göre üretilen döviz alış kurunun seyrini gösteren grafiğe ilişkin R kod bloğu ise aşağıdadır.

d1%>%ggplot(aes(Kur, Yıl))+
     geom_point(color="red")+
     scale_y_continuous(breaks=seq(1980, 2020, 4))+
     scale_x_continuous(breaks=seq(min(d1$Kur), max(d1$Kur),1.7))+
     labs(caption = "Source: Tevfik Bulut")+
     ggtitle("Yıllara Göre Dolar Alış Kurunun Seyri") +
     xlab("Kur (TL)") + ylab("Yıl")+
     theme(plot.title = element_text(family = "Trebuchet MS", face="bold", 
                                     size=14,hjust=0.5)) +
     theme(axis.title = element_text(family = "Trebuchet MS", face="bold", 
                                     size=10))

Yukarıdaki R kod bloğunun çalıştırılmasından sonra elde edilen yıllara göre dolar alış kuru seyri aşağıdaki grafikte verilmiştir.

Aylara göre döviz alış kurundaki maksimum ve minimum kur değerleri ile maksimum ve minimum kur farkının yüzdesel değişimi (Dalga Boyu)’ni hesaplamak için yazılan R kod bloğu aşağıdadır. Burada aynı zamanda tabloda yıl ve ayın olduğu sütunlar “Yilin_Ayi” adında birleştirilerek ayrı bir değişken olarak tanımlanmıştır.

ay<-d1 %>% group_by(Ay, Yıl)%>%summarise(Max_Kur=max(Kur), Min_Kur=min(Kur), Dalga_Boyu=((max(Kur)-min(Kur))/(min(Kur))*100))
ay$Yilin_Ayi<-paste(ay$Yıl,"-",ay$Ay)
ay

Dolar alış kurlarında aylık dalga boylarının en yüksek olduğu ayları içeren ilk 25 kayıt bulunduğu yılı içerek şekilde aşağıdaki kod bloğu ile verilmiştir.

k4<- ay %>% select(Yilin_Ayi, Dalga_Boyu)%>%
     arrange(desc(Dalga_Boyu))
k5<- head(k4[, -1],20)

k5 %>% ggplot(aes(x=Yilin_Ayi, y=Dalga_Boyu))+
     geom_area(size=2, color="red")+
     theme(axis.text.x = element_text(face="bold", 
                           size=8, angle=90),
           axis.text.y = element_text(face="bold", 
                           size=8, angle=90))+
     geom_hline(yintercept=mean(k5$Dalga_Boyu), linetype="twodash", color = 
     "red", size=1)+
     ggtitle("Döviz Alış Kuru Aylık Dalga Boyları") +
     xlab("Yılın Ayı") + ylab("Dalga Boyu (%)")+
     labs(caption = "Source: By Tevfik Bulut")+
     theme(plot.title = element_text(family = "Trebuchet MS", face="bold", 
     size=16, hjust=0.5)) +
     theme(axis.title = element_text(family = "Trebuchet MS", face="bold", 
     size=12))

Yukarıdaki kod bloğunun çalıştırılmasından sonra dolar alış kurlarında aylık dalga boylarının en yüksek olduğu ayları içeren ilk 20 kayıt bulunduğu yılı içerek şekilde aşağıdaki grafikte verilmiştir. Aşağıdaki şekilde x eksenine yatay yeşil çizgi dalga boylarının ortalamasını göstermektedir.

Dolar alış kurlarında yıllık dalga boylarının en yüksek olduğu ilk 20 kayıt aşağıdaki kod bloğu ile verilmiştir.

yil<-ay %>% select(Yıl, Dalga_Boyu)%>%
            arrange(desc(Dalga_Boyu))

ydb<-head(yil[,-1],20)

ydb %>% ggplot(aes(x=Yıl, y=Dalga_Boyu))+
        geom_line(arrow = arrow(angle = 15, ends = "both", type = 
                 "closed"),size=2, color="brown")+
        scale_x_continuous(breaks=seq(1980, 2020, 2))+
        theme(axis.text.x = element_text(face="bold", 
                           size=8, angle=90),
              axis.text.y = element_text(face="bold", 
                           size=8, angle=90))+
        geom_hline(yintercept=mean(ydb$Dalga_Boyu), linetype="twodash", 
                   color = "green", size=2)+
        ggtitle("Döviz Alış Kuru Yıllık Dalga Boyları") +
        xlab("Yıl") + ylab("Dalga Boyu (%)")+
        labs(caption = "Source: Tevfik Bulut")+
        theme(plot.title = element_text(family = "Trebuchet MS", 
              face="bold", size=16, hjust=0.5)) +
        theme(axis.title = element_text(family = "Trebuchet MS", 
              face="bold", size=12))

Yukarıdaki kod bloğunun çalıştırılmasından sonra dolar alış kurlarında yıllık dalga boylarının en yüksek olduğu ilk 25 kayıt aşağıdaki şekilde verilmiştir. Şekilde x eksenine yatay yeşil çizgi dalga boylarının ortalamasını göstermektedir. Şekilde verilen Dolar-TL alış kurundaki dalga boyları Türkiye’deki döviz şoklarını ve ekonomik kriz dönemlerini net bir şekilde ortaya koymaktadır.

Veri seti tahmin yöntemlerinde kullanılmak üzere zaman serisine formatına dönüştürülmüştür. Yapılan bu işleme ilişkin R kod bloğu aşağıda verilmiştir.

y10<-as.Date(df$Tarih, format = "%d - %m - %Y")
tev<-ts(as.vector(df[,2]), as.vector(y10))

data <- msts(tev,seasonal.periods=c(7,365.25))

TBATS Yöntemi

Dolar alış kurunun tahmininde kullanılan ilk yöntem TBATS olup, bu yönteme ilişkin algoritma aşağıdaki R kod bloğunda verilmiştir.

function (x) 
{
    if (!is.null(x$lambda)) {
        y <- BoxCox(x$y, x$lambda)
        lambda <- attr(y, "lambda")
    }
    else {
        y <- x$y
    }
    tau <- ifelse(!is.null(x$k.vector), 2 * sum(x$k.vector), 
        0)
    w <- .Call("makeTBATSWMatrix", smallPhi_s = x$damping.parameter, 
        kVector_s = as.integer(x$k.vector), arCoefs_s = x$ar.coefficients, 
        maCoefs_s = x$ma.coefficients, tau_s = as.integer(tau), 
        PACKAGE = "forecast")
    out <- cbind(observed = c(y), level = x$x[1, ])
    if (!is.null(x$beta)) {
        out <- cbind(out, slope = x$x[2, ])
    }
    if (tau > 0) {
        nonseas <- 2 + !is.null(x$beta)
        nseas <- length(x$seasonal.periods)
        seas.states <- cbind(x$seed.states, x$x)[-(1:(1 + !is.null(x$beta))), 
            ]
        seas.states <- seas.states[, -ncol(seas.states)]
        w <- w$w.transpose[, -(1:(1 + !is.null(x$beta))), drop = FALSE]
        w <- w[, 1:tau, drop = FALSE]
        j <- cumsum(c(1, 2 * x$k.vector))
        for (i in 1:nseas) out <- cbind(out, season = c(w[, j[i]:(j[i + 
            1] - 1), drop = FALSE] %*% seas.states[j[i]:(j[i + 
            1] - 1), ]))
        if (nseas > 1) {
            colnames(out)[nonseas + 1:nseas] <- paste("season", 
                1:nseas, sep = "")
        }
    }
    out <- ts(out)
    tsp(out) <- tsp(y)
    return(out)
}

Şimdi sıra TBATS yöntemi kullanılarak modelin oluşturulmasına gelmiştir. Dolar alış kuruna ait 353 günlük bir zaman serisi için tahmin yapılacağı için aşağıdaki R kod bloğunda h=353 olarak belirlenmiştir. Kurulan modele, kurulan modelden üretilen tahminlere ilişkin grafik için R kod bloğu bir bütün olarak aşağıda sunulmuştur.

data <- msts(tev,seasonal.periods=c(7,365.25))
model <- tbats(data)
sonuc<- forecast(model,h=353)
autoplot(sonuc) +
    ylab("Alış Kuru") +
    xlab("Zaman") +
 ggtitle("TBATS Yöntemi İle Tahmin Edilen Dolar Alış Kuru") 
 theme_bw()+
 theme(plot.title = element_text(hjust = 0.5))+
 labs(caption = "Source: Tevfik Bulut")

Yukarıdaki kod bloğunun çalıştırılmasından sonra elde edilen güven aralıklı (CI: Confidence Interval) 353 günlük dolar kuru tahminleri aşağıdaki şekilde verilmiştir. Burada, maviyle gösterilen alan güven aralıklarıyla birlikte dolar alış kuru tahminlerini, önceki alan ise mevcut dolar alış kuru gerçekleşmelerini göstermektedir. Maviyle gösterilen alanda yer alan eğri ise nokta tahmin (point forecast)’leri göstermektedir.

Elde edilen 353 günlük dolar alış kuru tahmin değerleri, tahmin edilen tarih ile bu tarihlere ait dolar alış kur değerleri xlsx (Microsoft Office Excel) uzantılı “tbats” adlı dosyaya yazdırılmıştır. Bahsedilen bu işlemleri gösterir R kod bloğunu aşağıda yer verilmiştir.

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(sonuc)
today4<-today3[, -2:-3]
tbats<-cbind(Tarih=today2, today4)

write.xlsx(tbats, file = "tbats.xlsx",
      sheetName = "tahmin_aliskuru", append = FALSE)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra elde edilen tahmini dolar alış kur değerleri tahmin edilen tarihe göre güven aralıkları ile birlikte xlsx uzantılı olarak aşağıda verilmiştir. Buradaki linkten sonuçları indirebilirsiniz.

TBATS yönteminin ortaya koyduğu hata türlerinden MAPE (Mean Absolute Percentage Error) değerine bakalım. MAPE değeri zaman serisi analizlerinden kullanılan ve modelin güvenilirliğinin ölçülmesinde sıklıkla başvurulan en güvenilir hata türlerinden birisidir. Bu amaçla aşağıdaki R kod bloğu çalıştırıldıktan sonra TBATS yönteminin sonuçlarına bakılarak MAPE ve diğer hata türlerine ulaşılabilir.

data <- msts(tev,seasonal.periods=c(7,365.25))
model <- tbats(data)
sonuc<- forecast(model,h=353)
summary(sonuc)

Yukarıdaki kod bloğunun çalıştılmasından sonra aşağıdaki sonuçlardan da görüleceği üzere TBATS yöntemi, dolar alış kuru tahminlerinde ürettiği MAPE hata değeri 0.4897634‘tür.

Forecast method: TBATS(0.049, {3,0}, -, {<7,3>, <365.25,8>})

Model Information:
TBATS(0.049, {3,0}, -, {<7,3>, <365.25,8>})

Call: tbats(y = data)

Parameters
  Lambda: 0.049011
  Alpha: 0.02034718
  Gamma-1 Values: 0.0002026845 -0.0001234526
  Gamma-2 Values: 0.0004084971 3.040264e-05
  AR coefficients: 1.129051 -0.296009 0.156864

Seed States:
               [,1]
 [1,] -7.984000e+00
 [2,] -2.453819e-04
 [3,] -4.667024e-06
 [4,] -1.400260e-04
 [5,] -1.331329e-04
 [6,]  6.942891e-05
 [7,] -1.398736e-05
 [8,]  1.230420e-02
 [9,]  1.054255e-03
[10,] -1.711990e-03
[11,] -1.504480e-03
[12,] -4.977709e-03
[13,] -1.359871e-03
[14,] -3.872218e-04
[15,] -1.010010e-03
[16,] -4.394557e-03
[17,]  3.579392e-03
[18,] -6.306786e-05
[19,] -1.700927e-03
[20,] -1.410837e-03
[21,]  2.297299e-04
[22,] -6.422550e-04
[23,] -3.995525e-04
[24,]  0.000000e+00
[25,]  0.000000e+00
[26,]  0.000000e+00
attr(,"lambda")
[1] 0.04901073

Sigma: 0.01017209
AIC: -47840.15

Error measures:
                       ME       RMSE         MAE        MPE      MAPE
Training set 0.0002509627 0.01998889 0.006809487 0.05236497 0.4897634
                   MASE        ACF1
Training set 0.02762049 0.009573125

ETS YÖNTEMİ

Dolar alış kurunun tahmininde kullanılan ikinci yöntem ETS olup, bu yöntemin algoritmasına aşağıda yer verilmiştir.

function (y, model = "ZZZ", damped = NULL, alpha = NULL, 
    beta = NULL, gamma = NULL, phi = NULL, additive.only = FALSE, 
    lambda = NULL, biasadj = FALSE, lower = c(rep(1e-04, 3), 
        0.8), upper = c(rep(0.9999, 3), 0.98), opt.crit = c("lik", 
        "amse", "mse", "sigma", "mae"), 
    nmse = 3, bounds = c("both", "usual", "admissible"), 
    ic = c("aicc", "aic", "bic"), restrict = TRUE, 
    allow.multiplicative.trend = FALSE, use.initial.values = FALSE, 
    na.action = c("na.contiguous", "na.interp", "na.fail"), 
    ...) 
{
    opt.crit <- match.arg(opt.crit)
    bounds <- match.arg(bounds)
    ic <- match.arg(ic)
    if (!is.function(na.action)) {
        na.fn_name <- match.arg(na.action)
        na.action <- get(na.fn_name)
    }
    seriesname <- deparse(substitute(y))
    if (any(class(y) %in% c("data.frame", "list", 
        "matrix", "mts"))) {
        stop("y should be a univariate time series")
    }
    y <- as.ts(y)
    if (missing(model) && is.constant(y)) {
        return(ses(y, alpha = 0.99999, initial = "simple")$model)
    }
    ny <- length(y)
    y <- na.action(y)
    if (ny != length(y) && na.fn_name == "na.contiguous") {
        warning("Missing values encountered. Using longest contiguous portion of time series")
        ny <- length(y)
    }
    orig.y <- y
    if (identical(class(model), "ets") && is.null(lambda)) {
        lambda <- model$lambda
    }
    if (!is.null(lambda)) {
        y <- BoxCox(y, lambda)
        lambda <- attr(y, "lambda")
        additive.only <- TRUE
    }
    if (nmse < 1 || nmse > 30) {
        stop("nmse out of range")
    }
    m <- frequency(y)
    if (any(upper < lower)) {
        stop("Lower limits must be less than upper limits")
    }
    if (class(model) == "ets") {
        alpha <- max(model$par["alpha"], 1e-10)
        beta <- model$par["beta"]
        if (is.na(beta)) {
            beta <- NULL
        }
        gamma <- model$par["gamma"]
        if (is.na(gamma)) {
            gamma <- NULL
        }
        phi <- model$par["phi"]
        if (is.na(phi)) {
            phi <- NULL
        }
        modelcomponents <- paste(model$components[1], model$components[2], 
            model$components[3], sep = "")
        damped <- (model$components[4] == "TRUE")
        if (use.initial.values) {
            errortype <- substr(modelcomponents, 1, 1)
            trendtype <- substr(modelcomponents, 2, 2)
            seasontype <- substr(modelcomponents, 3, 3)
            e <- pegelsresid.C(y, m, model$initstate, errortype, 
                trendtype, seasontype, damped, alpha, beta, gamma, 
                phi, nmse)
            np <- length(model$par) + 1
            model$loglik <- -0.5 * e$lik
            model$aic <- e$lik + 2 * np
            model$bic <- e$lik + log(ny) * np
            model$aicc <- model$aic + 2 * np * (np + 1)/(ny - 
                np - 1)
            model$mse <- e$amse[1]
            model$amse <- mean(e$amse)
            tsp.y <- tsp(y)
            model$states <- ts(e$states, frequency = tsp.y[3], 
                start = tsp.y[1] - 1/tsp.y[3])
            colnames(model$states)[1] <- "l"
            if (trendtype != "N") {
                colnames(model$states)[2] <- "b"
            }
            if (seasontype != "N") {
                colnames(model$states)[(2 + (trendtype != "N")):ncol(model$states)] <- paste("s", 
                  1:m, sep = "")
            }
            if (errortype == "A") {
                model$fitted <- ts(y - e$e, frequency = tsp.y[3], 
                  start = tsp.y[1])
            }
            else {
                model$fitted <- ts(y/(1 + e$e), frequency = tsp.y[3], 
                  start = tsp.y[1])
            }
            model$residuals <- ts(e$e, frequency = tsp.y[3], 
                start = tsp.y[1])
            model$sigma2 <- sum(model$residuals^2, na.rm = TRUE)/(ny - 
                np)
            model$x <- orig.y
            model$series <- seriesname
            if (!is.null(lambda)) {
                model$fitted <- InvBoxCox(model$fitted, lambda, 
                  biasadj, var(model$residuals))
                attr(lambda, "biasadj") <- biasadj
            }
            model$lambda <- lambda
            return(model)
        }
        else {
            model <- modelcomponents
            if (missing(use.initial.values)) {
                message("Model is being refit with current smoothing parameters but initial states are being re-estimated.\nSet 'use.initial.values=TRUE' if you want to re-use existing initial values.")
            }
        }
    }
    errortype <- substr(model, 1, 1)
    trendtype <- substr(model, 2, 2)
    seasontype <- substr(model, 3, 3)
    if (!is.element(errortype, c("M", "A", "Z"))) {
        stop("Invalid error type")
    }
    if (!is.element(trendtype, c("N", "A", "M", 
        "Z"))) {
        stop("Invalid trend type")
    }
    if (!is.element(seasontype, c("N", "A", "M", 
        "Z"))) {
        stop("Invalid season type")
    }
    if (m < 1 || length(y) <= m) {
        seasontype <- "N"
    }
    if (m == 1) {
        if (seasontype == "A" || seasontype == "M") {
            stop("Nonseasonal data")
        }
        else {
            substr(model, 3, 3) <- seasontype <- "N"
        }
    }
    if (m > 24) {
        if (is.element(seasontype, c("A", "M"))) {
            stop("Frequency too high")
        }
        else if (seasontype == "Z") {
            warning("I can't handle data with frequency greater than 24. Seasonality will be ignored. Try stlf() if you need seasonal forecasts.")
            substr(model, 3, 3) <- seasontype <- "N"
        }
    }
    if (restrict) {
        if ((errortype == "A" && (trendtype == "M" || 
            seasontype == "M")) | (errortype == "M" && 
            trendtype == "M" && seasontype == "A") || 
            (additive.only && (errortype == "M" || trendtype == 
                "M" || seasontype == "M"))) {
            stop("Forbidden model combination")
        }
    }
    data.positive <- (min(y) > 0)
    if (!data.positive && errortype == "M") {
        stop("Inappropriate model for data with negative or zero values")
    }
    if (!is.null(damped)) {
        if (damped && trendtype == "N") {
            stop("Forbidden model combination")
        }
    }
    n <- length(y)
    npars <- 2L
    if (trendtype == "A" || trendtype == "M") {
        npars <- npars + 2L
    }
    if (seasontype == "A" || seasontype == "M") {
        npars <- npars + m
    }
    if (!is.null(damped)) {
        npars <- npars + as.numeric(damped)
    }
    if (n <= npars + 4L) {
        if (!is.null(damped)) {
            if (damped) {
                warning("Not enough data to use damping")
            }
        }
        if (seasontype == "A" || seasontype == "M") {
            fit <- try(HoltWintersZZ(orig.y, alpha = alpha, beta = beta, 
                gamma = gamma, phi = phi, exponential = (trendtype == 
                  "M"), seasonal = ifelse(seasontype != 
                  "A", "multiplicative", "additive"), 
                lambda = lambda, biasadj = biasadj, warnings = FALSE), 
                silent = TRUE)
            if (!("try-error" %in% class(fit))) {
                fit$call <- match.call()
                fit$method <- as.character(fit)
                fit$series <- deparse(substitute(y))
                return(fit)
            }
            else {
                warning("Seasonal component could not be estimated")
            }
        }
        if (trendtype == "A" || trendtype == "M") {
            fit <- try(HoltWintersZZ(orig.y, alpha = alpha, beta = beta, 
                gamma = FALSE, phi = phi, exponential = (trendtype == 
                  "M"), lambda = lambda, biasadj = biasadj, 
                warnings = FALSE), silent = TRUE)
            if (!("try-error" %in% class(fit))) {
                fit$call <- match.call()
                fit$method <- as.character(fit)
                fit$series <- deparse(substitute(y))
                return(fit)
            }
            else {
                warning("Trend component could not be estimated")
            }
        }
        if (trendtype == "N" && seasontype == "N") {
            fit <- try(HoltWintersZZ(orig.y, alpha = alpha, beta = FALSE, 
                gamma = FALSE, lambda = lambda, biasadj = biasadj, 
                warnings = FALSE), silent = TRUE)
            if (!("try-error" %in% class(fit))) {
                fit$call <- match.call()
                fit$method <- as.character(fit)
                fit$series <- deparse(substitute(y))
                return(fit)
            }
        }
        fit1 <- try(HoltWintersZZ(orig.y, alpha = alpha, beta = beta, 
            gamma = FALSE, phi = phi, exponential = (trendtype == 
                "M"), lambda = lambda, biasadj = biasadj, 
            warnings = FALSE), silent = TRUE)
        fit2 <- try(HoltWintersZZ(orig.y, alpha = alpha, beta = FALSE, 
            gamma = FALSE, phi = phi, exponential = (trendtype == 
                "M"), lambda = lambda, biasadj = biasadj, 
            warnings = FALSE), silent = TRUE)
        if ("try-error" %in% class(fit1)) {
            fit <- fit2
        }
        else if (fit1$sigma2 < fit2$sigma2) {
            fit <- fit1
        }
        else {
            fit <- fit2
        }
        if ("try-error" %in% class(fit)) 
            stop("Unable to estimate a model.")
        fit$call <- match.call()
        fit$method <- as.character(fit)
        fit$series <- deparse(substitute(y))
        return(fit)
    }
    if (errortype == "Z") {
        errortype <- c("A", "M")
    }
    if (trendtype == "Z") {
        if (allow.multiplicative.trend) {
            trendtype <- c("N", "A", "M")
        }
        else {
            trendtype <- c("N", "A")
        }
    }
    if (seasontype == "Z") {
        seasontype <- c("N", "A", "M")
    }
    if (is.null(damped)) {
        damped <- c(TRUE, FALSE)
    }
    best.ic <- Inf
    for (i in 1:length(errortype)) {
        for (j in 1:length(trendtype)) {
            for (k in 1:length(seasontype)) {
                for (l in 1:length(damped)) {
                  if (trendtype[j] == "N" && damped[l]) {
                    next
                  }
                  if (restrict) {
                    if (errortype[i] == "A" && (trendtype[j] == 
                      "M" || seasontype[k] == "M")) {
                      next
                    }
                    if (errortype[i] == "M" && trendtype[j] == 
                      "M" && seasontype[k] == "A") {
                      next
                    }
                    if (additive.only && (errortype[i] == "M" || 
                      trendtype[j] == "M" || seasontype[k] == 
                      "M")) {
                      next
                    }
                  }
                  if (!data.positive && errortype[i] == "M") {
                    next
                  }
                  fit <- try(etsmodel(y, errortype[i], trendtype[j], 
                    seasontype[k], damped[l], alpha, beta, gamma, 
                    phi, lower = lower, upper = upper, opt.crit = opt.crit, 
                    nmse = nmse, bounds = bounds, ...), silent = TRUE)
                  if (is.element("try-error", class(fit))) 
                    fit.ic <- Inf
                  else fit.ic <- switch(ic, aic = fit$aic, bic = fit$bic, 
                    aicc = fit$aicc)
                  if (!is.na(fit.ic)) {
                    if (fit.ic < best.ic) {
                      model <- fit
                      best.ic <- fit.ic
                      best.e <- errortype[i]
                      best.t <- trendtype[j]
                      best.s <- seasontype[k]
                      best.d <- damped[l]
                    }
                  }
                }
            }
        }
    }
    if (best.ic == Inf) {
        stop("No model able to be fitted")
    }
    model$m <- m
    model$method <- paste("ETS(", best.e, ",", best.t, 
        ifelse(best.d, "d", ""), ",", best.s, 
        ")", sep = "")
    model$series <- seriesname
    model$components <- c(best.e, best.t, best.s, best.d)
    model$call <- match.call()
    model$initstate <- model$states[1, ]
    np <- length(model$par)
    model$sigma2 <- sum(model$residuals^2, na.rm = TRUE)/(ny - 
        np)
    model$x <- orig.y
    if (!is.null(lambda)) {
        model$fitted <- InvBoxCox(model$fitted, lambda, biasadj, 
            var(model$residuals))
        attr(lambda, "biasadj") <- biasadj
    }
    model$lambda <- lambda
    return(structure(model, class = "ets"))
}

Şimdi sıra ETS yöntemi kullanılarak modelin oluşturulmasına gelmiştir. Dolar alış kuruna ait 353 günlük bir zaman serisi için tahmin yapılacağı için aşağıdaki R kod bloğunda h=353 olarak belirlenmiştir. Kurulan modele, kurulan modelden üretilen tahminlere ilişkin grafik için R kod bloğu bir bütün olarak aşağıda sunulmuştur.

ETS <- forecast(ets(data), h=353)
autoplot(ETS) +
  ylab("Alış Kuru") +
  xlab("Zaman") +
  ggtitle("ETS Yöntemi İle Tahmin Edilen Dolar Alış Kuru") +
  theme_bw()+
  theme(plot.title = element_text(hjust = 0.5))

Yukarıdaki kod bloğunun çalıştırılmasından sonra elde edilen güven aralıklı (CI: Confidence Interval) 353 günlük dolar kuru tahminleri aşağıdaki şekilde verilmiştir. Burada, maviyle gösterilen alan güven aralıklarıyla birlikte dolar alış kuru tahminlerini, önceki alan ise mevcut dolar alış kuru gerçekleşmelerini göstermektedir. Maviyle gösterilen alanda yer alan eğri ise nokta tahmin (point forecast)’leri göstermektedir.

Elde edilen 353 günlük dolar alış kuru tahmin değerleri, tahmin edilen tarih ile bu tarihlere ait dolar alış kur değerleri xlsx (Microsoft Office Excel) uzantılı “ets” adlı dosyaya yazdırılmıştır. Bahsedilen bu işlemleri gösterir R kod bloğunu aşağıda yer verilmiştir.

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(ETS)
today4<-today3[, -2:-3]
ets<-cbind(Tarih=today2, today4)

write.xlsx(ets, file = "ets.xlsx",
      sheetName = "tahmin_aliskuru", append = FALSE)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra elde edilen tahmini dolar alış kur değerleri tahmin edilen tarihe göre güven aralıkları ile birlikte xlsx uzantılı olarak aşağıda verilmiştir. Buradaki linkten sonuçları indirebilirsiniz.

ETS yönteminin ortaya koyduğu hata türlerinden MAPE (Mean Absolute Percentage Error) değerine bakalım. Bu amaçla aşağıdaki R kod bloğu çalıştırıldıktan sonra ETS yönteminin sonuçlarına bakılarak MAPE ve diğer hata türlerine ulaşılabilir.

ETS <- forecast(ets(data), h=353)
summary(ETS)

Yukarıdaki kod bloğunun çalıştılmasından sonra aşağıdaki sonuçlardan da görüleceği üzere ETS yöntemi, dolar alış kuru tahminlerinde ürettiği MAPE hata değeri 0.505253‘tür.

Forecast method: ETS(M,Ad,N)

Model Information:
ETS(M,Ad,N) 

Call:
 ets(y = data) 

  Smoothing parameters:
    alpha = 0.9999 
    beta  = 0.0024 
    phi   = 0.9782 

  Initial states:
    l = 0 
    b = 0 

  sigma:  0.014

      AIC      AICc       BIC 
-43903.33 -43903.32 -43860.01 

Error measures:
                       ME      RMSE         MAE        MPE     MAPE       MASE
Training set 0.0005255783 0.0204113 0.006772561 0.07816683 0.505253 0.02747071
                  ACF1
Training set 0.1603195

ARIMA Yöntemi

Dolar alış kurunun tahmininde kullanılan üçüncü yöntem ARIMA olup, bu yöntemin algoritmasına aşağıda yer verilmiştir.

function (x, order = c(0L, 0L, 0L), seasonal = list(order = c(0L, 
    0L, 0L), period = NA), xreg = NULL, include.mean = TRUE, 
    transform.pars = TRUE, fixed = NULL, init = NULL, method = c("CSS-ML", 
        "ML", "CSS"), n.cond, SSinit = c("Gardner1980", 
        "Rossignol2011"), optim.method = "BFGS", 
    optim.control = list(), kappa = 1e+06) 
{
    "%+%" <- function(a, b) .Call(C_TSconv, a, b)
    SSinit <- match.arg(SSinit)
    SS.G <- SSinit == "Gardner1980"
    upARIMA <- function(mod, phi, theta) {
        p <- length(phi)
        q <- length(theta)
        mod$phi <- phi
        mod$theta <- theta
        r <- max(p, q + 1L)
        if (p > 0) 
            mod$T[1L:p, 1L] <- phi
        if (r > 1L) 
            mod$Pn[1L:r, 1L:r] <- if (SS.G) 
                .Call(C_getQ0, phi, theta)
            else .Call(C_getQ0bis, phi, theta, tol = 0)
        else mod$Pn[1L, 1L] <- if (p > 0) 
            1/(1 - phi^2)
        else 1
        mod$a[] <- 0
        mod
    }
    arimaSS <- function(y, mod) {
        .Call(C_ARIMA_Like, y, mod, 0L, TRUE)
    }
    armafn <- function(p, trans) {
        par <- coef
        par[mask] <- p
        trarma <- .Call(C_ARIMA_transPars, par, arma, trans)
        if (is.null(Z <- tryCatch(upARIMA(mod, trarma[[1L]], 
            trarma[[2L]]), error = function(e) NULL))) 
            return(.Machine$double.xmax)
        if (ncxreg > 0) 
            x <- x - xreg %*% par[narma + (1L:ncxreg)]
        res <- .Call(C_ARIMA_Like, x, Z, 0L, FALSE)
        s2 <- res[1L]/res[3L]
        0.5 * (log(s2) + res[2L]/res[3L])
    }
    armaCSS <- function(p) {
        par <- as.double(fixed)
        par[mask] <- p
        trarma <- .Call(C_ARIMA_transPars, par, arma, FALSE)
        if (ncxreg > 0) 
            x <- x - xreg %*% par[narma + (1L:ncxreg)]
        res <- .Call(C_ARIMA_CSS, x, arma, trarma[[1L]], trarma[[2L]], 
            as.integer(ncond), FALSE)
        0.5 * log(res)
    }
    arCheck <- function(ar) {
        p <- max(which(c(1, -ar) != 0)) - 1
        if (!p) 
            return(TRUE)
        all(Mod(polyroot(c(1, -ar[1L:p]))) > 1)
    }
    maInvert <- function(ma) {
        q <- length(ma)
        q0 <- max(which(c(1, ma) != 0)) - 1L
        if (!q0) 
            return(ma)
        roots <- polyroot(c(1, ma[1L:q0]))
        ind <- Mod(roots) < 1
        if (all(!ind)) 
            return(ma)
        if (q0 == 1) 
            return(c(1/ma[1L], rep.int(0, q - q0)))
        roots[ind] <- 1/roots[ind]
        x <- 1
        for (r in roots) x <- c(x, 0) - c(0, x)/r
        c(Re(x[-1L]), rep.int(0, q - q0))
    }
    series <- deparse(substitute(x))
    if (NCOL(x) > 1L) 
        stop("only implemented for univariate time series")
    method <- match.arg(method)
    x <- as.ts(x)
    if (!is.numeric(x)) 
        stop("'x' must be numeric")
    storage.mode(x) <- "double"
    dim(x) <- NULL
    n <- length(x)
    if (!missing(order)) 
        if (!is.numeric(order) || length(order) != 3L || any(order < 
            0)) 
            stop("'order' must be a non-negative numeric vector of length 3")
    if (!missing(seasonal)) 
        if (is.list(seasonal)) {
            if (is.null(seasonal$order)) 
                stop("'seasonal' must be a list with component 'order'")
            if (!is.numeric(seasonal$order) || length(seasonal$order) != 
                3L || any(seasonal$order < 0L)) 
                stop("'seasonal$order' must be a non-negative numeric vector of length 3")
        }
        else if (is.numeric(order)) {
            if (length(order) == 3L) 
                seasonal <- list(order = seasonal)
            else ("'seasonal' is of the wrong length")
        }
        else stop("'seasonal' must be a list with component 'order'")
    if (is.null(seasonal$period) || is.na(seasonal$period) || 
        seasonal$period == 0) 
        seasonal$period <- frequency(x)
    arma <- as.integer(c(order[-2L], seasonal$order[-2L], seasonal$period, 
        order[2L], seasonal$order[2L]))
    narma <- sum(arma[1L:4L])
    xtsp <- tsp(x)
    tsp(x) <- NULL
    Delta <- 1
    for (i in seq_len(order[2L])) Delta <- Delta %+% c(1, -1)
    for (i in seq_len(seasonal$order[2L])) Delta <- Delta %+% 
        c(1, rep.int(0, seasonal$period - 1), -1)
    Delta <- -Delta[-1L]
    nd <- order[2L] + seasonal$order[2L]
    n.used <- sum(!is.na(x)) - length(Delta)
    if (is.null(xreg)) {
        ncxreg <- 0L
    }
    else {
        nmxreg <- deparse(substitute(xreg))
        if (NROW(xreg) != n) 
            stop("lengths of 'x' and 'xreg' do not match")
        ncxreg <- NCOL(xreg)
        xreg <- as.matrix(xreg)
        storage.mode(xreg) <- "double"
    }
    class(xreg) <- NULL
    if (ncxreg > 0L && is.null(colnames(xreg))) 
        colnames(xreg) <- if (ncxreg == 1L) 
            nmxreg
        else paste0(nmxreg, 1L:ncxreg)
    if (include.mean && (nd == 0L)) {
        xreg <- cbind(intercept = rep(1, n), xreg = xreg)
        ncxreg <- ncxreg + 1L
    }
    if (method == "CSS-ML") {
        anyna <- anyNA(x)
        if (ncxreg) 
            anyna <- anyna || anyNA(xreg)
        if (anyna) 
            method <- "ML"
    }
    if (method == "CSS" || method == "CSS-ML") {
        ncond <- order[2L] + seasonal$order[2L] * seasonal$period
        ncond1 <- order[1L] + seasonal$period * seasonal$order[1L]
        ncond <- ncond + if (!missing(n.cond)) 
            max(n.cond, ncond1)
        else ncond1
    }
    else ncond <- 0
    if (is.null(fixed)) 
        fixed <- rep(NA_real_, narma + ncxreg)
    else if (length(fixed) != narma + ncxreg) 
        stop("wrong length for 'fixed'")
    mask <- is.na(fixed)
    no.optim <- !any(mask)
    if (no.optim) 
        transform.pars <- FALSE
    if (transform.pars) {
        ind <- arma[1L] + arma[2L] + seq_len(arma[3L])
        if (any(!mask[seq_len(arma[1L])]) || any(!mask[ind])) {
            warning("some AR parameters were fixed: setting transform.pars = FALSE")
            transform.pars <- FALSE
        }
    }
    init0 <- rep.int(0, narma)
    parscale <- rep(1, narma)
    if (ncxreg) {
        cn <- colnames(xreg)
        orig.xreg <- (ncxreg == 1L) || any(!mask[narma + 1L:ncxreg])
        if (!orig.xreg) {
            S <- svd(na.omit(xreg))
            xreg <- xreg %*% S$v
        }
        dx <- x
        dxreg <- xreg
        if (order[2L] > 0L) {
            dx <- diff(dx, 1L, order[2L])
            dxreg <- diff(dxreg, 1L, order[2L])
        }
        if (seasonal$period > 1L & seasonal$order[2L] > 0) {
            dx <- diff(dx, seasonal$period, seasonal$order[2L])
            dxreg <- diff(dxreg, seasonal$period, seasonal$order[2L])
        }
        fit <- if (length(dx) > ncol(dxreg)) 
            lm(dx ~ dxreg - 1, na.action = na.omit)
        else list(rank = 0L)
        if (fit$rank == 0L) {
            fit <- lm(x ~ xreg - 1, na.action = na.omit)
        }
        isna <- is.na(x) | apply(xreg, 1L, anyNA)
        n.used <- sum(!isna) - length(Delta)
        init0 <- c(init0, coef(fit))
        ses <- summary(fit)$coefficients[, 2L]
        parscale <- c(parscale, 10 * ses)
    }
    if (n.used <= 0) 
        stop("too few non-missing observations")
    if (!is.null(init)) {
        if (length(init) != length(init0)) 
            stop("'init' is of the wrong length")
        if (any(ind <- is.na(init))) 
            init[ind] <- init0[ind]
        if (method == "ML") {
            if (arma[1L] > 0) 
                if (!arCheck(init[1L:arma[1L]])) 
                  stop("non-stationary AR part")
            if (arma[3L] > 0) 
                if (!arCheck(init[sum(arma[1L:2L]) + 1L:arma[3L]])) 
                  stop("non-stationary seasonal AR part")
            if (transform.pars) 
                init <- .Call(C_ARIMA_Invtrans, as.double(init), 
                  arma)
        }
    }
    else init <- init0
    coef <- as.double(fixed)
    if (!("parscale" %in% names(optim.control))) 
        optim.control$parscale <- parscale[mask]
    if (method == "CSS") {
        res <- if (no.optim) 
            list(convergence = 0L, par = numeric(), value = armaCSS(numeric()))
        else optim(init[mask], armaCSS, method = optim.method, 
            hessian = TRUE, control = optim.control)
        if (res$convergence > 0) 
            warning(gettextf("possible convergence problem: optim gave code = %d", 
                res$convergence), domain = NA)
        coef[mask] <- res$par
        trarma <- .Call(C_ARIMA_transPars, coef, arma, FALSE)
        mod <- makeARIMA(trarma[[1L]], trarma[[2L]], Delta, kappa, 
            SSinit)
        if (ncxreg > 0) 
            x <- x - xreg %*% coef[narma + (1L:ncxreg)]
        arimaSS(x, mod)
        val <- .Call(C_ARIMA_CSS, x, arma, trarma[[1L]], trarma[[2L]], 
            as.integer(ncond), TRUE)
        sigma2 <- val[[1L]]
        var <- if (no.optim) 
            numeric()
        else solve(res$hessian * n.used)
    }
    else {
        if (method == "CSS-ML") {
            res <- if (no.optim) 
                list(convergence = 0L, par = numeric(), value = armaCSS(numeric()))
            else optim(init[mask], armaCSS, method = optim.method, 
                hessian = FALSE, control = optim.control)
            if (res$convergence == 0) 
                init[mask] <- res$par
            if (arma[1L] > 0) 
                if (!arCheck(init[1L:arma[1L]])) 
                  stop("non-stationary AR part from CSS")
            if (arma[3L] > 0) 
                if (!arCheck(init[sum(arma[1L:2L]) + 1L:arma[3L]])) 
                  stop("non-stationary seasonal AR part from CSS")
            ncond <- 0L
        }
        if (transform.pars) {
            init <- .Call(C_ARIMA_Invtrans, init, arma)
            if (arma[2L] > 0) {
                ind <- arma[1L] + 1L:arma[2L]
                init[ind] <- maInvert(init[ind])
            }
            if (arma[4L] > 0) {
                ind <- sum(arma[1L:3L]) + 1L:arma[4L]
                init[ind] <- maInvert(init[ind])
            }
        }
        trarma <- .Call(C_ARIMA_transPars, init, arma, transform.pars)
        mod <- makeARIMA(trarma[[1L]], trarma[[2L]], Delta, kappa, 
            SSinit)
        res <- if (no.optim) 
            list(convergence = 0, par = numeric(), value = armafn(numeric(), 
                as.logical(transform.pars)))
        else optim(init[mask], armafn, method = optim.method, 
            hessian = TRUE, control = optim.control, trans = as.logical(transform.pars))
        if (res$convergence > 0) 
            warning(gettextf("possible convergence problem: optim gave code = %d", 
                res$convergence), domain = NA)
        coef[mask] <- res$par
        if (transform.pars) {
            if (arma[2L] > 0L) {
                ind <- arma[1L] + 1L:arma[2L]
                if (all(mask[ind])) 
                  coef[ind] <- maInvert(coef[ind])
            }
            if (arma[4L] > 0L) {
                ind <- sum(arma[1L:3L]) + 1L:arma[4L]
                if (all(mask[ind])) 
                  coef[ind] <- maInvert(coef[ind])
            }
            if (any(coef[mask] != res$par)) {
                oldcode <- res$convergence
                res <- optim(coef[mask], armafn, method = optim.method, 
                  hessian = TRUE, control = list(maxit = 0L, 
                    parscale = optim.control$parscale), trans = TRUE)
                res$convergence <- oldcode
                coef[mask] <- res$par
            }
            A <- .Call(C_ARIMA_Gradtrans, as.double(coef), arma)
            A <- A[mask, mask]
            var <- crossprod(A, solve(res$hessian * n.used, A))
            coef <- .Call(C_ARIMA_undoPars, coef, arma)
        }
        else var <- if (no.optim) 
            numeric()
        else solve(res$hessian * n.used)
        trarma <- .Call(C_ARIMA_transPars, coef, arma, FALSE)
        mod <- makeARIMA(trarma[[1L]], trarma[[2L]], Delta, kappa, 
            SSinit)
        val <- if (ncxreg > 0L) 
            arimaSS(x - xreg %*% coef[narma + (1L:ncxreg)], mod)
        else arimaSS(x, mod)
        sigma2 <- val[[1L]][1L]/n.used
    }
    value <- 2 * n.used * res$value + n.used + n.used * log(2 * 
        pi)
    aic <- if (method != "CSS") 
        value + 2 * sum(mask) + 2
    else NA
    nm <- NULL
    if (arma[1L] > 0L) 
        nm <- c(nm, paste0("ar", 1L:arma[1L]))
    if (arma[2L] > 0L) 
        nm <- c(nm, paste0("ma", 1L:arma[2L]))
    if (arma[3L] > 0L) 
        nm <- c(nm, paste0("sar", 1L:arma[3L]))
    if (arma[4L] > 0L) 
        nm <- c(nm, paste0("sma", 1L:arma[4L]))
    if (ncxreg > 0L) {
        nm <- c(nm, cn)
        if (!orig.xreg) {
            ind <- narma + 1L:ncxreg
            coef[ind] <- S$v %*% coef[ind]
            A <- diag(narma + ncxreg)
            A[ind, ind] <- S$v
            A <- A[mask, mask]
            var <- A %*% var %*% t(A)
        }
    }
    names(coef) <- nm
    if (!no.optim) 
        dimnames(var) <- list(nm[mask], nm[mask])
    resid <- val[[2L]]
    tsp(resid) <- xtsp
    class(resid) <- "ts"
    structure(list(coef = coef, sigma2 = sigma2, var.coef = var, 
        mask = mask, loglik = -0.5 * value, aic = aic, arma = arma, 
        residuals = resid, call = match.call(), series = series, 
        code = res$convergence, n.cond = ncond, nobs = n.used, 
        model = mod), class = "Arima")
}

Şimdi sıra ARIMA yöntemi kullanılarak modelin oluşturulmasına gelmiştir. Dolar alış kuruna ait 353 günlük bir zaman serisi için tahmin yapılacağı için aşağıdaki R kod bloğunda h=353 olarak belirlenmiştir. Kurulan modele, kurulan modelden üretilen tahminlere ilişkin grafik için R kod bloğu bir bütün olarak aşağıda sunulmuştur.

ARIMA <- forecast(auto.arima(data), h=353)

Elde edilen 353 günlük dolar alış kuru tahmin değerleri, tahmin edilen tarih ile bu tarihlere ait dolar alış kur değerleri xlsx (Microsoft Office Excel) uzantılı “arima” adlı dosyaya yazdırılmıştır. Bahsedilen bu işlemleri gösterir R kod bloğuna aşağıda yer verilmiştir.

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(ARIMA)
today4<-today3[, -2:-3]
arima<-cbind(Tarih=today2, today4)

write.xlsx(arima, file = "arima.xlsx",
      sheetName = "tahmin_aliskuru", append = FALSE)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra elde edilen tahmini dolar alış kur değerleri tahmin edilen tarihe göre güven aralıkları ile birlikte xlsx uzantılı olarak aşağıda verilmiştir. Buradaki linkten sonuçları indirebilirsiniz.

ARIMA yönteminin ortaya koyduğu hata türlerinden MAPE (Mean Absolute Percentage Error) değerine bakalım. Bu amaçla aşağıdaki R kod bloğu çalıştırıldıktan sonra ARIMA yönteminin sonuçlarına bakılarak MAPE ve diğer hata türlerine ulaşılabilir.

ARIMA <- forecast(auto.arima(data), h=353)
summary(ARIMA)

Yukarıdaki kod bloğunun çalıştılmasından sonra aşağıdaki sonuçlardan da görüleceği üzere ARIMA yöntemi, dolar alış kuru tahminlerinde ürettiği MAPE hata değeri 0.5265276‘dır.

Forecast method: ARIMA(5,2,0)

Model Information:
Series: data 
ARIMA(5,2,0) 
Box Cox transformation: lambda= 0 

Coefficients:
          ar1      ar2      ar3      ar4      ar5
      -0.7279  -0.6671  -0.5238  -0.3363  -0.1811
s.e.   0.0098   0.0117   0.0124   0.0117   0.0098

sigma^2 estimated as 0.0001656:  log likelihood=29608.3
AIC=-59204.59   AICc=-59204.58   BIC=-59161.28

Error measures:
                        ME       RMSE         MAE         MPE      MAPE
Training set -0.0001702528 0.02194181 0.007389551 -0.01604272 0.5265276
                   MASE       ACF1
Training set 0.02997334 0.05974482

Naive Yöntemi

Dolar alış kurunun tahmininde kullanılan dördüncü yöntem Naive olup, bu yöntemin algoritmasına aşağıda yer verilmiştir.

function (y, h = 10, level = c(80, 95), fan = FALSE, lambda = NULL, 
    biasadj = FALSE, ..., x = y) 
{
    fc <- rwf(x, h = h, level = level, fan = fan, lambda = lambda, 
        drift = FALSE, biasadj = biasadj, ...)
    fc$model$call <- match.call()
    fc$series <- deparse(substitute(y))
    fc$method <- "Naive method"
    return(fc)
}

Şimdi sıra Naive yöntemi kullanılarak modelin oluşturulmasına gelmiştir. Dolar alış kuruna ait 353 günlük bir zaman serisi için tahmin yapılacağı için aşağıdaki R kod bloğunda h=353 olarak belirlenmiştir. Kurulan modele, kurulan modelden üretilen tahminlere ilişkin grafik için R kod bloğu bir bütün olarak aşağıda sunulmuştur.

naive <- naive(data, h=353)
autoplot(naive) +
  ylab("Alış Kuru") +
  xlab("Zaman") +
  ggtitle("Naive Yöntemi İle Tahmin Edilen Dolar Alış Kuru") +
  theme_bw()+
  theme(plot.title = element_text(hjust = 0.5))

Yukarıdaki kod bloğunun çalıştırılmasından sonra elde edilen güven aralıklı (CI: Confidence Interval) 353 günlük dolar kuru tahminleri aşağıdaki şekilde verilmiştir. Burada, maviyle gösterilen alan güven aralıklarıyla birlikte dolar alış kuru tahminlerini, önceki alan ise mevcut dolar alış kuru gerçekleşmelerini göstermektedir. Maviyle gösterilen alanda yer alan eğri ise nokta tahmin (point forecast)’leri göstermektedir.

Elde edilen 353 günlük dolar alış kuru tahmin değerleri, tahmin edilen tarih ile bu tarihlere ait dolar alış kur değerleri xlsx (Microsoft Office Excel) uzantılı “naive” adlı dosyaya yazdırılmıştır. Bahsedilen bu işlemleri gösterir R kod bloğunu aşağıda yer verilmiştir.

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(naive)
today4<-today3[, -2:-3]
naive<-cbind(Tarih=today2, today4)

write.xlsx(naive, file = "naive.xlsx",
      sheetName = "tahmin_aliskuru", append = FALSE)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra elde edilen tahmini dolar alış kur değerleri tahmin edilen tarihe göre güven aralıkları ile birlikte xlsx uzantılı olarak aşağıda verilmiştir. Buradaki linkten sonuçları indirebilirsiniz.

Naive yönteminin ortaya koyduğu hata türlerinden MAPE (Mean Absolute Percentage Error) değerine bakalım. Bu amaçla aşağıdaki R kod bloğu çalıştırıldıktan sonra Naive yönteminin sonuçlarına bakılarak MAPE ve diğer hata türlerine ulaşılabilir.

naive <- naive(data, h=353)
summary(naive)

Yukarıdaki kod bloğunun çalıştılmasından sonra aşağıdaki sonuçlardan da görüleceği üzere Naive yöntemi, dolar alış kuru tahminlerinde ürettiği MAPE hata değeri 0.4839495‘dir.

Forecast method: Naive method

Model Information:
Call: naive(y = data, h = 353) 

Residual sd: 0.0204 

Error measures:
                       ME       RMSE         MAE       MPE      MAPE       MASE
Training set 0.0005818318 0.02041678 0.006776669 0.1125204 0.4839495 0.02748738
                  ACF1
Training set 0.1624751

SES Yöntemi

Dolar alış kurunun tahmininde kullanılan beşinci yöntem SES olup, bu yöntemin algoritmasına aşağıda yer verilmiştir.

function (y, h = 10, level = c(80, 95), fan = FALSE, initial = c("optimal", 
    "simple"), alpha = NULL, lambda = NULL, biasadj = FALSE, 
    x = y, ...) 
{
    initial <- match.arg(initial)
    if (initial == "optimal") {
        fcast <- forecast(ets(x, "ANN", alpha = alpha, 
            opt.crit = "mse", lambda = lambda, biasadj = biasadj), 
            h, level = level, fan = fan, ...)
    }
    else {
        fcast <- forecast(HoltWintersZZ(x, alpha = alpha, beta = FALSE, 
            gamma = FALSE, lambda = lambda, biasadj = biasadj), 
            h, level = level, fan = fan, ...)
    }
    fcast$method <- fcast$model$method <- "Simple exponential smoothing"
    fcast$model$call <- match.call()
    fcast$series <- deparse(substitute(y))
    return(fcast)
}

Şimdi sıra SES yöntemi kullanılarak modelin oluşturulmasına gelmiştir. Dolar alış kuruna ait 353 günlük bir zaman serisi için tahmin yapılacağı için aşağıdaki R kod bloğunda h=353 olarak belirlenmiştir. Kurulan modele, kurulan modelden üretilen tahminlere ilişkin grafik için R kod bloğu bir bütün olarak aşağıda sunulmuştur.

ses<-ses(data, h=353)
autoplot(ses) +
  ylab("Alış Kuru") +
  xlab("Zaman") +
  ggtitle("SES Yöntemi İle Tahmin Edilen Dolar Alış Kuru") +
  theme_bw()+
  theme(plot.title = element_text(hjust = 0.5))

Yukarıdaki kod bloğunun çalıştırılmasından sonra elde edilen güven aralıklı (CI: Confidence Interval) 353 günlük dolar kuru tahminleri aşağıdaki şekilde verilmiştir. Burada, maviyle gösterilen alan güven aralıklarıyla birlikte dolar alış kuru tahminlerini, önceki alan ise mevcut dolar alış kuru gerçekleşmelerini göstermektedir. Maviyle gösterilen alanda yer alan eğri ise nokta tahmin (point forecast)’leri göstermektedir.

Elde edilen 353 günlük dolar alış kuru tahmin değerleri, tahmin edilen tarih ile bu tarihlere ait dolar alış kur değerleri xlsx (Microsoft Office Excel) uzantılı “ses” adlı dosyaya yazdırılmıştır. Bahsedilen bu işlemleri gösterir R kod bloğunu aşağıda yer verilmiştir.

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(ses)
today4<-today3[, -2:-3]
ses<-cbind(Tarih=today2, today4)

write.xlsx(ses, file = "ses.xlsx",
      sheetName = "tahmin_aliskuru", append = FALSE)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra elde edilen tahmini dolar alış kur değerleri tahmin edilen tarihe göre güven aralıkları ile birlikte xlsx uzantılı olarak aşağıda verilmiştir. Buradaki linkten sonuçları indirebilirsiniz.

SES yönteminin ortaya koyduğu hata türlerinden MAPE (Mean Absolute Percentage Error) değerine bakalım. Bu amaçla aşağıdaki R kod bloğu çalıştırıldıktan sonra SES yönteminin sonuçlarına bakılarak MAPE ve diğer hata türlerine ulaşılabilir.

ses<-ses(data, h=353)
summary(ses)

Yukarıdaki kod bloğunun çalıştılmasından sonra aşağıdaki sonuçlardan da görüleceği üzere SES yöntemi, dolar alış kuru tahminlerinde ürettiği MAPE hata değeri 0.5705732‘dir.

Forecast method: Simple exponential smoothing

Model Information:
Simple exponential smoothing 

Call:
 ses(y = data, h = 353) 

  Smoothing parameters:
    alpha = 0.9999 

  Initial states:
    l = -3e-04 

  sigma:  0.0204

     AIC     AICc      BIC 
14504.53 14504.53 14526.18 

Error measures:
                       ME      RMSE         MAE       MPE      MAPE       MASE
Training set 0.0005818628 0.0204161 0.006776099 0.1991842 0.5705732 0.02748506
                  ACF1
Training set 0.1625604

Driftli Rassal Yürüyüş Yöntemi

Dolar alış kurunun tahmininde kullanılan yedinci yöntem Driftli Rassal Yürüyüş olup, bu yöntemin algoritmasına aşağıda yer verilmiştir.

function (y, h = 10, drift = TRUE, level = c(80, 95), fan = FALSE, 
    lambda = NULL, biasadj = FALSE, ..., x = y) 
{
    fit <- lagwalk(x, lag = 1, drift = drift, lambda = lambda, 
        biasadj = biasadj)
    fc <- forecast(fit, h = h, level = level, fan = fan, lambda = fit$lambda, 
        biasadj = biasadj, ...)
    fc$model$call <- match.call()
    fc$series <- deparse(substitute(y))
    if (drift) {
        fc$method <- "Random walk with drift"
    }
    else {
        fc$method <- "Random walk"
    }
    return(fc)
}

Şimdi sıra Drift yöntemi kullanılarak modelin oluşturulmasına gelmiştir. Dolar alış kuruna ait 353 günlük bir zaman serisi için tahmin yapılacağı için aşağıdaki R kod bloğunda h=353 olarak belirlenmiştir. Kurulan modele, kurulan modelden üretilen tahminlere ilişkin grafik için R kod bloğu bir bütün olarak aşağıda sunulmuştur.

drift<-rwf(data, h = 353, drift = T)
autoplot(drift) +
  ylab("Alış Kuru") +
  xlab("Zaman") +
  ggtitle("Drift Yöntemi İle Tahmin Edilen Dolar Alış Kuru") +
  theme_bw()+
  theme(plot.title = element_text(hjust = 0.5))

Yukarıdaki kod bloğunun çalıştırılmasından sonra elde edilen güven aralıklı (CI: Confidence Interval) 353 günlük dolar kuru tahminleri aşağıdaki şekilde verilmiştir. Burada, maviyle gösterilen alan güven aralıklarıyla birlikte dolar alış kuru tahminlerini, önceki alan ise mevcut dolar alış kuru gerçekleşmelerini göstermektedir. Maviyle gösterilen alanda yer alan eğri ise nokta tahmin (point forecast)’leri göstermektedir.

Elde edilen 353 günlük dolar alış kuru tahmin değerleri, tahmin edilen tarih ile bu tarihlere ait dolar alış kur değerleri xlsx (Microsoft Office Excel) uzantılı “drift” adlı dosyaya yazdırılmıştır. Bahsedilen bu işlemleri gösterir R kod bloğunu aşağıda yer verilmiştir.

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(drift)
today4<-today3[, -2:-3]
drift<-cbind(Tarih=today2, today4)

write.xlsx(drift, file = "drift.xlsx",
      sheetName = "tahmin_aliskuru", append = FALSE)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra elde edilen tahmini dolar alış kur değerleri tahmin edilen tarihe göre güven aralıkları ile birlikte xlsx uzantılı olarak aşağıda verilmiştir. Buradaki linkten sonuçları indirebilirsiniz.

Drift yönteminin ortaya koyduğu hata türlerinden MAPE (Mean Absolute Percentage Error) değerine bakalım. Bu amaçla aşağıdaki R kod bloğu çalıştırıldıktan sonra Drift yönteminin sonuçlarına bakılarak MAPE ve diğer hata türlerine ulaşılabilir.

drift<-rwf(data, h = 353, drift = T)
summary(drift)

Yukarıdaki kod bloğunun çalıştılmasından sonra aşağıdaki sonuçlardan da görüleceği üzere Drift yöntemi, dolar alış kuru tahminlerinde ürettiği MAPE hata değeri 63.48552‘dir.

Forecast method: Random walk with drift

Model Information:
Call: rwf(y = data, h = 353, drift = T) 

Drift: 6e-04  (se 2e-04)
Residual sd: 0.0204 

Error measures:
                     ME       RMSE         MAE       MPE     MAPE       MASE
Training set 2.8526e-17 0.02040849 0.007005999 -63.13675 63.48552 0.02841758
                  ACF1
Training set 0.1624751

Driftsiz Rassal Yürüyüş Yöntemi

Dolar alış kurunun tahmininde kullanılan yedinci yöntem Driftsiz Rassal Yürüyüş olup, bu yöntemin kullanımına aşağıda yer verilmiştir.

function (y, h = 10, drift = FALSE, level = c(80, 95), fan = FALSE, 
    lambda = NULL, biasadj = FALSE, ..., x = y) 
{
    fit <- lagwalk(x, lag = 1, drift = drift, lambda = lambda, 
        biasadj = biasadj)
    fc <- forecast(fit, h = h, level = level, fan = fan, lambda = fit$lambda, 
        biasadj = biasadj, ...)
    fc$model$call <- match.call()
    fc$series <- deparse(substitute(y))
    if (drift) {
        fc$method <- "Random walk with drift"
    }
    else {
        fc$method <- "Random walk"
    }
    return(fc)
}

Şimdi sıra Driftsiz yöntemi kullanılarak modelin oluşturulmasına gelmiştir. Dolar alış kuruna ait 353 günlük bir zaman serisi için tahmin yapılacağı için aşağıdaki R kod bloğunda h=353 olarak belirlenmiştir. Kurulan modele, kurulan modelden üretilen tahminlere ilişkin grafik için R kod bloğu bir bütün olarak aşağıda sunulmuştur.

driftsiz<-rwf(data, h = 353, drift = F)
autoplot(driftsiz) +
  ylab("Alış Kuru") +
  xlab("Zaman") +
  ggtitle("Driftsiz Rassal Yürüyüş Yöntemi İle Tahmin Edilen Dolar Alış 
           Kuru") +
  theme_bw()+
  theme(plot.title = element_text(hjust = 0.5))

Yukarıdaki kod bloğunun çalıştırılmasından sonra elde edilen güven aralıklı (CI: Confidence Interval) 353 günlük dolar kuru tahminleri aşağıdaki şekilde verilmiştir. Burada, maviyle gösterilen alan güven aralıklarıyla birlikte dolar alış kuru tahminlerini, önceki alan ise mevcut dolar alış kuru gerçekleşmelerini göstermektedir. Maviyle gösterilen alanda yer alan eğri ise nokta tahmin (point forecast)’leri göstermektedir.

Elde edilen 353 günlük dolar alış kuru tahmin değerleri, tahmin edilen tarih ile bu tarihlere ait dolar alış kur değerleri xlsx (Microsoft Office Excel) uzantılı “driftsiz” adlı dosyaya yazdırılmıştır. Bahsedilen bu işlemleri gösterir R kod bloğuna aşağıda yer verilmiştir.

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(driftsiz)
today4<-today3[, -2:-3]
driftsiz<-cbind(Tarih=today2, today4)


write.xlsx(driftsiz, file = "driftsiz.xlsx",
      sheetName = "tahmin_aliskuru", append = FALSE)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra elde edilen tahmini dolar alış kur değerleri tahmin edilen tarihe göre güven aralıkları ile birlikte xlsx uzantılı olarak aşağıda verilmiştir. Buradaki linkten sonuçları indirebilirsiniz

Driftsiz yönteminin ortaya koyduğu hata türlerinden MAPE (Mean Absolute Percentage Error) değerine bakalım. Bu amaçla aşağıdaki R kod bloğu çalıştırıldıktan sonra Driftsiz yönteminin sonuçlarına bakılarak MAPE ve diğer hata türlerine ulaşılabilir.

driftsiz<-rwf(data, h = 353, drift = F)
summary(driftsiz)

Yukarıdaki kod bloğunun çalıştılmasından sonra aşağıdaki sonuçlardan da görüleceği üzere Driftsiz yöntem, dolar alış kuru tahminlerinde ürettiği MAPE hata değeri 0.4839495‘tir.

Forecast method: Random walk

Model Information:
Call: rwf(y = data, h = 353, drift = F) 

Residual sd: 0.0204 

Error measures:
                       ME       RMSE         MAE       MPE      MAPE       MASE
Training set 0.0005818318 0.02041678 0.006776669 0.1125204 0.4839495 0.02748738
                  ACF1
Training set 0.1624751

Holt Metodu

Dolar alış kurunun tahmininde kullanılan sekizinci yöntem Holt olup, bu yöntemin kullanımına aşağıda yer verilmiştir.

holt(
  y,
  h = 10,
  damped = FALSE,
  level = c(80, 95),
  fan = FALSE,
  initial = c("optimal", "simple"),
  exponential = FALSE,
  alpha = NULL,
  beta = NULL,
  phi = NULL,
  lambda = NULL,
  biasadj = FALSE,
  x = y,
  ...
)

Şimdi sıra Holt yöntemi kullanılarak modelin oluşturulmasına gelmiştir. Dolar alış kuruna ait 353 günlük bir zaman serisi için tahmin yapılacağı için aşağıdaki R kod bloğunda h=353 olarak belirlenmiştir. Kurulan modele, kurulan modelden üretilen tahminlere ilişkin grafik için R kod bloğu bir bütün olarak aşağıda sunulmuştur. Kurulan bu modelden sonuçların elde edilmesi diğer yöntemlere göre daha uzun sürmektedir.

holt <- holt(data, h=353)
autoplot(holt) +
  ylab("Alış Kuru") +
  xlab("Zaman") +
  ggtitle("Holt Yöntemi İle Tahmin Edilen Dolar Alış Kuru") +
  theme_bw()+
  theme(plot.title = element_text(hjust = 0.5))

Yukarıdaki kod bloğunun çalıştırılmasından sonra elde edilen güven aralıklı (CI: Confidence Interval) 353 günlük dolar kuru tahminleri aşağıdaki şekilde verilmiştir. Burada, maviyle gösterilen alan güven aralıklarıyla birlikte dolar alış kuru tahminlerini, önceki alan ise mevcut dolar alış kuru gerçekleşmelerini göstermektedir. Maviyle gösterilen alanda yer alan eğri ise nokta tahmin (point forecast)’leri göstermektedir.

Elde edilen 353 günlük dolar alış kuru tahmin değerleri, tahmin edilen tarih ile bu tarihlere ait dolar alış kur değerleri xlsx (Microsoft Office Excel) uzantılı “holt” adlı dosyaya yazdırılmıştır. Bahsedilen bu işlemleri gösterir R kod bloğuna aşağıda yer verilmiştir.

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(holt)
today4<-today3[,-2:-3]
holt<-cbind(Tarih=today2, today4)

write.xlsx(holt, file = "holt.xlsx",
      sheetName = "tahmin_aliskuru", append = FALSE)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra elde edilen tahmini dolar alış kur değerleri tahmin edilen tarihe göre güven aralıkları ile birlikte xlsx uzantılı olarak aşağıda verilmiştir. Buradaki linkten sonuçları indirebilirsiniz.

Holt yönteminin ortaya koyduğu hata türlerinden MAPE (Mean Absolute Percentage Error) değerine bakalım. Bu amaçla aşağıdaki R kod bloğu çalıştırıldıktan sonra Holt yönteminin sonuçlarına bakılarak MAPE ve diğer hata türlerine ulaşılabilir.

holt <- holt(data, h=353)
summary(holt)

Yukarıdaki kod bloğunun çalıştılmasından sonra aşağıdaki sonuçlardan da görüleceği üzere ELM yöntemi, dolar alış kuru tahminlerinde ürettiği MAPE hata değeri 108.3473‘tür.

Forecast method: Holt's method

Model Information:
Holt's method 

Call:
 holt(y = data, h = 353) 

  Smoothing parameters:
    alpha = 0.9999 
    beta  = 0.001 

  Initial states:
    l = -0.2047 
    b = 6e-04 

  sigma:  0.0205

     AIC     AICc      BIC 
14596.25 14596.26 14632.35 

Error measures:
                       ME       RMSE         MAE      MPE     MAPE       MASE
Training set 0.0001682216 0.02050503 0.006873361 7.650097 108.3473 0.02787958
                  ACF1
Training set 0.1597678

NNAR Metodu

Dolar alış kurunun tahmininde kullanılan sekizinci yöntem ileri beslemeli ve tek gizli tabakalı (feed-forward neural networks with a single hidden layer) olan NNAR (Neural Network Auto Regression) olup, bu yöntemin algoritmasına aşağıda yer verilmiştir.

function (y, p, P = 1, size, repeats = 20, xreg = NULL, lambda = NULL, 
    model = NULL, subset = NULL, scale.inputs = TRUE, x = y, 
    ...) 
{
    useoldmodel <- FALSE
    yname <- deparse(substitute(y))
    if (!is.null(model)) {
        useoldmodel <- TRUE
        if (!is.nnetar(model)) {
            stop("Model must be a nnetar object")
        }
        m <- max(round(frequency(model$x)), 1L)
        minlength <- max(c(model$p, model$P * m)) + 1
        if (length(x) < minlength) {
            stop(paste("Series must be at least of length", 
                minlength, "to use fitted model"))
        }
        if (tsp(as.ts(x))[3] != m) {
            warning(paste("Data frequency doesn't match fitted model, coercing to frequency =", 
                m))
            x <- ts(x, frequency = m)
        }
        if (!is.null(model$xreg)) {
            if (is.null(xreg)) {
                stop("No external regressors provided")
            }
            if (NCOL(xreg) != NCOL(model$xreg)) {
                stop("Number of external regressors does not match fitted model")
            }
        }
        lambda <- model$lambda
        size <- model$size
        p <- model$p
        P <- model$P
        if (P > 0) {
            lags <- sort(unique(c(1:p, m * (1:P))))
        }
        else {
            lags <- 1:p
        }
        if (is.null(model$scalex)) {
            scale.inputs <- FALSE
        }
    }
    else {
        if (length(y) < 3) {
            stop("Not enough data to fit a model")
        }
        constant_data <- is.constant(na.interp(x))
        if (constant_data) {
            warning("Constant data, setting p=1, P=0, lambda=NULL, scale.inputs=FALSE")
            scale.inputs <- FALSE
            lambda <- NULL
            p <- 1
            P <- 0
        }
        if (!is.null(xreg)) {
            constant_xreg <- any(apply(as.matrix(xreg), 2, function(x) is.constant(na.interp(x))))
            if (constant_xreg) {
                warning("Constant xreg column, setting scale.inputs=FALSE")
                scale.inputs <- FALSE
            }
        }
    }
    if (any(is.na(x))) {
        warning("Missing values in x, omitting rows")
    }
    if (!is.null(lambda)) {
        xx <- BoxCox(x, lambda)
        lambda <- attr(xx, "lambda")
    }
    else {
        xx <- x
    }
    xsub <- rep(TRUE, length(x))
    if (is.numeric(subset)) {
        xsub[-subset] <- FALSE
    }
    if (is.logical(subset)) {
        xsub <- subset
    }
    scalex <- NULL
    if (scale.inputs) {
        if (useoldmodel) {
            scalex <- model$scalex
        }
        else {
            tmpx <- scale(xx[xsub], center = TRUE, scale = TRUE)
            scalex <- list(center = attr(tmpx, "scaled:center"), 
                scale = attr(tmpx, "scaled:scale"))
        }
        xx <- scale(xx, center = scalex$center, scale = scalex$scale)
        xx <- xx[, 1]
    }
    xxreg <- NULL
    scalexreg <- NULL
    if (!is.null(xreg)) {
        xxreg <- xreg <- as.matrix(xreg)
        if (length(x) != NROW(xreg)) {
            stop("Number of rows in xreg does not match series length")
        }
        if (any(is.na(xreg))) {
            warning("Missing values in xreg, omitting rows")
        }
        if (scale.inputs) {
            if (useoldmodel) {
                scalexreg <- model$scalexreg
            }
            else {
                tmpx <- scale(xxreg[xsub, ], center = TRUE, scale = TRUE)
                scalexreg <- list(center = attr(tmpx, "scaled:center"), 
                  scale = attr(tmpx, "scaled:scale"))
            }
            xxreg <- scale(xxreg, center = scalexreg$center, 
                scale = scalexreg$scale)
        }
    }
    n <- length(xx)
    xx <- as.ts(xx)
    m <- max(round(frequency(xx)), 1L)
    if (!useoldmodel) {
        if (m == 1) {
            if (missing(p)) {
                p <- max(length(ar(na.interp(xx))$ar), 1)
            }
            if (p >= n) {
                warning("Reducing number of lagged inputs due to short series")
                p <- n - 1
            }
            lags <- 1:p
            if (P > 1) {
                warning("Non-seasonal data, ignoring seasonal lags")
            }
            P <- 0
        }
        else {
            if (missing(p)) {
                if (n > 2 * m) {
                  x.sa <- seasadj(mstl(na.interp(xx)))
                }
                else {
                  x.sa <- na.interp(xx)
                }
                p <- max(length(ar(x.sa)$ar), 1)
            }
            if (p >= n) {
                warning("Reducing number of lagged inputs due to short series")
                p <- n - 1
            }
            if (P > 0 && n >= m * P + 2) {
                lags <- sort(unique(c(1:p, m * (1:P))))
            }
            else {
                lags <- 1:p
                if (P > 0) {
                  warning("Series too short for seasonal lags")
                  P <- 0
                }
            }
        }
    }
    maxlag <- max(lags)
    nlag <- length(lags)
    y <- xx[-(1:maxlag)]
    lags.X <- matrix(NA_real_, ncol = nlag, nrow = n - maxlag)
    for (i in 1:nlag) lags.X[, i] <- xx[(maxlag - lags[i] + 1):(n - 
        lags[i])]
    lags.X <- cbind(lags.X, xxreg[-(1:maxlag), ])
    if (missing(size)) {
        size <- round((NCOL(lags.X) + 1)/2)
    }
    j <- complete.cases(lags.X, y)
    j <- j & xsub[-(1:maxlag)]
    if (NROW(lags.X[j, , drop = FALSE]) == 0) {
        stop("No data to fit (possibly due to NA or NaN)")
    }
    if (useoldmodel) {
        fit <- oldmodel_avnnet(lags.X[j, , drop = FALSE], y[j], 
            size = size, model)
    }
    else {
        fit <- avnnet(lags.X[j, , drop = FALSE], y[j], size = size, 
            repeats = repeats, ...)
    }
    out <- list()
    out$x <- as.ts(x)
    out$m <- m
    out$p <- p
    out$P <- P
    out$scalex <- scalex
    out$scalexreg <- scalexreg
    out$size <- size
    out$xreg <- xreg
    out$lambda <- lambda
    out$subset <- (1:length(x))[xsub]
    out$model <- fit
    out$nnetargs <- list(...)
    if (useoldmodel) {
        out$nnetargs <- model$nnetargs
    }
    if (NROW(lags.X[j, , drop = FALSE]) == 1) {
        fits <- c(rep(NA_real_, maxlag), mean(sapply(fit, predict)))
    }
    else {
        fits <- c(rep(NA_real_, maxlag), rowMeans(sapply(fit, 
            predict)))
    }
    if (scale.inputs) {
        fits <- fits * scalex$scale + scalex$center
    }
    fits <- ts(fits)
    if (!is.null(lambda)) {
        fits <- InvBoxCox(fits, lambda)
    }
    out$fitted <- ts(rep(NA_real_, length(out$x)))
    out$fitted[c(rep(TRUE, maxlag), j)] <- fits
    tsp(out$fitted) <- tsp(out$x)
    out$residuals <- out$x - out$fitted
    out$lags <- lags
    out$series <- yname
    out$method <- paste("NNAR(", p, sep = "")
    if (P > 0) {
        out$method <- paste(out$method, ",", P, sep = "")
    }
    out$method <- paste(out$method, ",", size, ")", 
        sep = "")
    if (P > 0) {
        out$method <- paste(out$method, "[", m, "]", 
            sep = "")
    }
    out$call <- match.call()
    return(structure(out, class = c("nnetar")))
}

Şimdi sıra NNAR yöntemi kullanılarak modelin oluşturulmasına gelmiştir. Dolar alış kuruna ait 353 günlük bir zaman serisi için tahmin yapılacağı için aşağıdaki R kod bloğunda h=353 olarak belirlenmiştir. Kurulan modele, kurulan modelden üretilen tahminlere ilişkin grafik için R kod bloğu bir bütün olarak aşağıda sunulmuştur. Kurulan bu modelden sonuçların elde edilmesi diğer yöntemlere göre daha uzun sürmektedir.

model <- nnetar(data, lambda=0)
nnar <- forecast(model,h=353)

autoplot (nnar) +
         ylab("Alış Kuru") +
         xlab("Zaman") +
         ggtitle("Driftsiz Rassal Yürüyüş Yöntemi İle Tahmin Edilen Dolar 
                 Alış Kuru") +
         theme_bw()+
         theme(plot.title = element_text(hjust = 0.5))

Yukarıdaki kod bloğunun çalıştırılmasından sonra elde edilen güven aralıklı (CI: Confidence Interval) 353 günlük dolar kuru tahminleri aşağıdaki şekilde verilmiştir. Burada, maviyle gösterilen alan güven aralıklarıyla birlikte dolar alış kuru tahminlerini, önceki alan ise mevcut dolar alış kuru gerçekleşmelerini göstermektedir. Maviyle gösterilen alanda yer alan eğri ise nokta tahmin (point forecast)’leri göstermektedir.

Elde edilen 353 günlük dolar alış kuru tahmin değerleri, tahmin edilen tarih ile bu tarihlere ait dolar alış kur değerleri xlsx (Microsoft Office Excel) uzantılı “nnar” adlı dosyaya yazdırılmıştır. Bahsedilen bu işlemleri gösterir R kod bloğuna aşağıda yer verilmiştir.

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(nnar)
today4<-today3
nnar<-cbind(Tarih=today2, today4)

write.xlsx(nnar, file = "nnar.xlsx",
      sheetName = "tahmin_aliskuru", append = FALSE)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra elde edilen tahmini dolar alış kur değerleri tahmin edilen tarihe göre güven aralıkları ile birlikte xlsx uzantılı olarak aşağıda verilmiştir. Buradaki linkten sonuçları indirebilirsiniz.

NNAR yönteminin ortaya koyduğu hata türlerinden MAPE (Mean Absolute Percentage Error) değerine bakalım. Bu amaçla aşağıdaki R kod bloğu çalıştırıldıktan sonra NNAR yönteminin sonuçlarına bakılarak MAPE ve diğer hata türlerine ulaşılabilir.

model <- nnetar(data, lambda=0)
nnar <- forecast(model,h=353)
summary(nnar)

Yukarıdaki kod bloğunun çalıştılmasından sonra aşağıdaki sonuçlardan da görüleceği üzere NNAR yönteminin dolar alış kuru tahminlerinde ürettiği MAPE hata değeri 0.6250022’dir.

Forecast method: NNAR(1,1,2)[365]

Model Information:

Average of 20 networks, each of which is
a 2-2-1 network with 9 weights
options were - linear output units 

Error measures:
                      ME       RMSE         MAE          MPE      MAPE
Training set 0.001965417 0.02524943 0.008746252 -0.004684467 0.6250022
                   MASE      ACF1
Training set 0.03547636 0.4467661

Theta Metodu

Dolar alış kurunun tahmininde kullanılan onuncu yöntem Theta olup, bu yöntemin algoritmasına aşağıda yer verilmiştir.

function (y, h = ifelse(frequency(y) > 1, 2 * frequency(y), 10), 
    level = c(80, 95), fan = FALSE, x = y) 
{
    if (fan) {
        level <- seq(51, 99, by = 3)
    }
    else {
        if (min(level) > 0 && max(level) < 1) {
            level <- 100 * level
        }
        else if (min(level) < 0 || max(level) > 99.99) {
            stop("Confidence limit out of range")
        }
    }
    n <- length(x)
    x <- as.ts(x)
    m <- frequency(x)
    if (m > 1 && !is.constant(x) && n > 2 * m) {
        r <- as.numeric(acf(x, lag.max = m, plot = FALSE)$acf)[-1]
        stat <- sqrt((1 + 2 * sum(r[-m]^2))/n)
        seasonal <- (abs(r[m])/stat > qnorm(0.95))
    }
    else {
        seasonal <- FALSE
    }
    origx <- x
    if (seasonal) {
        decomp <- decompose(x, type = "multiplicative")
        if (any(abs(seasonal(decomp)) < 1e-10)) 
            warning("Seasonal indexes equal to zero. Using non-seasonal Theta method")
        else x <- seasadj(decomp)
    }
    fcast <- ses(x, h = h)
    tmp2 <- lsfit(0:(n - 1), x)$coef[2]/2
    alpha <- pmax(1e-10, fcast$model$par["alpha"])
    fcast$mean <- fcast$mean + tmp2 * (0:(h - 1) + (1 - (1 - 
        alpha)^n)/alpha)
    if (seasonal) {
        fcast$mean <- fcast$mean * rep(tail(decomp$seasonal, 
            m), trunc(1 + h/m))[1:h]
        fcast$fitted <- fcast$fitted * decomp$seasonal
    }
    fcast$residuals <- origx - fcast$fitted
    fcast.se <- sqrt(fcast$model$sigma) * sqrt((0:(h - 1)) * 
        alpha^2 + 1)
    nconf <- length(level)
    fcast$lower <- fcast$upper <- ts(matrix(NA, nrow = h, ncol = nconf))
    tsp(fcast$lower) <- tsp(fcast$upper) <- tsp(fcast$mean)
    for (i in 1:nconf) {
        zt <- -qnorm(0.5 - level[i]/200)
        fcast$lower[, i] <- fcast$mean - zt * fcast.se
        fcast$upper[, i] <- fcast$mean + zt * fcast.se
    }
    fcast$x <- origx
    fcast$level <- level
    fcast$method <- "Theta"
    fcast$model <- list(alpha = alpha, drift = tmp2, sigma = fcast$model$sigma)
    fcast$model$call <- match.call()
    return(fcast)
}

Şimdi sıra Theta yöntemi kullanılarak modelin oluşturulmasına gelmiştir. Dolar alış kuruna ait 353 günlük bir zaman serisi için tahmin yapılacağı için aşağıdaki R kod bloğunda h=353 olarak belirlenmiştir. Kurulan modele, kurulan modelden üretilen tahminlere ilişkin grafik için R kod bloğu bir bütün olarak aşağıda sunulmuştur.

theta<-thetaf(data, h=353)

autoplot(theta) +
  ylab("Alış Kuru") +
  xlab("Zaman") +
  ggtitle("Theta Yöntemi İle Tahmin Edilen Dolar Alış Kuru") +
  theme_bw()+
  theme(plot.title = element_text(hjust = 0.5))

Yukarıdaki kod bloğunun çalıştırılmasından sonra elde edilen güven aralıklı (CI: Confidence Interval) 353 günlük dolar kuru tahminleri aşağıdaki şekilde verilmiştir. Burada, maviyle gösterilen alan güven aralıklarıyla birlikte dolar alış kuru tahminlerini, önceki alan ise mevcut dolar alış kuru gerçekleşmelerini göstermektedir. Maviyle gösterilen alanda yer alan eğri ise nokta tahmin (point forecast)’leri göstermektedir.

Elde edilen 353 günlük dolar alış kuru tahmin değerleri, tahmin edilen tarih ile bu tarihlere ait dolar alış kur değerleri xlsx (Microsoft Office Excel) uzantılı “theta” adlı dosyaya yazdırılmıştır. Bahsedilen bu işlemleri gösterir R kod bloğuna aşağıda yer verilmiştir.

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(theta)
today4<-today3[,-2:-3]
theta<-cbind(Tarih=today2, today4)

write.xlsx(theta, file = "theta.xlsx",
      sheetName = "tahmin_aliskuru", append = FALSE)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra elde edilen tahmini dolar alış kur değerleri tahmin edilen tarihe göre güven aralıkları ile birlikte xlsx uzantılı olarak aşağıda verilmiştir. Buradaki linkten sonuçları indirebilirsiniz.

Theta yönteminin ortaya koyduğu hata türlerinden MAPE (Mean Absolute Percentage Error) değerine bakalım. Bu amaçla aşağıdaki R kod bloğu çalıştırıldıktan sonra Theta yönteminin sonuçlarına bakılarak MAPE ve diğer hata türlerine ulaşılabilir.

theta<-thetaf(data, h=353)
summary(theta)

Yukarıdaki kod bloğunun çalıştılmasından sonra aşağıdaki sonuçlardan da görüleceği üzere Theta yönteminin dolar alış kuru tahminlerinde ürettiği MAPE hata değeri 0.5917247‘dir.

Forecast method: Theta

Model Information:
$alpha
[1] 0.9999

$drift
           X 
0.0002007181 

$sigma
[1] 0.0003995984

$call
thetaf(y = data, h = 353)


Error measures:
                       ME       RMSE         MAE       MPE      MAPE       MASE
Training set 0.0005853508 0.01998895 0.006803491 0.2005714 0.5917247 0.02759617
                  ACF1
Training set 0.1619785

SONUÇ

Hacim olarak oldukça güvenilir 40 yıllık günlük Dolar-TL alış kuru veri setinin kullanılması başlı başına çok değerli çıkarımlar ortaya konulmasına katkı sağladığından oluşturulan model farklı yöntemlerle karşılaştırmalı olarak test edilerek MAPE (Mean Absolute Percentage Error) değerleri açsısından en iyi yöntemin hangisinin olduğuna karar verilmiştir. Deneysel olarak Merkez Bankası veri tabanından 02.01.1980 tarihinden 13.01.2020 tarihine kadar (dahil) indirilmiş dolar alış kuru verisi üzerinden 31.12.2020 tarihine kadar (dahil) geçen 353 günlük bir tahmin yapılmıştır. Tahminler yapılırken otomatik (default) olarak veri seti kullanılan yöntem içerisinde eğitilerek (training) aşağıda yer alan yöntemlerle Dolar-TL alış kuru tahmin edilmiştir.

  1. TBATS (Exponential smoothing state space model with Box-Cox transformation, ARMA errors, Trend and Seasonal components)
  2. ARIMA (Autoregressive Integrated Moving Average)
  3. ETS (Exponential Smoothing State Space Model)
  4. Naive
  5. NNAR (Neural Network Autoregression): Otoregresyon Sinir Ağı
  6. Holt
  7. SES (Simple Exponential Smoothing)
  8. Driftli Rassal Yürüyüş Yöntemi (Random Walk Forecast with Drift)
  9. Driftsiz Rassal Yürüyüş Yöntemi (Random Walk Forecast without Drift)
  10. Theta

Yukarıdaki bahsedilen yöntemlerle dolar alış kur değerleri tahmin edildikten sonra elde edilen Dolar-TL alış kur değerlerine göre tahmin yöntemleri hata oranları açısından karşılaştırılmıştır. Bu bağlamda kullanılan hata oranları göstergesi olarak MAPE (Mean Absolute Percentage Error)‘den yararlanılmıştır. MAPE hata değeri en düşük olan tahmin yöntemi Dolar-TL alış kuru tahminleri açısından en iyi yöntem olarak belirlenmiştir. Ancak istenirse önceki kısımlarda diğer hata türlerine de yer verildiğinden bu hata türleri açısından kullanılan tahmin yöntemleri karşılaştırılabilir.

Döviz alış kuru tahminlerine bakıldığında MAPE hata değerleri, kullanılan 10 tahmin yöntemine göre aşağıdaki kod bloğunda verilmiştir.

Yontem<-c("TBATS","ETS", "ARIMA", "Naive", "SES","Driftli Rassal Yürüyüş", 
          "Driftsiz Rassal Yürüyüş","Holt","NNAR", "Theta")

MAPE_Hata_Değerleri<-c(0.4897634, 0.505253, 0.5265276, 0.4839495, 
                       0.5705732,63.48552, 0.4839495, 108.3473, 0.6250022, 
                       0.5917247)

tablo<-tibble(Yöntem=Yontem, MAPE=MAPE_Hata_Değerleri)

t1<-tablo %>% arrange((MAPE))

formattable(t1)  

Yukarıdaki R kod bloğu çalıştırıldıktan sonra kullanılan tahmin yöntemine göre ortaya konulan MAPE hata değerleri aşağıdaki tabloda verilmiştir. Literatürde MAPE değerleri en düşük olan tahmin metodu diğer metotlara göre daha iyi olduğu kabul edilmektedir.

Kullanılan Tahmin Yöntemine Göre MAPE Hata Değerleri

Yukarıdaki tabloda MAPE değerlerine bakıldığında en iyi ilk üç tahmin yönteminin sırasıyla Naive, Driftsiz Rassal Yürüyüş ve TBATS yöntemleri olduğu görülmektedir. Bu üç yöntemin 31.12.2020 dönem sonuna kadar (bu tarih dahil) tahminlerine yukarıdaki bölümlerde yer verilmiştir. Sonuçlar bu bölümlerdeki linklerden xlsx uzantılı olarak indirilebilir. Ancak kullanılan tahmin sonuçlarına gerek ulaşım kolaylığı gerekse bir bütün olarak bir arada görülebilmesi adına yöntemlerden üretilen MAPE değerlerine göre aşağıda verilmiştir. Buradaki linklerden kullanılan tahmin yöntemine göre Dolar-TL alış kuru tahmin sonuçları indirilebilir.

Naive Yöntemi

Driftsiz Rassal Yürüyüş Yöntemi

TBATS Yöntemi

ETS Yöntemi

ARIMA Yöntemi

SES Yöntemi

Theta Yöntemi

NNAR Yöntemi

Driftli Rassal Yürüyüş Yöntemi

Holt Yöntemi

MAPE hata değerleri en düşük İlk 4 yönteme göre ortaya konulan 2020 yılı sonu son 10 Dolar-TL alış kur tahmin sonuçları TBATs yönteminden başlanarak verilmiştir.

TBATS Yöntemi Dolar-TL Alış Kuru Tahmin Sonuçları

TBATS yöntemi 2020 yılı sonu son 10 tahmin sonuçlarına ilişkin R kod bloğu aşağıda verilmiştir.

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(sonuc)
today4<-today3[, -2:-5]
tbats<-tibble(Tarih=today2,Nokta_Tahmin=digits(today4$`Point Forecast`, 4))
tbats10<-tail(tbats,10)
      
formattable(tbats10, 
            align = c("l","c"),
            list('Tarih' = formatter("span", style = ~ style(color = "grey", font.weight = "bold")), 
                 'Nokta_Tahmin' = color_bar("#FA614B"), digits('Nokta_Tahmin',4)))

Yukarıdaki R kod bloğu çalıştırıldıktan sonra TBATS yöntemine göre ortaya konulan 2020 yılı sonu son 10 Dolar-TL alış kuru tahmini tarihe göre aşağıdaki tabloda verilmiştir.

TBATS yöntemi kullanılarak ortaya konulan 353 günlük Dolar-TL alış kuru seyri ise aşağıdaki R kod bloğunda verilmiştir.

tbats<-zoo(tbats[,2], seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1))

tbats<-as.xts(tbats)

plot(tbats, main="TBATS: 2020 Yılı Dolar-TL Alış Kuru Tahminleri", col="red", cex.main=0.6, cex.lab=1)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra TBATS yönteminden elde edilen Dolar-TL alış kuru tahmin değerlerinin seyri aşağıdaki grafikte verilmiştir.

Naive ve Driftsiz Rassal Yürüyüş Yöntemlerine Göre Dolar-TL Alış Kuru Tahmin Sonuçları

Bu iki yönteme göre 14.01.2020 tarihinden 31.12.2020 tarihine kadar (dahil) tahmin edilen Dolar-TL alış kuru tahmin değeri 5.817’dir. Her iki yöntemden elde edilen nokta kur tahmin değerleri aynı olup, güven aralıkları sadece farklılık göstermektedir.

ETS Yöntemi Dolar-TL Alış Kuru Tahmin Sonuçları

ETS yöntemi 2020 yılı sonu son 10 tahmin sonuçlarına ilişkin R kod bloğu aşağıda verilmiştir.

ETS <- forecast(tev, h=353)

today1 <- seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1)
today2<-format(today1, format="%d/%m/%Y")
today3<-as_tibble(ETS)
today4<-today3[, -2:-5]
ets<-tibble(Tarih=today2,Nokta_Tahmin=digits(today4$`Point Forecast`, 7))
ets10<-tail(ets,10)
formattable(ets10, 
            align = c("l","c"),
            list('Tarih' = formatter("span", style = ~ style(color = "grey", font.weight = "bold")), 
                 'Nokta_Tahmin' = color_bar("#FA614B")))

Yukarıdaki R kod bloğu çalıştırıldıktan sonra ETS yöntemine göre ortaya konulan 2020 yılı sonu son 10 Dolar-TL alış kuru tahmini tarihe göre aşağıdaki tabloda verilmiştir.

ETS yöntemi kullanılarak ortaya konulan 353 günlük Dolar-TL alış kuru seyri ise aşağıdaki R kod bloğunda verilmiştir.

ets<-zoo(ets[,2], seq(from = as.Date("2020-01-14"), to = as.Date("2020-12-31"), by = 1))

ets<-as.xts(ets)

plot(ets, main="ETS: 2020 Yılı Dolar-TL Alış Kuru Tahminleri", col="red", cex.main=0.6, cex.lab=1)

Yukarıdaki R kod bloğunun çalıştırılmasından sonra ETS yönteminden elde edilen Dolar-TL alış kuru tahmin değerlerinin seyri aşağıdaki grafikte verilmiştir.

Bu çalışma özellikle dolar kuru tahminlerinde bilimselliğe dayalı olarak çok farklı ve sayıda tahmin metotlarının bir arada karşılaştırmalı olarak kullanıldığı ilk çalışma olması açısından son derece büyük önem arz etmektedir.

Faydalı olması ve farkındalık oluşturması dileğiyle.

Bilimle ve teknolojiyle kalınız.

Saygılarımla…

Not: Kaynak gösterilmeden alıntı yapılamaz veya kopyalanamaz.

Note: It can not be cited or copied without referencing.

Yararlanılan Kaynaklar (References)

Assimakopoulos, V. and Nikolopoulos, K. (2000). The theta model: a decomposition approach to forecasting. International Journal of Forecasting 16, 521-530.

Hyndman, R.J., and Billah, B. (2003) Unmasking the Theta method. International J. Forecasting, 19, 287-290.

https://www.r-project.org/

De Livera, Alysha M. “Automatic forecasting with a modified exponential smoothing state space framework.” Monash Econometrics and Business Statistics Working Papers 10, no. 10 (2010).

De Livera, Alysha M., Rob J. Hyndman, and Ralph D. Snyder. “Forecasting time series with complex seasonal patterns using exponential smoothing.” Journal of the American Statistical Association 106, no. 496 (2011): 1513-1527.

http://tagteam.harvard.edu/hub_feeds/1981/feed_items/273923

sonaligupta.pdf erişimi için tıklayın

7c33e1a4f01c45c44479df3356ad191dafb6.pdf erişimi için tıklayın

Antonio Preti & Gianluca Lentini (2016) Forecast models for suicide: Time-series analysis with data from Italy, Chronobiology International, 33:9, 1235-1246, DOI:10.1080/07420528.2016.1211669

https://yintingchou.com/posts/bats-and-tbats-model/

https://michaeltoth.me/the-ultimate-opinionated-guide-to-base-r-date-format-functions.html

https://robjhyndman.com/publications/complex-seasonality/

https://otexts.com/fpp2/combinations.html

https://tevfikbulut.com/2019/09/30/doviz-kurlarindaki-dalga-boylarinin-hesaplanmasina-yonelik-yontem-onerileri-ii-wt-ve-ct-yontemleri/

Hyndman, R.J., Koehler, A.B., Snyder, R.D., and Grose, S. (2002) “A state space framework for automatic forecasting using exponential smoothing methods”, International J. Forecasting, 18(3), 439–454.

Hyndman, R.J., Akram, Md., and Archibald, B. (2008) “The admissible parameter space for exponential smoothing models”. Annals of Statistical Mathematics, 60(2), 407–426.

Hyndman, R.J., Koehler, A.B., Ord, J.K., and Snyder, R.D. (2008) Forecasting with exponential smoothing: the state space approach, Springer-Verlag. http://www.exponentialsmoothing.net.

Hyndman and Athanasopoulos (2018) Forecasting: principles and practice, 2nd edition, OTexts: Melbourne, Australia. https://OTexts.org/fpp2/

For an introduction to neural networks see: Ord K., Fildes R., Kourentzes N. (2017) Principles of Business Forecasting 2e. Wessex Press Publishing Co., Chapter 10.

For combination operators see: Kourentzes N., Barrow B.K., Crone S.F. (2014) Neural network ensemble operators for time series forecasting. Expert Systems with Applications, 41(9), 4235-4244.

For variable selection see: Crone S.F., Kourentzes N. (2010) Feature selection for time series prediction A combined filter and wrapper approach for neural networks. Neurocomputing, 73(10), 1923-1936.

For ELMs see: Huang G.B., Zhou H., Ding X. (2006) Extreme learning machine: theory and applications. Neurocomputing, 70(1), 489-501.

9de5d49e26e933b5a731318390fe907d4957.pdf erişimi için tıklayın

nnfor.pdf erişimi için tıklayın

JSS2008.pdf erişimi için tıklayın

https://otexts.com/fpp2/nnetar.html

1401.1333.pdf erişimi için tıklayın

Assimakopoulos, V. and Nikolopoulos, K. (2000). The theta model: a decomposition approach to forecasting. International Journal of Forecasting 16, 521-530.

https://tevfikbulut.com/2020/01/06/dolar-kurunun-tahmini-uzerine-bir-vaka-calismasi-a-case-study-on-forecast-of-usd-exchange-rate/

https://tevfikbulut.com/2019/09/30/doviz-kurlarindaki-dalga-boylarinin-hesaplanmasina-yonelik-yontem-onerileri-ii-wt-ve-ct-yontemleri/

T.C. Merkez Bankası:https://evds2.tcmb.gov.tr/index.php?/evds/serieMarket/#collapse_2. Ulaşım Tarihi: 13/01/2020.

Türkiye Cumhuriyeti Devletinin Para Birimi Hakkında Kanun,
Kanun No: 5083, Resmi Gazete Tarihi: 31/01/2004, Resmi Gazete Sayısı: 25363 http://www.resmigazete.gov.tr/eskiler/2004/01/20040131.htm#3.Ulaşım Tarihi: 19/02/2019.

Tukey, J. W. (1993). Exploratory Data Analysis: Past, Present, and Future. Princeton University, Department of Statistics, Technical Report No:302. https://apps.dtic.mil/dtic/tr/fulltext/u2/a266775.pdf. Ulaşım Tarihi: 19/02/2019.

Döviz Kurlarındaki Dalga Boylarının Hesaplanmasına Yönelik Yöntem Önerileri: Wt ve Ct Yöntemleri: https://tevfikbulut.com/2019/02/24/21-yillik-doviz-verisinin-kesifsel-analizi/

https://www.r-project.org/

Hyndman, R.J., and Billah, B. (2003) Unmasking the Theta method. International J. Forecasting, 19, 287-290.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Google fotoğrafı

Google hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s