Python and Finance - عزز جداول البيانات الخاصة بك
نشرت: 2022-03-11ملخص تنفيذي
لماذا تعتبر Python لغة برمجة رائعة ليتعلمها المحترفون الماليون؟
- Python هي لغة برمجة عالية المستوى ، مما يعني أنها تلخص وتتعامل مع العديد من الجوانب الفنية للبرمجة ، مثل إدارة الذاكرة ، والتي يجب التعامل معها صراحة بلغات أخرى. هذا يجعل Python سهلة الاستخدام لمن ليس لديهم خلفية تقنية.
- نظرًا لأن اللغة تم تصميمها مع مراعاة سهولة القراءة وسهولة الاستخدام ، فهي واحدة من أسهل اللغات للتعلم. كود Python موجز وقريب من اللغة الإنجليزية البسيطة.
- تعد Python مثالية للنماذج الأولية والتطور السريع والتكراري. توفر أدوات المترجم التفاعلي الخاص بها بيئات يمكنك من خلالها كتابة وتنفيذ كل سطر من التعليمات البرمجية بمعزل عن غيرها ورؤية النتائج على الفور.
- في الوقت نفسه ، تعد Python قوية وفعالة ، مما يجعلها خيارًا قابلاً للتطبيق أيضًا للأنظمة الأساسية والتطبيقات الأكبر حجمًا.
- بالإضافة إلى مكتبتها القياسية الكبيرة من الأدوات المفيدة ، تمتلك Python مكتبات خارجية رائعة للتحليل المالي والحوسبة ، مثل مكتبات Pandas و NumPy المستخدمة في هذا البرنامج التعليمي.
ما هي بعض حالات الاستخدام لتطبيق Python والتمويل معًا؟
- يمكن استخدام برامج Python النصية لأتمتة المهام المتكررة وسير العمل ، مما يوفر الوقت ويقلل من مخاطر الأخطاء اليدوية.
- تسمح البرامج النصية للمستخدمين بسحب البيانات بسهولة من جداول البيانات وقواعد البيانات وواجهات برمجة التطبيقات ، أو حتى كشط بيانات الويب ، والتي يمكن بعد ذلك معالجتها وتحليلها باستخدام أدوات إحصائية وتحليلية قوية.
- تسمح المكونات الإضافية المختلفة لبرنامج Excel للمستخدمين بإنشاء روابط ثنائية الاتجاه في الوقت الفعلي بين جداول البيانات الخاصة بك وكود Python.
- تتيح Python أنواعًا جديدة من التحليل ، مثل محاكاة مونت كارلو ، التي لا تتوفر بسهولة في جداول البيانات القياسية.
- لم يعد التداول الخوارزمي المجال الحصري لصناديق التحوط والبنوك الاستثمارية الكبيرة. باستخدام Python ، يمكنك تطوير استراتيجيات التداول الخاصة بك واختبارها ونشرها في وقت قصير وبتكلفة منخفضة.
بالنسبة للمهن التي اعتمدت منذ فترة طويلة على البحث في جداول البيانات ، تعد لغة بايثون ذات قيمة خاصة. قدم Citigroup ، وهو بنك أمريكي ، دورة تدريبية مكثفة في Python لمحلليه المتدربين. - الإيكونوميست
يتمتع المتخصصون في الشؤون المالية بإمكانية الوصول إلى VBA (Visual Basic للتطبيقات) في Excel منذ فترة طويلة لإنشاء وظائف مخصصة وأتمتة مهام سير العمل. مع ظهور جداول بيانات Google في السنوات الأخيرة كمنافس جاد في مساحة جداول البيانات ، تقدم Google Apps Script الآن خيارًا إضافيًا.
ومع ذلك ، أود أن ألفت الانتباه إلى خيار ثالث ، وهو لغة برمجة Python ، التي أصبحت شائعة بشكل كبير في عدد من المجالات.
في هذه المقالة ، سأقدم بعض الأمثلة على ما يمكنك تحقيقه باستخدام Python ، بدءًا من نظرة عامة على اللغة نفسها ولماذا أصبحت شائعة جدًا في مجموعة متنوعة من المجالات ، بدءًا من تطوير الويب والتعلم الآلي والتمويل ، العلم والتعليم ، على سبيل المثال لا الحصر. سيتألف النصف الثاني بعد ذلك من برنامج تعليمي خطوة بخطوة.
هدفي من كتابة هذا هو مساعدتك في تحديد ما إذا كانت Python تبدو مثيرة للاهتمام بما يكفي لكي تفكر في إضافتها إلى صندوق أدواتك المالي. إذا اتخذت قفزة ، فهناك العديد من التطبيقات والدورات التدريبية ومقاطع الفيديو والمقالات والكتب ومنشورات المدونات المتاحة لتعلم اللغة. في نهاية المقال ، قمت بإدراج بعض الموارد التي ساعدتني على طول الطريق.
حالات الاستخدام: أمثلة لما استخدمت Python من أجله
كانت مقدمة البرمجة الخاصة بي هي تعلم BASIC على Oric 1 في منتصف الثمانينيات. في ذلك الوقت كانت لغة BASIC هي لغة المبتدئين الأكثر شيوعًا. اللغات الأخرى التي انخرطت فيها في أواخر الثمانينيات حتى منتصف التسعينيات كانت لغة باسكال وسي ، لكنني لم أستخدمها مطلقًا بأي صفة احترافية ، ولم أتوقع أن أحتاج إلى مهارات البرمجة أو أستخدمها. على حد علمي في ذلك الوقت في أواخر التسعينيات ، كان التمويل والبرمجة مجالين مختلفين للغاية ، عندما اخترت الشروع في مسار وظيفي في التمويل.
تقدم سريعًا إلى عام 2012 ، وكنت أتطلع إلى اختيار البرمجة احتياطيًا كهواية ، لذلك بدأت في البحث عن اللغات المتاحة في ذلك الوقت. لقد اتضح أن القليل قد حدث ، وعندما صادفت بايثون كنت مدمن مخدرات ، للعديد من الأسباب التي سأوضحها في القسم التالي. منذ ذلك الحين ، استخدمت Python في مجموعة واسعة من المهام ، من البرامج النصية الصغيرة إلى المشاريع الأكبر ، على المستويين الشخصي والمهني. لقد اشتمل الكثير ، ولكن ليس كلهم ، على جداول البيانات ، ومنضدة عمل العديد من المتخصصين الماليين.
فيما يلي بعض الأمثلة حول مدى نجاح جداول البيانات و Python معًا:
1. تتبع المئات من الأنشطة على مدار الوقت في إعداد PMO لتكامل الاندماج والاستحواذ
أنا أعمل في جميع جوانب معاملات الاندماج والاستحواذ ، ليس فقط التنفيذ ، ولكن أيضًا التكامل. في حالة حديثة ، قرر فريق PMO اتباع نهج هجين لإدارة البرامج والمشاريع ، باستخدام تخطيط الشلال ومخططات جانت للخطط عالية المستوى لكل من مسارات عمل التكامل الاثني عشر ، بالإضافة إلى لوحة Kanban لتتبع مئات الأنشطة الجارية في أي وقت محدد ، في أول خطة مدتها 100 يوم وما بعدها. تحتوي أداة كانبان التي تم اختيارها ، MeisterTask ، على عدد من الميزات الإحصائية والتقارير ، لكن احتياجاتنا تجاوزت ذلك من حيث التحليل والعرض التقديمي ، الأمر الذي تطلب حلاً مخصصًا. هذا هو سير العمل الذي أتممته آليًا باستخدام Python:
- احفظ حالة اللوحة بأكملها أسبوعيًا كملف CSV.
- اقرأ جميع ملفات CSV التاريخية في Pandas DataFrame.
- قم بفرز البيانات وتصفيتها وتجميعها ومعالجتها في تنسيقات متفق عليها للطريقة التي نريد بها تتبع التقدم (حسب حالة النشاط ومسار العمل وما إلى ذلك).
- اكتب المخرجات في ملف Excel مع البيانات من كل تحليل في الورقة الخاصة به ، منسقة بطريقة يمكن ببساطة نسخها ولصقها في مخططات خلايا التفكير.
- قم بإنشاء جداول ومخططات لحزمة التقارير للاجتماع الشهري للجنة التوجيهية.
يتطلب تطوير النص استثمارًا مقدمًا لبضع ساعات ، ولكن الآن ، يستغرق تحديث مجموعة التقارير لاجتماعات اللجنة التوجيهية أو التحليل المخصص بضع دقائق. حرفيًا ، حوالي 30 ثانية للانتقال إلى المجلد الأيمن وتشغيل البرنامج النصي باستخدام أمر من سطر واحد ، ثم بضع دقائق لنسخ ولصق الإخراج في مجموعة الشرائح. مع وجود حوالي 500 نشاط (بطاقة) عبر اثني عشر مسار عمل بالفعل قيد التنفيذ لمدة شهر تقريبًا ، والتتبع الأسبوعي لكيفية تحركهم ، داخل جدول زمني للبرنامج لمدة عامين ، ستجد نفسك سريعًا تتعامل مع الآلاف ، وفي النهاية عشرات الآلاف من نقاط البيانات عبر العشرات من الملفات. بدون الأتمتة ، نتحدث هنا عن بعض المهام الشاقة للغاية.
تعتبر مقايضة "القيمة الزمنية للمال" بين مجرد التعامل مع الأشياء ، أو إضافة المزيد من عبء العمل الأولي عن طريق إعداد الأتمتة موضوعًا شائعًا في مجال التمويل. لقد اتخذت قرارًا مشابهًا في الخطوة الأولى من هذه العملية ، من خلال تصدير البيانات كملفات CSV. يحتوي MeisterTask ، مثل العديد من تطبيقات الويب الحديثة ، على واجهة برمجة تطبيقات يمكن توصيلها بتطبيق Python الخاص بك ، لكن الوقت المستغرق في إعداده يفوق بكثير توفير الوقت لحالة الاستخدام هنا.
لذلك ، كما ترى ، في كثير من الأحيان يكون الحل الأمثل هو أتمتة خطوات معينة من سير العمل والحفاظ على دليل آخر.
2. تحليل إحصائيات أسعار المنازل باستخدام تجريف الويب و Google Maps API و Excel
مثال آخر هو شيء فعلته بدافع الاهتمام الشخصي ولكني أريد تسليط الضوء عليه لأنه يحتوي على بعض العناصر الأخرى المثيرة للاهتمام لفائدة بايثون:
- كشط بيانات قوائم العقارات ، بما في ذلك العنوان والحجم وعدد الغرف وسعر الطلب والميزات الأخرى لمنطقة معينة ؛ بضع مئات إلى ألف سطر في المجموع.
- حفظ في هيكل بيانات بايثون.
- اتصل بواجهة برمجة تطبيقات خرائط Google ، ولكل قائمة ، استرجع المسافة بين الممتلكات والمعالم الرئيسية مثل البحر ، ووسط المدينة ، وأقرب محطة قطار ، وأقرب مطار ، وما إلى ذلك.
- تصدير البيانات إلى ملف Excel.
- استخدم وظيفة Excel القياسية لتشغيل الانحدارات وحساب الإحصائيات وإنشاء مخططات على المقاييس القياسية مثل السعر لكل متر مربع والمسافة إلى المعالم.
يمكن دمج النتائج هنا مع الأوزان الشخصية الخاصة بك من حيث التفضيلات والقيود المالية عند البحث عن العقارات.
هذان مثالان فقط ، يركزان على أتمتة العمل المرتبط بجداول البيانات وإضافة ميزات ، لكن الفرص مع Python تكاد لا تنتهي. في القسم التالي ، سأوجز الأسباب التي جعلتها تحظى بشعبية كبيرة ، قبل الانتقال إلى برنامج تعليمي لمحاكاة مونت كارلو خطوة بخطوة في بايثون.
لماذا تعد Python خيارًا رائعًا للمحترفين الماليين
لغة البرمجة Python موجودة منذ عام 1990 ، ولكن لم تنتشر شعبيتها إلا في السنوات الأخيرة.
هناك عدة أسباب لذلك ، دعونا نلقي نظرة على كل منها على حدة.
1. بايثون هي لغة برمجة عالية المستوى
لغة البرمجة عالية المستوى هي تلك التي تلخص الكثير من تفاصيل الأعمال الداخلية للكمبيوتر. وخير مثال على ذلك هو إدارة الذاكرة. تتطلب لغات البرمجة ذات المستوى الأدنى فهمًا تفصيليًا لتعقيدات كيفية تخطيط ذاكرة الكمبيوتر وتخصيصها وإصدارها ، بالإضافة إلى الوقت المستغرق وأسطر التعليمات البرمجية المطلوبة للتعامل مع المهام. تلخص Python العديد من هذه التفاصيل وتعالجها تلقائيًا ، مما يتركك تركز على ما تريد تحقيقه.
2. أنها موجزة
نظرًا لأن Python هي لغة برمجة عالية المستوى ، فإن الشفرة تكون أكثر إيجازًا وتركز بالكامل تقريبًا على منطق الأعمال لما تريد تحقيقه ، بدلاً من تفاصيل التنفيذ الفني. تساهم خيارات تصميم اللغة في هذا: على سبيل المثال ، لا تتطلب Python استخدام الأقواس المعقوفة أو الفاصلة المنقوطة لتحديد الوظائف والحلقات والخطوط بالطريقة التي تعمل بها العديد من اللغات الأخرى ، مما يجعلها أكثر إيجازًا ، كما يجادل البعض ، مقروئية.
3. سهل التعلم والفهم
إحدى الملاحظات التي أثرت على خيارات تصميم اللغة في بايثون هي أن البرامج تُقرأ أكثر مما تُكتب. تتفوق Python هنا لأن كودها يبدو قريبًا جدًا من اللغة الإنجليزية البسيطة ، خاصة إذا قمت بتسمية المكونات المختلفة للبرنامج النصي أو البرنامج بطريقة معقولة.
4. مناسبة للتطور السريع والتكراري
يتفوق الخطأ والتجربة المستنيرة على تخطيط العقول الخالية من العيوب. - ديفيد كيلي
تعد Python مثالية للنماذج الأولية والتطوير السريع والمتكرر (ونعم ، التجربة والخطأ) لأن أدوات المترجم التفاعلي مثل Python shell و IPython و Jupyter هي في المقدمة وفي المنتصف في Python toolchain. في هذه البيئات التفاعلية ، يمكنك كتابة وتنفيذ كل سطر من التعليمات البرمجية على حدة ورؤية النتائج (أو رسالة خطأ مفيدة) على الفور. اللغات الأخرى لديها هذا أيضًا ، ولكن في معظم الحالات ليس بنفس درجة بايثون.
5. يمكن استخدامها في كل من النماذج الأولية وكود الإنتاج
بالإضافة إلى كونها رائعة للنماذج الأولية ، تعد Python أيضًا لغة ممتازة وقوية لتطبيقات الإنتاج الكبيرة. تستخدم بعض أكبر شركات البرمجيات في العالم لغة Python بكثافة في مجموعة متنوعة من التطبيقات وحالات الاستخدام.
6. يأتي مع "بطاريات مشمولة:" مكتبة Python القياسية
تم تضمين كل ما هو مطلوب للعمليات الأساسية في اللغة مباشرةً ، ولكن بالإضافة إلى ذلك ، تحتوي مكتبة Python القياسية على أدوات للعمل مع الملفات والوسائط والشبكات ومعلومات التاريخ والوقت وغير ذلك الكثير. يتيح لك ذلك إنجاز مجموعة متنوعة من المهام دون الحاجة إلى البحث عن حزم الجهات الخارجية.
7. مكتبات الطرف الثالث العظيمة للتحليل المالي
للمحترفين الماليين ، تعد Pandas بكائنات DataFrame و Series الخاصة بها ، و Numpy مع ndarray هي وحدات العمل للتحليل المالي باستخدام Python. بالاقتران مع matplotlib ومكتبات التصور الأخرى ، لديك أدوات رائعة تحت تصرفك للمساعدة في الإنتاجية.
8. بايثون مجاني!
تم تطوير Python بموجب ترخيص مفتوح المصدر يجعلها مجانية أيضًا للاستخدام التجاري.
برنامج تعليمي خطوة بخطوة حول استخدام Python و Finance معًا
ما يلي هو برنامج تعليمي خطوة بخطوة يوضح كيفية إنشاء نسخة مبسطة من محاكاة مونت كارلو الموضحة في منشور المدونة السابق ، ولكن باستخدام Python بدلاً من المكون الإضافيRISK لبرنامج Excel.
تعتمد طرق مونت كارلو على أخذ العينات العشوائية للحصول على نتائج عددية. أحد هذه التطبيقات هو سحب عينات عشوائية من توزيع احتمالي يمثل حالات مستقبلية محتملة غير مؤكدة للعالم حيث يمكن أن تأخذ المتغيرات أو الافتراضات مجموعة من القيم.
من المفيد إجراء محاكاة مونت كارلو على نموذج مبسط لتقييم التدفقات النقدية المخصومة بدلاً من الأمثلة الأكثر شيوعًا التي تراها تُظهر تقييم الخيارات أو المشتقات الأخرى ، لأننا لهذا لا نحتاج إلى أي حسابات تتجاوز أساسيات حساب البيانات المالية و خصم التدفقات النقدية ، مما يسمح لنا بالتركيز على مفاهيم وأدوات بايثون. يرجى ملاحظة أن هذا النموذج التعليمي الأساسي يهدف إلى توضيح المفاهيم الأساسية ، وليس مفيدًا كما هو لأية أغراض عملية. لن أتطرق أيضًا إلى أي من الجوانب الأكاديمية لمحاكاة مونت كارلو.
يفترض البرنامج التعليمي أنك معتاد على اللبنات الأساسية للبرمجة ، مثل المتغيرات والوظائف. إذا لم يكن الأمر كذلك ، فقد يكون من المفيد أن تستغرق 10 دقائق للتحقق من المفاهيم الأساسية في هذه المقدمة على سبيل المثال.
نقطة البداية والنتيجة المرجوة
أبدأ بنفس نموذج تقييم DCF المبسط جدًا المستخدم في البرنامج التعليمي لمحاكاة مونت كارلو. يحتوي على بعض العناصر الرئيسية من البيانات المالية الثلاثة ، وثلاث خلايا إدخال مميزة ، والتي تحتوي في إصدار Excel على تقديرات نقطية نريد الآن استبدالها بتوزيعات احتمالية لبدء استكشاف النطاقات المحتملة للنتائج.
نهج من خطوتين لتطوير نص صغير
اجعلها تعمل ، اجعلها صحيحة ، اجعلها سريعة - كينت بيك
الهدف من هذا البرنامج التعليمي هو إعطاء المتخصصين الماليين الجدد في Python مقدمة ليس فقط لما قد يبدو عليه البرنامج المفيد ، ولكن أيضًا مقدمة للعملية التكرارية التي يمكنك استخدامها لتطويره. لذلك يتكون من جزأين:
- أولاً ، أقوم بتطوير نموذج أولي عملي باستخدام نهج مباشر أعتقد أنه من السهل اتباعه ولا يختلف تمامًا عن العملية التي يمكن للمرء استخدامها لبدء هذا المشروع إذا كنت ستبدأ من نقطة الصفر.
- بعد ذلك ، بعد تطوير النموذج الأولي العامل ، أمارس عملية إعادة البناء - تغيير هيكل الكود دون تغيير وظائفه. قد ترغب في الاستمرار في هذا الجزء - إنه حل أكثر أناقة من الحل الأول ، وكمكافأة ، فهو أسرع بحوالي 75 مرة من حيث وقت التنفيذ.
1. تطوير نموذج عمل
إعداد دفتر Jupyter
يعد دفتر Jupyter أداة رائعة للعمل مع Python بشكل تفاعلي. إنه مترجم Python تفاعلي يحتوي على خلايا يمكن أن تحتوي على تعليمات برمجية أو نص Markdown أو صور أو بيانات أخرى. في هذا البرنامج التعليمي ، استخدمت Python Quant Platform ، لكن يمكنني أيضًا أن أوصي بـ Colaboratory من Google ، وهو مجاني ويعمل في السحابة. بمجرد الوصول إلى هناك ، ما عليك سوى تحديد "New Python 3 Notebook" في قائمة "ملف" ، وستكون جاهزًا للانطلاق.
بعد القيام بذلك ، فإن الخطوة التالية هي استيراد حزم الجهات الخارجية التي نحتاجها لمعالجة البيانات والتصورات ، وإخبار البرنامج أننا نريد أن نرى الرسوم البيانية مضمنة في دفتر ملاحظاتنا ، بدلاً من النوافذ المنفصلة:
import numpy as np import pandas as pd import matplotlib.pyplot as plt %matplotlib inline
ملاحظة قبل أن نبدأ في تسمية المتغيرات الأولى. كما أوضحت بالفعل ، تعد قابلية القراءة إحدى نقاط قوة بايثون. يقطع تصميم اللغة شوطًا طويلاً في دعم ذلك ، ولكن كل شخص يكتب رمزًا مسؤولاً عن جعله قابلاً للقراءة ومفهومًا ، ليس فقط للآخرين ولكن أيضًا لأنفسهم. كما ينص قانون إيجلسون ، "أي رمز خاص بك لم تنظر إليه لمدة ستة أشهر أو أكثر ربما كتبه شخص آخر."
تتمثل إحدى القواعد العامة الجيدة في تسمية مكونات برنامجك بطريقة تقلل من الحاجة إلى التعليقات المنفصلة التي تشرح ما يفعله برنامجك.
مع وضع ذلك في الاعتبار ، دعنا ننتقل.
إنشاء القوائم المالية
هناك العديد من الطرق التي يمكننا من خلالها العمل مع بيانات جداول البيانات الموجودة في Python. يمكننا ، على سبيل المثال ، قراءة ورقة في Pandas DataFrame بسطر واحد من التعليمات البرمجية باستخدام الأمر read_excel
. إذا كنت تريد تكاملًا أكثر إحكامًا ورابطًا في الوقت الفعلي بين جدول البيانات الخاص بك ورمز Python ، فهناك خيارات مجانية وتجارية متاحة لتوفير هذه الوظيفة.

