Python và Tài chính - Tăng sức mạnh cho Bảng tính của bạn

Tóm tắt Điều hành

Tại sao Python là ngôn ngữ lập trình tuyệt vời cho các chuyên gia tài chính học?
  • Python là ngôn ngữ lập trình cấp cao, có nghĩa là nó trừu tượng hóa và xử lý nhiều khía cạnh kỹ thuật của lập trình, chẳng hạn như quản lý bộ nhớ, phải được xử lý rõ ràng bằng các ngôn ngữ khác. Điều này làm cho Python dễ sử dụng đối với những người không có nền tảng kỹ thuật.
  • Bởi vì ngôn ngữ được thiết kế với mục đích dễ đọc và dễ sử dụng, nó là một trong những ngôn ngữ dễ học nhất. Mã Python ngắn gọn và gần với tiếng Anh thuần túy.
  • Python lý tưởng cho việc tạo mẫu và phát triển nhanh chóng, lặp đi lặp lại. Các công cụ thông dịch tương tác của nó cung cấp môi trường nơi bạn có thể viết và thực thi từng dòng mã một cách riêng biệt và xem kết quả ngay lập tức.
  • Đồng thời, Python mạnh mẽ và hiệu quả, khiến nó trở thành một lựa chọn khả thi cho các hệ thống cốt lõi và các ứng dụng lớn hơn.
  • Ngoài thư viện tiêu chuẩn lớn gồm các công cụ hữu ích, Python còn có các thư viện của bên thứ ba tuyệt vời để phân tích tài chính và tính toán, chẳng hạn như thư viện Pandas và NumPy được sử dụng trong hướng dẫn này.
Một số trường hợp sử dụng để triển khai Python và tài chính cùng nhau là gì?
  • Các tập lệnh Python có thể được sử dụng để tự động hóa các tác vụ và quy trình làm việc lặp đi lặp lại, tiết kiệm thời gian và giảm nguy cơ mắc lỗi thủ công.
  • Tập lệnh cho phép người dùng dễ dàng lấy dữ liệu từ bảng tính, cơ sở dữ liệu và API, hoặc thậm chí thu thập dữ liệu web, sau đó có thể được xử lý và phân tích bằng các công cụ thống kê và phân tích mạnh mẽ.
  • Các plugin khác nhau dành cho Excel cho phép người dùng tạo các liên kết hai chiều trong thời gian thực giữa bảng tính và mã Python của bạn.
  • Python cho phép các kiểu phân tích mới, chẳng hạn như mô phỏng Monte Carlo, không có sẵn trong bảng tính tiêu chuẩn.
  • Giao dịch theo thuật toán không còn là lĩnh vực độc quyền của các quỹ đầu cơ và ngân hàng đầu tư lớn. Với Python, bạn có thể phát triển, kiểm tra lại và triển khai các chiến lược giao dịch của riêng mình trong thời gian ngắn với chi phí thấp.

Đối với những ngành nghề lâu nay phụ thuộc vào việc tìm kiếm thông qua các bảng tính, Python đặc biệt có giá trị. Citigroup, một ngân hàng của Mỹ, đã giới thiệu một khóa học về Python cho các nhà phân tích học viên của mình. - Nhà kinh tế học

Các chuyên gia tài chính từ lâu đã có quyền truy cập vào VBA (Visual Basic for Applications) trong Excel để xây dựng chức năng tùy chỉnh và tự động hóa quy trình làm việc. Với sự xuất hiện của Google Trang tính trong những năm gần đây như một đối thủ nặng ký trong không gian bảng tính, Google Apps Script hiện cung cấp thêm một sự lựa chọn.

Tuy nhiên, tôi muốn thu hút sự chú ý đến tùy chọn thứ ba, ngôn ngữ lập trình Python, đã trở nên rất phổ biến trong một số lĩnh vực.

Trong bài viết này, tôi sẽ cung cấp một số ví dụ về những gì bạn có thể đạt được với Python, bắt đầu với tổng quan về ngôn ngữ này và tại sao nó lại trở nên phổ biến trong nhiều lĩnh vực như vậy, bao gồm phát triển web, học máy, tài chính, khoa học và giáo dục, chỉ là một vài cái tên. Sau đó, nửa sau sẽ bao gồm hướng dẫn từng bước.

Mục đích của tôi khi viết bài này là để giúp bạn quyết định xem liệu Python có đủ hấp dẫn để bạn cân nhắc thêm nó vào hộp công cụ tài chính của mình hay không. Nếu bạn thực hiện bước nhảy vọt, có rất nhiều ứng dụng, khóa học, video, bài báo, sách và bài đăng trên blog để học ngôn ngữ. Ở cuối phần, tôi đã liệt kê một số tài nguyên đã giúp tôi trong suốt quá trình.

