Strasmore Research
Edukasi Matt ConnorOleh Matt Connor · data as of August 12, 2026 · refreshed weekly

Mengenal libitofin: Porting QuantLib ke Bahasa Rust

libitofin adalah porting QuantLib ke Rust yang dapat diakses melalui Python. Artikel ini membahas keunggulan pustaka penentuan harga dan pentingnya menggunakan rilis stabil.

QuantLib in Rust adalah deskripsi satu baris untuk libitofin: sebuah porting dari QuantLib, pustaka C++ yang telah menjadi referensi sumber terbuka untuk penentuan harga derivatif sejak awal tahun 2000-an, ke dalam Rust, dengan paket Python bernama itofin di atasnya. Per Agustus 2026, proyek ini melabeli dirinya sebagai pra-1.0, dan label tersebut menentukan segala aspek praktis dalam penggunaannya. Sebuah pustaka penentuan harga mendapatkan nilainya melalui mekanisme yang membungkus rumus, dan mekanisme tersebut merupakan pekerjaan yang sama di bahasa pemrograman apa pun.

Apa yang diberikan pustaka penentuan harga yang tidak dimiliki rumus spreadsheet

Sel Black-Scholes dalam spreadsheet memerlukan lima input dan menghasilkan harga. Rumusnya adalah bagian yang mudah. Empat lapisan melingkupinya, dan lapisan-lapisan itulah yang membentuk pustaka tersebut.

Struktur suku bunga (Term structures). Suku bunga diskonto adalah kurva di sepanjang tenor, dengan aturan interpolasi untuk celah di antara titik-titik yang benar-benar dikutip. Panel di bawah ini adalah bahan mentahnya: tenor Treasury yang dikutip pada satu tanggal tertentu.

QueryKurva Treasury pada tanggal kuotasi terkini
SQL tepat di balik setiap angka
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 i
Run this yourself

Per Aug 10, 2026, kurva yang dikutip memiliki 7 tenor, mulai dari 3.79% pada 1 month hingga 5.25% pada 30 years. Spreadsheet menangani ini dengan pencarian (lookup) dan angka 4% yang dikodekan secara statis. Pustaka menanganinya dengan objek kurva yang digunakan oleh setiap instrumen untuk penentuan harga, di bawah interpolasi yang ditetapkan (linear pada suku bunga nol, log-linear pada faktor diskonto, monotone splines) dan kebijakan ekstrapolasi yang ditetapkan setelah titik terakhir. Geser satu objek tersebut sebesar satu basis point dan setiap sensitivitas dalam buku akan bergerak secara konsisten bersamanya.

Konvensi perhitungan hari (Day-count conventions). Bunga terakumulasi selama sebagian dari satu tahun, dan definisi pecahan tersebut adalah konvensi yang melekat pada instrumen. Actual/360 membagi hari yang berlalu dengan 360. Actual/365 membagi dengan 365. Keluarga 30/360 mengasumsikan setiap bulan memiliki 30 hari. Business/252 menghitung sesi perdagangan terhadap tahun 252 hari, yang memerlukan kalender bursa nyata dengan hari libur yang sudah dimuat. Ambil contoh hipotetis pinjaman satu juta dolar dengan bunga 5% selama 90 hari: actual/360 mengakumulasi $12.500 dan actual/365 mengakumulasi $12.329 pada perdagangan yang sama. Panel di bawah ini menunjukkan mengapa basis hari kerja memerlukan kalender, bukan sekadar pembagi.

QuerySesi perdagangan dibandingkan hari kalender, per bulan
SQL tepat di balik setiap angka
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
Run this yourself

Selama 12 bulan yang ditampilkan, 2026-07 memiliki 22 sesi terhadap 31 hari kalender. Tidak ada aturan aritmatika yang menghasilkan angka pertama tersebut. Angka itu berasal dari kalender hari libur, dan setiap bulan memiliki jawabannya sendiri. Sebuah pustaka menyediakan kalender tersebut per lokasi dan per negara; spreadsheet meminta Anda untuk memeliharanya sendiri.

Mekanisme kalibrasi. Parameter model tidak dikutip di mana pun. Anda memilihnya dengan mencocokkan harga model terhadap harga pasar yang teramati di seluruh permukaan kuotasi, lalu menyesuaikannya kembali saat permukaan tersebut bergerak. Itu adalah masalah kuadrat terkecil (least-squares) yang dibatasi, dan pustaka menyediakan loop di sekitarnya: pengoptimal Levenberg-Marquardt, transformasi parameter yang menjaga varians tetap positif tanpa batasan keras, fungsi biaya di atas set kuotasi, dan kriteria konvergensi yang gagal dengan memberikan peringatan alih-alih diam-diam mengembalikan tebakan awal.

