tidyquant ile Finansal Analize Giriş

Bu yazımızda tidyquant kütüphanesini kullanarak kantitatif veri analizi yapacağız. tidyquant kütüphanesi ile tanışmadan önce, kantitatif finansal analiz fonksiyonlarını kullanmak için ts veya xts yapılarıyla zaman serileri oluşturma yoluna gidiyorduk. tidyquant paketi ile birlikte xts, zoo, quantmod, TTR, ve PerformanceAnalytics paketlerinin fonksiyonları kullanarak veri seti yapısı ve tidyverse mantığında analizler yapabiliyoruz. Bu entegrasyonu sağlamak için iki temel fonksiyon ile çalışıyoruz:

  • tq_transmute(): girdiden farklı periyodiklikte düzenli veri seti döner.
  • tq_mutate(): var olan düzenli veri setine yeni sütun ekler.

Gerekli Kütüphaneler ve Tanımlamalar

Kullanacağımız tüm kütüphaneler ile ilgili detaylar şu şekildedir:

  • tidyquant: finansal veri analizi
  • skimr: kompakt ve esnek veri özeti

Tüm yazılarımızda olduğu gibi, sisteminizde eksik olan kütüphanelerin kurulumunu yapalım.

install.packages(c("tidyquant","skimr"))

Ana kütüphaneleri aktif hale getirelim.

library(tidyquant)
library(skimr)

Ön Hazırlık/Veri Aktarımı

tidyquant fonksiyonlarından tq_get ile kantitatif veriyi çalışma ortamımıza tibble formatında alabiliriz. İlgili semboller için alınacak veriler tq_get fonksiyonunun get argümanı ile belirlenmektedir. get argümanının içerdiği seçeneklere bakalım:

  • stock.prices: Yahoo Finance üzerinden ilgili semboller için open, high, low, close, volume ve adjusted fiyatlarının getirir. quantmod paketindeki getSymbols() fonksiyonunu kapsar.
  • stock.prices.japan: Yahoo Finance Japon üzerinden ilgili semboller için open, high, low, close, volume ve adjusted fiyatlarının getirir. quantmod paketindeki getSymbols.yahooj() fonksiyonunu kapsar.
  • key.ratios: Morningstar üzerinden 89 tarihsel büyüme, kârlılık, mali sağlık, verimlilik ve değerleme rasyolarını getirir.
  • dividends: Yahoo Finance üzerinden ilgili stok sembolleri için temettüleri getirir. quantmod paketindeki getDividends() fonksiyonunu kapsar.
  • splits: Yahoo Finance üzerinden ilgili stok sembolleri için bölünmeleri getirir. quantmod paketindeki getSplits() fonksiyonunu kapsar.
  • economic.data: FRED üzerinden ekonomik verileri getirir. quantmod paketindeki getSymbols.FRED() fonksiyonunu kapsar.
  • metal.prices: Oanda üzerinden metal fiyatlarını getirir. quantmod paketindeki getMetals() fonksiyonunu kapsar.
  • exchange.rates: Oanda üzerinden döviz kurlarını getirir. quantmod paketindeki getFX() fonksiyonunu kapsar.
  • quandl: Quandl üzerinden veri setlerini getirir. Quandl paketindeki Quandl() fonksiyonunu kapsar.
  • quandl.datatable: Quandl üzerinden veri tablolarını getirir. Quandl paketindeki Quandl.datatable() fonksiyonunu kapsar.
  • alphavantager: Alpha Vantage üzerinden veri setlerini getirir. alphavantager paketindeki av_get() fonksiyonunu kapsar.
  • rblpapi: Bloomberg üzerinden veri setlerini getirir. Rblpapi paketindeki blpConnect() fonksiyonunu kapsar.

Önceklikle stock.prices ile Yahoo Finance üzerinden belirli kurların open, high, low, close, volume ve adjusted fiyatlarını çekerek veri setimizi oluşturalım. Fiyatları getirilecek kur sembollerini symbols adlı vektörde toplayalım. Belirlenen tarih aralığında ilgili stoklar için fiyatları getirmiş olacağız.

symbols <- c("EURTRY=X", "GBPUSD=X", "EURUSD=X")

exchangeP <- tq_get(symbols,
                        get  = "stock.prices",
                        from = "2010-01-01",
                        to   = "2018-01-01")
