Python 和金融——為您的電子表格提供動力

已發表: 2022-03-11

執行摘要

為什麼 Python 是金融專業人士學習的絕佳編程語言?
  • Python 是一種高級編程語言,這意味著它抽象並處理了許多必須在其他語言中明確處理的編程技術方面,例如內存管理。 這使得沒有技術背景的人可以輕鬆使用 Python。
  • 因為該語言的設計考慮到了可讀性和易用性,所以它是最容易學習的語言之一。 Python 代碼簡潔,接近於簡單的英語。
  • Python 是原型設計和快速迭代開發的理想選擇。 它的交互式解釋器工具提供了環境,您可以在其中單獨編寫和執行每一行代碼並立即查看結果。
  • 同時,Python 健壯且高性能,使其成為核心系統和大型應用程序的可行選擇。
  • 除了包含有用工具的大型標準庫外,Python 還擁有出色的第三方財務分析和計算庫,例如本教程中使用的 Pandas 和 NumPy 庫。
有哪些可以同時實現 Python 和金融的用例?
  • Python 腳本可用於自動化重複性任務和工作流程,從而節省時間並降低人為錯誤的風險。
  • 腳本允許用戶輕鬆地從電子表格、數據庫和 API 中提取數據,甚至可以抓取 Web 數據,然後可以使用強大的統計和分析工具對其進行處理和分析。
  • Excel 的各種插件允許用戶在電子表格和 Python 代碼之間創建實時雙向鏈接。
  • Python 支持新類型的分析,例如蒙特卡洛模擬,這些在標準電子表格中並不容易獲得。
  • 算法交易不再是對沖基金和大型投資銀行的專屬領域。 使用 Python,您可以在短時間內以低成本開發、回測和部署自己的交易策略。

對於長期依賴於電子表格拖網的職業來說,Python 尤其有價值。 美國銀行花旗集團為其實習分析師開設了 Python 速成課程。 - 經濟學家

財務專業人員長期以來一直可以訪問 Excel 中的 VBA(Visual Basic for Applications)來構建自定義功能和自動化工作流程。 隨著近年來 Google Sheets 成為電子表格領域的有力競爭者,Google Apps Script 現在提供了額外的選擇。

但是,我想提請注意第三種選擇,即 Python 編程語言,它在許多領域都非常流行。

在本文中,我將提供一些示例來說明您可以使用 Python 完成什麼,首先是對語言本身的概述以及為什麼它在如此廣泛的領域如此受歡迎,包括 Web 開發、機器學習、金融、科學和教育,僅舉幾例。 下半部分將包括一個分步教程。

我寫這篇文章的目的是幫助您確定 Python 是否看起來足夠吸引您考慮將其添加到您的財務工具箱中。 如果你邁出這一步,有許多應用程序、課程、視頻、文章、書籍和博客文章可用於學習該語言。 在文章的最後,我列出了一些對我有幫助的資源。

用例:我使用 Python 的示例

我對編程的介紹是在 1980 年代中期在 Oric 1 上學習 BASIC。 當時 BASIC 是最常見的初學者語言。 我在 80 年代後期到 90 年代中期涉足的其他語言是 Pascal 和 C,但我從未以任何專業身份使用過它們,而且我沒想到需要或使用編程技能。 據我當時所知,在 90 年代後期,當我選擇走上金融職業道路時,金融和編程是截然不同的領域。

快進到 2012 年,我希望將編程作為一種愛好,所以我開始研究當時可用的語言。 結果發生了很多事情,當我遇到 Python 時,我被迷住了,原因有很多,我將在下一節中概述。 從那時起,我將 Python 用於各種任務,從小型腳本到大型項目,無論是個人還是專業。 許多(但不是全部)都涉及電子表格,這是許多金融專業人士的工作台。

以下是電子表格和 Python 可以很好地結合使用的幾個示例:

1. 在併購整合 PMO 設置中隨時間跟踪數百項活動