Trường hợp sử dụng:Ví dụ về những gì tôi đã sử dụng Python cho

Lời giới thiệu của tôi về lập trình là học BASIC trên Oric 1 vào giữa những năm 1980. Hồi đó BASIC là ngôn ngữ phổ biến nhất dành cho người mới bắt đầu. Các ngôn ngữ khác mà tôi đã sử dụng vào cuối những năm 80 cho đến giữa những năm 90 là Pascal và C, nhưng tôi chưa bao giờ sử dụng chúng trong bất kỳ năng lực chuyên môn nào và tôi không mong đợi sẽ cần hoặc sử dụng các kỹ năng lập trình. Theo hiểu biết của tôi vào thời điểm cuối những năm 90, tài chính và lập trình là hai lĩnh vực rất khác nhau, khi tôi chọn con đường khởi nghiệp trong lĩnh vực tài chính.

Nhanh chóng chuyển tiếp sang năm 2012, và tôi đã tìm kiếm lập trình trở lại như một sở thích, vì vậy tôi bắt đầu nghiên cứu các ngôn ngữ có sẵn vào thời điểm đó. Hóa ra khá nhiều điều đã xảy ra, và khi tôi bắt gặp Python, tôi đã bị cuốn hút, vì nhiều lý do mà tôi sẽ trình bày trong phần tiếp theo. Kể từ đó, tôi đã sử dụng Python cho một loạt các tác vụ, từ các tập lệnh nhỏ đến các dự án lớn hơn, cả cá nhân và chuyên nghiệp. Nhiều, nhưng không phải tất cả, có liên quan đến bảng tính, bàn làm việc của nhiều chuyên gia tài chính.

Dưới đây là một vài ví dụ về cách bảng tính và Python có thể kết hợp với nhau tốt như thế nào:

1. Theo dõi hàng trăm hoạt động theo thời gian trong thiết lập PMO tích hợp M&A

Tôi làm việc với tất cả các khía cạnh của giao dịch M&A, không chỉ là thực hiện mà còn cả tích hợp. Trong một trường hợp gần đây, nhóm PMO đã quyết định phương pháp quản lý dự án và chương trình kết hợp, sử dụng lập kế hoạch thác nước và biểu đồ Gantt cho các kế hoạch cấp cao cho từng trong số mười hai dòng công việc tích hợp, ngoài ra còn có bảng Kanban để theo dõi hàng trăm hoạt động đang diễn ra. vào bất kỳ thời điểm nào, trong kế hoạch 100 ngày đầu tiên và hơn thế nữa. Công cụ Kanban đã được chọn, MeisterTask, có một số tính năng thống kê và báo cáo, nhưng nhu cầu của chúng tôi vượt ra ngoài điều đó về phân tích và trình bày, đòi hỏi một giải pháp tùy chỉnh. Đây là quy trình làm việc mà tôi đã tự động hóa bằng Python:

  1. Lưu trạng thái của cả bảng hàng tuần dưới dạng tệp CSV.
  2. Đọc tất cả các tệp CSV lịch sử trong một Pandas DataFrame.
  3. Sắp xếp, lọc, nhóm và xử lý dữ liệu thành các định dạng đã thống nhất về cách chúng tôi muốn theo dõi tiến độ (theo trạng thái hoạt động, luồng công việc, v.v.).
  4. Ghi kết quả đầu ra vào tệp Excel với dữ liệu từ mỗi bản phân tích trong trang tính của chính nó, được định dạng theo cách để có thể sao chép và dán một cách đơn giản vào biểu đồ tế bào suy nghĩ.
  5. Tạo bảng và biểu đồ cho gói báo cáo cho cuộc họp ban chỉ đạo hàng tháng.

Việc phát triển kịch bản yêu cầu một khoản đầu tư trả trước trong vài giờ, nhưng hiện tại, việc cập nhật gói báo cáo cho các cuộc họp của ban chỉ đạo hoặc phân tích đột xuất chỉ mất vài phút. Theo nghĩa đen, khoảng 30 giây để chuyển đến đúng thư mục và chạy tập lệnh bằng lệnh một dòng, sau đó vài phút để sao chép-dán đầu ra vào trang trình bày. Với khoảng 500 hoạt động (thẻ) trên mười hai dòng công việc đã được thực thi khoảng một tháng, theo dõi hàng tuần về cách chúng di chuyển, trong dòng thời gian chương trình hai năm, bạn nhanh chóng thấy mình đang xử lý hàng nghìn và cuối cùng là hàng chục nghìn điểm dữ liệu trên hàng chục trong số các tệp. Nếu không có tự động hóa, chúng ta đang nói về một số nhiệm vụ rất tẻ nhạt ở đây.