exchangeP
## # A tibble: 4,532 x 8
##    symbol   date        open  high   low close volume adjusted
##    <chr>    <date>     <dbl> <dbl> <dbl> <dbl>  <dbl>    <dbl>
##  1 EURTRY=X 2016-08-17  3.30  3.30  3.30  3.30      0     3.30
##  2 EURTRY=X 2016-08-18  3.32  3.32  3.32  3.32      0     3.32
##  3 EURTRY=X 2016-08-21  3.31  3.31  3.31  3.31      0     3.31
##  4 EURTRY=X 2016-08-22  3.33  3.33  3.33  3.33      0     3.33
##  5 EURTRY=X 2016-08-23  3.33  3.33  3.33  3.33      0     3.33
##  6 EURTRY=X 2016-08-24  3.32  3.32  3.32  3.32      0     3.32
##  7 EURTRY=X 2016-08-25  3.31  3.31  3.31  3.31      0     3.31
##  8 EURTRY=X 2016-08-28  3.31  3.31  3.31  3.31      0     3.31
##  9 EURTRY=X 2016-08-29  3.30  3.30  3.30  3.30      0     3.30
## 10 EURTRY=X 2016-08-30  3.31  3.31  3.31  3.31      0     3.31
## # ... with 4,522 more rows

Yazının devamında, daha önceki yazılarımızda yaptığımız gibi işlevler arası bağlantığıyı pipeline (%>%) operatörü kullanarak sağlayacağız.

Getirileri hesaplamadan önce ggplot2 paketindeki fonksiyonları kullanarak “EUR/TRY”, “GBP/TRY”, “EUR/TRY” kurlarının günlük kapanış fiyatlarını grafikte görelim.

exchangeP %>% 
    ggplot(aes(x = date, y = close, fill = symbol )) +
    geom_line(aes(colour = symbol), linetype = 1) +
      labs(title = "Kapanış Fiyatları",
           y = "Günlük Fiyatlar", x = "") +
    facet_wrap(~ symbol, ncol = 2, scales = "free_y") +
    theme_tq() + 
    scale_fill_tq()

Getiri Hesabı

Bu bölümde tq_transmute fonksiyonunu kullanarak ilgili kurların kapanış fiyatlarından getirileri hesaplayacağız. tq_transmute fonksiyon argümanlarından mutate_fun ile xts, quantmod, TTR paket fonksiyonlarından ilgili dönüşüm fonksiyonu belirlenmektedir. Bu yazımızda getiri hesabı için quandmod fonksiyonlarından periodReturn fonksiyonunu kullanacağız.

select argümanı ile dönüşüm fonksiyonuna gönderilecek sütun seçilmektedir. period ve type argümanları ise periodReturn fonksiyonun argümanları olup getirinin periyodunu ve tipini belirler. Her bir kurun ayrı ayrı logaritmik günlük getirilerini hesaplamak için tq_transmute fonksiyonunu veri setini sembollere göre grupladıktan
sonra uygulayacağız.

Sembol bazında gruplanmış veri setindeki her bir sembol grubunun son iki getirisini do fonksiyonunu kullanarak görelim. do fonksiyonu fonksiyonların grup bazında uygulannmasını sağlar.

exchangeR_daily <- exchangeP %>% 
  group_by(symbol) %>%
  tq_transmute(select = close, 
               mutate_fun = periodReturn, 
               period = "daily", 
               type = "log",
               col_rename = "daily_log_returns") 

 exchangeR_daily %>% group_by(symbol) %>% do(tail(., 2)) %>% ungroup()
## # A tibble: 6 x 3
##   symbol   date       daily_log_returns
##   <chr>    <date>                 <dbl>
## 1 EURTRY=X 2017-12-29          -0.00659
## 2 EURTRY=X 2018-01-01           0.0100 
## 3 EURUSD=X 2017-12-29           0.00343
## 4 EURUSD=X 2018-01-01           0.00528
## 5 GBPUSD=X 2017-12-29           0.00275
## 6 GBPUSD=X 2018-01-01           0.00558

Günlük logaritmik getirilerinin olasılık yoğunluk grafiklerini oluşturalım.

exchangeR_daily %>%
    ggplot(aes(x = daily_log_returns, fill = symbol)) +
    geom_density(alpha = 0.5) +
    labs(title = "Günlük Kayıt Getirileri",
         x = "Aylık Getirileri",
         y = "Yoğunluk") +
    theme_tq() +
    scale_fill_tq() + 
    facet_wrap(~ symbol, ncol = 2)