我處理併購交易的各個方面,不僅僅是執行,還有整合。 在最近的一個案例中,PMO 團隊決定採用混合計劃和項目管理方法,使用瀑布規劃和甘特圖為 12 個集成工作流中的每一個進行高級計劃,此外還使用看板來跟踪數百個正在進行的活動在任何給定時間,在第一個 100 天計劃及以後。 選擇的看板工具 MeisterTask 具有許多統計和報告功能,但我們的需求超出了分析和呈現方面的需求,這需要定制解決方案。 這是我使用 Python 自動化的工作流程:

  1. 每週將整個董事會的狀態保存為 CSV 文件。
  2. 將所有歷史 CSV 文件讀入 Pandas DataFrame。
  3. 對數據進行排序、過濾、分組和操作,以我們希望如何跟踪進​​度的約定格式(通過活動狀態、工作流等)。
  4. 將輸出寫入 Excel 文件,其中每個分析的數據都包含在其自己的工作表中,其格式可以簡單地複制並粘貼到 think-cell 圖表中。
  5. 為每月指導委員會會議的報告包創建表格和圖表。

開發腳本需要幾個小時的前期投資,但現在,為指導委員會會議或臨時分析更新報告包只需幾分鐘。 從字面上看,大約需要 30 秒才能轉到正確的文件夾並使用一行命令運行腳本,然後再花幾分鐘將輸出複制粘貼到幻燈片中。 12 個工作流中的大約 500 個活動(卡片)已經執行大約一個月,每週跟踪它們的移動方式,在兩年的計劃時間線內,您很快就會發現自己要處理成千上萬個數據點,最終數十萬個數據點的文件。 如果沒有自動化,我們在這裡討論的是一些非常乏味的任務。

在繼續做事情或通過設置自動化增加更多初始工作量之間的“金錢時間價值”權衡是金融界的一個常見主題。 我在此過程的第一步中做出了類似的決定,將數據導出為 CSV 文件。 MeisterTask 與許多現代 Web 應用程序一樣,有一個 API,可以連接到您的 Python 應用程序,但是設置它所花費的時間將遠遠超過我們在此用例中節省的時間。

因此,如您所見,最佳解決方案通常是自動化工作流程的某些步驟,而讓其他步驟保持手動。

2. 使用 Web Scraping、Google Maps API 和 Excel 分析房價統計數據

另一個例子是我出於個人興趣而做的,但我想強調它,因為它包含 Python 實用程序的一些其他有趣元素:

  1. 抓取特定區域的房地產清單數據,包括地址、大小、房間數量、要價和其他特徵; 總共幾百到一千行。
  2. 保存到 Python 數據結構中。
  3. 連接到 Google Maps API,並為每個列表檢索物業與主要地標之間的距離,例如大海、市中心、最近的火車站、最近的機場等。
  4. 將數據導出到 Excel 文件。
  5. 使用標準 Excel 功能運行回歸、計算統計數據並根據標準指標(例如每平方米價格和到地標的距離)創建圖表。

此處的結果可以與您自己在偏好方面的個人權重以及尋找房地產時的財務限制相結合。

這只是兩個示例,專注於自動化電子表格相關工作和添加功能,但 Python 的機會幾乎是無窮無盡的。 在下一節中,我將概述它如此受歡迎的原因,然後再繼續使用 Python 進行逐步蒙特卡羅模擬教程。

為什麼 Python 是金融專業人士的絕佳選擇

編程語言 Python 自 1990 年以來一直存在,但直到最近幾年它的受歡迎程度才呈爆炸式增長。

python是搜索最多的編程語言

這有幾個原因,讓我們依次看一下。

1. Python 是一種高級編程語言

高級編程語言是一種抽像出計算機內部工作的許多細節的語言。 一個很好的例子是內存管理。 除了處理任務所需的時間和代碼行數之外,低級編程語言還需要詳細了解計算機內存的佈局、分配和釋放方式的複雜性。 Python 會自動抽象並處理其中的許多細節,讓您專注於您想要完成的事情。

2.簡潔

因為 Python 是一種高級編程語言,所以代碼更加簡潔,幾乎完全專注於你想要實現的業務邏輯,而不是技術實現細節。 語言設計選擇促成了這一點:例如,Python 不需要像許多其他語言那樣使用花括號或分號來描述函數、循環和行,這使得它更加簡潔,並且正如一些人認為的那樣,改進了可讀性。

3. 易於學習和理解