Lapisan numerik. Di bawah segalanya terdapat aljabar linear dan integrasi. Dekomposisi QR dan SVD menyelesaikan sistem yang dihasilkan oleh penyesuaian, kuadratur dan integrasi Fourier menentukan harga model yang rumusnya berupa integral, dan pencari akar (root finders) mengeluarkan volatilitas tersirat. Lapisan ini membosankan, dan justru lapisan inilah yang sering diimplementasikan ulang dengan buruk. Versi klasiknya adalah pemecah Newton buatan sendiri yang konvergen pada kuotasi at-the-money yang likuid namun melenceng pada kuotasi deep out-of-the-money. Yang kedua adalah invers matriks yang kehilangan presisi pada penyesuaian yang hampir singular dan mengembalikan parameter yang terlihat sangat masuk akal. Jika Anda menyusun model mental dari awal, buku perdagangan kuantitatif sumber terbuka adalah titik awal yang lebih baik daripada referensi API pustaka mana pun.

Apa itu libitofin, dan apakah itu QuantLib dalam Rust?

Ya, dalam pengertian yang penting. Ini adalah porting desain QuantLib ke dalam Rust, dan proyek tersebut menyatakan bahwa kodenya diuji terhadap rangkaian pengujian QuantLib sendiri. Itulah cara jujur untuk melakukan porting pustaka numerik: hasil diperiksa terhadap implementasi referensi, bukan terhadap ekspektasi yang ditulis tangan tentang seperti apa seharusnya jawabannya. Jalur Python-nya adalah paket bernama itofin, sehingga proses Python dapat menjangkau mesin Rust tanpa memerlukan toolchain C++ dalam loop-nya.

Label yang lebih penting adalah pra-1.0. Di bawah konvensi penomoran versi Rust, rilis 0.x tidak membawa janji kompatibilitas antar versi minor: 0.4 ke 0.5 diizinkan untuk mengubah nama, memindahkan, atau menghapus apa pun yang diinginkan. Anggap API tersebut sebagai target yang bergerak, dan beberapa kebiasaan berikut perlu diikuti.

  • Sematkan rilis bertanda (tagged release) yang tepat di lockfile Anda dan lakukan peningkatan dengan sengaja, dengan rangkaian pengujian Anda sendiri sebagai gerbangnya.
  • Simpan wrapper tipis milik Anda sendiri di sekitar tipe data pustaka, sehingga perubahan nama hanya perlu diperbaiki di satu file, bukan empat puluh.
  • Catat versi pustaka di samping angka yang dihasilkannya, sehingga jika ada hasil yang berbeda saat dijalankan ulang, Anda dapat merujuk pada peningkatan versi, bukan pada pasar.
  • Simpan angka margin produksi, agunan, dan risiko regulasi pada sesuatu yang membawa janji kompatibilitas hingga versi 1.0 tiba.

Tidak satu pun dari hal di atas merupakan kritik terhadap proyek tersebut. Pra-1.0 adalah deskripsi diri yang akurat dan tempat yang tepat bagi porting muda dari pustaka yang sangat besar. Mode kegagalannya adalah jika pembaca menganggapnya sebagai pengganti langsung QuantLib dan menemui perubahan tanda tangan (signature) dalam rilis minor, di tengah-tengah kuartal. Instruksi instalasi juga berubah seiring versi, dan baik cargo maupun pip memerlukan akses jaringan untuk menyelesaikan apa pun, jadi bacalah README proyek itu sendiri pada tag yang ingin Anda sematkan, bukan cuplikan yang disalin dari postingan blog, termasuk yang ini.

Python, mesin terkompilasi, atau Rust?

Dua pertanyaan menentukan ini, dan tidak satu pun tentang selera. Berapa kali per detik Anda melakukan penentuan harga ulang, dan apakah angka Anda harus cocok di seluruh proses yang terpisah? Ukuran rantai (chain size) menentukan skala pertanyaan pertama.

QueryKontrak opsi unik yang diperdagangkan dalam satu sesi
SQL tepat di balik setiap angka
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 DESC
Run this yourself

Pada Aug 11, 2026, SPY memiliki 5336 kontrak berbeda yang diperdagangkan dalam satu sesi, dibandingkan 360 untuk KO. Menentukan harga rantai yang luas sekali saja bukanlah apa-apa. Menentukan harganya dengan lima sensitivitas per kontrak, pada setiap pembaruan kuotasi, di seluruh buku aset dasar, adalah program yang berbeda dengan batasan yang berbeda.

Tetap gunakan Python dengan pustaka yang sudah mapan ketika loop diukur dalam ribuan penilaian per menit dan pekerjaan di sekitarnya adalah riset, analisis, atau penandaan akhir hari. Binding Python milik QuantLib sendiri adalah pilihan yang matang: mesin C++ yang sama, cakupan instrumen terluas, dan pengalaman produksi bertahun-tahun. Kecepatan jarang menjadi batasan utama dalam kode riset; cakupan dan kebenaranlah yang utama.

Panggil mesin terkompilasi dari Python ketika loop-nya intensif dan kode di sekitarnya tidak. Biaya yang harus diperhatikan adalah batas itu sendiri. Panggilan per kontrak dari Python membayar overhead pada setiap persilangan, dan solusinya adalah memberikan array ke mesin dan mengambil array kembali. Inilah posisi yang dituju itofin, bersama dengan QuantLib-Python.