Đánh đổi “giá trị thời gian của tiền bạc” giữa việc chỉ bắt tay vào làm hay tăng thêm khối lượng công việc ban đầu bằng cách thiết lập tự động hóa là một chủ đề phổ biến trong tài chính. Tôi đã đưa ra quyết định tương tự với bước đầu tiên của quy trình này, bằng cách xuất dữ liệu dưới dạng tệp CSV. MeisterTask, giống như nhiều ứng dụng web hiện đại, có một API, có thể được kết nối với ứng dụng Python của bạn, nhưng thời gian dành cho việc thiết lập nó sẽ vượt xa thời gian tiết kiệm cho trường hợp sử dụng của chúng tôi ở đây.

Vì vậy, như bạn thấy, đôi khi giải pháp tối ưu là tự động hóa các bước nhất định của quy trình làm việc và giữ các bước khác theo cách thủ công.

2. Phân tích thống kê giá nhà bằng cách sử dụng Web Scraping, API Google Maps và Excel

Một ví dụ khác là một cái gì đó tôi đã làm vì sở thích cá nhân nhưng tôi muốn làm nổi bật nó vì nó chứa một số yếu tố thú vị khác của tiện ích Python:

  1. Thu thập dữ liệu về danh sách bất động sản, bao gồm địa chỉ, kích thước, số lượng phòng, giá chào bán và các đặc điểm khác, cho một khu vực nhất định; tổng cộng vài trăm đến có lẽ là một nghìn dòng.
  2. Lưu vào cấu trúc dữ liệu Python.
  3. Kết nối với API Google Maps và đối với mỗi danh sách, truy xuất khoảng cách giữa nơi nghỉ và các địa danh chính như biển, trung tâm thành phố, ga xe lửa gần nhất, sân bay gần nhất, v.v.
  4. Xuất dữ liệu sang tệp Excel.
  5. Sử dụng chức năng Excel tiêu chuẩn để chạy hồi quy, tính toán thống kê và tạo biểu đồ trên các chỉ số tiêu chuẩn như giá mỗi mét vuông và khoảng cách đến các mốc.

Kết quả ở đây có thể được kết hợp với trọng lượng cá nhân của riêng bạn về sở thích và giới hạn tài chính khi tìm kiếm bất động sản.

Đây chỉ là hai ví dụ, tập trung vào việc tự động hóa công việc liên quan đến bảng tính và thêm các tính năng, nhưng cơ hội với Python là gần như vô tận. Trong phần tiếp theo, tôi sẽ phác thảo lý do tại sao nó trở nên phổ biến như vậy, trước khi chuyển sang hướng dẫn mô phỏng Monte Carlo từng bước bằng Python.

Tại sao Python là lựa chọn tuyệt vời cho các chuyên gia tài chính

Ngôn ngữ lập trình Python đã xuất hiện từ năm 1990, nhưng phải đến những năm gần đây, sự phổ biến của nó mới bùng nổ.

Có một số lý do giải thích cho điều này, chúng ta hãy lần lượt xem xét từng lý do.

1. Python là một ngôn ngữ lập trình cấp cao

Ngôn ngữ lập trình cấp cao là ngôn ngữ trừu tượng hóa nhiều chi tiết về hoạt động bên trong của máy tính. Một ví dụ điển hình là quản lý bộ nhớ. Các ngôn ngữ lập trình cấp thấp hơn yêu cầu sự hiểu biết chi tiết về sự phức tạp của cách bố trí, cấp phát và giải phóng bộ nhớ của máy tính, bên cạnh thời gian sử dụng và các dòng mã cần thiết để xử lý các tác vụ. Python tóm tắt và tự động xử lý nhiều chi tiết này, giúp bạn tập trung vào những gì bạn muốn hoàn thành.

2. Thật ngắn gọn

Bởi vì Python là một ngôn ngữ lập trình cấp cao, mã ngắn gọn hơn và gần như hoàn toàn tập trung vào logic nghiệp vụ của những gì bạn muốn đạt được, thay vì các chi tiết triển khai kỹ thuật. Các lựa chọn thiết kế ngôn ngữ góp phần vào điều này:ví dụ, Python không yêu cầu sử dụng dấu ngoặc nhọn hoặc dấu chấm phẩy để mô tả các hàm, vòng lặp và dòng theo cách mà nhiều ngôn ngữ khác làm, điều này làm cho nó ngắn gọn hơn và như một số lập luận, cải thiện dễ đọc.

3. Dễ học và dễ hiểu