影響 Python 語言設計選擇的一個觀察結果是,程序的閱讀頻率高於編寫頻率。 Python 在這裡表現出色,因為它的代碼看起來非常接近簡單的英語,尤其是當您以合理的方式命名腳本或程序的不同組件時。

4. 適合快速、迭代開發

開明的試錯勝過完美智慧的計劃。 - 大衛凱利

Python 是原型設計和快速迭代開發(是的,試錯法)的理想選擇,因為 Python shell、IPython 和 Jupyter 筆記本等交互式解釋器工具是 Python 工具鏈的前沿和中心。 在這些交互式環境中,您可以單獨編寫和執行每一行代碼,並立即查看結果(或有用的錯誤消息)。 其他語言也有這種情況,但在大多數情況下,程度與 Python 不同。

5. 可用於原型設計和生產代碼

除了非常適合原型設計之外,Python 還是用於大型生產應用程序的優秀且強大的語言。 世界上一些最大的軟件公司在各種應用程序和用例中大量使用 Python。

6. 附帶“包含的電池”:Python 標準庫

基本操作所需的一切都內置在語言中,但除此之外,Python 標準庫還具有用於處理文件、媒體、網絡、日期和時間信息等的工具。 這使您無需尋找第三方軟件包即可完成各種任務。

7. 優秀的財務分析第三方庫

對於金融專業人士來說,帶有DataFrameSeries對象的 Pandas 以及帶有ndarray的 Numpy 是使用 Python 進行金融分析的主力軍。 結合 matplotlib 和其他可視化庫,您可以使用出色的工具來提高生產力。

8. Python 是免費的!

Python 是在開源許可下開發的,因此也可以免費用於商業用途。

一起使用 Python 和金融的分步教程

下面是一個分步教程,展示瞭如何創建我之前的博客文章中描述的蒙特卡洛模擬的簡化版本,但使用 Python 而不是 Excel 的 @RISK 插件。

蒙特卡洛方法依靠隨機抽樣來獲得數值結果。 一個這樣的應用是從代表世界不確定的潛在未來狀態的概率分佈中抽取隨機樣本,其中變量或假設可以採用一系列值。

在簡化的 DCF 估值模型上進行蒙特卡洛模擬是有幫助的,而不是您看到的顯示期權或其他衍生品估值的更常見示例,因為為此我們不需要任何超出計算財務報表和貼現現金流,使我們能夠專注於 Python 概念和工具。 請注意,儘管此基本教程模型旨在說明關鍵概念,但對於任何實際目的都沒有用處。 我也不會涉及蒙特卡洛模擬的任何學術方面。

本教程假定您熟悉編程的基本構建塊,例如變量和函數。 如果沒有,花 10 分鐘時間檢查一下本介紹中的關鍵概念可能會有所幫助。

起點和期望的結果

我從蒙特卡洛模擬教程中使用的非常簡化的 DCF 估值模型開始。 它包含三個財務報表中的一些關鍵行項目,以及三個突出顯示的輸入單元格,在 Excel 版本中,這些單元格具有點估計值,我們現在希望用概率分佈替換這些點估計值,以開始探索潛在的結果範圍。

財務預測示例

開發小腳本的兩步法

讓它發揮作用,讓它正確,讓它快速 - 肯特貝克

本教程的目的是向不熟悉 Python 的金融專業人士介紹一個有用的程序可能是什麼樣子,還介紹了您可以用來開發它的迭代過程。 因此,它有兩個部分:

  1. 首先,我使用一種簡單的方法開發了一個工作原型,我認為這種方法很容易遵循,並且與從頭開始可以用來啟動這個項目的過程完全不同。
  2. 然後,在開發出工作原型之後,我會經歷重構的過程——在不改變其功能的情況下改變代碼的結構。 您可能希望繼續使用該部分 - 它是一個比第一個解決方案更優雅的解決方案,並且作為獎勵,它在執行時間方面快了大約 75 倍。

1. 開發工作原型

設置 Jupyter Notebook

Jupyter notebook 是一個很好的交互式使用 Python 的工具。 它是一個交互式 Python 解釋器,其單元格可以包含代碼、Markdown 文本、圖像或其他數據。 對於本教程,我使用了 Python Quant Platform,但我也可以推薦 Google 的 Colaboratory,它是免費的並且在雲中運行。 在那裡,只需在“文件”菜單中選擇“新建 Python 3 Notebook”,就可以開始了。

