En zor soru üzerinde bir uygulama yapalım: Borsa düşecek mi çıkacak mı? Öncelikle kullanacağımız R paketlerini yükleyelim ve yahoo finance üzerinden BİST100 endeksinin günlük verilerini alalım
install.packages("quantmod") #Finansal veri paketi
install.packages("e1071") #SVM paketi
library(quantmod)
library(e1071)
getSymbols("XU100.IS", from="2010-01-01")
Bu kodla çalışma alanınızda XU100.IS adlı bir zaman serisi (xts) yüklenmiş olacak. Bu zaman serisinde BİST100'ün açılış, kapanış, yüksek, düşük, hacim ve düzeltilmiş fiyat bilgileri var. Veriye bakarsanız hacim verisinin hep $0$ olduğunu göreceksiniz, ayrıca düzeltilmiş değer hisse senetleri için manalı ama endeks için manalı değil. Bu yüzden o değişkenleri sileceğiz. Ayrıca Türkiye'nin resmi tatillerinde borsa kapalı olduğu için bazı günlerde veri eksik, yani NA olarak kaydedilmiş. Bunları da ayıklamamız lazım. Veriyi işlemeye başlamadan evvel orijinal veriyi bir yere kaydetmek her zaman iyi fikirdir.
XU100<-XU100.IS #Orijinal veri elimizde dursun, gerekirse geri döneriz
XU100.IS<-na.omit(XU100.IS) #NA değerli gözlemleri sil
XU100.IS<-XU100.IS[,-5] #5 numaralı kolonu sil (Hacim)
XU100.IS<-XU100.IS[,-5] #Geri kalan veride 5 numaralı kolonu sil (düzeitilmiş değer)
Şimdi quantmod paketinin hızlıca hesaplamamızı sağladığı bazı finansal göstergeleri verimize ekleyelim.
#Relative Strength Indicator
den<-RSI(XU100.IS$XU100.IS.Close)
XU100.IS<-merge.xts(XU100.IS,den)
colnames(XU100.IS)[5]<-"RSI"
#Volatility
den<-volatility(XU100.IS)
XU100.IS<-merge.xts(XU100.IS,den)
colnames(XU100.IS)[6]<-"Volatility"
#SMA (Basit hareketli ortalama)
den<- SMA(XU100.IS$XU100.IS.Close, n=21)
XU100.IS<-merge.xts(XU100.IS,den)
colnames(XU100.IS)[7]<-"SMA21"
den<- SMA(XU100.IS$XU100.IS.Close, n=13)
XU100.IS<-merge.xts(XU100.IS,den)
colnames(XU100.IS)[8]<-"SMA13"
den<- SMA(XU100.IS$XU100.IS.Close, n=34)
XU100.IS<-merge.xts(XU100.IS,den)
colnames(XU100.IS)[9]<-"SMA34"
#XU100'ün bir sonraki gün yönü
XU100.IS$direction<-as.xts(Next(XU100.IS$XU100.IS.Close, k=1))-XU100.IS$XU100.IS.Close
XU100.IS$direction[XU100.IS$direction <= 0] <- 0
XU100.IS$direction[XU100.IS$direction > 0] <- 1
Şimdi elimizde ham verinin üzerine inşaa ettiğimiz bir takım finansal göstergeler ve ayrıca bir sonraki gün borsanın yönü var (0 düşüş, 1 çıkış). Dikkat edin bu yeni veri setinde bazı NA değerler var, mesela 13 birimlik hareketli ortalamada ilk 12 satır boş olmalı. Bunları da veriden ayıklayacağız. Bakalım SVM bunları kullanarak borsanın yönünü bilebilecek mi?
XU100.IS<-XU100.IS[complete.cases(XU100.IS),] #NA'ları ayıklama
train<-data.frame(XU100.IS["2015-01-01/2015-12-31"]) #SVM'i eğitmek için
test<-data.frame(XU100.IS["2016-01-01/2016-04-15"]) #SVM'in sonuçlarını test etmek için
train[,10]<-as.factor(train[,10]) #İkili sınıflama için değişken "factor" olmalı
test[,10]<-as.factor(test[,10])
svm_model <- svm(direction ~ . , data=train ) #SVM modeli hazırla
tahmin <- predict(svm_model,test[,-10]) #Hazırlanan modelle tahminleri yap
table(tahmin,test[,10]) #Tahminlerle gerçek sonuçları karşılaştır
Yukarıdaki kodu çalıştırınca aşağıdaki sonucu bulacaksınız (confusion matrix denir, Türkçesini bilemedim):
tahmin 0 1
0 19 27
1 9 19
Bu şu demek:
- SVM modelimiz 19 kere düşüşü doğru bilmiş
- SVM modelimiz 27 kere düşüş demiş ama borsa artmış
- SVM modelimiz 9 kere artış demiş ama borsa düşmüş
- SVM modelimiz 19 kere artışı doğru bilmiş
Toplamda 74 günün 38'inde yani yüzde 51 civarında bir başarıyla yönü doğru bilmişiz. Öte yandan modelimiz artış dediğinde yüzde 67 başarı oranı ($19/28$) yakalamış. Bir strateji SVM düşüş dediğinde pas geçip artış dediğinde artış oynamak olabilir.
Fakat aman diyeyim buna güvenip yatırım yapmayın çünkü sadece bir aralıkta eğitip bir aralıkta denedik modelimizi ve model parametrelerini optimize etmeye çalışmadık bile. Ayrıca ham finansal veri SVM için çok da uygun bir veri çeşidi değildir, zaman serilerinde ham veri yerine farklara bakmak makuldur. Yukarıdaki sadece tekniğin nasıl uygulandığına dair bir örnek, kesinlikle daha fazlası değil.