نظرًا لأن النموذج هنا بسيط جدًا ، ولتركيزنا على مفاهيم Python ، سنقوم بإعادة إنشائه من نقطة الصفر في البرنامج النصي الخاص بنا. في نهاية الجزء الأول ، سأوضح كيف يمكنك تصدير ما أنشأناه إلى جدول بيانات.
كخطوة أولى نحو إنشاء تمثيل Python للبيانات المالية ، سنحتاج إلى بنية بيانات مناسبة. هناك الكثير للاختيار من بينها ، بعضها مدمج في Python ، والبعض الآخر من مكتبات مختلفة ، أو يمكننا إنشاء مكتبتنا الخاصة. في الوقت الحالي ، دعنا نستخدم سلسلة من مكتبة Pandas لإلقاء نظرة على وظائفها:
years = ['2018A', '2019B', '2020P', '2021P', '2022P', '2023P'] sales = pd.Series(index=years) sales['2018A'] = 31.0 sales
يتم عرض هذا الإدخال والمخرجات المقابلة له أدناه:
مع الأسطر الثلاثة الأولى ، أنشأنا بنية بيانات بمؤشر يتكون من سنوات (تم وضع علامة على كل منها لإظهار ما إذا كانت فعلية أو ميزانية أو متوقعة) ، وقيمة ابتدائية (بملايين اليورو ، كما في نموذج DCF الأصلي) ، و خلايا فارغة (NaN ، "ليس رقمًا") للإسقاطات. يطبع السطر الرابع تمثيلاً للبيانات - بشكل عام ، ستمنحك كتابة اسم متغير أو كائنات أخرى في المترجم التفاعلي تمثيلاً معقولاً لها.
بعد ذلك ، نعلن عن متغير يمثل النمو المتوقع للمبيعات السنوية. في هذه المرحلة ، هو تقدير نقطي ، وهو نفس الرقم الموجود في نموذج DCF الأصلي الخاص بنا. نريد أولاً استخدام نفس المدخلات والتأكد من أن إصدار Python يعمل بنفس الأداء ويعطي نفس النتيجة مثل إصدار Excel ، قبل النظر في استبدال تقديرات النقاط بتوزيعات الاحتمالية. باستخدام هذا المتغير ، نقوم بإنشاء حلقة تحسب المبيعات في كل سنة من التوقعات بناءً على العام السابق ومعدل النمو:
growth_rate = 0.1 for year in range(1, 6): sales[year] = sales[year - 1] * (1 + growth_rate) sales
لدينا الآن مبيعات متوقعة ، بدلاً من NaN:
باستخدام نفس النهج ، نواصل من خلال البيانات المالية ، والإعلان عن المتغيرات التي نحتاجها وإجراء الحسابات اللازمة للوصول في النهاية إلى التدفق النقدي الحر. بمجرد أن نصل إلى هناك ، يمكننا التحقق من أن ما لدينا يتوافق مع ما يقوله إصدار Excel من نموذج DCF.
ebitda_margin = 0.14 depr_percent = 0.032 ebitda = sales * ebitda_margin depreciation = sales * depr_percent ebit = ebitda - depreciation nwc_percent = 0.24 nwc = sales * nwc_percent change_in_nwc = nwc.shift(1) - nwc capex_percent = depr_percent capex = -(sales * capex_percent) tax_rate = 0.25 tax_payment = -ebit * tax_rate tax_payment = tax_payment.apply(lambda x: min(x, 0)) free_cash_flow = ebit + depreciation + tax_payment + capex + change_in_nwc free_cash_flow
هذا يعطينا التدفقات النقدية المجانية:
السطر الأول أعلاه والذي ربما يحتاج إلى تعليق في هذه المرحلة هو المرجع الثاني tax_payment
. هنا ، نطبق دالة صغيرة للتأكد من أنه في السيناريوهات التي يصبح فيها الربح قبل الضريبة سالبًا ، لن يكون لدينا دفعة ضريبية موجبة. يوضح هذا مدى فعالية تطبيق الوظائف المخصصة على جميع الخلايا في سلسلة Pandas أو DataFrame. الوظيفة الفعلية المطبقة هي ، بالطبع ، تبسيط. النموذج الأكثر واقعية لممارسة التقييم الأكبر سيكون له نموذج ضريبي منفصل يحسب الضرائب النقدية الفعلية المدفوعة بناءً على عدد من العوامل الخاصة بالشركة.
إجراء تقييم التدفقات النقدية المخصومة
بعد الوصول إلى التدفقات النقدية المتوقعة ، يمكننا الآن حساب قيمة نهائية بسيطة وخصم جميع التدفقات النقدية إلى الوقت الحاضر للحصول على نتيجة التدفقات النقدية المخصومة. يقدم الكود التالي الفهرسة والتقطيع ، مما يسمح لنا بالوصول إلى عنصر واحد أو أكثر في بنية البيانات ، مثل كائن سلسلة Pandas.
نصل إلى العناصر عن طريق كتابة أقواس مربعة بعد اسم الهيكل مباشرة. تصل الفهرسة البسيطة إلى العناصر من خلال موضعها ، بدءًا من الصفر ، مما يعني أن free_cash_flow[1]
سيعطينا العنصر الثاني. [-1]
هو اختصار للوصول إلى العنصر الأخير (يتم استخدام التدفق النقدي للعام الماضي لحساب القيمة النهائية) ، واستخدام النقطتين يعطينا شريحة ، مما يعني أن [1:]
يعطينا جميع العناصر باستثناء العنصر الأول ، نظرًا لأننا لا نريد تضمين العام التاريخي 2018A
في تقييم التدفقات النقدية المخصومة.
cost_of_capital = 0.12 terminal_growth = 0.02 terminal_value = ((free_cash_flow[-1] * (1 + terminal_growth)) / (cost_of_capital - terminal_growth)) discount_factors = [(1 / (1 + cost_of_capital)) ** i for i in range (1,6)] dcf_value = (sum(free_cash_flow[1:] * discount_factors) + terminal_value * discount_factors[-1]) dcf_value
هذا يختتم الجزء الأول من نموذجنا الأولي - لدينا الآن نموذج DCF عامل ، وإن كان بدائيًا للغاية ، في Python.
تصدير البيانات
قبل الانتقال إلى محاكاة مونت كارلو الفعلية ، قد يكون هذا هو الوقت المناسب لذكر إمكانات التصدير المتاحة في حزمة Pandas. إذا كان لديك كائن Pandas DataFrame ، فيمكنك كتابته في ملف Excel بسطر واحد باستخدام طريقة to_excel
. هناك وظائف مماثلة للتصدير إلى أكثر من اثني عشر تنسيقات ووجهات أخرى أيضًا.
output = pd.DataFrame([sales, ebit, free_cash_flow], index=['Sales', 'EBIT', 'Free Cash Flow']).round(1) output.to_excel('Python DCF Model Output.xlsx') output
إنشاء توزيعات احتمالية لمحاكاة مونت كارلو الخاصة بنا
نحن الآن جاهزون لمواجهة التحدي التالي: استبدال بعض مدخلات تقدير النقاط بتوزيعات احتمالية. في حين أن الخطوات حتى هذه النقطة قد تبدو مرهقة إلى حد ما مقارنة ببناء نفس النموذج في Excel ، فإن هذه الأسطر القليلة التالية ستمنحك لمحة عن مدى قوة Python.
خطوتنا الأولى هي تحديد عدد التكرارات التي نريد تشغيلها في المحاكاة. يؤدي استخدام 1000 كنقطة بداية إلى إحداث توازن بين الحصول على نقاط بيانات كافية للحصول على مخططات إخراج معقولة ، مقابل الحصول على إنهاء المحاكاة في إطار زمني معقول. بعد ذلك ، نقوم بإنشاء التوزيعات الفعلية. من أجل البساطة ، قمت بإنشاء ثلاثة توزيعات عادية هنا ، لكن مكتبة NumPy بها عدد كبير من التوزيعات للاختيار من بينها ، وهناك أماكن أخرى للبحث عنها أيضًا ، بما في ذلك مكتبة Python القياسية. بعد تحديد التوزيع المراد استخدامه ، نحتاج إلى تحديد المعلمات المطلوبة لوصف شكلها ، مثل الانحراف المتوسط والمعياري ، وعدد النتائج المرغوبة.
iterations = 1000 sales_growth_dist = np.random.normal(loc=0.1, scale=0.01, size=iterations) ebitda_margin_dist = np.random.normal(loc=0.14, scale=0.02, size=iterations) nwc_percent_dist = np.random.normal(loc=0.24, scale=0.01, size=iterations) plt.hist(sales_growth_dist, bins=20) plt.show()
هنا يمكنك أن تجادل بأن الأرباح قبل الفوائد والضرائب والإهلاك والاستهلاك لا ينبغي أن تكون متغيرًا عشوائيًا منفصلاً ومستقلاً عن المبيعات ولكن بدلاً من ذلك يرتبط بالمبيعات إلى حد ما. أود أن أتفق مع هذا ، وأضيف أنه يجب أن يكون مدفوعًا بفهم قوي لديناميكيات هيكل التكلفة (التكاليف المتغيرة وشبه المتغيرة والثابتة) ومحركات التكلفة الرئيسية (قد يكون لبعضها توزيعات احتمالية خاصة به ، مثل أسعار سلع المدخلات على سبيل المثال) ، لكنني أترك هذه التعقيدات جانبًا هنا من أجل المساحة والوضوح.
كلما قلت البيانات التي تحتاجها لإبلاغ اختيارك للتوزيع والمعلمات ، زاد الاعتماد على نتائج مسارات عمل العناية الواجبة المتنوعة ، جنبًا إلى جنب مع الخبرة ، لتكوين رأي إجماعي حول نطاقات من السيناريوهات المحتملة. في هذا المثال ، مع توقعات التدفق النقدي ، سيكون هناك مكون شخصي كبير ، مما يعني أن تصور التوزيعات الاحتمالية يصبح مهمًا. هنا ، يمكننا الحصول على تصور أساسي ، يوضح توزيع نمو المبيعات ، مع سطرين قصيرين فقط من التعليمات البرمجية. وبهذه الطريقة يمكننا بسرعة عرض أي توزيع على مقلة العين يعكس بشكل أفضل وجهة نظر الفريق الجماعية.
الآن لدينا جميع اللبنات الأساسية التي نحتاجها لتشغيل المحاكاة ، لكنها ليست بتنسيق مناسب لتشغيل المحاكاة. إليك نفس الكود الذي عملنا معه حتى الآن ولكن تم تجميعها جميعًا في خلية واحدة وإعادة ترتيبها في وظيفة للراحة:
def run_mcs(): # Create probability distributions sales_growth_dist = np.random.normal(loc=0.1, scale=0.01, size=iterations) ebitda_margin_dist = np.random.normal(loc=0.14, scale=0.02, size=iterations) nwc_percent_dist = np.random.normal(loc=0.24, scale=0.01, size=iterations) # Calculate DCF value for each set of random inputs output_distribution = [] for i in range(iterations): for year in range(1, 6): sales[year] = sales[year - 1] * (1 + sales_growth_dist[0]) ebitda = sales * ebitda_margin_dist[i] depreciation = (sales * depr_percent) ebit = ebitda - depreciation nwc = sales * nwc_percent_dist[i] change_in_nwc = nwc.shift(1) - nwc capex = -(sales * capex_percent) tax_payment = -ebit * tax_rate tax_payment = tax_payment.apply(lambda x: min(x, 0)) free_cash_flow = ebit + depreciation + tax_payment + capex + change_in_nwc # DCF valuation terminal_value = (free_cash_flow[-1] * 1.02) / (cost_of_capital - 0.02) free_cash_flow[-1] += terminal_value discount_factors = [(1 / (1 + cost_of_capital)) ** i for i in range (1,6)] dcf_value = sum(free_cash_flow[1:] * discount_factors ) output_distribution.append(dcf_value) return output_distribution
يمكننا الآن تشغيل المحاكاة بالكامل ورسم توزيع المخرجات ، والتي ستكون قيمة التدفق النقدي المخصوم لهذه الشركة في كل من 1000 تكرار ، مع الكود التالي. الأمر %time
ليس كود Python ولكنه اختصار في دفتر ملاحظات يقيس الوقت اللازم لتشغيل شيء ما (يمكنك بدلاً من ذلك استخدام وظيفة Python من المكتبة القياسية). يعتمد ذلك على الكمبيوتر الذي تقوم بتشغيله عليه ، لكن هذا الإصدار يحتاج إلى ثانية أو ثانيتين لتشغيل 1000 تكرار وتصور النتيجة.
%time plt.hist(run_mcs(), bins=20, color='r') plt.show()
2. تنقيح النموذج الأولي
الشك الكامن في إمكانية تبسيط شيء ما هو أغنى مصدر في العالم لمكافأة التحديات. - إدسجر ديكسترا
تشير إعادة البناء إلى عملية إعادة كتابة الكود الحالي لتحسين هيكله دون تغيير وظائفه ، ويمكن أن يكون أحد أكثر عناصر الترميز متعةً ومكافأة. يمكن أن يكون هناك عدة أسباب للقيام بذلك. قد يكون من أجل:
- تنظيم الأجزاء المختلفة بطريقة أكثر منطقية.
- أعد تسمية المتغيرات والوظائف لتوضيح الغرض منها وطرق عملها.
- السماح والاستعداد للميزات المستقبلية.
- قم بتحسين سرعة التنفيذ أو تأثير الذاكرة أو استخدام الموارد الأخرى.
لإظهار الشكل الذي قد تبدو عليه خطوة واحدة في هذه العملية ، قمت بتنظيف النموذج الأولي الذي مررنا به للتو من خلال جمع جميع المتغيرات الأولية في مكان واحد ، بدلاً من التشتت في جميع الأنحاء كما في النموذج الأولي النصي ، وقمت بتحسين سرعة تنفيذه من خلال عملية تسمى التوجيه .
يمكّنك استخدام مصفوفات NumPy من التعبير عن العديد من أنواع مهام معالجة البيانات كتعبيرات مصفوفة موجزة قد تتطلب خلاف ذلك حلقات كتابة. يشار إلى هذه الممارسة المتمثلة في استبدال الحلقات الصريحة بتعبيرات المصفوفة على أنها متجهية. ويس ماكيني
يبدو الآن أنظف وأسهل في الفهم:
# Key inputs from DCF model years = 5 starting_sales = 31.0 capex_percent = depr_percent = 0.032 sales_growth = 0.1 ebitda_margin = 0.14 nwc_percent = 0.24 tax_rate = 0.25 # DCF assumptions r = 0.12 g = 0.02 # For MCS model iterations = 1000 sales_std_dev = 0.01 ebitda_std_dev = 0.02 nwc_std_dev = 0.01
def run_mcs(): # Generate probability distributions sales_growth_dist = np.random.normal(loc=sales_growth, scale=sales_std_dev, size=(years, iterations)) ebitda_margin_dist = np.random.normal(loc=ebitda_margin, scale=ebitda_std_dev, size=(years, iterations)) nwc_percent_dist = np.random.normal(loc=nwc_percent, scale=nwc_std_dev, size=(years, iterations)) # Calculate free cash flow sales_growth_dist += 1 for i in range(1, len(sales_growth_dist)): sales_growth_dist[i] *= sales_growth_dist[i-1] sales = sales_growth_dist * starting_sales ebitda = sales * ebitda_margin_dist ebit = ebitda - (sales * depr_percent) tax = -(ebit * tax_rate) np.clip(tax, a_min=None, a_max=0) nwc = nwc_percent_dist * sales starting_nwc = starting_sales * nwc_percent prev_year_nwc = np.roll(nwc, 1, axis=0) prev_year_nwc[0] = starting_nwc delta_nwc = prev_year_nwc - nwc capex = -(sales * capex_percent) free_cash_flow = ebitda + tax + delta_nwc + capex # Discount cash flows to get DCF value terminal_value = free_cash_flow[-1] * (1 + g) / (r - g) discount_rates = [(1 / (1 + r)) ** i for i in range (1,6)] dcf_value = sum((free_cash_flow.T * discount_rates).T) dcf_value += terminal_value * discount_rates[-1] return dcf_value
الفرق الرئيسي الذي ستلاحظه بين هذا الإصدار والإصدار السابق هو عدم وجود حلقة for i in range(iterations)
. باستخدام عملية مصفوفة NumPy ، يتم تشغيل هذا الإصدار في 18 مللي ثانية مقارنة بـ 1.35 ثانية لإصدار النموذج الأولي - أسرع بحوالي 75x.
%time plt.hist(run_mcs(), bins=20, density=True, color="r") plt.show()
أنا متأكد من أن المزيد من التحسين ممكن ، لأنني جمعت كل من النموذج الأولي والنسخة المكررة في وقت قصير فقط لغرض هذا البرنامج التعليمي.
أخذها إلى أبعد من ذلك
أظهر هذا البرنامج التعليمي بعض الميزات القوية لـ Python ، وإذا كنت ستعمل على تطوير هذا بشكل أكبر ، فإن الفرص لا حصر لها تقريبًا. يمكنك على سبيل المثال:
- كشط أو تنزيل إحصاءات الشركة أو القطاع ذات الصلة من صفحات الويب أو مصادر البيانات الأخرى ، للمساعدة في تحديد اختيارك للافتراضات وتوزيعات الاحتمالات.
- استخدم Python في تطبيقات التمويل الكمي ، مثل خوارزمية التداول الآلي بناءً على عوامل أساسية و / أو اقتصادية كلية.
- قم ببناء قدرات التصدير التي تنشئ مخرجات في جدول بيانات و / أو تنسيق عرض تقديمي ، لاستخدامها كجزء من عملية مراجعة المعاملات الداخلية والموافقة عليها ، أو للعروض التقديمية الخارجية.
لم أتطرق حتى إلى ما يمكنك فعله أيضًا مع مختلف تطبيقات الويب وعلوم البيانات والتعلم الآلي التي ساهمت في نجاح Python.
باختصار: لغة مفيدة لمجموعة الأدوات المالية الخاصة بك
قدم هذا المقال مقدمة عن لغة برمجة بايثون ، وسرد بعض الأسباب التي جعلت من هذه اللغة شائعة جدًا في مجال التمويل وأظهر كيفية بناء نص صغير من لغة بايثون. في برنامج تعليمي خطوة بخطوة ، استعرضت كيف يمكن استخدام Python للنماذج الأولية التكرارية والتحليل المالي التفاعلي ولرمز التطبيق لنماذج التقييم وبرامج التداول الخوارزمية والمزيد.
بالنسبة لي ، في نهاية المطاف ، الميزة القاتلة لتقنية Python هي أنه من الممتع العمل بها! إذا كنت تستمتع بحل المشكلات وبناء الأشياء وجعل سير العمل أكثر كفاءة ، فأنا أشجعك على تجربته. أحب أن أسمع ما فعلته به أو تود أن أفعله به.
الموارد الموصى بها لمتخصصي الشؤون المالية لتعلم لغة بايثون
- كتب أورايلي. يمكنني أن أوصي بشكل خاص بما يلي:
- Python for Finance by Yves Hilpisch
- Learning Python by Mark Lutz
- Fluent Python by Luciano Ramalho
- The Python Quants
- PyCon talks on YouTube
- Udemy