Her gün milyonlarca insan bankalar aracılığıyla döviz alım ve satım işlemi yapar. Hayatımızın rutin bir parçası haline gelen bu işleme hiç yakından baktınız mı? Bankalar, piyasalarda neredeyse anlık olarak değişen kurları eş zamanlı olarak müşterilerine nasıl sağlar? Bankaların döviz kurlarını belirlemek için kullandıkları uluslararası kaynaklar nelerdir? İç ve dış piyasalarda yaşanan krizlere paralel olarak yoğun gelen müşteri taleplerinde sistemlerin aksamadan hizmet vermeye devam edebilmesi gerekir. Peki bunun için kurgulanan altyapı ve bu altyapıyı oluşturmak için kullanılan teknolojiler nelerdir? Bu soruların ve çok daha fazlasının cevabını yazının ilerleyen kısımlarında bulacaksınız ancak konunun teknik detaylarına inmeden önce basit ve temel kavramlardan bahsetmek istiyorum.
Döviz kuru, bir para biriminin değerinin diğeriyle karşılaştırıldığı bir ölçüdür. Döviz kurunun amacıysa, bir para biriminin başka bir para birimine kıyasla satın alma gücünü bulmaktır. Peki neden bir para biriminin döviz kurunu bilmek isteyelim? Çünkü tüm para birimleri birim başına aynı satın alma gücüne sahip değildir, bu nedenle döviz kurunu bilmek bir miktar paranın “değerini” belirlemeye yardımcı olur. Döviz kurları hem yerel para birimi değerinden hem de yabancı para değerinden etkilenir. Döviz kurlarının çoğu dalgalı olarak tanımlanır ve piyasadaki arz ve talebe göre yükselir veya düşer. Döviz kurları birçok ekonomik faktörü ve değişkeni kapsar ve çeşitli nedenlerle dalgalanabilir.
Bu dalgalanmanın nedenlerinden bazıları şunlardır:
Faiz oranları,
Enflasyon oranları,
Devlet borçları,
Politik istikrar,
İhracat ve ithalat faaliyetleri,
Spekülasyonlar.
Müşterilere sunulan kurların oluşturulmasında farklı finansal data sağlayıcı firmalardan veri çekilmektedir. Bu firmalardan sadece kur verisi değil aynı zamanda kira sertifikası fiyatları, depo oranları gibi farklı finansal veriler de çekilebilmektedir. Veri akışı milisaniyeler seviyesinde sürekli bir şekilde sağlanmaktadır. Bu firmalardan en bilineni ve Architecht olarak bizim de uzun bir zaman tek veri kaynağı olarak kullandığımız firma Refinitiv, eski adıyla da Reuters firmasıdır. Zamanla değişen yapımızda geldiğimiz noktada Refinitiv dışında Bloomberg, Integral, 360T ve Tradair firmalarından da finansal veriler çekiyoruz. Bu da veri kaynağımızın çok daha zengin olmasını sağlıyor. Bu firmalardan Refinitiv ve Bloomberg firmalarının kendi kütüphanelerini kullanarak entegrasyon sağlıyoruz. Veriyi bu şirketlerden bize tahsis edilmiş özel hatlar üzerinden (leased line) alıyoruz. Verinin cachelenmesi ve yetkilendirme sistemleri de bu hizmetle beraber gelen tanımlama sistemleri üzerinden yapılıyor. Integral, 360t ve Tradair firmalarının entegrasyonunda ise FIX mesajlaşma altyapısını kullanıyoruz.
FIX (Financial Information Exchange)’den biraz bahsedecek olursak; FIX finansal mesajlaşmaların sağlandığı bir protokoldür. Dünyanın dört bir yanından bankalar, komisyoncular, borsalar, endüstri kuruluşları ve dernekleri, kurumsal yatırımcılar ve bilgi teknolojisi sağlayıcılarının iş birliğiyle geliştirilmiştir. FIX organizasyonu tarafından yayınlanan 4.0, 4.2, 5.0 vb. gibi özelliklerin birçok sürümü vardır. QuickFIX ise, FIX protokolünün c++, java, ruby, dotnet vb. gibi çeşitli dillerde ücretsiz ve açık kaynaklı bir uygulamasıdır. QuickFIX dll’ini uygulamanıza dahil ederek, mesajlaşma altyapısına entegre olabilirsiniz. Şekil 1’ de FIX altyapısının çalışma sistemi gösterilmektedir.
Peki bu kaynaklardan çektiğimiz verileri nasıl yönetiyoruz? Sağladığımız entegrasyonlarla çektiğimiz veriyi olduğu gibi veri tabanımızda ham veri tablolarımıza aktarıyoruz. Bu tablolar sürekli veri tabanına kayıt işlemi alan tablolar olduğu için, tablolar üzerinde ekstra maliyet oluşturabilecek farklı bir işlem (güncelleme, silme) yapılmıyor. Tablolar üzerinde kaydetme işlemi sonrasında çalışan tetikleyiciler (trigger) sayesinde son güncel verilerimizi her bir kaynak için farklı birer tabloya alıyoruz. Böylece en güncel verileri özet olarak elde etmiş oluyoruz. Boa Ana Bankacılık Uygulamamız üzerinde iş birimlerimiz veri kaynaklarının belirlenen özelliklerini (tercih sırası, kullanımda olup olmaması, zaman toleransı vb.) yönetebiliyor. Sonrasında çalıştırdığımız çeşitli algoritmalar ile banka işlemlerinde kullanılacak kurları oluşturuyoruz ve müşterilerimize sunuyoruz. Kur oluşturma sürecinin akışı Şekil 2’de gösterilmektedir.
Kurlar oluşturulurken alım ve satım fiyatları arasındaki farka kur marjı diyoruz. Kur marjları hem otomatik oluşturduğumuz sistemler doğrultusunda hem de iş birimlerimiz tarafından manuel olarak yönetilebiliyor. Döviz çifti bazında alım için farklı bir marj oranı, satım için farklı bir marj oranı uygulanabiliyor. Oranlar döviz alım satım hacmi, mesai saatleri, resmî tatiller, piyasa koşulları gibi nedenler dahilinde güncellenebiliyor.
Daha önce tombul parmak sendromunu duymuş muydunuz? Cevabınız hayır ise bu ifadeden bahsedelim. Tombul parmak sendromu kısaca yapılan işlem sırasında yanlış bir tuşa basılarak istenen alım seviyesi ya da fiyatından çok daha fazlasının gerçekleşmesine denir. Aynı durumun tam tersi de olabilir. Beklenen değerden daha düşük bir oranda veri de üretilebilir. Daha önce bu sendromun birçok örneği bulunmaktadır. Peki biz bu gibi senaryolardan nasıl korunuyoruz? Veri kaynaklarımızdan geçen verilerden en güncel verileri farklı bir tabloda tuttuğumuzdan bahsetmiştik. Bu tabloda güncel verimizi tutarken aynı zamanda verinin kendinden önceki en güncel son 4 verisini de tutuyoruz. Her gelen yeni güncellemede bu değerler kaydırılmış oluyor. Son durumda bu satıra ait veriyi kullanırken de 5 değerin ortalamasını alarak hatalı verinin etkisini yumuşatmış oluyoruz. Ayrıca birden fazla kaynaktan fiyatı kıyaslayarak müşteriye kur sunabildiğimiz için de avantajsız olan kur elenmiş oluyor. Değerlerin 0 ya da alakasız çok farklı bir değer olmaması için ayrıca kod kontrollerimiz de var. Alış değeri, satış değerinden yüksek olmaması durumunu da yine kontrol ediyoruz özellikle. Buna ek olarak oluşturduğumuz sistem izleme tanımlarımız bulunuyor. Bu sistem izleme tanımlarıyla da belli bir sürede her bir kaynaktan veri alınamama durumu var mı, uzun zamandır güncellenmeyen veriler var mı gibi durumları takip ediyoruz. Böylece piyasada oluşabilecek olumsuz bir durumdan korunmuş oluyoruz.
Yukarıda anlatıldığı gibi yabancı kur kaynaklarından gelen veriler veri tabanına kaydedilir ancak bu işlem yeterli değildir. Müşterilerden anlık ve yoğun olarak gelen döviz alım, satım ve kur listesini görme taleplerinde her bir istek için veri tabanına gidip kur çekmek çok maliyetlidir. Veri tabanının bu gibi durumlarda gelen her isteğe cevap verememesi halinde bankanın bütün sistemlerini etkileyecek krizler oluşabilir. İşte bu noktada Redis tam olarak aradığımız çözüm olarak karşımıza çıkmaktadır. Redis, verilerin key-value çifti şeklinde in-memory olarak tutulduğu açık kaynaklı bir veri tabanıdır. Veriler bellekte tutulduğu için erişim çok hızlıdır.
Müşteriden gelen talepleri Redis üzerinden karşılamak için verilerin ilk önce Redis’e aktarılması gerekmektedir. Bunun için kurduğumuz yapıda tüm varyasyonlarıyla hesapladığımız kurları 2 saniyede bir toplu veri olarak Redis cluster’a kaydediyoruz. Kaydettiğimiz verinin maksimum geçerli olması süresi 10 saniye oluyor. Bu süre henüz dolmadan aynı key’e ait bir veri gelirse redisteki value değeri güncelleniyor.
Redis’e veri aktaramadığımız durumda ya da Redis cluster’da sorun oluşması gibi istisnai durumlarda Şekil 4’deki gibi veri tabanına gidilerek veri çekilir ve Redis’e kaydedilir. Müşterilerin gördükleri kurla, işlem yaptıklarında gelen kur her durumda veri tabanından valide edilir. Genel olarak Redis cluster mimarisi aşağıda Şekil 3’deki gösterildiği gibidir.
Kaydettiğimiz kurları en fazla 10 saniye Redis’te tutabiliyoruz demiştik. Bu sürenin sonunda veri Redis’ten silinmiş oluyor. Peki geçmişe dönük bir veriyi nasıl temin edebiliriz? Bu veriye denetim sırasında, müşteri şikayetlerinde ya da rapor bilgisi olarak ihtiyacımız olabiliyor, müşterinin o anda gördüğü kur bilgisini bilmemiz gerekebiliyor bu gibi durumlarda. Bunun için de Kafka’yı kullanıyoruz. Veriyi Redis’e kaydettikten hemen sonra, veriyi Kafka’da yayın (publish) yapıyoruz.
Kafka nedir, nasıl çalışır? Biraz da bundan bahsedelim. Kafka veriyi toplayıp, diğer sistemlere dağıtmak amacıyla kullanılır. Bunun için asenkron kuyruk yapısı kullanılır. Mesajların bir grup altında toplanmasına topic adı verilir. Topic’ler performans amaçlı partition adı verilen farklı parçalardan oluşurlar. Producer topic’lere mesaj yayını yapan yapılardır, consumer ise topic’leri dinleyen yapılardır. Yani veri yayınlandıktan sonra topic olarak, Kafka kuyruğuna atılır. Sonrasında ise consumer’lar aracılığıyla bu kuyruktan eritilir. Şekil 5’de Kafka’nın çalışma sistemi gösterilmektedir. Bizim kurduğumuz yapıda veri Kafka’ya atıldıktan sonrasında, Kafka kuyruğundan veriyi alarak tablolarımıza yazıyoruz. Kafka’ya veri yayınlamak, Redis’te de olduğu gibi oldukça düşük maliyetlidir. Tabloya yazma kısmı farklı bir işlem olarak yürütüldüğü için ana işlem sırasında ekstra maliyete neden olmaz. Bu kısımda gecikme toleransı kabul edilebilirdir. Sonuçta anlık bir işlem gerçekleştirilmeyecek, geçmişe dönük bir veri kontrol edilecektir.
Döviz işlemlerinin arka planında neler olduğundan ve mevcut sistemlerimizden bahsetmeye çalıştım. Architecht Hazine ekibi olarak sistemlerimizi dünyada kullanılan teknolojilere paralel olarak geliştirmekte ve en güçlü şekilde kullanıma sunmaya devam etmekteyiz.
Kaynakça:
- Exchange Rate
(https://www.financestrategists.com/wealth-management/exchange-rate/) (https://www.investopedia.com/terms/e/exchangerate.asp)(https://corporatefinanceinstitute.com/resources/economics/exchange-rate) - FIX Trading Community
(https://www.fixtrading.org/) - FIX Message Implementation
(https://www.codeproject.com/Articles/145174/Fix-Message-Implementation-using-QuickFix) - Refinitiv
(https://www.refinitiv.com/en/financial-data/) - Bloomberg
(https://www.bloomberg.com/professional/product/market-data/) - Tradair
(https://www.tradair.com/) - 360T
(https://www.360t.com/products/market-data/) - Redis
(https://redis.com/redis-enterprise/technology/redis-enterprise-cluster-architecture/) - Kafka
(https://kafka.apache.org/)