Một quan sát đã ảnh hưởng đến các lựa chọn thiết kế ngôn ngữ trong Python là các chương trình được đọc thường xuyên hơn chúng được viết. Python vượt trội ở đây vì mã của nó trông rất gần với tiếng Anh thuần túy, đặc biệt nếu bạn đặt tên cho các thành phần khác nhau của tập lệnh hoặc chương trình của mình theo cách hợp lý.

4. Thích hợp cho phát triển nhanh, lặp đi lặp lại

Thử và sai được chứng ngộ vượt trội hơn việc lập kế hoạch của những trí tuệ hoàn mỹ. - David Kelley

Python lý tưởng cho việc tạo mẫu và phát triển nhanh chóng, lặp đi lặp lại (và, vâng, thử-và-sai) vì các công cụ thông dịch tương tác như Python shell, IPython và sổ ghi chép Jupyter nằm ở phía trước và trung tâm trong chuỗi công cụ Python. Trong các môi trường tương tác này, bạn có thể viết và thực thi từng dòng mã một cách riêng biệt và xem kết quả (hoặc một thông báo lỗi hữu ích) ngay lập tức. Các ngôn ngữ khác cũng có điều này, nhưng trong hầu hết các trường hợp, không giống với Python.

5. Có thể được sử dụng cho cả việc tạo mẫu và mã sản xuất

Ngoài khả năng tuyệt vời cho việc tạo mẫu, Python cũng là một ngôn ngữ tuyệt vời và mạnh mẽ cho các ứng dụng sản xuất lớn. Một số công ty phần mềm lớn nhất trên thế giới sử dụng rất nhiều Python trong nhiều ứng dụng và trường hợp sử dụng khác nhau.

6. Đi kèm với “Pin kèm theo:” Thư viện chuẩn Python

Mọi thứ cần thiết cho các hoạt động cơ bản đều được tích hợp ngay trong ngôn ngữ này, nhưng ngoài ra, thư viện chuẩn Python có các công cụ để làm việc với tệp, phương tiện, mạng, thông tin ngày và giờ, v.v. Điều này cho phép bạn hoàn thành nhiều nhiệm vụ khác nhau mà không cần phải tìm kiếm các gói của bên thứ ba.

7. Thư viện bên thứ ba tuyệt vời để phân tích tài chính

Đối với các chuyên gia tài chính, Pandas với DataFrame Sê-ri các đối tượng và Numpy với ndarray của nó là các bài tập về phân tích tài chính với Python. Kết hợp với matplotlib và các thư viện trực quan khác, bạn có các công cụ tuyệt vời để hỗ trợ năng suất.

8. Python miễn phí!

Python được phát triển theo giấy phép nguồn mở, nó cũng miễn phí để sử dụng cho mục đích thương mại.

Hướng dẫn từng bước về việc sử dụng Python và tài chính cùng nhau

Sau đây là hướng dẫn từng bước chỉ ra cách tạo phiên bản đơn giản của mô phỏng Monte Carlo được mô tả trong bài đăng blog trước của tôi, nhưng sử dụng Python thay vì plugin @RISK cho Excel.

Phương pháp Monte Carlo dựa trên lấy mẫu ngẫu nhiên để thu được kết quả số. Một ứng dụng như vậy là vẽ các mẫu ngẫu nhiên từ phân bố xác suất đại diện cho các trạng thái tiềm ẩn không chắc chắn trong tương lai của thế giới nơi các biến hoặc giả định có thể đảm nhận một loạt giá trị.

Sẽ rất hữu ích nếu thực hiện mô phỏng Monte Carlo trên mô hình định giá DCF đơn giản thay vì các ví dụ phổ biến hơn mà bạn thấy hiển thị giá trị quyền chọn hoặc các công cụ phái sinh khác, vì đối với điều này, chúng tôi không cần bất kỳ phép toán nào ngoài những điều cơ bản về tính toán báo cáo tài chính và chiết khấu dòng tiền, cho phép chúng tôi tập trung vào các khái niệm và công cụ Python. Xin lưu ý rằng mô hình hướng dẫn cơ bản này nhằm minh họa các khái niệm chính và không hữu ích cho bất kỳ mục đích thực tế nào. Tôi cũng sẽ không đề cập đến bất kỳ khía cạnh học thuật nào của mô phỏng Monte Carlo.

Hướng dẫn giả định rằng bạn đã quen thuộc với các khối xây dựng cơ bản của lập trình, chẳng hạn như các biến và hàm. Nếu không, có thể hữu ích nếu bạn dành 10 phút để kiểm tra các khái niệm chính trong phần giới thiệu này.

Điểm khởi đầu và kết quả mong muốn

