Risk Analitiği: R ile Hisse Senedi Verisi Üzerinde Value at Risk Uygulaması – II
Herkese merhaba,
Serinin ilk bölümünde “Value at Risk kavramı nedir? Uygulanan istatistiksel yöntemler nelerdir? Bir hissenin, portföyün veya pozisyonun riski nasıl hesaplanır ve yorumlanır?” gibi sorulara yanıtlar aradık.
Bu bölümde sliding (kaydırma) yöntemini kullanarak, hesaplanan VaR değerlerinin bactest (geriye dönük test) işlemini yapacağız. Bu şekilde, ilgili veri seti için uygun olan VaR hesaplama yöntemi seçilir ve bir hissenin, portföyün veya pozisyonun riski belirli bir sayı ile ifade edilmiş olur.
Sliding İşlemi
Sliding işlemi, veri setini dilimlere bölerek ayrı ayrı değerlendirmeye imkan sunmaktadır. Çalışmada 252 gözlem eğitim verisi olarak seçilmiş ve bir sonraki gözlem, test seti olarak kullanılmıştır. Şekilde 1’de görüldüğü üzere ilk adımda 1:252’inci gözlemler arası (siyah ile işaretli olan) VaR hesaplanacak olan eğitim seti, 253. gözlem (turuncu ile işaretli olan) alanı ifade etmekte. Bu şekilde veri setinin son gözlemine kadar kaydırmalı olarak ilerliyoruz. Her bir adım için hesaplanan VaR değerinin, test seti olarak belirlenen gözlemden büyük olduğu durumda 0, küçük olduğu durumda ise 1 değeri atayarak yeni bir veri seti oluşturmuş oluyoruz. Bu şekilde, her bir adımda hesaplanan maksimum kayıp değerinin aşılıp aşılmadığı bilgisi hesaplanmış oluyor.
#banvt ve #nthol hisse senetleri üzerinde uygulanan sliding yöntemi aşağıdaki gibidir. Uygulamaya ulaşmak ve tüm adımları incelemek için github linkini takip edebilirsiniz.
Veri Seti Oluşturulması
30 dakikalık, %95 güven düzeyinde kaydırmalı yöntem ile hesaplanan, Parametrik, Tarihsel, Monte Carlo ve Yaş Ağırlıklı Tarihsel Simülasyon (AWH) yöntemleri için VaR değerleri banvt_30_95 ve nthol_30_95 değişkenlerine kaydedilmiştir.
Ek olarak, hesaplanan VaR değerlerinin aşımlarını kontrol etmek için ise ayrı olarak backtest veri setleri oluşturulmuştur
# VaR | SLIDING | (30 MINUTES) | ALPHA = 0.05 -----------------------------
lambda <- 0.98
banvt_30_95 <- data.frame(parametric_VaR = NA,
historic_VaR = NA,
monte_carlo_VaR = NA,
awh_VaR = NA) # VaR hesaplamaları veri seti
nthol_30_95 <- data.frame(parametric_VaR = NA,
historic_VaR = NA,
monte_carlo_VaR = NA,
awh_VaR = NA)
banvt_30_95_backtest <- data.frame(Actual = NA, param_VaR = NA, hist_VaR = NA, mc_VaR = NA, ewhs_VaR = NA)
nthol_30_95_backtest <- data.frame(Actual = NA, param_VaR = NA, hist_VaR = NA, mc_VaR = NA, ewhs_VaR = NA)
Sliding İşlemi
for(i in 1:((nrow(tbl_30)-252)-1)){
## PARAMETRIC VaR
mean_banvt <- mean(tbl_30 %>% slice(i:(252+i-1)) %>% pull(banvt_return))
mean_nthol <- mean(tbl_30 %>% slice(i:(252+i-1)) %>% pull(nthol_return))
sd_dr_banvt <- sd(tbl_30 %>% slice(i:(252+i-1)) %>% pull(banvt_return))
sd_dr_nthol <- sd(tbl_30 %>% slice(i:(252+i-1)) %>% pull(nthol_return))
banvt_30_95_backtest[,1] <- tbl_30 %>% slice(253:nrow(tbl_30)) %>% select(banvt_return)
banvt_30_95_backtest[i,2] <- -mean_banvt + z*sd_dr_banvt
nthol_30_95_backtest[,1] <- tbl_30 %>% slice(253:nrow(tbl_30)) %>% select(nthol_return)
nthol_30_95_backtest[i,2] <- -mean_nthol + z*sd_dr_nthol
banvt_30_95[i,1] <- ifelse(-mean_nthol + z*sd_dr_nthol >
tbl_30 %>% select(banvt_return) %>% filter(row_number() == 252+i) %>% pull(),
0,1)
nthol_30_95[i,1] <- ifelse(-mean_nthol + z*sd_dr_nthol >
tbl_30 %>% select(nthol_return) %>% filter(row_number() == 252+i) %>% pull(),
0,1)
## HISTORICAL VaR
banvt_q <- quantile(tbl_30 %>% slice(i:(252+i-1)) %>% pull(banvt_return), alpha_)
nthol_q <- quantile(tbl_30 %>% slice(i:(252+i-1)) %>% pull(nthol_return), alpha_)
banvt_30_95_backtest[i,3] <- banvt_q
nthol_30_95_backtest[i,3] <- nthol_q
banvt_30_95[i,2] <- ifelse(banvt_q>
tbl_30 %>% select(banvt_return) %>% filter(row_number() == 252+i) %>% pull(),
0,1)
nthol_30_95[i,2] <- ifelse(nthol_q>
tbl_30 %>% select(nthol_return) %>% filter(row_number() == 252+i) %>% pull(),
0,1)
## MONTE CARLO SIMULATION
mean_dr_banvt <- tbl_30 %>% slice(i:(252+i-1)) %>% pull(banvt_return) %>% mean()
mean_dr_nthol <- tbl_30 %>% slice(i:(252+i-1)) %>% pull(nthol_return) %>% mean()
simulated_returns_banvt <- replicate(1000,
calculate_one_period_change(mean = mean_dr_banvt,
sd = sd_dr_banvt))
simulated_returns_nthol <- replicate(1000,
calculate_one_period_change(mean = mean_dr_nthol,
sd = sd_dr_nthol))
banvt_30_95_backtest[i,4] <- quantile(simulated_returns_banvt, alpha_)
nthol_30_95_backtest[i,4] <- quantile(simulated_returns_nthol, alpha_)
banvt_30_95[i,3] <- ifelse(quantile(simulated_returns_banvt, alpha_)>
tbl_30 %>% select(banvt_return) %>% filter(row_number() == 252+i) %>% pull(),
0,1)
nthol_30_95[i,3] <- ifelse(quantile(simulated_returns_nthol, alpha_)>
tbl_30 %>% select(nthol_return) %>% filter(row_number() == 252+i) %>% pull(),
0,1)
# AGE-WEIGHTED HISTORICAL SIMULATION | INTERPOLATION
## BANVT
basic_histor_banvt <- tbl_30 %>% select(banvt, banvt_return) %>%
slice(i:(252+i-1)) %>%
mutate(Periods_30 = 1:k) %>%
arrange(banvt_return) %>%
mutate(eq_weights = 1/k,
cum_eq_weigths = cumsum(eq_weights))
awh_banvt <- basic_histor_banvt %>%
mutate(hybrid_weights = ((1-lambda)*(lambda^(Periods_30-1)))/(1-lambda^k),
hybrid_cum_weights = cumsum(hybrid_weights))
banvt_30_95_backtest[i,5] <- approx(x =awh_banvt$hybrid_cum_weights,
y = awh_banvt$banvt_return,
xout=alpha_)$y
banvt_30_95[i,4] <- ifelse(approx(x =awh_banvt$hybrid_cum_weights,
y = awh_banvt$banvt_return,
xout=alpha_)$y>
tbl_30 %>% select(banvt_return) %>% filter(row_number() == 252+i) %>% pull(),
0,1)
## NTHOL
basic_histor_nthol <- tbl_30 %>% select(nthol, nthol_return) %>%
slice(i:(252+i-1)) %>%
mutate(Periods_30 = 1:k) %>%
arrange(nthol_return) %>%
mutate(eq_weights = 1/k,
cum_eq_weigths = cumsum(eq_weights))
awh_nthol <- basic_histor_nthol %>%
mutate(hybrid_weights = ((1-lambda)*(lambda^(Periods_30-1)))/(1-lambda^k),
hybrid_cum_weights = cumsum(hybrid_weights))
nthol_30_95_backtest[i,5] <- approx(x =awh_nthol$hybrid_cum_weights,
y = awh_nthol$nthol_return,
xout=alpha_)$y
nthol_30_95[i,4] <- ifelse(approx(x =awh_nthol$hybrid_cum_weights,
y = awh_nthol$nthol_return,
xout=alpha_)$y>
tbl_30 %>% select(banvt_return) %>% filter(row_number() == 252+i) %>% pull(),
0,1)
}
Geriye Dönük Testler (Backtest)
Hesaplanan VaR değerini aşan gözlemlerin, belirlenen güven düzeyine göre karşılaştırması çeşitli yöntemlerle yapılmaktadır.
Aşımların Ortalaması
Yeni oluşan veri seti, hesaplanan VaR sınır değerini geçen ve geçmeyen gözlemlere göre 0 ve 1 değerlerini içermekte. Dolayısıyla bu veri setinin ortalamasını almak, aslında bir hisse senedi için hesaplanan VaR değerinin performansını gösterebilir.
Ortalama alma işlemi bilgi vericidir ancak belirlenen alpha değerine göre istatistiksel olarak ayrışıp ayrışmadığı, aşımların sistematik olarak gerçekleşip gerçekleşmediği bilgisi için daha karmaşık testlere ihtiyaç duyulmuştur.
Tablo 1’de, 30 dakikalık #banvt hisse senedine ait aşımların ortalamarı verilmiştir.
Traffic Lights Yaklaşımı
Basel Komitesine göre bir VaR modelinin aşım sayıları, ve bu aşımlara karşılık gelen renklendirmeler Tablo 2’deki gibidir.
Yeşil bölge, kullanılan VaR modelinin uygun olduğunu, Sarı bölge başka alternatif modeller var ise uygunalabilir olduğunu ve Kırmızı bölge, ilgili var modelinin başarısız olduğunu ifade etmektedir. Bir önceki bölümde VaR değerleri ile hesaplanan veri setlerinde alınan ortalama değerler aşım sayıları hakkında bilgi vermekteydi. Dolayısıyla Parametrik ve Monte Carlo yöntemlerinin Traffic Lights yaklaşımına göre Yeşil bölgede, Tarihsel ve AWH modelinin ise sarı bölgede olduğu gözlenmektedir. Ancak modellerin yeşil bölgede olması doğru model olduğu anlamına gelmez, istatistiksel olarak belirlenen önem düzeyine yakın değerlere sahip modeller tercih edilmelidir. Burada amaç, tutarlı sonuçlara ulaşmaktır.
Kupiec’s Testi
Aşımların oranının, alpha önem düzeyi ile istatistiksel olarak ayrışıp ayrışmadığını test etmektedir. Test edilen hipotez aşağıdaki gibidir;
p: alpha önem düzeyi,
x: Aşım sayısı, T: Modele dahil edilen gözlem sayısı
Test istatistiği, En Çok Olabilirlik Kesitiricisi (Maksimum Likelihood Estimator) yöntemi ile tahmin edilir.
Elde edilen LR (olabilirlik oranı) değeri 1 serbestlik dereceli Chi-Square dağılımına uymaktadır. Elde edilen Chi-square değerine ait p-değeri, alpha değerinden küçük ise “H0 hipotezini reddedecek yeterli kanıt olduğu”, dolayısıyla aşımların, ilgili alpha değeri ile istatistiksel olarak ayrıştığı söylenir.
Christoffersen’s testi
Christoffersen’s testi, aşımların sayısı ve sistematik olup olmadığını incelemektedir. Test edilen hipotez aşağıdaki gibidir;
Test istatistiği hesaplanırken, Kupiec test istatistiği ile bağımsızlığı temsil eden olabilirlik test istatistiği toplanır ve nihai karar için test istatistiği oluşturulmuş olur.
Hesaplanan LR istatistiği 2 serbestlik dereceli Chi-Square dağılımına uymaktadır. Elde edilen 2 serbestlik dereceli Chi-square değerine ait p-değeri, alpha değerinden küçük ise “H0 hipotezini reddedecek yeterli kanıt olduğu”, dolayısıyla aşımların, ilgili alpha değeri ile istatistiksel olarak ayrıştığı söylenir.
Hipotez Testi Sonuçları
Tablo 3’de görüldüğü üzere, Parametric VaR ve Monte Carlo VaR yöntemleri Traffic Lights yaklaşımında yeşil bölgede olmalarına rağmen Kupiec ve Christoffersen testlerine göre yokluk hipotezleri reddedilmiş ve aşımların 0.05 önem düzeyine istatistiksel olarak eşit olmadığı ve aşımlarda sistematik bir örüntü bulunduğu test edilmiştir.
Tarihsel ve AWH VaR modelleri sarı bölgede olmalarına rağmen, alpha değerinden istatistiksel olarak ayrışmadığı gözlemlenmiştir. Dolayısıyla hesaplanan p değerlerinin alpha değerlerinden büyük olması sebebiyle, bu modeller ile hesaplanan VaR değeri daha tutarlıdır.
Günlük VaR Hesaplama Sonuçları
#banvt veri setini, günlük olarak %90 güven düzeyinde incelediğimizde sonuçlar aşağıdaki gibidir;
Aşımların Ortalama Değerleri
Tablo 4’te sunulan, %90 güven ile hesaplanan VaR değerlerine ait sonuçların, %95 güvenle hesaplanan değerlerden düşük olması doğaldır. Hata oranı, yani alpha değeri yükseldikçe, modellerin hata yapması ihtimali daha da yükselecektir. Elde edilen geriye dönük test sonuçları aşağıdaki gibidir;
Sonuç olarak, kaydırma (sliding) yöntemi ile Parametrik, Tarihsel, Monte Carlo ve AWH yöntemlerini uygulamış olduk. Her bir adımda hesaplanan VaR değerinin, bir sonraki adımda aşılıp aşılmadığını Traffic Lights, Kupiec’s ve Christoffersen’s geri dönük testleri (backtest) ile test etmiş olduk.
İyi uygulama olarak, model tercih etme aşamasında veriler günlük olarak, %99 güven düzeyi ile ve en az 252 gözlem eğitim verisi olarak ayrılacak şekilde uygulanması önemlidir. Günlük hesaplama işlemlerinde Parametric VaR ve AWH VaR hesaplamaları ile elde edilen sonuçların daha güvenilir ve tutarlı olduğu gözlemlenmiştir. İleri bir çalışma olarak alpha önem düzeyi düşürülebilir ve en iyi yöntem tercihi, yüksek güven aralığı üzerinden hesaplanabilir…
Sağlıklı günler
Versiyon bilgileri: R version 4.0.2
IDE: RStudio
Kaynaklar