Tulis dalam Rust ketika loop penentuan harga adalah produknya: pricer di dalam layanan kuotasi, perhitungan risiko pada jadwal yang tidak boleh terlewat, atau biner yang dikirim ke kotak tanpa Python di dalamnya. Pertanyaan kedua juga bermuara di sini. Hasil floating point bergantung pada urutan operasi, sehingga model yang sama yang diimplementasikan dua kali bisa berbeda pada digit terakhir, dan buku catatan riset yang tidak setuju dengan layanan produksi berarti seminggu forensik. Satu mesin yang digunakan dari kedua sisi menghilangkan seluruh kategori ketidaksesuaian tersebut, yang merupakan argumen kuat untuk inti terkompilasi dengan binding dalam bahasa apa pun ia ditulis. Insting yang sama berlaku untuk pekerjaan strategi, sebagaimana ditunjukkan oleh backtest yang dapat direproduksi.

Di mana target kalibrasi sebenarnya berada

Kalibrasi memerlukan sesuatu untuk dicocokkan, dan sesuatu itu adalah permukaan volatilitas tersirat pasar. Sisi pencarian akar dari hal tersebut dibahas dalam bagaimana volatilitas tersirat dihitung. Bentuk di bawah ini adalah apa yang harus dicocokkan oleh model.

QueryImplied volatility near-the-money AAPL berdasarkan waktu jatuh tempo
SQL tepat di balik setiap angka
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)
Run this yourself

Di dekat harga (near the money), kontrak AAPL dalam bucket 0 to 7 days rata-rata memiliki 29.6% volatilitas tersirat di seluruh sesi yang ditampilkan, dibandingkan 29.3% pada 241 days or more. Model yang membawa satu parameter volatilitas tidak dapat berada pada kedua titik sekaligus, itulah alasan mengapa model dengan struktur suku bunga volatilitas ada. Mencocokkan satu model ke permukaan seperti ini adalah langkah kalibrasi, dan sensitivitas yang dihasilkan dari model yang disesuaikan adalah greek, yang dibahas dalam penjelasan option greeks.

Bagaimana panel ini dibuat

Panel kurva membaca tanggal kuotasi terbaru dalam seri Treasury dan membuka sebelas kolom tenornya menjadi baris, membuang tenor apa pun tanpa kuotasi pada hari itu. Panel sesi menghitung tanggal berbeda pada tape SPY per bulan, yang merupakan proksi bersih untuk jumlah sesi bursa penuh. Panel rantai menghitung kode kontrak berbeda dengan volume bukan nol pada sesi terbaru yang tersedia, dikelompokkan berdasarkan aset dasar. Panel volatilitas hanya menyimpan hasil yang konvergen dengan volume bukan nol dan harga strike dalam 5% dari penutupan aset dasar, yang merupakan pita standar near-the-money; bucket depan mencakup kedaluwarsa hari yang sama.

FAQ

Apakah libitofin pengganti langsung untuk QuantLib?

Tidak. Per Agustus 2026, ini adalah porting pra-1.0 yang mencakup sebagian permukaan QuantLib dan memvalidasi hasilnya terhadap rangkaian pengujian QuantLib sendiri. QuantLib itu sendiri, yang diakses melalui binding Python-nya, tetap menjadi pilihan yang lebih luas dan stabil untuk pekerjaan produksi.

Apa arti pra-1.0 bagi pustaka penentuan harga?

Di bawah konvensi penomoran versi Rust, rilis 0.x tidak memberikan janji kompatibilitas: versi minor berikutnya bebas untuk mengubah nama atau menghapus apa pun. Dalam praktiknya, itu berarti menyematkan rilis bertanda yang tepat dan menjalankan ulang rangkaian pengujian Anda sendiri pada setiap peningkatan.

Apakah saya perlu menulis Rust untuk menggunakan libitofin?

Tidak. Proyek ini menerbitkan paket Python bernama itofin, sehingga mesin tersebut dapat dipanggil dari proses Python biasa. Menulis Rust menjadi relevan ketika loop penentuan harga itu sendiri adalah hal yang Anda kirimkan.

Apa yang diberikan pustaka penentuan harga yang tidak dimiliki rumus spreadsheet?

Kurva alih-alih suku bunga tunggal, konvensi perhitungan hari dengan kalender bursa nyata di belakangnya, loop kalibrasi yang menyesuaikan parameter model dengan harga yang dikutip, dan lapisan numerik yang teruji di bawah ketiganya. Rumus bentuk tertutup (closed-form) hanyalah bagian kecil dari pekerjaan tersebut.

Apakah bahasa pemrograman mengubah harga opsi?

Tidak secara matematis. Ini mengubah reproduktibilitas: hasil floating point bergantung pada urutan operasi, sehingga dua implementasi dari satu model bisa berbeda pada digit terakhir. Menjalankan riset dan produksi dari mesin yang sama menghilangkan celah tersebut.


Setiap panel di sini membawa SQL persisnya di bawahnya, jadi perluas salah satu untuk melihat bagaimana penghitungan dilakukan. Pertanyaan kurva, kalender, dan rantai yang sama dapat ditanyakan dalam bahasa Inggris sederhana di terminal Strasmore.