مكتبة بايثون للتمويل الرياضي.
https://pypi.org/project/QFin/
pip install qfin
يتم إعادة بناء QFin للاستفادة من المزيد من مبادئ البرمجة الشيئية. تم إهمال العديد من الوحدات في هذا الإصدار جنبًا إلى جنب مع حلول PDEs/SDEs (بشكل رئيسي في وحدة الخيارات).
يحتوي QFin الآن على وحدة تسمى "Stochastics" والتي ستكون مسؤولة إلى حد كبير عن معايرة النموذج وتسعير الخيارات. يتم أيضًا إنشاء Cython/C++ المكافئ لـ QFin، لذا ترقبوا ذلك!
تعمل المعادلات التفاضلية العشوائية التي تمثل ديناميكيات الأصول الأساسية على توسيع فئة "StochasticModel" وتمتلك قائمة من معلمات النموذج ووظائف تسعير الفانيليا، والمعايرة لأسطح التقلب الضمنية، ومحاكاة مونت كارلو (مفيدة بشكل خاص بعد المعايرة للخيارات المعتمدة على مسار التسعير).
فيما يلي مثال تافه باستخدام ArithmeticBrownianMotion - قم أولاً باستيراد StochasticModel...
من qfin.stochastics استيراد ArithmeticBrownianMotion
بعد ذلك، قم بتهيئة كائن الفئة عن طريق تحديد معلمات النموذج...
# abm تم تحديد معلماته بواسطة Bachelier vol = .3abm = ArithmeticBrownianMotion([.3])
يمكن الآن استخدام abm لتسعير خيار شراء/وضع الفانيليا (الأسعار الافتراضية هي "CALL") ضمن مجموعة المعلمات المحددة...
# F0 = 101# X = 100# T = 1abm.vanilla_pricing(101, 100, 1, "CALL")# سعر المكالمة: 1.0000336233656906
باستخدام أسعار التكافؤ في وضع المكالمة، يمكن أيضًا الحصول على أسعار...
# F0 = 99# X = 100# T = 1abm.vanilla_pricing(99, 100, 1, "PUT")# سعر البيع: 1.0000336233656952
تتوفر أيضًا المعايرة والمحاكاة اللاحقة للعملية - لاحظ أن بعض العمليات لها تقلب ثابت ولا يمكن معايرتها على سطح دائري.
يمكن محاكاة الحركة البراونية الحسابية على النحو التالي...
# F0 = 100# n (الخطوات) = 10000# dt = 1/252# T = 1abm.simulate(100, 10000, 1/252, 1)
يتم تخزين نتائج المحاكاة بالإضافة إلى خصائص المحاكاة تحت فئة "path_characteristics": (paths, n, dt, T).
باستخدام خصائص المسار المخزن قد نجد سعر المكالمة تمامًا كما كان من قبل عن طريق حساب متوسط كل عائد مسار مخفض (بافتراض عملية المخزون) بمعدلات صفر يمكننا تجنب الخصم على النحو التالي والعثور على قيمة الخيار على النحو التالي...
# قائمة مدفوعات المسار = []# سعر إضراب الخيارX = 99# تكرار من خلال قيم المسار الطرفي لتحديد مكافأة المسار في abm.path_characteristics[0]: # إلحاق مكافأة CALL payoffs.append(max((path[-1] - X ), 0))# قيمة الخيار اليومnp.average(payoffs)# سعر المكالمة: 1.0008974837343871
يمكننا أن نرى هنا أن السعر المحاكى يتقارب مع السعر بشكل قريب.
يتوفر تسعير الخيارات النظرية للأسهم التي لا تدفع أرباحًا عبر فئتي BlackScholesCall وBlackScholesPut.
من qfin.options import BlackScholesCallfrom qfin.options import BlackScholesPut# 100 - سعر الأصل الأساسي الأولي # .3 - التقلب الأساسي للأصل # 100 - سعر تنفيذ الخيار # 1 - الوقت حتى الاستحقاق (سنوي) # 01 - معدل الفائدة الخالي من المخاطر لـ Interesteuro_call = بلاك سكولز كول (100، .3، 100، 1، .01)euro_put = BlackScholesPut(100, .3, 100, 1, .01)
طباعة('سعر المكالمة:'، euro_call.price)طباعة('سعر البيع:'، euro_put.price)
Call price: 12.361726191532611 Put price: 11.366709566449416
تتوفر المشتقات الجزئية من الدرجة الأولى وبعض المشتقات الجزئية من الدرجة الثانية لنموذج تسعير بلاك سكولز.
مشتق جزئي من الدرجة الأولى فيما يتعلق بسعر الأصل الأساسي.
طباعة ('دلتا الاتصال:'، euro_call.delta)طباعة ('ضع دلتا:'، euro_put.delta)
Call delta: 0.5596176923702425 Put delta: -0.4403823076297575
مشتق جزئي من الدرجة الثانية فيما يتعلق بسعر الأصل الأساسي.
طباعة ('استدعاء جاما:'، euro_call.gamma)طباعة ('وضع جاما:'، euro_put.gamma)
Call gamma: 0.018653923079008084 Put gamma: 0.018653923079008084
مشتق جزئي من الدرجة الأولى فيما يتعلق بتقلبات الأصول الأساسية.
طباعة ('اتصل بـ vega:'، euro_call.vega)طباعة ('Put vega:'، euro_put.vega)
Call vega: 39.447933090788894 Put vega: 39.447933090788894
مشتق جزئي من الدرجة الأولى فيما يتعلق بوقت الاستحقاق.
طباعة ('اتصل بثيتا:'، euro_call.theta)طباعة ('ضع ثيتا:'، euro_put.theta)
Call theta: -6.35319039407325 Put theta: -5.363140560324083
تتوفر محاكاة مسارات الأصول باستخدام العمليات العشوائية الشائعة.
النموذج القياسي لتنفيذ الحركة البراونية الهندسية.
من qfin.simulations import GeometricBrownianMotion# 100 - سعر الأصل الأساسي الأولي # 0 - انجراف الأصول الأساسي (mu)# .3 - تقلب الأصول الأساسي # 1/52 - الخطوات الزمنية (dt) # 1 - الوقت حتى الاستحقاق (سنوي)gbm = حركة براونية هندسية (100، 0، .3، 1/52، 1)
طباعة (gbm.simulated_path)
[107.0025048205179, 104.82320056538235, 102.53591127422398, 100.20213816642244, 102.04283245358256, 97.75115579923988, 95.19613943526382, 96.9876745495834, 97.46055174410736, 103.93032659279226, 107.36331603194304, 108.95104494118915, 112.42823319947456, 109.06981862825943, 109.10124426285238, 114.71465058375804, 120.00234814086286, 116.91730159923688, 118.67452601825876, 117.89233466917202, 118.93541257993591, 124.36106523035058, 121.26088015675688, 120.53641952983601, 113.73881043255554, 114.91724168548876, 112.94192281337791, 113.55773877160591, 107.49491796151044, 108.0715118831013, 113.01893111071472, 110.39204535739405, 108.63917240906524, 105.8520395233433, 116.2907247951675, 114.07340779267213, 111.06821275009212, 109.65530380775077, 105.78971667172465, 97.75385009989282, 97.84501925249452, 101.90695475825825, 106.0493833583297, 105.48266575656817, 106.62375752876223, 112.39829297429974, 111.22855058562658, 109.89796974828265, 112.78068777325248, 117.80550869036715, 118.4680557054793, 114.33258212280838]
نموذج التقلب العشوائي بناءً على ورقة هيستون (1993).
من qfin.simulations استيراد StochasticVarianceModel# 100 - سعر الأصل الأساسي الأولي # 0 - انجراف الأصول الأساسية (mu) # .01 - معدل الفائدة الخالي من المخاطر # .05 - الأرباح المستمرة # 2 - المعدل الذي يعود فيه التباين إلى المدى الطويل الضمني التباين # .25 - التباين الضمني على المدى الطويل حيث يميل الوقت إلى اللانهاية # -.7 - ارتباط الحركة المتولدة # .3 - تقلب التباين# 1/52 - الخطوات الزمنية (dt)# 1 - الوقت حتى الاستحقاق (سنوي)svm = StochasticVarianceModel(100, 0, .01, .05, 2, .25, -.7, .3, .09, 1/52، 1)
طباعة (svm.simulated_path)
[98.21311553503577, 100.4491317019877, 89.78475515902066, 89.0169762497475, 90.70468848525869, 86.00821802256675, 80.74984494892573, 89.05033807013137, 88.51410029337134, 78.69736798230346, 81.90948751054125, 83.02502248913251, 83.46375102829755, 85.39018282900138, 78.97401642238059, 78.93505221741903, 81.33268688455111, 85.12156706038515, 79.6351983987908, 84.2375291273571, 82.80206517176038, 89.63659376223292, 89.22438477640516, 89.13899271995662, 94.60123239511816, 91.200165507022, 96.0578905115345, 87.45399399599378, 97.908745925816, 97.93068975065052, 103.32091104292813, 110.58066464778392, 105.21520242908348, 99.4655106985056, 106.74882010453683, 112.0058519886151, 110.20930861932342, 105.11835510815085, 113.59852610881678, 107.13315204738092, 108.36549026977205, 113.49809943785571, 122.67910031073885, 137.70966794451425, 146.13877267735612, 132.9973784430374, 129.75750117504984, 128.7467891695649, 127.13115959080305, 130.47967713110302, 129.84273088908265, 129.6411527208744]
يتوفر تسعير المحاكاة للخيارات الغريبة في ظل الافتراضات المرتبطة بالعمليات العشوائية المعنية. الحركة البراونية الهندسية هي القاعدة الأساسية للعملية العشوائية المستخدمة في كل محاكاة لمونت كارلو. ومع ذلك، في حالة توفير معلمات إضافية، سيتم استخدام العملية العشوائية المناسبة لإنشاء كل مسار عينة.
من qfin.simulations import MonteCarloCallfrom qfin.simulations import MonteCarloPut# 100 - سعر الإضراب # 1000 - عدد مسارات الأسعار المحاكاة # .01 - معدل الفائدة الخالي من المخاطر # 100 - سعر الأصل الأساسي الأولي # 0 - انجراف الأصول الأساسية (mu)# .3 - تقلبات الأصول الأساسية # 1/52 - الخطوات الزمنية (dt) # 1 - الوقت حتى الاستحقاق (سنوي)call_option = MonteCarloCall(100, 1000, .01, 100, 0, .3, 1/52, 1)# ستؤدي هذه المعلمات الإضافية إلى إنشاء سعر مونت كارلو بناءً على عملية التقلب العشوائية# 2 - معدل التباين يعود إلى التباين الضمني على المدى الطويل # .25 - التباين الضمني على المدى الطويل مع ميل الوقت إلى اللانهاية# -.5 - ارتباط الحركة المتولدة# .02 - الأرباح المستمرة# .3 - تقلب التباينput_option = MonteCarloPut(100, 1000, .01, 100, 0, .3, 1/52, 1, 2, .25, -.5، .02، .3)
طباعة (call_option.price) طباعة (put_option.price)
12.73812121792851 23.195814963576286
من qfin.simulations import MonteCarloBinaryCallfrom qfin.simulations import MonteCarloBinaryPut# 100 - سعر الإضراب # 50 - دفع تعويضات الخيار الثنائي # 1000 - عدد مسارات الأسعار المحاكاة # .01 - معدل الفائدة الخالي من المخاطر # 100 - سعر الأصل الأساسي الأولي # 0 - الأساسي انجراف الأصول (mu)# .3 - تقلب الأصول الأساسية # 1/52 - الخطوات الزمنية (dt)# 1 - الوقت حتى الاستحقاق (سنوي)binary_call = MonteCarloBinaryCall(100, 50, 1000, .01, 100, 0, .3, 1/52, 1)binary_put = MonteCarloBinaryPut(100, 50, 1000) ، .01، 100، 0، .3، 1/52، 1)
طباعة (binary_call.price) طباعة (binary_put.price)
22.42462873441866 27.869902820039087
من qfin.simulations import MonteCarloBarrierCallfrom qfin.simulations import MonteCarloBarrierPut# 100 - سعر الإضراب # 50 - دفع تعويضات الخيار الثنائي # 1000 - عدد مسارات الأسعار المحاكاة # .01 - معدل الفائدة الخالي من المخاطر # 100 - سعر الأصل الأساسي الأولي # 0 - الأساسي انجراف الأصول (mu)# .3 - تقلبات الأصول الأساسية # 1/52 - الوقت الخطوات (dt)# 1 - وقت الاستحقاق (سنوي)# صحيح/خطأ - الحاجز لأعلى أو لأسفل# صحيح/خطأ - الحاجز موجود أو Outbarrier_call = MonteCarloBarrierCall(100, 1000, 150, .01, 100, 0, . 3، 1/52، 1، أعلى=صحيح، خارج=صحيح)barrier_put = MonteCarloBarrierCall(100, 1000, 95, .01, 100, 0, .3, 1/52, 1, up=False, out=False)
طباعة (binary_call.price) طباعة (binary_put.price)
4.895841997908933 5.565856754630819
من qfin.simulations import MonteCarloAsianCallfrom qfin.simulations import MonteCarloAsianPut# 100 - سعر الإضراب # 1000 - عدد مسارات الأسعار المحاكاة # .01 - معدل الفائدة الخالي من المخاطر # 100 - سعر الأصل الأساسي الأولي # 0 - انجراف الأصول الأساسية (mu) # .3 - تقلبات الأصول الأساسية # 1/52 - الخطوات الزمنية (dt) # 1 - الوقت حتى الاستحقاق (سنوي)asian_call = MonteCarloAsianCall(100, 1000, .01, 100, 0, .3, 1/52, 1)asian_put = MonteCarloAsianPut(100, 1000, .01, 100, 0, .3, 1/ 52، 1)
طباعة (asian_call.price)طباعة (asian_put.price)
6.688201154529573 7.123274528125894
من qfin.simulations import MonteCarloExtendibleCallfrom qfin.simulations import MontecarloExtendiblePut# 100 - سعر التنفيذ # 1000 - عدد مسارات الأسعار المحاكاة # .01 - معدل الفائدة الخالي من المخاطر # 100 - سعر الأصل الأساسي الأولي # 0 - انجراف الأصول الأساسية (mu)# .3 - تقلبات الأصول الأساسية # 1/52 - خطوات زمنية (dt)# 1 - الوقت حتى الاستحقاق (سنوي)# .5 - التمديد إذا نفدت الأموال عند expirationextendible_call = MonteCarloExtendibleCall(100, 1000, .01, 100, 0, .3, 1/52, 1, .5) Extendible_put = MonteCarloExtendiblePut(100, 1000, .01، 100، 0، .3، 1/52، 1، .5)
طباعة (extendible_call.price)طباعة (extendible_put.price)
13.60274931789973 13.20330578685724