python期权价格计算器
The following passages shortly describe how to build a Python program that can calculate the fair value of a company, using data from Yahoo Finance. Before jumping into the Python technicalities, it makes sense to have a quick look at the factors that impact the fair value of a company.
吨他下面的段落简短描述了如何构建一个Python程序,可以计算出公司的合理价值,利用雅虎财经的数据。 在开始使用Python技术之前,先快速了解影响公司公允价值的因素是有意义的。
一,理论背景 (I. Theoretical Background)
Financial theory posits that the fair value of a firm is equal to the sum of all future cash flows generated by the business, discounted using a risk-adjusted rate. In other words the current value of any company is equal to the cash that the company will generate, adjusted to account for the risk-profile of that company. This essentially boils down to the following equation:
财务理论认为,企业的公允价值等于该企业产生的所有未来现金流量的总和,并使用风险调整率对其进行折现。 换句话说,任何公司的现值等于该公司将产生的现金,并经过调整以考虑该公司的风险状况。 这实质上可以归结为以下等式:
![Image for post](https://miro.medium.com/max/9999/1*fpWht41jLly3SQr1Sulo9g.png)
where PV is the present value of the company, FCF are the free cash flows generated in year i, and r is the risk-adjusted discount rate. As it gets difficult to forecast cash flows with any reasonable degree of accuracy for more than 5 years into the future, it makes sense to calculate a terminal company value after this time span. Here, we can treat the company as a growing perpetuity, which can be valued with the following formula:
其中PV是公司的现值,FCF是第i年产生的自由现金流量,而r是风险调整后的折现率。 由于未来5年以上很难以任何合理的准确度预测现金流量,因此在此时间段之后计算终端公司的价值是有意义的。 在这里,我们可以将公司视为永续经营,可以通过以下公式对其进行估值:
![Image for post](https://miro.medium.com/max/9999/1*KrLYpAu69Hd4CJjbwkHZXQ.png)
where FCF are the free cash flows generated by the company in year 6, r is the discount rate, and g is the long-term growth rate of the company. This terminal value of the company also needs to be discounted subsequently to get its present value.
其中FCF是公司在第6年产生的自由现金流量,r是折现率,g是公司的长期增长率。 公司的最终价值也需要随后折价才能获得其现值。
二。 金融理论的涵义 (II. Implications of Financial Theory)
To get a general structure for the Python program, we can basically just take the PV formula from above and split it into its main components.
要获得Python程序的一般结构,我们基本上可以仅从上方获取PV公式并将其拆分为其主要组成部分。
II.1自由现金流量 (II.1 Free Cash Flows)
The free cash flows generated by the company in year i are usually calculated by taking the cash flows generated by the firm’s operations and deducting capital expenditures. The resulting number is the amount of cash that debt and equity holders of the business could take out of the company in year i. Forecasting these cash flows can get pretty complicated and you usually need to build extensive Excel models to get to a reasonable estimate for these values. It is possible to get around this by using several (over)simplifying assumptions, which are outlined in a bit.
公司在第一年产生的自由现金流量通常是通过计算公司运营产生的现金流量并减去资本支出来计算的。 结果数字是该业务的债务和股权持有人在第一年可以从公司中提取的现金量。 预测这些现金流量可能会变得非常复杂,通常需要构建广泛的Excel模型以对这些值进行合理的估算。 可以通过使用几个(过度)简化的假设来解决此问题,这些假设在下文中进行了概述。
II.2折现率 (II.2 Discount Rate)
The second major component that is needed to calculate the enterprise value of a company is an adequate risk-adjusted discount rate. The appropriate rate to use here is the weighted average cost of capital (WACC), which is the average cost of capital to the firm (that is for both debt and equity financing combined). The formula looks as follows:
计算公司的企业价值所需的第二个主要组成部分是适当的风险调整后的折现率。 此处使用的适当比率是加权平均资本成本(WACC),即公司的平均资本成本(即债务和股权融资的总和)。 该公式如下所示:
![Image for post](https://miro.medium.com/max/9999/1*c__TPUCzHrs_oYY0fLqwOw.png)
where E is the market value of the company’s equity, D is the value of the company’s debt, r denotes the return required by equity and debt holders, respectively, and tau denotes the company’s tax rate.
其中E是公司股权的市场价值,D是公司债务的价值,r分别表示权益和债务持有人所需的收益,tau表示公司的税率。
II.3简化假设 (II.3 Simplifying Assumptions)
As mentioned earlier, getting these two major components can take weeks of calculations and model building. As this is more of a sparing exercise, rather than a full-blown quant project, several simplifying assumptions are made to keep the complexity of the program to a reasonable level.
如前所述,获得这两个主要组成部分可能需要数周的计算和模型构建。 由于这只是一个有限的练习,而不是一个成熟的量化项目,因此,我们进行了一些简化的假设,以将程序的复杂性保持在合理的水平。
Firstly, the task of obtaining future free cash flows can be simplified by assuming the company earnings before interest and taxes (EBIT) are an adequate proxy for free cash flows generated by a company. This is reasonable especially for companies in later stages that no longer have large growth CapEx but rather maintenance CapEx that is approximately on the level of the company’s depreciation of fixed assets.
首先,假设公司的息税前利润(EBIT)足以代替公司产生的自由现金流,可以简化获取未来自由现金流的任务。 这对于那些不再具有较大增长资本支出,但维持资本支出大约与公司固定资产折旧水平相当的公司而言,是合理的。
Secondly, we will assume that the average revenue growth rate and the average EBIT margin of the company in the past three years will continue to apply for the next five years. Using this approach, generating EBIT forecasts is pretty straightforward.
其次,我们假设过去三年中公司的平均收入增长率和平均息税前利润率将在未来五年中继续适用。 使用这种方法,生成EBIT预测非常简单。
Finally, to calculate the WACC, we will assume that company debt is adequately priced by the market, making the yield on outstanding debt the return required by debt holders. Calculating the required equity return is a bit more tricky. Here the capital asset pricing model (CAPM) is used to get to the equity rate of return:
最后,为了计算WACC,我们将假定公司债务已由市场充分定价,从而使未偿债务的收益成为债务持有人所需的回报。 计算所需的股本回报会比较棘手。 在这里,资本资产定价模型(CAPM)用于获得股本收益率:
![Image for post](https://miro.medium.com/max/9999/1*mf6FiGy69v4hFHOdKj7RWg.png)
where the equity beta is essentially the co-movement of the stock return and the general market return, which can be proxied using the S&P500. The equity beta is calculated as the covariance of stock and market returns divided by the variance of the market returns.
其中,权益beta实质上是股票收益和一般市场收益的共同变动,可以使用S&P500进行代理。 权益beta的计算方法是:股票和市场收益的协方差除以市场收益的方差。
三, 用Python实现 (III. Implementation with Python)
I used Apple Inc. (AAPL) as the company being valued in the subsequent code, however, the program works with the ticker of any large publicly traded company.
我使用Apple Inc.(AAPL)作为后续代码中被评估的公司,但是,该程序可与任何大型上市公司的股票一起使用。
For the program to work, several modules need to be imported to pull financial information from Yahoo Finance and store it appropriately.
为了使程序正常运行,需要导入几个模块以从Yahoo Finance中提取财务信息并适当地存储它。
from bs4 import BeautifulSoup as bs
import pandas as pd
import requests
import pandas_datareader as dr
import datetime
As discussed subsequently, certain values that are tedious to obtain or simply not available via Yahoo Finance are hard coded initially.
如随后讨论的那样,最初很难对某些难以获得或根本无法通过Yahoo Finance获得的值进行编码。
company_ticker = 'AAPL'
timespan = 100 #timespan for the equity beta calculation
market_risk_premium = 0.0523
long_term_growth = 0.01
debt_return = 0.01
tax_rate = 0.3
III.1从Yahoo Finance提取财务数据 (III.1 Pulling Financial Data from Yahoo Finance)
Yahoo Finance has an API that provides a lot of information, however, web-scraping is needed on top to get the specific income statement and balance sheet financials. For this, BeautifulSoup and the requests module are great tools.
Yahoo Finance有一个提供大量信息的API,但是,首先需要进行网络爬网以获得特定的损益表和资产负债表财务状况。 为此,BeautifulSoup和请求模块是出色的工具。
income_statement_url = '<https://finance.yahoo.com/quote/>' + company_ticker + '/financials?p=' + company_tickerincome_statement_html = requests.get(income_statement_url)
income_statement_soup = bs(income_statement_html.text, 'html.parser')
After creating the BeautifulSoup object, we have to navigate the website to get the correct pieces of information and store them in one pandas dataframe that contains the required information. To that end, we first create a dataframe with the correct dates as column names.
创建BeautifulSoup对象后,我们必须浏览网站以获取正确的信息并将其存储在包含所需信息的一个熊猫数据框中。 为此,我们首先创建一个以正确日期作为列名的数据框。
income_statement_table = income_statement_soup.find('div', class_='M(0) Whs(n) BdEnd Bdc($seperatorColor) D(itb)')
income_statement_header = income_statement_table.find('div', class_='D(tbr) C($primaryColor)')
header_lst = []
for i in income_statement_header.find_all('div'):
if len(i) != 0:
header_lst.append(i.text)
header_lst = header_lst[::-1]
del header_lst[len(header_lst)-1]
header_lst.insert(0,'Breakdown')
income_statement_df = pd.DataFrame(columns = header_lst)
After that, the revenue and EBIT figures provided by Yahoo Finance can be appended for the respective year.
之后,可以附加相应年份的Yahoo Finance提供的收入和EBIT数据。
revenue_row = income_statement_table.find('div', class_='D(tbr) fi-row Bgc($hoverBgColor):h')
revenue_lst = []
for i in revenue_row.find_all('div', attrs={'data-test':'fin-col'}):
i = i.text
i = i.replace(",","")
revenue_lst.append(int(i))
revenue_lst = revenue_lst[::-1]
revenue_lst.insert(0,'Total Revenue')
income_statement_df.loc[0] = revenue_lstEBIT_row = income_statement_table.find('div', attrs={'title':'EBIT'}).parent.parent
EBIT_lst = []
for i in EBIT_row.find_all('div', attrs={'data-test':'fin-col'}):
i = i.text
i = i.replace(",","")
EBIT_lst.append(int(i))
EBIT_lst = EBIT_lst[::-1]
EBIT_lst.insert(0,'EBIT')
income_statement_df.loc[1] = EBIT_lstincome_statement_df = income_statement_df.drop('ttm', axis=1)
When exporting the Pandas dataframe to a csv-file, we get the following:
将Pandas数据框导出到csv文件时,我们得到以下信息:
![Image for post](https://miro.medium.com/max/9999/1*SJzvMexqKeiZbrmybOEovA.png)
III.2预测收入和息税前利润 (III.2 Forecasting Revenues and EBIT)
As mentioned earlier, revenues and EBIT are forecasted for the coming five years by extrapolating from past sales and EBIT data. To do this, we calculate the revenue compound annual growth rate (CAGR) and EBIT margin for the past years.
如前所述,根据过去的销售和EBIT数据推断出未来五年的收入和EBIT。 为此,我们计算了过去几年的收入复合年增长率(CAGR)和EBIT利润率。
latest_rev = income_statement_df.iloc[0,len(income_statement_df.columns)-1]
earliest_rev = income_statement_df.iloc[0,1]
rev_CAGR = (latest_rev/earliest_rev)**(float(1/(len(income_statement_df.columns)-2)))-1EBIT_margin_lst = []
for year in range(1,len(income_statement_df.columns)):
EBIT_margin = income_statement_df.iloc[1,year]/income_statement_df.iloc[0,year]
EBIT_margin_lst.append(EBIT_margin)
avg_EBIT_margin = sum(EBIT_margin_lst)/len(EBIT_margin_lst)
Using these figures, it is possible to forecast revenues and EBIT.
使用这些数字,可以预测收入和息税前收益。
forecast_df = pd.DataFrame(columns=['Year ' + str(i) for i in range(1,7)])rev_forecast_lst = []
for i in range(1,7):
if i != 6:
rev_forecast = latest_rev*(1+rev_CAGR)**i
else:
rev_forecast = latest_rev*(1+rev_CAGR)**(i-1)*(1+long_term_growth)
rev_forecast_lst.append(int(rev_forecast))
forecast_df.loc[0] = rev_forecast_lstEBIT_forecast_lst = []
for i in range(0,6):
EBIT_forecast = rev_forecast_lst[i]*avg_EBIT_margin
EBIT_forecast_lst.append(int(EBIT_forecast))
forecast_df.loc[1] = EBIT_forecast_lst
The resulting csv file of the forecast dataframe looks as follows, where the rows indexed as 0 and 1 provide the forecasted revenue and EBIT figures, respectively.
预测数据帧的结果csv文件如下所示,其中索引为0和1的行分别提供了预测收入和EBIT数字。
![Image for post](https://miro.medium.com/max/9999/1*ezRYGsM46MAYfh93h21gYg.png)
III.3计算WACC (III.3 Calculating the WACC)
To calculate the WACC, we first need to find the rate of return demanded by equity holders. This requires finding the risk-free rate (proxied here by the yield of the 10-year US Treasury note) and determining the market risk premium.
要计算WACC,我们首先需要找到股权持有人要求的回报率。 这要求找到无风险利率(此处附有10年期美国国库券的收益率)并确定市场风险溢价。
Determining the risk-free rate is relatively straightforward, as we only need the current yield on the 10-year US treasury note.
确定无风险利率相对简单,因为我们只需要10年期美国国债的当前收益率即可。
current_date = datetime.date.today()
past_date = current_date-datetime.timedelta(days=timespan)risk_free_rate_df = dr.DataReader('^TNX', 'yahoo', past_date, current_date)
risk_free_rate_float = (risk_free_rate_df.iloc[len(risk_free_rate_df)-1,5])/100
Instead of calculating an adequate estimate of the market risk premium myself, I used the rate provided by NYU finance professor Aswath Damodaran, who also publishes a lot of other very interesting financial statistics. Currently he estimates the market premium to be 5.23% annually for the US market.
我没有自己计算出足够的市场风险溢价估算,而是使用纽约大学金融学教授阿斯瓦斯·达莫达兰 ( Aswath Damodaran)提供的费率,他还发布了许多其他非常有趣的金融统计数据。 目前,他估计美国市场的市场溢价每年为5.23%。
Calculating the equity beta of the company requires several inputs. First, we have to access the API of Yahoo Finance to get price information on the company stock and the market. These prices are stored in a pandas dataframe and the values are used to calculate daily returns for both sets of prices. Subsequently, the covariance of the stock and the market returns is divided by the variance of the market returns.
计算公司的权益贝塔系数需要几个输入。 首先,我们必须访问Yahoo Finance的API,以获取有关公司股票和市场的价格信息。 这些价格存储在熊猫数据框中,并且这些值用于计算两组价格的每日收益。 随后,将股票和市场收益的协方差除以市场收益的方差。
price_information_df = pd.DataFrame(columns=['Stock Prices', 'Market Prices'])stock_price_df = dr.DataReader(company_ticker, 'yahoo', past_date, current_date)
price_information_df['Stock Prices'] = stock_price_df['Adj Close']market_price_df = dr.DataReader('^GSPC', 'yahoo', past_date, current_date)
price_information_df['Market Prices'] = market_price_df['Adj Close']returns_information_df = pd.DataFrame(columns =['Stock Returns', 'Market Returns'])stock_return_lst = []
for i in range(1,len(price_information_df)):
open_price = price_information_df.iloc[i-1,0]
close_price = price_information_df.iloc[i,0]
stock_return = (close_price-open_price)/open_price
stock_return_lst.append(stock_return)
returns_information_df['Stock Returns'] = stock_return_lstmarket_return_lst = []
for i in range(1,len(price_information_df)):
open_price = price_information_df.iloc[i-1,1]
close_price = price_information_df.iloc[i,1]
market_return = (close_price-open_price)/open_price
market_return_lst.append(market_return)
returns_information_df['Market Returns'] = market_return_lstcovariance_df = returns_information_df.cov()
covariance_float = covariance_df.iloc[1,0]
variance_df = returns_information_df.var()
market_variance_float = variance_df.iloc[1]equity_beta = covariance_float/market_variance_float
equity_return = risk_free_rate_float+equity_beta*(market_risk_premium)
Pulling bond information from the internet is more difficult than it is for equities, which is why we can simply look up bond yields and hardcode them manually. Apple is AA+ rated by S&P, which is why yields on the company’s outstanding bonds are relatively low, at around 1%.
从互联网上获取债券信息比股票要困难得多,这就是为什么我们可以简单地查询债券收益率并手动对其进行硬编码的原因。 苹果被标准普尔(S&P)评为AA +级,这就是为什么该公司未偿还债券的收益率相对较低,约为1%。
Finally, to calculate the WACC, we need pull the amount of company net debt outstanding and the market value of the firm’s equity from Yahoo Finance.
最后,要计算WACC,我们需要从Yahoo Finance中提取公司的未偿债务净额和公司股权的市值。
balance_sheet_url = '<https://finance.yahoo.com/quote/>' + company_ticker + '/balance-sheet?p=' + company_tickerbalance_sheet_html = requests.get(balance_sheet_url)
balance_sheet_soup = bs(balance_sheet_html.text, 'html.parser')balance_sheet_table = balance_sheet_soup.find('div', class_='D(tbrg)')net_debt_lst = []net_debt_row = balance_sheet_table.find('div', attrs={'title':'Net Debt'}).parent.parent
for value in net_debt_row.find_all('div'):
value = value.text
value = value.replace(',','')
net_debt_lst.append(value)
net_debt_int = int(net_debt_lst[3])market_cap_url = '<https://finance.yahoo.com/quote/>' + company_ticker + '?p=' + company_ticker
market_cap_html = requests.get(market_cap_url)
market_cap_soup = bs(market_cap_html.text, 'html.parser')market_cap_int = 0market_cap_row = market_cap_soup.find('td', attrs={'data-test':'MARKET_CAP-value'})
market_cap_str = market_cap_row.text
market_cap_lst = market_cap_str.split('.')if market_cap_str[len(market_cap_str)-1] == 'T':
market_cap_length = len(market_cap_lst[1])-1
market_cap_lst[1] = market_cap_lst[1].replace('T',(9-market_cap_length)*'0')
market_cap_int = int(''.join(market_cap_lst))if market_cap_str[len(market_cap_str)-1] == 'B':
market_cap_length = len(market_cap_lst[1])-1
market_cap_lst[1] = market_cap_lst[1].replace('B',(6-market_cap_length)*'0')
market_cap_int = int(''.join(market_cap_lst))company_value = market_cap_int + net_debt_intWACC = market_cap_int/company_value * equity_return + net_debt_int/company_value * debt_return * (1-tax_rate)
III.4现金流量折现 (III.4 Discounting the Cash Flows)
Finally, we need to discount all the cash flows to get the present value and the overall enterprise value of the company. First, the forecasted EBIT (i.e. FCF) for the next five years are discounted and the present value of the terminal value of the company is added to this amount.
最后,我们需要对所有现金流量进行折现以获得公司的现值和整体企业价值。 首先,对未来五年的预测EBIT(即FCF)进行折现,然后将公司最终价值的现值添加到该金额中。
As the resulting value gives us the enterprise value of the company, which is the value to both equity and debt holders, we need to deduct the company’s net debt to arrive at the equity value of the firm.
由于最终的价值使我们获得了公司的企业价值,即对股权和债务持有人的价值,因此我们需要扣除公司的净债务以得出公司的股权价值。
discounted_EBIT_lst = []for year in range(0,5):
discounted_EBIT = forecast_df.iloc[1,year]/(1+WACC)**(year+1)
discounted_EBIT_lst.append(int(discounted_EBIT))terminal_value = forecast_df.iloc[1,5]/(WACC-long_term_growth)
PV_terminal_value = int(terminal_value/(1+WACC)**5)enterprise_value = sum(discounted_EBIT_lst)+PV_terminal_value
equity_value = enterprise_value-net_debt_int
IV。 模型表现 (IV. Model Performance)
Just to get a feeling for whether or not the program is performing somewhat accurately, I calculated intrinsic values for large US stocks and compared the valuations with the market caps of the respective companies. As stock in the companies chosen is heavily traded, great discrepancies between intrinsic and market value are unlikely, which is why market prices should provide a good indication of the actual value of the companies.
只是为了了解程序是否执行得有些准确,我计算了美国大型股票的内在价值,并将估值与各自公司的市值进行了比较。 由于所选公司的股票交易量很大,因此内在价值和市场价值之间的巨大差异不太可能出现,这就是为什么市场价格应能很好地表明公司的实际价值。
![Image for post](https://miro.medium.com/max/9999/1*I8FZWCzmKtQ0UZhDwQ5vgQ.png)
![Image for post](https://miro.medium.com/max/9999/1*TFqNkzA0WdS9YZMC4rltKg.png)
As can be seen, the model does a reasonably good job for certain companies, while its quite off for others. The two main issues at play here are firstly that the somewhat questionable assumptions on which the model is built are simply unreasonable for certain companies. Secondly, the model output is highly sensitive to the WACC input data due to the approach used to calculate the terminal company value. A more appropriate approach would be to apply an EBIT or EBITDA multiple based on comparable companies, as this entails a lower sensitivity of the program output to the WACC and the terminal growth rate.
可以看出,该模型对于某些公司而言做得相当不错,而对其他公司而言则相当不理想。 这里发挥的两个主要问题是,首先,对于某些公司而言,建立模型所基于的有点可疑的假设是完全不合理的。 其次,由于用于计算终端公司价值的方法,模型输出对WACC输入数据高度敏感。 一种更合适的方法是在可比公司的基础上应用EBIT或EBITDA倍数,因为这会使程序输出对WACC和最终增长率的敏感性降低。
五,结语 (V. Concluding Remarks)
Obviously, the program described above is a simplified approach to valuation and is unlikely to be accurate if the underlying assumptions are violated. Still, the tool might be useful in determining the aggregate intrinsic value of a large number of companies.
显然,上述程序是一种简化的估值方法,如果违反了基本假设,则该程序就不太可能是准确的。 尽管如此,该工具在确定大量公司的总内在价值时可能还是有用的。
V.1免责声明 (V.1 Disclaimer)
The code above is only a side-project and should not be used to make investment decisions. Further, the information pulled from Yahoo Finance should not be used for any commercial purposes. As mentioned earlier, the program is simply a fun exercise of applying Python programming to finance and I recommend against employing web-scraping if resulting information is to be used for commercial purposes.
上面的代码仅是一个附属项目,不应用于做出投资决策。 此外,从Yahoo Finance提取的信息不得用于任何商业目的。 如前所述,该程序只是将Python编程应用于金融的一项有趣的练习,如果将所得信息用于商业目的,我建议不要使用网络抓取。
V.2最终代码 (V.2 Final Code)
The final code looks as follows. In order to run it, you will have to install Python (I use version 3.7.8.) and pip install BeautifulSoup, pandas, requests, and pandas-datareader.
最终代码如下所示。 为了运行它,您将必须安装Python(我使用版本3.7.8。)并pip安装BeautifulSoup,pandas,requests和pandas-datareader。
from bs4 import BeautifulSoup as bs
import pandas as pd
import requests
import pandas_datareader as dr
import datetime'''---------- // Hard-coded variables below // ----------'''
company_ticker = 'AAPL'
timespan = 100 #timespan for the equity beta calculation
market_risk_premium = 0.0523
long_term_growth = 0.01
debt_return = 0.01
tax_rate = 0.3
'''---------- // Hard-coded variables above // ----------''''''----- // I. Financial Information from Yahoo Finance // -----'''
income_statement_url = '<https://finance.yahoo.com/quote/>' + company_ticker + '/financials?p=' + company_ticker
income_statement_html = requests.get(income_statement_url)
income_statement_soup = bs(income_statement_html.text, 'html.parser')
income_statement_table = income_statement_soup.find('div', class_='M(0) Whs(n) BdEnd Bdc($seperatorColor) D(itb)')
income_statement_header = income_statement_table.find('div', class_='D(tbr) C($primaryColor)')
header_lst = []
for i in income_statement_header.find_all('div'):
if len(i) != 0:
header_lst.append(i.text)
header_lst = header_lst[::-1]
del header_lst[len(header_lst)-1]
header_lst.insert(0,'Breakdown')
income_statement_df = pd.DataFrame(columns = header_lst)
revenue_row = income_statement_table.find('div', class_='D(tbr) fi-row Bgc($hoverBgColor):h')
revenue_lst = []
for i in revenue_row.find_all('div', attrs={'data-test':'fin-col'}):
i = i.text
i = i.replace(",","")
revenue_lst.append(int(i))
revenue_lst = revenue_lst[::-1]
revenue_lst.insert(0,'Total Revenue')
income_statement_df.loc[0] = revenue_lst
EBIT_row = income_statement_table.find('div', attrs={'title':'EBIT'}).parent.parent
EBIT_lst = []
for i in EBIT_row.find_all('div', attrs={'data-test':'fin-col'}):
i = i.text
i = i.replace(",","")
EBIT_lst.append(int(i))
EBIT_lst = EBIT_lst[::-1]
EBIT_lst.insert(0,'EBIT')
income_statement_df.loc[1] = EBIT_lst
income_statement_df = income_statement_df.drop('ttm', axis=1)'''---------- // II. Forecasting Revenues and EBIT // ----------'''
latest_rev = income_statement_df.iloc[0,len(income_statement_df.columns)-1]
earliest_rev = income_statement_df.iloc[0,1]
rev_CAGR = (latest_rev/earliest_rev)**(float(1/(len(income_statement_df.columns)-2)))-1
EBIT_margin_lst = []
for year in range(1,len(income_statement_df.columns)):
EBIT_margin = income_statement_df.iloc[1,year]/income_statement_df.iloc[0,year]
EBIT_margin_lst.append(EBIT_margin)
avg_EBIT_margin = sum(EBIT_margin_lst)/len(EBIT_margin_lst)
forecast_df = pd.DataFrame(columns=['Year ' + str(i) for i in range(1,7)])
rev_forecast_lst = []
for i in range(1,7):
if i != 6:
rev_forecast = latest_rev*(1+rev_CAGR)**i
else:
rev_forecast = latest_rev*(1+rev_CAGR)**(i-1)*(1+long_term_growth)
rev_forecast_lst.append(int(rev_forecast))
forecast_df.loc[0] = rev_forecast_lst
EBIT_forecast_lst = []
for i in range(0,6):
EBIT_forecast = rev_forecast_lst[i]*avg_EBIT_margin
EBIT_forecast_lst.append(int(EBIT_forecast))
forecast_df.loc[1] = EBIT_forecast_lst
'''---------- // III. Calculating the WACC // ----------'''
current_date = datetime.date.today()
past_date = current_date-datetime.timedelta(days=timespan)
risk_free_rate_df = dr.DataReader('^TNX', 'yahoo', past_date, current_date)
risk_free_rate_float = (risk_free_rate_df.iloc[len(risk_free_rate_df)-1,5])/100
price_information_df = pd.DataFrame(columns=['Stock Prices', 'Market Prices'])
stock_price_df = dr.DataReader(company_ticker, 'yahoo', past_date, current_date)
price_information_df['Stock Prices'] = stock_price_df['Adj Close']
market_price_df = dr.DataReader('^GSPC', 'yahoo', past_date, current_date)
price_information_df['Market Prices'] = market_price_df['Adj Close']
returns_information_df = pd.DataFrame(columns =['Stock Returns', 'Market Returns'])
stock_return_lst = []
for i in range(1,len(price_information_df)):
open_price = price_information_df.iloc[i-1,0]
close_price = price_information_df.iloc[i,0]
stock_return = (close_price-open_price)/open_price
stock_return_lst.append(stock_return)
returns_information_df['Stock Returns'] = stock_return_lst
market_return_lst = []
for i in range(1,len(price_information_df)):
open_price = price_information_df.iloc[i-1,1]
close_price = price_information_df.iloc[i,1]
market_return = (close_price-open_price)/open_price
market_return_lst.append(market_return)
returns_information_df['Market Returns'] = market_return_lst
covariance_df = returns_information_df.cov()
covariance_float = covariance_df.iloc[1,0]
variance_df = returns_information_df.var()
market_variance_float = variance_df.iloc[1]
equity_beta = covariance_float/market_variance_float
equity_return = risk_free_rate_float+equity_beta*(market_risk_premium)
balance_sheet_url = '<https://finance.yahoo.com/quote/>' + company_ticker + '/balance-sheet?p=' + company_ticker
balance_sheet_html = requests.get(balance_sheet_url)
balance_sheet_soup = bs(balance_sheet_html.text, 'html.parser')
balance_sheet_table = balance_sheet_soup.find('div', class_='D(tbrg)')
net_debt_lst = []
net_debt_row = balance_sheet_table.find('div', attrs={'title':'Net Debt'}).parent.parent
for value in net_debt_row.find_all('div'):
value = value.text
value = value.replace(',','')
net_debt_lst.append(value)
net_debt_int = int(net_debt_lst[3])
market_cap_url = '<https://finance.yahoo.com/quote/>' + company_ticker + '?p=' + company_ticker
market_cap_html = requests.get(market_cap_url)
market_cap_soup = bs(market_cap_html.text, 'html.parser')
market_cap_int = 0
market_cap_row = market_cap_soup.find('td', attrs={'data-test':'MARKET_CAP-value'})
market_cap_str = market_cap_row.text
market_cap_lst = market_cap_str.split('.')
if market_cap_str[len(market_cap_str)-1] == 'T':
market_cap_length = len(market_cap_lst[1])-1
market_cap_lst[1] = market_cap_lst[1].replace('T',(9-market_cap_length)*'0')
market_cap_int = int(''.join(market_cap_lst))
if market_cap_str[len(market_cap_str)-1] == 'B':
market_cap_length = len(market_cap_lst[1])-1
market_cap_lst[1] = market_cap_lst[1].replace('B',(6-market_cap_length)*'0')
market_cap_int = int(''.join(market_cap_lst))
company_value = market_cap_int + net_debt_int
WACC = market_cap_int/company_value * equity_return + net_debt_int/company_value * debt_return * (1-tax_rate)
'''-------- // IV. Discounting the Forecasted EBIT // --------'''
discounted_EBIT_lst = []
for year in range(0,5):
discounted_EBIT = forecast_df.iloc[1,year]/(1+WACC)**(year+1)
discounted_EBIT_lst.append(int(discounted_EBIT))
terminal_value = forecast_df.iloc[1,5]/(WACC-long_term_growth)
PV_terminal_value = int(terminal_value/(1+WACC)**5)
enterprise_value = sum(discounted_EBIT_lst)+PV_terminal_value
equity_value = enterprise_value-net_debt_int
翻译自: https://medium.com/analytics-vidhya/building-an-intrinsic-value-calculator-with-python-7986833962cd
python期权价格计算器