Bu adımda ise getiri tipini ve periyodunu değiştirerek aylık aritmetik getiri hesaplayalım.

exchangeR_monthly <- exchangeP %>% 
  group_by(symbol) %>%
  tq_transmute(select = close, 
               mutate_fun = periodReturn, 
               period = "monthly", 
               type = "arithmetic")


exchangeR_monthly %>% 
  group_by(symbol) %>% do(tail(.,2)) %>% ungroup()
## # A tibble: 6 x 3
##   symbol   date       monthly.returns
##   <chr>    <date>               <dbl>
## 1 EURTRY=X 2017-12-29        -0.0381 
## 2 EURTRY=X 2018-01-01         0.0101 
## 3 EURUSD=X 2017-12-29         0.00757
## 4 EURUSD=X 2018-01-01         0.00529
## 5 GBPUSD=X 2017-12-29         0.00176
## 6 GBPUSD=X 2018-01-01         0.00560

Aylık aritmetik getirilerin grafiklerini oluşturalım.

exchangeR_monthly  %>%
    ggplot(aes(x = date, y = monthly.returns, fill = symbol)) +
    geom_bar(stat = "identity", linetype=1, width=15)+
    geom_hline(yintercept = 0, color = palette_light()[[1]])+
    scale_y_continuous(labels = scales::percent) +
    labs(title = "Aylık Getiriler",
         y = "Aylık Getiriler", x = "") + 
    facet_wrap(~ symbol, ncol = 2) +
    theme_tq() + 
    scale_fill_tq()

İstatiksel Veri Özeti

Base R’ın summary fonksiyonları ile benzer işlevde olan skimr paketi ile değişkenlerin çeşitli istatiksel özetleri elde edilebilir. skimr paketi veri seti yapısına odaklanmaktadır.

Aylık getirilere bazı skimr fonksiyonlarını uygulayalım ve çıktıyı inceleyelim.

skimr fonksiyonu veri seti değişkenlerini değişken tipine göre ayırarak değişken tipi bazında istatiksel hesaplamalar yapmaktadır.

exchangeR_monthly %>% skim()
## Skim summary statistics
##  n obs: 212 
##  n variables: 3 
##  group variables: symbol 
## 
## -- Variable type:Date ---------------------------------------------------------------
##    symbol variable missing complete  n        min        max     median n_unique
##  EURTRY=X     date       0       18 18 2016-08-31 2018-01-01 2017-05-15       18
##  EURUSD=X     date       0       97 97 2010-01-29 2018-01-01 2014-01-31       97
##  GBPUSD=X     date       0       97 97 2010-01-29 2018-01-01 2014-01-31       97
## 
## -- Variable type:numeric -----------------------------------------------------------
##    symbol        variable missing complete  n    mean    sd     p0     p25
##  EURTRY=X monthly.returns       0       18 18  0.019  0.035 -0.056  0.0033
##  EURUSD=X monthly.returns       0       97 97 -0.0015 0.027 -0.08  -0.018 
##  GBPUSD=X monthly.returns       0       97 97 -0.0015 0.023 -0.08  -0.015 
##
##       p50   p75  p100
##   0.019   0.03  0.087
##  -0.00066 0.016 0.074
##  -0.002   0.017 0.044

Nümerik tipteki değişkenleri filtreleyerek sembol bazında monthly.returns sütunu için özet bilgi elde edelim.

exchangeR_monthly %>% skim_to_wide() %>% filter(type=="numeric")
## # A tibble: 3 x 18
##   type  symbol variable missing complete n     min   max   median n_unique
##   <chr> <chr>  <chr>    <chr>   <chr>    <chr> <chr> <chr> <chr>  <chr>   
## 1 nume~ EURTR~ monthly~ 0       18       18    <NA>  <NA>  <NA>   <NA>    
## 2 nume~ EURUS~ monthly~ 0       97       97    <NA>  <NA>  <NA>   <NA>    
## 3 nume~ GBPUS~ monthly~ 0       97       97    <NA>  <NA>  <NA>   <NA>    
## # ... with 8 more variables: mean <chr>, sd <chr>, p0 <chr>, p25 <chr>,
## #   p50 <chr>, p75 <chr>, p100 <chr>, hist <chr>