Rust ile QuantLib kullanımı: libitofin kütüphanesi
Rust dilinde geliştirilen QuantLib portu libitofin ve Python entegrasyonu inceleniyor. Fiyatlama kütüphanelerinin elektronik tablolara göre avantajları ve sürüm sabitleme önemi.
Bir fiyatlama kütüphanesinin elektronik tablodan farkı
Bir elektronik tablodaki Black-Scholes hücresi beş girdi alır ve bir fiyat döndürür. Formül işin en kolay kısmıdır. Formülün etrafında dört katman bulunur ve kütüphane dediğimiz şey bu katmanların bütünüdür.
Vade yapıları. İskonto oranı, vadeler boyunca uzanan bir eğridir ve piyasada kotasyonu olan noktalar arasındaki boşluklar için bir enterpolasyon kuralı gerektirir. Aşağıdaki panel, ham veriyi; yani tek bir tarihteki Hazine tahvili vadelerini gösterir.
Her verinin arkasındaki tam SQL
SELECT
arrayElement(tenors, i) AS tenor,
round(arrayElement(rates, i), 2) AS yield_pct,
formatDateTime(curve_date, '%b %e, %Y') AS as_of
FROM
(
SELECT
date AS curve_date,
['1 month', '3 months', '6 months', '1 year', '2 years', '3 years',
'5 years', '7 years', '10 years', '20 years', '30 years'] AS tenors,
[toFloat64(yield_1_month), toFloat64(yield_3_month), toFloat64(yield_6_month),
toFloat64(yield_1_year), toFloat64(yield_2_year), toFloat64(yield_3_year),
toFloat64(yield_5_year), toFloat64(yield_7_year), toFloat64(yield_10_year),
toFloat64(yield_20_year), toFloat64(yield_30_year)] AS rates,
arrayJoin(range(1, 12)) AS i
FROM global_markets.treasury_yields
WHERE date = (SELECT max(date) FROM global_markets.treasury_yields)
)
WHERE yield_pct > 0
ORDER BY iAug 10, 2026 itibarıyla kotasyon eğrisi, 1 month seviyesindeki 3.79% vadesinden 30 years seviyesindeki 5.25% vadesine kadar uzanan 7 adet vadeyi kapsamaktaydı. Bir elektronik tablo bu durumu bir arama fonksiyonu ve sabit bir yüzde dört oranıyla karşılar. Bir kütüphane ise bunu, her enstrümanın fiyatlamasını dayandırdığı bir eğri nesnesiyle ele alır; bu nesne, tanımlı bir enterpolasyon (sıfır kuponlu oranlarda doğrusal, iskonto faktörlerinde log-doğrusal, monoton spline) ve son noktadan sonrası için tanımlı bir ekstrapolasyon politikası içerir. Bu nesneyi bir baz puan kaydırdığınızda, portföydeki tüm duyarlılıklar (sensitivities) buna tutarlı bir şekilde tepki verir.
Gün sayım konvansiyonları. Faiz, yılın bir kesri üzerinden tahakkuk eder ve bu kesrin tanımı, enstrümana bağlı bir konvansiyondur. Actual/360, geçen gün sayısını üç yüz altmışa böler. Actual/365 ise üç yüz altmış beşe böler. 30/360 ailesi her ayı otuz gün kabul eder. Business/252, işlem seanslarını iki yüz elli iki günlük bir yıla göre sayar; bu da tatillerin yüklü olduğu gerçek bir borsa takvimi gerektirir. Yüzde beş faizle doksan günlüğüne borç alınan bir milyon doları ele alalım: Actual/360 yönteminde tahakkuk on iki bin beş yüz dolar iken, aynı işlemde actual/365 yönteminde on iki bin üç yüz yirmi dokuz dolar olur. Aşağıdaki panel, iş günü bazının neden bir bölenden ziyade bir takvime ihtiyaç duyduğunu gösterir.
Her verinin arkasındaki tam SQL
SELECT
formatDateTime(toStartOfMonth(date), '%Y-%m') AS month,
countDistinct(date) AS trading_days,
toUInt8(toDayOfMonth(toLastDayOfMonth(max(date)))) AS calendar_days
FROM global_markets.stocks_daily_aggs
WHERE ticker = 'SPY'
AND date >= toStartOfMonth(today() - 365)
AND date < toStartOfMonth(today())
GROUP BY month
ORDER BY monthİncelenen 12 ay boyunca, 2026-07, 31 takvim gününe karşılık 22 işlem seansı içermiştir. Hiçbir aritmetik kural bu ilk sayıyı üretemez. Bu sayı bir tatil takviminden gelir ve her ayın kendine has bir cevabı vardır. Bir kütüphane bu takvimleri her piyasa ve ülke için hazır sunar; elektronik tablo ise bunları sizin yönetmenizi bekler.
Kalibrasyon mekanizması. Model parametreleri hiçbir yerde doğrudan kotasyon olarak yer almaz. Bu parametreleri, model fiyatlarını gözlemlenen piyasa fiyatlarına tüm kotasyon yüzeyi boyunca uyumlayarak seçer ve yüzey değiştikçe yeniden uyumlarsınız. Bu, sınırlı bir en küçük kareler problemidir ve kütüphane bunun etrafındaki döngüyü sağlar: Levenberg-Marquardt optimizasyon aracı, varyansı katı kısıtlamalar olmaksızın pozitif tutan parametre dönüşümleri, kotasyon seti üzerinde bir maliyet fonksiyonu ve başlangıç tahminini sessizce döndürmek yerine başarısızlığı net bir şekilde bildiren yakınsama kriterleri.
Sayısal analiz katmanı. Her şeyin altında doğrusal cebir ve integrasyon yatar. QR ve SVD ayrıştırmaları, uyumlamanın ürettiği sistemleri çözer; kuadratür ve Fourier integrasyonu, formülleri integral olan modelleri fiyatlar; kök bulucular ise zımni oynaklığı (implied volatility) hesaplar. Bu katman sıkıcıdır ve tam olarak kötü bir şekilde yeniden uygulanan katmandır. Klasik versiyonu, likit ve at-the-money kotasyonlarda yakınsayan ancak derin out-of-the-money kotasyonlarda sapan, elle yazılmış bir Newton çözücüsüdür. Bunun hemen ardından, neredeyse tekil (near-singular) bir uyumlamada hassasiyetini kaybeden ve tamamen makul görünen parametreler döndüren bir matris tersi gelir. Eğer zihinsel modelinizi sıfırdan oluşturuyorsanız, açık kaynaklı bir kantitatif işlem kitabı herhangi bir kütüphanenin API referansından daha iyi bir başlangıç noktasıdır.
libitofin nedir ve Rust dilindeki QuantLib midir?
Evet, önemli olan anlamda öyledir. QuantLib tasarımının Rust diline bir portudur ve proje, QuantLib'in kendi test paketiyle test edildiğini belirtmektedir. Bir sayısal analiz kütüphanesini port etmenin dürüst yolu budur: sonuçlar, cevabın ne olması gerektiğine dair elle yazılmış bir beklentiye göre değil, referans uygulamaya göre kontrol edilir. Python tarafı itofin adında bir pakettir, böylece bir Python süreci, döngü içinde bir C++ araç zinciri olmadan Rust motoruna erişebilir.
Daha önemli olan etiket, 1.0 öncesi (pre-1.0) olmasıdır. Rust'ın sürümleme konvansiyonuna göre, 0.x sürümü ara sürümler arasında hiçbir uyumluluk sözü taşımaz: 0.4'ten 0.5'e geçişte herhangi bir şeyin yeniden adlandırılmasına, taşınmasına veya silinmesine izin verilir. API'yi hareketli bir hedef olarak görün ve şu alışkanlıkları edinin:
- Lockfile dosyanızda tam etiketli bir sürümü sabitleyin ve yükseltmeyi kendi test paketinizle kontrollü bir şekilde yapın.
- Kütüphane türlerinin etrafında kendi ince sarmalayıcınızı (wrapper) tutun, böylece bir yeniden adlandırma kırk dosya yerine tek bir dosyada düzeltilebilir.
- Ürettiği sayıların yanına kütüphane sürümünü kaydedin, böylece tutarsız bir yeniden çalıştırma durumunda sorun piyasada değil, yükseltmede aranır.
- Üretim ortamındaki teminat, marjin ve düzenleyici risk sayılarını, 1.0 sürümü gelene kadar uyumluluk sözü taşıyan bir yapıda tutun.
Bunların hiçbiri projeye yönelik bir eleştiri değildir. 1.0 öncesi, çok büyük bir kütüphanenin genç bir portu için doğru ve dürüst bir tanımlamadır. Hata, bir okuyucunun bunu doğrudan QuantLib yerine kullanıp bir ara sürümde değişen bir imza ile karşılaşmasıdır. Kurulum talimatları da sürümlerle birlikte değişir ve hem cargo hem de pip, herhangi bir şeyi çözümlemek için ağ erişimine ihtiyaç duyar; bu nedenle, bir blog yazısından kopyalanan bir kesit yerine, sabitlemeyi düşündüğünüz etiketteki projenin kendi README dosyasını okuyun.
Python, derlenmiş bir motor mu yoksa Rust mı?
Bu soruyu iki nokta belirler ve ikisi de kişisel tercihle ilgili değildir. Saniyede kaç kez yeniden fiyatlama yapıyorsunuz ve sayılarınız ayrı süreçler arasında eşleşmek zorunda mı? Zincir boyutu, ilk sorunun ölçeğini belirler.
Her verinin arkasındaki tam SQL
WITH (SELECT max(date) FROM global_markets.options_greeks) AS last_session
SELECT
underlying_symbol AS symbol,
countDistinct(ticker) AS contracts_priced,
formatDateTime(max(date), '%b %e, %Y') AS as_of
FROM global_markets.options_greeks
WHERE date = last_session
AND underlying_symbol IN ('SPY', 'AAPL', 'NVDA', 'MSFT', 'KO')
AND volume > 0
GROUP BY symbol
ORDER BY contracts_priced DESCAug 11, 2026 tarihinde, SPY tek bir seansta 5336 farklı sözleşme işlem görürken, KO için bu sayı 360 olmuştur. Geniş bir zinciri bir kez fiyatlamak hiçbir şeydir. Bunu her kotasyon güncellemesinde, dayanak varlıklar portföyü genelinde, sözleşme başına beş duyarlılıkla fiyatlamak, farklı kısıtlamalara sahip farklı bir programdır.
Döngü dakikada binlerce değerleme ile ölçüldüğünde ve çevresindeki iş araştırma, analiz veya gün sonu değerlemeleri olduğunda, yerleşik bir kütüphane ile Python'da kalın. QuantLib'in kendi Python bağlamaları olgun bir tercihtir: aynı C++ motoru, en geniş enstrüman kapsamı ve yılların üretim tecrübesi. Araştırma kodunda hız nadiren bağlayıcı kısıttır; kapsam ve doğruluk daha önemlidir.
Döngü yoğun olduğunda ve çevresindeki kod yoğun olmadığında, Python'dan derlenmiş bir motoru çağırın. Dikkat edilmesi gereken maliyet, sınırın kendisidir. Python'dan sözleşme başına yapılan bir çağrı, her geçişte ek yük getirir; bunun çözümü, motora bir dizi (array) verip bir dizi geri almaktır. itofin'in, QuantLib-Python ile birlikte hedeflediği yer burasıdır.
Fiyatlama döngüsü ürünün kendisi olduğunda Rust yazın: bir kotasyon hizmeti içindeki fiyatlayıcı, kaçıramayacağınız bir programda çalışan risk analizi veya içinde Python olmayan bir sunucuya gönderilen bir ikili dosya. İkinci soru da burada devreye girer. Kayan noktalı sayı sonuçları işlem sırasına bağlıdır; bu nedenle aynı modelin iki farklı uygulaması son basamaklarda farklılık gösterebilir ve üretim hizmetiyle uyuşmayan bir araştırma not defteri, bir haftalık adli bilişim çalışması demektir. Her iki taraftan kullanılan tek bir motor, bu tutarsızlık kategorisini tamamen ortadan kaldırır; hangi dilde yazılmış olursa olsun, bağlamaları olan derlenmiş bir çekirdeğin kalıcı argümanı budur. Aynı içgüdü, tekrarlanabilir bir backtest örneğinde görüldüğü gibi strateji çalışmaları için de geçerlidir.
Kalibrasyon hedefi aslında nerede yaşar?
Kalibrasyonun uyumlanacak bir şeye ihtiyacı vardır ve bu şey, piyasa zımni oynaklıkları yüzeyidir. Bunun kök bulma tarafı zımni oynaklığın nasıl hesaplandığı bölümünde ele alınmıştır. Aşağıdaki şekil, bir modelin eşleşmesi gereken yapıdır.
Her verinin arkasındaki tam SQL
SELECT
multiIf(days_to_expiry <= 7, '0 to 7 days',
days_to_expiry <= 30, '8 to 30 days',
days_to_expiry <= 60, '31 to 60 days',
days_to_expiry <= 120, '61 to 120 days',
days_to_expiry <= 240, '121 to 240 days',
'241 days or more') AS dte_bucket,
round(avg(implied_volatility) * 100, 1) AS iv_pct,
countDistinct(ticker) AS contracts
FROM global_markets.options_greeks
WHERE underlying_symbol = 'AAPL'
AND date >= today() - 10
AND days_to_expiry >= 0
AND iv_converged = 1
AND volume > 0
AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.05
GROUP BY dte_bucket
ORDER BY min(days_to_expiry)At-the-money yakınlarında, 0 to 7 days sepetindeki AAPL sözleşmeleri, incelenen seanslar boyunca ortalama 29.6% zımni oynaklık sergilerken, 241 days or more seviyesinde bu oran 29.3% olmuştur. Tek bir oynaklık parametresi taşıyan bir model, her iki noktada aynı anda duramaz; oynaklık vade yapısına sahip modellerin var olma nedeni budur. Bir modeli böyle bir yüzeye uyumlamak kalibrasyon adımıdır ve uyumlanmış modelden elde edilen duyarlılıklar, opsiyon yunanlıları (greeks) bölümünde açıklanan yunanlılardır.
Bu paneller nasıl oluşturuldu?
Eğri paneli, Hazine serisindeki en son kotasyon tarihini okur ve on bir vade sütununu satırlara dönüştürerek o gün kotasyonu olmayan vadeleri eler. Seans paneli, tam bir borsa seansı sayımı için temiz bir gösterge olan SPY verisindeki farklı tarihleri ay bazında sayar. Zincir paneli, dayanak varlığa göre gruplandırılmış, en son seans itibarıyla sıfır olmayan hacme sahip farklı sözleşme kodlarını sayar. Oynaklık paneli, yalnızca yakınsayan çözümleri ve standart at-the-money bandı olan dayanak varlık kapanışının yüzde beş içindeki strike fiyatlarını tutar; ön sepet aynı gün vadesi dolanları içerir.
SSS
libitofin, QuantLib'in doğrudan bir alternatifi midir?
Hayır. Ağustos 2026 itibarıyla, QuantLib'in yüzeyinin bir kısmını kapsayan ve sonuçlarını QuantLib'in kendi test paketiyle doğrulayan 1.0 öncesi bir porttur. Python bağlamaları aracılığıyla erişilen QuantLib, üretim çalışmaları için daha geniş ve kararlı bir seçenek olmaya devam etmektedir.
Bir fiyatlama kütüphanesi için 1.0 öncesi ne anlama gelir?
Rust'ın sürümleme konvansiyonuna göre, 0.x sürümü hiçbir uyumluluk sözü vermez: bir sonraki ara sürüm herhangi bir şeyi yeniden adlandırmakta veya kaldırmakta özgürdür. Pratikte bu, tam etiketli bir sürümü sabitlemek ve her yükseltmede kendi test paketinizi yeniden çalıştırmak anlamına gelir.
libitofin kullanmak için Rust bilmem gerekiyor mu?
Hayır. Proje, itofin adında bir Python paketi yayınlamaktadır, bu nedenle motor normal bir Python sürecinden çağrılabilir. Rust yazmak, fiyatlama döngüsünün kendisini dağıttığınız bir ürün haline getirdiğinizde önem kazanır.
Bir fiyatlama kütüphanesi bana elektronik tablodan ne fazlasını verir?
Tek oranlar yerine eğriler, arkasında gerçek borsa takvimleri olan gün sayım konvansiyonları, model parametrelerini kotasyon fiyatlarına uyumlayan bir kalibrasyon döngüsü ve bunların altında test edilmiş bir sayısal analiz katmanı. Kapalı formül, işin küçük bir parçasıdır.
Programlama dili opsiyon fiyatını değiştirir mi?
Matematiksel olarak hayır. Ancak tekrarlanabilirliği değiştirir: kayan noktalı sayı sonuçları işlem sırasına bağlıdır, bu nedenle bir modelin iki farklı uygulaması son basamaklarda farklılık gösterebilir. Araştırma ve üretim süreçlerini aynı motor üzerinden yürütmek bu farkı ortadan kaldırır.
Buradaki her panel, kendi SQL sorgusunu içerir; sayımın nasıl yapıldığını görmek için birini genişletin. Aynı eğri, takvim ve zincir soruları Strasmore terminalinde sade bir dille sorulabilir.