Tôi bắt đầu với cùng một mô hình định giá DCF rất đơn giản được sử dụng trong hướng dẫn mô phỏng Monte Carlo. Nó có một số chi tiết đơn hàng chính từ ba báo cáo tài chính và ba ô đầu vào được đánh dấu, trong phiên bản Excel có các ước tính điểm mà bây giờ chúng tôi muốn thay thế bằng phân phối xác suất để bắt đầu khám phá các phạm vi kết quả tiềm năng.

Phương pháp tiếp cận hai bước để phát triển kịch bản nhỏ

Làm cho nó hoạt động, làm cho nó đúng, làm cho nó nhanh chóng - Kent Beck

Mục đích của hướng dẫn này là cung cấp cho các chuyên gia tài chính mới làm quen với Python không chỉ giới thiệu về một chương trình hữu ích có thể trông như thế nào, mà còn giới thiệu về quy trình lặp đi lặp lại mà bạn có thể sử dụng để phát triển nó. Do đó, nó có hai phần:

  1. Đầu tiên, tôi phát triển một nguyên mẫu hoạt động bằng cách sử dụng một cách tiếp cận đơn giản mà tôi nghĩ là dễ làm theo và không hoàn toàn khác với quy trình mà người ta có thể sử dụng để bắt đầu dự án này nếu bạn bắt đầu lại từ đầu.
  2. Sau đó, sau khi đã phát triển nguyên mẫu hoạt động, tôi thực hiện quá trình tái cấu trúc - thay đổi cấu trúc mã mà không thay đổi chức năng của nó. Bạn có thể muốn tiếp tục phần đó - đây là một giải pháp thanh lịch hơn so với giải pháp đầu tiên và như một phần thưởng, nó nhanh hơn khoảng 75 lần về thời gian thực hiện.

1. Phát triển một nguyên mẫu làm việc

Thiết lập Máy tính xách tay Jupyter

Sổ ghi chép Jupyter là một công cụ tuyệt vời để làm việc với Python một cách tương tác. Nó là một trình thông dịch Python tương tác với các ô có thể chứa mã, văn bản Markdown, hình ảnh hoặc dữ liệu khác. Đối với hướng dẫn này, tôi đã sử dụng Nền tảng lượng tử Python, nhưng tôi cũng có thể giới thiệu Colaboratory của Google, miễn phí và chạy trên đám mây. Khi đó, chỉ cần chọn “Máy tính xách tay Python 3 mới” trong menu “Tệp” và bạn đã sẵn sàng.

Sau khi thực hiện xong, bước tiếp theo là nhập các gói của bên thứ ba mà chúng tôi cần để thao tác và trực quan hóa dữ liệu, đồng thời cho chương trình biết rằng chúng tôi muốn xem biểu đồ nội tuyến trong sổ ghi chép của mình, thay vì trong các cửa sổ riêng biệt:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

Một lưu ý trước khi chúng ta bắt đầu đặt tên cho các biến đầu tiên của mình. Như tôi đã nhấn mạnh, khả năng đọc là một trong những điểm mạnh của Python. Ngôn ngữ thiết kế đi một chặng đường dài để hỗ trợ điều đó, nhưng mọi người viết mã có trách nhiệm làm cho nó dễ đọc và dễ hiểu, không chỉ cho người khác mà còn cho chính họ. Như Luật của Eagleson đã tuyên bố, “Bất kỳ mã nào của riêng bạn mà bạn chưa xem xét trong sáu tháng trở lên cũng có thể đã được viết bởi người khác.”

Một nguyên tắc chung là đặt tên cho các thành phần của chương trình của bạn theo cách mà bạn giảm thiểu nhu cầu nhận xét riêng biệt giải thích những gì chương trình của bạn thực hiện.

Với ý nghĩ đó, hãy tiếp tục.

Tạo Báo cáo tài chính

Có nhiều cách mà chúng ta có thể làm việc với dữ liệu bảng tính hiện có bằng Python. Ví dụ:chúng tôi có thể đọc một trang tính vào Pandas DataFrame bằng một dòng mã bằng cách sử dụng read_excel yêu cầu. Nếu bạn muốn tích hợp chặt chẽ hơn và liên kết thời gian thực giữa bảng tính và mã Python của mình, thì có cả tùy chọn thương mại và miễn phí để cung cấp chức năng đó.

Vì mô hình ở đây rất đơn giản và để tập trung vào các khái niệm Python, chúng tôi sẽ tạo lại nó từ đầu trong tập lệnh của mình. Ở cuối phần đầu tiên, tôi sẽ chỉ cho bạn cách xuất những gì chúng tôi đã tạo sang bảng tính.