完成後,下一步是導入數據操作和可視化所需的第三方包,並告訴程序我們希望在筆記本中查看圖表,而不是在單獨的窗口中:

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

在我們開始命名我們的第一個變量之前的註釋。 正如我已經強調的那樣,可讀性是 Python 的優勢之一。 語言設計在很大程度上支持這一點,但每個編寫代碼的人都有責任使其可讀性和可理解性,不僅是為了他人,也是為了他們自己。 正如伊格森定律所說,“任何你自己的代碼,如果你有六個月或更長時間沒有看過,那也可能是別人寫的。”

一個好的經驗法則是以這樣一種方式命名程序的組件,以盡量減少對解釋程序功能的單獨註釋的需求。

考慮到這一點,讓我們繼續前進。

創建財務報表

我們可以通過多種方式在 Python 中處理現有的電子表格數據。 例如,我們可以使用read_excel命令通過一行代碼將工作表讀入 Pandas DataFrame。 如果您想在電子表格和 Python 代碼之間實現更緊密的集成和實時鏈接,可以使用免費和商業選項來提供該功能。

由於這裡的模型非常簡單,並且為了讓我們專注於 Python 概念,我們將在腳本中從頭開始重新創建它。 在第一部分的最後,我將展示如何將我們創建的內容導出到電子表格中。

作為創建財務報表的 Python 表示的第一步,我們需要一個合適的數據結構。 有很多可供選擇,一些內置於 Python,另一些來自各種庫,或者我們可以創建自己的。 現在,讓我們使用 Pandas 庫中的 Series 來看看它的功能:

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

該輸入及其對應的輸出如下所示:

從 python 庫創建一個系列

在前三行中,我們創建了一個數據結構,其索引由年份(每個標記以顯示它是實際、預算還是預計)、起始值(以百萬歐元為單位,如在原始 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:

python 和金融:預測銷售數字

使用相同的方法,我們繼續查看財務報表,根據需要聲明變量並執行必要的計算以最終得出自由現金流。 一旦我們到達那裡,我們就可以檢查我們所擁有的是否與 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

這給了我們自由現金流:

python的貼現現金流輸出

在此階段可能需要評論的上面一行是第二個tax_payment參考。 在這裡,我們應用了一個小函數來確保在稅前利潤變為負數的情況下,我們不會有正的納稅。 這顯示了您可以如何有效地將自定義函數應用於 Pandas 系列或 DataFrame 中的所有單元格。 當然,實際應用的功能是一種簡化。 對於更大的估值活動,更現實的模型將有一個單獨的稅收模型,該模型根據許多公司特定因素計算實際支付的現金稅。

執行 DCF 估值

得出預計現金流後,我們現在可以計算一個簡單的終值並將所有現金流折現到現在,以獲得 DCF 結果。 以下代碼介紹了索引和切片,它允許我們訪問數據結構中的一個或多個元素,例如 Pandas Series 對象。

我們通過在結構名稱後直接寫方括號來訪問元素。 簡單索引按位置訪問元素,從零開始,這意味著free_cash_flow[1]將給我們第二個元素。 [-1]是訪問最後一個元素的簡寫(最後一年的現金流用於計算終值),使用冒號給了我們一個切片,意思是[1:]給了我們除了第一個元素之外的所有元素,因為我們不想在我們的 DCF 估值中包含歷史年份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 

python貼現現金流計算的dcf輸出

我們原型的第一部分到此結束——我們現在有一個可用的 DCF 模型,儘管它是一個非常初級的 Python 模型。

導出數據

在繼續進行實際的蒙特卡洛模擬之前,現在可能是提一下 Pandas 包中可用的導出功能的好時機。 如果您有一個 Pandas DataFrame 對象,您可以使用to_excel方法將其寫入一個 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 

使用python生成的excel表格輸出示例

為我們的蒙特卡洛模擬創建概率分佈

現在我們準備好應對下一個挑戰:用概率分佈替換一些點估計輸入。 雖然與在 Excel 中構建相同的模型相比,到目前為止的步驟可能看起來有些繁瑣,但接下來的幾行將讓您了解 Python 的強大功能。

我們的第一步是決定我們要在模擬中運行多少次迭代。 使用 1,000 作為起點可以在獲得足夠的數據點以獲得合理的輸出圖與在合理的時間範圍內完成模擬之間取得平衡。 接下來,我們生成實際分佈。 為了簡單起見,我這裡生成了三個正態分佈,但是 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() 

python的蒙特卡羅模擬輸出

在這裡,您可以爭辯說 EBITDA 不應該是獨立於銷售額的單獨隨機變量,而是在某種程度上與銷售額相關。 我同意這一點,並補充說,它應該由對成本結構動態(可變、半可變和固定成本)和關鍵成本驅動因素(其中一些可能有自己的概率分佈,例如輸入商品價格),但為了篇幅和清晰起見,我將這些複雜性放在一邊。

您選擇分佈和參數所需的數據越少,您就越需要依賴各種盡職調查工作流的結果,並結合經驗,就可能的情景範圍形成共識。 在這個例子中,對於現金流量預測,會有很大的主觀成分,這意味著可視化概率分佈變得很重要。 在這裡,我們可以得到一個基本的可視化,顯示銷售增長分佈,只需要兩行短代碼。 通過這種方式,我們可以快速查看最能反映團隊集體觀點的任何分佈。

現在我們擁有了運行模擬所需的所有構建塊,但它們的格式不適合運行模擬。 這是迄今為止我們使用的相同代碼,但所有代碼都集中在一個單元格中,並為方便起見重新排列為一個函數:

 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 函數)。 這取決於您運行它的計算機,但此版本需要 1-2 秒來運行 1,000 次迭代並可視化結果。

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

