Rust मधील QuantLib: libitofin पोर्टची माहिती
Rust मधील QuantLib पोर्ट libitofin आणि पायथन मधील itofin बद्दल जाणून घ्या. स्प्रेडशीटच्या तुलनेत प्राइसिंग लायब्ररीचे महत्त्व आणि प्री-वन पॉईंट झिरो रिलीज वापरण्याचे कारण.
Rust मधील QuantLib हे libitofin चे एक-ओळीतील वर्णन आहे: हे QuantLib चे Rust मधील पोर्ट आहे. QuantLib ही C++ लायब्ररी 2000 च्या दशकाच्या सुरुवातीपासून डेरिव्हेटिव्ह्ज प्राइसिंगसाठी ओपन सोर्स संदर्भाचे काम करत आहे. यावर itofin नावाचे पायथन पॅकेज उपलब्ध आहे. ऑगस्ट 2026 पर्यंत, हा प्रकल्प स्वतःला pre-1.0 म्हणून संबोधतो आणि हे लेबल त्याच्या वापराशी संबंधित सर्व व्यावहारिक बाबींवर लागू होते. एक प्राइसिंग लायब्ररी तिच्या सूत्राभोवती असलेल्या यंत्रणेमुळे (machinery) आपले स्थान निर्माण करते आणि ही यंत्रणा कोणत्याही भाषेत सारखीच असते.
स्प्रेडशीट फॉर्म्युला देऊ शकत नाही अशी कोणती गोष्ट प्राइसिंग लायब्ररी देते
स्प्रेडशीटमधील ब्लॅक-शोल्स (Black-Scholes) सेल पाच इनपुट घेते आणि किंमत देते. सूत्र हा सोपा भाग आहे. त्याच्याभोवती चार स्तर असतात आणि ते स्तर म्हणजे लायब्ररी.
टर्म स्ट्रक्चर्स (Term structures). डिस्काउंट रेट म्हणजे मॅच्युरिटीनुसार असलेली एक वक्ररेषा (curve), ज्यामध्ये प्रत्यक्ष कोट केलेल्या बिंदूंमधील अंतरासाठी इंटरपोलेशन नियम असतात. खालील पॅनेल कच्चा माल दर्शवते: एका विशिष्ट तारखेला कोट केलेले ट्रेझरी टेनर्स.
प्रत्येक आकड्यामागील अचूक 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 पर्यंत, कोट केलेल्या कर्वमध्ये 7 टेनर्स होते, जे 3.79% (1 month वर) पासून 5.25% (30 years वर) पर्यंत होते. स्प्रेडशीटमध्ये हे लूकअप आणि हार्डकोड केलेल्या 4% दराने हाताळले जाते. लायब्ररीमध्ये हे एका कर्व ऑब्जेक्टद्वारे हाताळले जाते, ज्यावर प्रत्येक इन्स्ट्रुमेंटची किंमत ठरवली जाते. यामध्ये ठराविक इंटरपोलेशन (झिरो रेट्सवर लिनियर, डिस्काउंट फॅक्टर्सवर लॉग-लिनियर, मोनोटोन स्प्लाइन्स) आणि शेवटच्या बिंदूनंतरची एक्सट्रॅप्युलेशन पॉलिसी असते. त्या एका ऑब्जेक्टला एका बेसिस पॉइंटने हलवल्यास, पुस्तकातील प्रत्येक सेन्सिटिव्हिटी त्यानुसार सुसंगतपणे बदलते.
डे-काउंट कन्व्हेन्शन्स (Day-count conventions). व्याजाची गणना वर्षाच्या एका भागावर केली जाते आणि त्या भागाची व्याख्या म्हणजे इन्स्ट्रुमेंटशी जोडलेली एक प्रथा असते. Actual/360 मध्ये एकूण दिवसांना 360 ने भागले जाते. Actual/365 मध्ये 365 ने भागले जाते. 30/360 पद्धतीत प्रत्येक महिन्यात 30 दिवस मानले जातात. Business/252 मध्ये 252-दिवसांच्या वर्षाच्या तुलनेत ट्रेडिंग सत्रे मोजली जातात, ज्यासाठी सुट्ट्यांसह असलेले प्रत्यक्ष एक्सचेंज कॅलेंडर आवश्यक असते. समजा, 90 दिवसांसाठी 5% दराने एक दशलक्ष डॉलर्स उसने घेतले: Actual/360 नुसार $12,500 आणि Actual/365 नुसार $12,329 व्याज मिळते. खालील पॅनेल दर्शवते की बिझनेस-डे बेसिससाठी विभाजकापेक्षा कॅलेंडरची गरज का असते.
प्रत्येक आकड्यामागील अचूक 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पाहिलेल्या 12 महिन्यांत, 2026-07 मध्ये 31 कॅलेंडर दिवसांच्या तुलनेत 22 सत्रे होती. कोणताही अंकगणितीय नियम हा पहिला आकडा देऊ शकत नाही. तो सुट्टीच्या कॅलेंडरवरून येतो आणि प्रत्येक महिन्याचे उत्तर वेगळे असते. लायब्ररी प्रत्येक ठिकाणचे आणि देशाचे कॅलेंडर पुरवते; स्प्रेडशीटमध्ये तुम्हाला ते स्वतः सांभाळावे लागते.
कॅलिब्रेशन यंत्रणा (Calibration machinery). मॉडेलचे पॅरामीटर्स कुठेही कोट केलेले नसतात. तुम्ही ते कोट्सच्या संपूर्ण पृष्ठभागावर (surface) बाजारातील किमतींशी जुळवून निवडता आणि पृष्ठभाग बदलल्यावर पुन्हा जुळवता. ही एक बाउंडेड लीस्ट-स्क्वेअर्स समस्या आहे आणि लायब्ररी त्याभोवती लूप पुरवते: लेव्हनबर्ग-मार्क्वार्ड (Levenberg-Marquardt) ऑप्टिमायझर, पॅरामीटर ट्रान्सफॉर्म्स जे कठोर अटींशिवाय व्हेरिएन्स पॉझिटिव्ह ठेवतात, कोट सेटवर कॉस्ट फंक्शन आणि कन्वर्जन्स निकष जे सुरुवातीचा अंदाज न देता स्पष्टपणे अपयशी ठरतात.
न्यूमेरिक्स लेयर (Numerics layer). प्रत्येक गोष्टीच्या खाली लिनियर अल्जेब्रा आणि इंटिग्रेशन असते. QR आणि SVD डिकंपोझिशन फिटिंगमुळे निर्माण होणाऱ्या सिस्टिम्स सोडवतात, क्वाड्रॅचर आणि फूरियर इंटिग्रेशन अशा मॉडेल्सची किंमत ठरवतात ज्यांची सूत्रे इंटिग्रल्स आहेत आणि रूट फाइंडर्स इम्प्लाइड व्होलॅटिलिटी काढतात. हा स्तर कंटाळवाणा आहे आणि नेमका याच स्तराची अंमलबजावणी चुकीच्या पद्धतीने केली जाते. क्लासिक आवृत्ती म्हणजे हाताने बनवलेला न्यूटन सॉल्वर, जो लिक्विड ॲट-द-मनी कोट्सवर कन्वर्ज होतो पण डीप आऊट-ऑफ-द-मनी कोट्सवर भरकटतो. त्यानंतर मॅट्रिक्स इन्व्हर्सचा क्रमांक लागतो, जो नजीकच्या सिंग्युलर फिटवर अचूकता गमावतो आणि पूर्णपणे तर्कसंगत वाटणारे पॅरामीटर्स देतो. जर तुम्ही सुरुवातीपासून मानसिक मॉडेल तयार करत असाल, तर ओपन सोर्स क्वांट ट्रेडिंग बुक हे कोणत्याही लायब्ररीच्या API संदर्भापेक्षा चांगले सुरुवातीचे ठिकाण आहे.
libitofin म्हणजे काय आणि ते Rust मधील QuantLib आहे का?
हो, महत्त्वाच्या अर्थाने. हे QuantLib च्या डिझाइनचे Rust मधील पोर्ट आहे आणि प्रकल्पानुसार, याची चाचणी QuantLib च्या स्वतःच्या टेस्ट सूटवर केली जाते. न्यूमेरिक्स लायब्ररी पोर्ट करण्याचा हाच प्रामाणिक मार्ग आहे: निकालांची पडताळणी ही उत्तराच्या हाताने लिहिलेल्या अपेक्षेपेक्षा संदर्भ अंमलबजावणीशी केली जाते. पायथनसाठी itofin नावाचे पॅकेज आहे, त्यामुळे पायथन प्रक्रिया C++ टूलचेनशिवाय Rust इंजिनपर्यंत पोहोचू शकते.
महत्त्वाचे लेबल pre-1.0 हे आहे. Rust च्या व्हर्जनिंग कन्व्हेन्शननुसार, 0.x रिलीजमध्ये मायनर व्हर्जन्समध्ये सुसंगततेचे (compatibility) कोणतेही आश्वासन नसते: 0.4 ते 0.5 मध्ये काहीही नाव बदलणे, हलवणे किंवा हटवणे शक्य आहे. API ला बदलणारे लक्ष्य (moving target) समजा आणि काही सवयी पाळा.
- तुमच्या लॉकफाइलमध्ये नेमके टॅग केलेले रिलीज पिन करा आणि स्वतःच्या टेस्ट सूटच्या आधारे अपग्रेड करा.
- लायब्ररीच्या प्रकारांभोवती स्वतःचे एक पातळ रॅपर (wrapper) ठेवा, जेणेकरून नाव बदलल्यास ते चाळीस फाइल्सऐवजी एकाच फाइलमध्ये सुधारावे लागेल.
- लायब्ररीचे व्हर्जन उत्पादित आकड्यांच्या शेजारी नोंदवा, जेणेकरून निकालात तफावत आढळल्यास ती बाजाराऐवजी अपग्रेडमुळे असल्याचे स्पष्ट होईल.
- उत्पादन मार्जिन, कोलॅटरल आणि नियामक जोखीम आकडे अशा गोष्टींवर ठेवा ज्यांना 1.0 येईपर्यंत सुसंगततेचे आश्वासन आहे.
यातील कशाचाही प्रकल्पावर टीका करण्याचा हेतू नाही. Pre-1.0 हे एक अचूक स्व-वर्णन आहे आणि एका मोठ्या लायब्ररीच्या नवीन पोर्टसाठी हे योग्य स्थान आहे. जर वाचकाने याला थेट QuantLib चा पर्याय मानले आणि मायनर रिलीजमध्ये सिग्नेचर बदलल्याचे आढळले, तर तो अपयशाचा प्रकार आहे. इन्स्टॉल करण्याच्या सूचनाही व्हर्जननुसार बदलतात आणि cargo व pip या दोघांनाही काहीही रिझॉल्व्ह करण्यासाठी नेटवर्क ॲक्सेसची गरज असते, त्यामुळे ब्लॉग पोस्टमधील स्निपेटऐवजी प्रकल्पाच्या README ला भेट द्या.
पायथन, कंपाइल्ड इंजिन की Rust?
दोन प्रश्न हे ठरवतात आणि त्यापैकी कोणताही आवडीनिवडीचा नाही. तुम्ही प्रति सेकंद किती वेळा रिप्राइस करता आणि तुमचे आकडे वेगवेगळ्या प्रक्रियांमध्ये जुळणे आवश्यक आहे का? चेन साइज पहिल्या प्रश्नाचे प्रमाण ठरवते.
प्रत्येक आकड्यामागील अचूक 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 रोजी, SPY मध्ये एकाच सत्रात 5336 वेगळे कॉन्ट्रॅक्ट्स ट्रेड झाले, तर KO साठी हा आकडा 360 होता. मोठी चेन एकदा प्राइस करणे सोपे आहे. प्रत्येक कोट अपडेटवर, प्रत्येक कॉन्ट्रॅक्टसाठी पाच सेन्सिटिव्हिटीसह, अंडरलाइंग्सच्या संपूर्ण बुकवर प्राइसिंग करणे हा वेगळ्या मर्यादा असलेला वेगळा प्रोग्राम आहे.
जेव्हा लूपची मोजणी प्रति मिनिट हजारो व्हॅल्युएशन्समध्ये असते आणि आजूबाजूचे काम संशोधन, विश्लेषण किंवा एंड-ऑफ-डे मार्क्सचे असते, तेव्हा प्रस्थापित लायब्ररीसह पायथनमध्येच राहा. QuantLib चे स्वतःचे पायथन बाइंडिंग्स हा परिपक्व पर्याय आहे: तेच C++ इंजिन, सर्वाधिक इन्स्ट्रुमेंट कव्हरेज आणि अनेक वर्षांचा अनुभव. संशोधन कोडमध्ये वेग ही क्वचितच मुख्य मर्यादा असते; कव्हरेज आणि अचूकता अधिक महत्त्वाची असते.
जेव्हा लूप वेगवान असतो आणि आजूबाजूचा कोड तसा नसतो, तेव्हा पायथनवरून कंपाइल्ड इंजिन कॉल करा. बाउंड्रीवर लक्ष देणे आवश्यक आहे. पायथनकडून प्रति-कॉन्ट्रॅक्ट कॉल केल्यास प्रत्येक वेळी ओव्हरहेड लागतो, त्यावर उपाय म्हणजे इंजिनला एक ॲरे देणे आणि परत घेणे. itofin हे QuantLib-Python सोबत याच ठिकाणी काम करत आहे.
जेव्हा प्राइसिंग लूप हेच उत्पादन असते, तेव्हा Rust मध्ये लिहा: जसे की कोटिंग सर्व्हिसमधील प्राइसर, वेळेचे बंधन असलेली जोखीम गणना किंवा पायथन नसलेल्या बॉक्सवर पाठवलेली बायनरी. दुसरा प्रश्नही येथेच लागू होतो. फ्लोटिंग पॉइंट निकाल ऑपरेशन्सच्या क्रमावर अवलंबून असतात, त्यामुळे एकाच मॉडेलची दोनदा केलेली अंमलबजावणी शेवटच्या अंकांबाबत असहमत असू शकते. एकाच इंजिनचा दोन्ही बाजूंनी वापर केल्यास विसंगतीचा हा प्रकार पूर्णपणे दूर होतो, जो कंपाइल्ड कोअरसाठी एक भक्कम युक्तिवाद आहे. हीच गोष्ट स्ट्रॅटेजी कामासाठीही लागू होते, जसे की रिप्रोड्युसिबल बॅकटेस्ट मध्ये दिसते.
कॅलिब्रेशनचे लक्ष्य प्रत्यक्षात कुठे असते
कॅलिब्रेशनसाठी फिटिंग करण्यासाठी काहीतरी आवश्यक असते आणि ते म्हणजे मार्केट-इम्प्लाइड व्होलॅटिलिटीचा पृष्ठभाग. रूट-फाइंडिंगचा भाग इम्प्लाइड व्होलॅटिलिटी कशी मोजली जाते यामध्ये समाविष्ट आहे. खालील आकार मॉडेलला जुळवावा लागतो.
प्रत्येक आकड्यामागील अचूक 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)मनीच्या जवळ, 0 to 7 days बकेटमधील AAPL कॉन्ट्रॅक्ट्सची सरासरी इम्प्लाइड व्होलॅटिलिटी 29.6% होती, तर 29.3% (241 days or more वर) होती. एक व्होलॅटिलिटी पॅरामीटर असलेले मॉडेल दोन्ही बिंदूंवर एकाच वेळी बसू शकत नाही, म्हणूनच व्होलॅटिलिटी टर्म स्ट्रक्चर असलेली मॉडेल्स अस्तित्वात आहेत. अशा पृष्ठभागावर फिटिंग करणे ही कॅलिब्रेशनची पायरी आहे आणि फिट केलेल्या मॉडेलमधून बाहेर पडणाऱ्या सेन्सिटिव्हिटी म्हणजे ग्रीक्स (greeks), ज्या ऑप्शन ग्रीक्स स्पष्टीकरण मध्ये समाविष्ट आहेत.
ही पॅनेल्स कशी तयार केली गेली
कर्व पॅनेल ट्रेझरी मालिकेतील सर्वात अलीकडील कोट केलेली तारीख वाचते आणि त्याचे अकरा टेनर्स कॉलम्स ओळींमध्ये उलगडते, ज्या दिवशी कोट नाही असे टेनर्स काढून टाकते. सत्र पॅनेल दर महिन्याला SPY टेपवरील वेगळ्या तारखा मोजते, जे पूर्ण एक्सचेंज सत्राच्या मोजणीसाठी एक चांगला पर्याय आहे. चेन पॅनेल उपलब्ध असलेल्या नवीनतम सत्रावर शून्य नसलेले व्हॉल्यूम असलेले वेगळे कॉन्ट्रॅक्ट कोड मोजते, जे अंडरलाइंगनुसार गटबद्ध केलेले असतात. व्होलॅटिलिटी पॅनेल केवळ शून्य नसलेले व्हॉल्यूम आणि अंडरलाइंग क्लोजच्या 5% च्या आत स्ट्राइक असलेले कन्वर्ज्ड सॉल्व्ह्स ठेवते; फ्रंट बकेटमध्ये त्याच दिवशी संपणारी एक्सपायरीज समाविष्ट आहेत.
वारंवार विचारले जाणारे प्रश्न (FAQ)
libitofin हे QuantLib ला पूर्णपणे बदलू शकते का?
नाही. ऑगस्ट 2026 पर्यंत, हे एक pre-1.0 पोर्ट आहे जे QuantLib च्या पृष्ठभागाचा काही भाग कव्हर करते आणि QuantLib च्या स्वतःच्या टेस्ट सूटवर निकालांची पडताळणी करते. QuantLib स्वतः, त्याच्या पायथन बाइंडिंग्सद्वारे, उत्पादनाच्या कामासाठी अधिक व्यापक आणि स्थिर पर्याय आहे.
प्राइसिंग लायब्ररीसाठी pre-1.0 चा अर्थ काय आहे?
Rust च्या व्हर्जनिंग कन्व्हेन्शननुसार, 0.x रिलीजमध्ये सुसंगततेचे कोणतेही आश्वासन नसते: पुढील मायनर व्हर्जनमध्ये काहीही नाव बदलणे किंवा काढून टाकणे शक्य आहे. व्यवहारात याचा अर्थ असा की, नेमके टॅग केलेले रिलीज पिन करणे आणि प्रत्येक अपग्रेडवर स्वतःच्या टेस्ट सूटची पुन्हा चाचणी करणे.
libitofin वापरण्यासाठी मला Rust लिहिणे आवश्यक आहे का?
नाही. हा प्रकल्प itofin नावाचे पायथन पॅकेज प्रकाशित करतो, त्यामुळे इंजिन सामान्य पायथन प्रक्रियेतून कॉल करता येते. जेव्हा प्राइसिंग लूप स्वतःच तुमचे उत्पादन असते, तेव्हा Rust लिहिणे संबंधित ठरते.
स्प्रेडशीट फॉर्म्युला देऊ शकत नाही अशी कोणती गोष्ट प्राइसिंग लायब्ररी देते?
सिंगल रेट्सऐवजी कर्व्स, प्रत्यक्ष एक्सचेंज कॅलेंडरसह डे-काउंट कन्व्हेन्शन्स, मॉडेल पॅरामीटर्सना कोट केलेल्या किमतींशी जुळवणारे कॅलिब्रेशन लूप आणि या तिन्हींच्या खाली एक टेस्ट केलेले न्यूमेरिक्स लेयर. क्लोज्ड-फॉर्म फॉर्म्युला हा कामाचा छोटा भाग आहे.
प्रोग्रामिंग भाषा बदलल्याने ऑप्शनची किंमत बदलते का?
गणितीयदृष्ट्या नाही. यामुळे पुनरुत्पादकता (reproducibility) बदलते: फ्लोटिंग पॉइंट निकाल ऑपरेशन्सच्या क्रमावर अवलंबून असतात, त्यामुळे एकाच मॉडेलच्या दोन अंमलबजावणी शेवटच्या अंकांबाबत असहमत असू शकतात. संशोधन आणि उत्पादन एकाच इंजिनवर चालवल्याने ही तफावत दूर होते.
येथील प्रत्येक पॅनेलच्या खाली त्याचा नेमका SQL आहे, त्यामुळे मोजणी कशी केली गेली हे पाहण्यासाठी तो विस्तारून पहा. तेच कर्व, कॅलेंडर आणि चेन प्रश्न Strasmore टर्मिनलवर साध्या इंग्रजीत विचारले जाऊ शकतात.