Bước đầu tiên hướng tới việc tạo bản trình bày báo cáo tài chính bằng Python, chúng ta sẽ cần một cấu trúc dữ liệu phù hợp. Có rất nhiều thứ để bạn lựa chọn, một số được tích hợp sẵn trong Python, một số khác từ các thư viện khác nhau hoặc chúng ta có thể tạo của riêng mình. Bây giờ, hãy sử dụng Chuỗi từ thư viện Pandas để xem chức năng của nó:

years = ['2018A', '2019B', '2020P', '2021P', '2022P', '2023P']
sales = pd.Series(index=years)
sales['2018A'] = 31.0  
sales

Đầu vào này và đầu ra tương ứng của nó được hiển thị bên dưới:

Với ba dòng đầu tiên, chúng tôi đã tạo cấu trúc dữ liệu với chỉ mục bao gồm các năm (mỗi dòng được đánh dấu để hiển thị là Thực tế, Ngân sách hay Dự kiến), giá trị khởi điểm (tính bằng triệu euro, như trong mô hình DCF ban đầu) và ô trống (NaN, “Không phải số”) cho các phép chiếu. Dòng thứ tư in ra một biểu diễn của dữ liệu - nói chung, việc nhập tên của một biến hoặc các đối tượng khác trong trình thông dịch tương tác thường sẽ cung cấp cho bạn một biểu diễn hợp lý về nó.

Tiếp theo, chúng tôi khai báo một biến để đại diện cho mức tăng trưởng doanh số hàng năm dự kiến. Ở giai đoạn này, nó là một ước tính điểm, con số tương tự như trong mô hình DCF ban đầu của chúng tôi. Trước tiên, chúng tôi muốn sử dụng các đầu vào giống nhau đó và xác nhận rằng phiên bản Python của chúng tôi hoạt động tương tự và cho kết quả tương tự như phiên bản Excel, trước khi xem xét việc thay thế các ước tính điểm bằng phân phối xác suất. Sử dụng biến này, chúng tôi tạo một vòng lặp tính toán doanh số bán hàng trong từng năm của các dự báo dựa trên năm trước và tốc độ tăng trưởng:

growth_rate = 0.1
for year in range(1, 6):
    sales[year] = sales[year - 1] * (1 + growth_rate)
    
sales

Bây giờ chúng tôi có doanh số bán hàng dự kiến, thay vì NaN:

Sử dụng phương pháp tương tự, chúng tôi tiếp tục thông qua các báo cáo tài chính, khai báo các biến khi chúng tôi cần và thực hiện các tính toán cần thiết để cuối cùng đạt được dòng tiền tự do. Khi chúng tôi đến đó, chúng tôi có thể kiểm tra xem những gì chúng tôi có có tương ứng với những gì phiên bản Excel của mô hình DCF nói hay không.

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

Điều này mang lại cho chúng tôi dòng tiền tự do:

Một dòng ở trên có lẽ cần nhận xét ở giai đoạn này là tax_payment thứ hai tài liệu tham khảo. Ở đây, chúng tôi áp dụng một chức năng nhỏ để đảm bảo rằng trong các tình huống mà lợi nhuận trước thuế trở nên âm, khi đó chúng tôi sẽ không có khoản thanh toán thuế dương. Điều này cho thấy bạn có thể áp dụng các chức năng tùy chỉnh cho tất cả các ô trong Chuỗi Pandas hoặc DataFrame một cách hiệu quả như thế nào. Tất nhiên, chức năng thực tế được áp dụng là một sự đơn giản hóa. Một mô hình thực tế hơn cho một bài tập định giá lớn hơn sẽ có một mô hình thuế riêng để tính toán các khoản thuế tiền mặt thực tế phải trả dựa trên một số yếu tố cụ thể của công ty.

Thực hiện Định giá DCF

Sau khi đạt được dòng tiền dự kiến, bây giờ chúng ta có thể tính toán một giá trị đầu cuối đơn giản và chiết khấu tất cả các dòng tiền trở lại hiện tại để có được kết quả DCF. Đoạn mã sau giới thiệu tính năng lập chỉ mục và phân loại, cho phép chúng tôi truy cập một hoặc nhiều phần tử trong cấu trúc dữ liệu, chẳng hạn như đối tượng Chuỗi Pandas.

Chúng tôi truy cập các phần tử bằng cách viết dấu ngoặc vuông ngay sau tên của cấu trúc. Lập chỉ mục đơn giản truy cập các phần tử theo vị trí của chúng, bắt đầu bằng 0, nghĩa là free_cash_flow[1] sẽ cung cấp cho chúng tôi yếu tố thứ hai. [-1] là cách viết tắt để truy cập phần tử cuối cùng (dòng tiền của năm trước được sử dụng để tính giá trị đầu cuối) và việc sử dụng dấu hai chấm cho chúng ta một phần, có nghĩa là [1:] cung cấp cho chúng tôi tất cả các yếu tố ngoại trừ yếu tố đầu tiên, vì chúng tôi không muốn đưa vào năm lịch sử 2018A trong định giá DCF của chúng tôi.

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