python腳本的蒙特卡羅模擬輸出

2. 完善原型

對某些事情可以簡化的潛在懷疑是世界上最富有挑戰性的挑戰的來源。 - Edsger Dijkstra

重構是指重寫現有代碼以改進其結構而不改變其功能的過程,它可能是編碼中最有趣和最有價值的元素之一。 這樣做可能有幾個原因。 它可能是:

  1. 以更合理的方式組織不同的部分。
  2. 重命名變量和函數,使它們的用途和工作更清晰。
  3. 允許並為未來的功能做準備。
  4. 提高執行速度、內存佔用或其他資源利用率。

為了展示該過程中的一個步驟可能是什麼樣子,我通過將所有初始變量收集在一個地方來清理我們剛剛完成的原型,而不是像原型腳本中那樣分散在各處,並通過一個名為矢量化

使用 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 秒——大約快了 75 倍。

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

NumPy 數組操作示例

我確信進一步的優化是可能的,因為我只是為了本教程的目的而在短時間內將原型和改進版本放在一起。

更進一步

本教程展示了 Python 的一些強大功能,如果您要進一步開發它,機會幾乎是無窮無盡的。 例如,您可以:

  • 從網頁或其他數據源中抓取或下載相關的公司或行業統計數據,以幫助您選擇假設和概率分佈。
  • 在量化金融應用程序中使用 Python,例如在基於基本和/或宏觀經濟因素的自動交易算法中。
  • 構建以電子表格和/或演示格式生成輸出的導出功能,用作內部交易審查和批准流程的一部分,或用於外部演示。

我什至還沒有提到你還可以使用各種 Web、數據科學和機器學習應用程序來做什麼,這些應用程序對 Python 的成功做出了貢獻。

總結:金融工具箱的有用語言

本文介紹了 Python 編程語言,列出了它在金融領域如此流行的一些原因,並展示瞭如何構建一個小型 Python 腳本。 在分步教程中,我介紹瞭如何使用 Python 進行迭代原型設計、交互式財務分析以及估值模型、算法交易程序等的應用程序代碼。

對我來說,歸根結底,Python 技術的殺手鐧就是使用起來很有趣! 如果您喜歡解決問題、構建事物和提高工作流程效率,那麼我鼓勵您嘗試一下。 我很想听聽你用它做了什麼或想用它做什麼。

金融專業人士學習 Python 的推薦資源

  • 奧萊利的書。 我可以特別推薦:
    • Yves Hilpisch 的 Python 金融
    • Learning Python by Mark Lutz
    • Fluent Python by Luciano Ramalho
  • The Python Quants
  • PyCon talks on YouTube
  • 烏迪米