Điều đó kết thúc phần đầu tiên của nguyên mẫu của chúng tôi - bây giờ chúng tôi có một mô hình DCF đang hoạt động, mặc dù là một mô hình rất thô sơ, bằng Python.

Xuất dữ liệu

Trước khi chuyển sang mô phỏng Monte Carlo thực tế, đây có thể là thời điểm tốt để đề cập đến khả năng xuất có sẵn trong gói Pandas. Nếu bạn có đối tượng Pandas DataFrame, bạn có thể ghi đối tượng đó vào tệp Excel bằng một dòng bằng cách sử dụng to_excel phương pháp. Cũng có chức năng tương tự để xuất sang hơn một chục định dạng và điểm đến khác.

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

Tạo Phân phối Xác suất cho Mô phỏng Monte Carlo của chúng tôi

Bây giờ chúng tôi đã sẵn sàng để giải quyết thách thức tiếp theo:thay thế một số đầu vào ước tính điểm bằng phân phối xác suất. Mặc dù các bước cho đến thời điểm này có vẻ hơi rườm rà so với việc xây dựng cùng một mô hình trong Excel, nhưng vài dòng tiếp theo sẽ cho bạn cái nhìn sơ lược về sức mạnh của Python.

Bước đầu tiên của chúng tôi là quyết định số lần lặp lại mà chúng tôi muốn chạy trong mô phỏng. Sử dụng 1.000 làm điểm bắt đầu tạo ra sự cân bằng giữa việc nhận đủ điểm dữ liệu để có được các biểu đồ đầu ra hợp lý, so với việc kết thúc mô phỏng trong một khung thời gian hợp lý. Tiếp theo, chúng tôi tạo các bản phân phối thực tế. Để đơn giản, tôi đã tạo ba bản phân phối bình thường ở đây, nhưng thư viện NumPy có một số lượng lớn các bản phân phối để lựa chọn và cũng có những nơi khác để xem, bao gồm cả thư viện chuẩn Python. Sau khi quyết định sử dụng phân phối nào, chúng ta cần chỉ định các tham số cần thiết để mô tả hình dạng của chúng, chẳng hạn như trung bình và độ lệch chuẩn, và số lượng kết quả mong muốn.

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()

Ở đây, bạn có thể tranh luận rằng EBITDA không nên là một biến ngẫu nhiên riêng biệt độc lập với doanh số bán hàng mà thay vào đó tương quan với doanh số bán hàng ở một mức độ nào đó. Tôi đồng ý với điều này và nói thêm rằng nó phải được thúc đẩy bởi sự hiểu biết vững chắc về động lực của cấu trúc chi phí (chi phí biến đổi, bán biến đổi và cố định) và các yếu tố thúc đẩy chi phí chính (một số trong số đó có thể có phân phối xác suất riêng, chẳng hạn như giá hàng hóa đầu vào chẳng hạn), nhưng tôi để những phức tạp đó sang một bên ở đây vì lợi ích của không gian và sự rõ ràng.

Bạn càng có ít dữ liệu để cung cấp thông tin cho lựa chọn phân phối và tham số của mình, bạn càng phải dựa vào kết quả của các dòng công việc thẩm định khác nhau, kết hợp với kinh nghiệm, để hình thành quan điểm đồng thuận về phạm vi các tình huống có thể xảy ra. Trong ví dụ này, với dự báo dòng tiền, sẽ có một thành phần chủ quan lớn, có nghĩa là việc hình dung các phân phối xác suất trở nên quan trọng. Ở đây, chúng ta có thể hình dung cơ bản, cho thấy sự phân bổ tăng trưởng doanh số, chỉ với hai dòng mã ngắn. Bằng cách này, chúng tôi có thể nhanh chóng xem bất kỳ phân phối nào cho nhãn cầu phản ánh tốt nhất quan điểm chung của nhóm.

Bây giờ chúng ta có tất cả các khối xây dựng mà chúng ta cần để chạy mô phỏng, nhưng chúng không ở định dạng thuận tiện cho việc chạy mô phỏng. Đây là cùng một đoạn mã mà chúng tôi đã làm việc cho đến nay nhưng tất cả được tập hợp trong một ô và được sắp xếp lại thành một hàm để thuận tiện:

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

Bây giờ chúng ta có thể chạy toàn bộ mô phỏng và vẽ biểu đồ phân phối đầu ra, sẽ là giá trị dòng tiền chiết khấu của công ty này trong mỗi 1.000 lần lặp, với đoạn mã sau. %time lệnh không phải là mã Python mà là một tốc ký sổ tay đo thời gian để chạy một thứ gì đó (thay vào đó bạn có thể sử dụng hàm Python từ thư viện chuẩn). Nó phụ thuộc vào máy tính bạn chạy, nhưng phiên bản này cần 1-2 giây để chạy 1.000 lần lặp và hình dung kết quả.

%time plt.hist(run_mcs(), bins=20, color='r')
plt.show()

2. Tinh chỉnh Nguyên mẫu

Sự nghi ngờ tiềm ẩn rằng một cái gì đó có thể được đơn giản hóa là nguồn thách thức bổ ích phong phú nhất trên thế giới. - Edsger Dijkstra

Tái cấu trúc đề cập đến quá trình viết lại mã hiện có để cải thiện cấu trúc mà không thay đổi chức năng của nó và nó có thể là một trong những yếu tố thú vị và bổ ích nhất của mã hóa. Có thể có một số lý do để làm điều này. Nó có thể là:

  1. Sắp xếp các phần khác nhau theo cách hợp lý hơn.
  2. Đổi tên các biến và hàm để làm rõ ràng hơn mục đích và hoạt động của chúng.
  3. Cho phép và chuẩn bị cho các tính năng trong tương lai.
  4. Cải thiện tốc độ thực thi, dung lượng bộ nhớ hoặc việc sử dụng tài nguyên khác.

Để cho thấy một bước trong quy trình đó có thể trông như thế nào, tôi đã dọn dẹp nguyên mẫu mà chúng tôi vừa xem qua bằng cách thu thập tất cả các biến ban đầu ở một nơi, thay vì nằm rải rác như trong tập lệnh nguyên mẫu và tối ưu hóa tốc độ thực thi của nó thông qua một quy trình được gọi là vectơ hóa .

Sử dụng mảng NumPy cho phép bạn thể hiện nhiều loại tác vụ xử lý dữ liệu dưới dạng các biểu thức mảng ngắn gọn có thể yêu cầu viết các vòng lặp. Thực hành thay thế các vòng lặp rõ ràng bằng các biểu thức mảng thường được gọi là vectơ hóa. Wes McKinney

Giờ đây, nó trông gọn gàng và dễ hiểu hơn:

# 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

The main difference you will notice between this version and the previous one is the absence of the for i in range(iterations) loop. Using NumPy’s array operation, this version runs in 18 milliseconds compared to the 1.35 seconds for the prototype version - roughly 75x faster.

%time plt.hist(run_mcs(), bins=20, density=True, color="r")
plt.show()

I’m sure that further optimization is possible, since I put together both the prototype and refined version in a short time solely for the purpose of this tutorial.

Taking it Further

This tutorial showed some of the powerful features of Python, and if you were to develop this further the opportunities are almost endless. You could for example:

  • Scrape or download relevant company or sector statistics from web pages or other data sources, to help inform your choice of assumptions and probability distributions.
  • Use Python in quantitative finance applications, such as in an automated trading algorithm based on fundamental and/or macroeconomic factors.
  • Build exporting capabilities that generate output in a spreadsheet and/or presentation format, to be used as part of your internal transaction review and approval process, or for external presentations.

I haven’t even touched upon what you could also do with the various web, data science, and machine learning applications that have contributed to Python’s success.

In Summary:A Useful Language for Your Financial Toolbox

This article gave an introduction to the Python programming language, listed some of the reasons why it has become so popular in finance and showed how to build a small Python script. In a step-by-step tutorial, I walked through how Python can be used for iterative prototyping, interactive financial analysis, and for application code for valuation models, algorithmic trading programs and more.

For me, at the end of the day, the killer feature of Python technology is that it is simply fun to work with! If you enjoy problem-solving, building things and making workflows more efficient, then I encourage you to try it out. I would love to hear what you have done with it or would like to do with it.

  • O’Reilly books. I can especially recommend:
    • Python for Finance by Yves Hilpisch
    • Learning Python by Mark Lutz
    • Fluent Python by Luciano Ramalho
  • The Python Quants
  • PyCon talks on YouTube
  • Udemy

Tài chính doanh nghiệp
  1. Kế toán
  2. Chiến lược kinh doanh
  3. Việc kinh doanh
  4. Quản trị quan hệ khách hàng
  5. tài chính
  6. Quản lý chứng khoán
  7. Tài chính cá nhân
  8. đầu tư
  9. Tài chính doanh nghiệp
  10. ngân sách
  11. Tiết kiệm
  12. bảo hiểm
  13. món nợ
  14. về hưu