Spaces:
Sleeping
Sleeping
app file
Browse files
app.py
ADDED
@@ -0,0 +1 @@
|
|
|
|
0 |
# Max Rows and Columns
|
1 |
pd.set_option('display.max_columns', 500)
|
2 |
pd.set_option('display.max_rows', None)
|
3 |
|
4 |
# Two Decimals
|
5 |
pd.options.display.float_format = '{:.2f}'.format
|
6 |
|
7 |
# The stock symbol
|
8 |
symbol = ticker
|
9 |
ticker = yf.Ticker(symbol)
|
10 |
company_name = ticker.info.get("longName", "N/A")
|
11 |
|
12 |
# Get historical share prices
|
13 |
price_history = ticker.history(period='5y')
|
14 |
|
15 |
# Extract the closing prices at the end of each fiscal year
|
16 |
# We will reindex to have end-of-year dates that match the years of the income statements
|
17 |
year_end_prices = price_history.resample('A').last()['Close']
|
18 |
year_end_prices.index = year_end_prices.index.year
|
19 |
|
20 |
# Get the number of shares from the info or financials
|
21 |
shares_outstanding = ticker.info.get('sharesOutstanding')
|
22 |
|
23 |
# Get the annual income statement data
|
24 |
income_statement = ticker.financials
|
25 |
|
26 |
# Transpose the income statement to have years as rows
|
27 |
income_statement = income_statement.T
|
28 |
|
29 |
# Extract net income and calculate EPS
|
30 |
income_statement['EPS'] = income_statement['Net Income'] / shares_outstanding
|
31 |
|
32 |
# Convert the 'Date' index to a year
|
33 |
income_statement.index = income_statement.index.year
|
34 |
|
35 |
# Combine EPS and closing prices into one DataFrame
|
36 |
pe_ratios_df = pd.DataFrame({
|
37 |
'Year': income_statement.index,
|
38 |
'EPS': income_statement['EPS'],
|
39 |
'Revenue': income_statement['Total Revenue'],
|
40 |
'Closing Price': year_end_prices.reindex(income_statement.index).values
|
41 |
})
|
42 |
|
43 |
# Calculate the P/E ratio
|
44 |
pe_ratios_df['P/E Ratio'] = pe_ratios_df['Closing Price'] / pe_ratios_df['EPS']
|
45 |
|
46 |
# Calculate Market Capitalization for each year (Closing Price * Shares Outstanding)
|
47 |
pe_ratios_df['Market Cap'] = pe_ratios_df['Closing Price'] * shares_outstanding
|
48 |
|
49 |
# Calculate the P/S ratio
|
50 |
pe_ratios_df['P/S Ratio'] = pe_ratios_df['Market Cap'] / pe_ratios_df['Revenue']
|
51 |
|
52 |
# Create DataFrame with last 10 years
|
53 |
current_year = datetime.now().year
|
54 |
|
55 |
# Create a list of the last 10 years
|
56 |
years = list(range(current_year - 9, current_year + 1))
|
57 |
|
58 |
# Create a DataFrame
|
59 |
df_years = pd.DataFrame({'Year': years})
|
60 |
|
61 |
# Get the historical dividend data
|
62 |
dividend_data = ticker.dividends
|
63 |
|
64 |
# Convert the Series to a DataFrame
|
65 |
dividend_df = dividend_data.reset_index()
|
66 |
|
67 |
# Rename the columns for clarity
|
68 |
dividend_df.columns = ['Date', 'Dividend']
|
69 |
|
70 |
# Extract the year from the Date column
|
71 |
dividend_df['Year'] = dividend_df['Date'].dt.year
|
72 |
|
73 |
# Group by Year and get the last dividend of each year
|
74 |
dividend_df = dividend_df.groupby('Year').last().reset_index()
|
75 |
|
76 |
# Merge DataFrames
|
77 |
dividend_df = pd.merge(df_years, dividend_df, on='Year', how='left')
|
78 |
|
79 |
# Replace NaN with last years value
|
80 |
dividend_df['Dividend'] = dividend_df['Dividend'].ffill()
|
81 |
|
82 |
# Sort the DataFrame by Year
|
83 |
dividend_df = dividend_df.sort_values(by='Year')
|
84 |
|
85 |
# Calculate the 3-year percentage change
|
86 |
dividend_df['Dividend Growth (3y)'] = dividend_df['Dividend'].pct_change(periods=3) * 100
|
87 |
|
88 |
# Calculate the 5-year percentage change
|
89 |
dividend_df['Dividend Growth (5y)'] = dividend_df['Dividend'].pct_change(periods=5) * 100
|
90 |
|
91 |
# Calculate the 10-year percentage change
|
92 |
dividend_df['Dividend Growth (10y)'] = dividend_df['Dividend'].pct_change(periods=10) * 100
|
93 |
|
94 |
# Drop Columns
|
95 |
dividend_df = dividend_df.drop(columns=['Dividend'])
|
96 |
|
97 |
print(dividend_df)
|
98 |
|
99 |
# Get the historical stock price data for the last 10 years
|
100 |
price_history = ticker.history(period='10y')
|
101 |
|
102 |
# Initialize a list to accumulate the annual data
|
103 |
value_data = []
|
104 |
|
105 |
# Start with an initial investment value of 1 share
|
106 |
initial_value = price_history['Close'].iloc[0]
|
107 |
cumulative_value = initial_value
|
108 |
|
109 |
# Track the last year processed to ensure we only capture the final value for each year
|
110 |
last_year = price_history.index[0].year
|
111 |
|
112 |
# Iterate over each date in the price history to calculate the value including dividends
|
113 |
for i in range(len(price_history)):
|
114 |
current_date = price_history.index[i]
|
115 |
current_price = price_history['Close'].iloc[i]
|
116 |
current_year = current_date.year
|
117 |
|
118 |
# Check if any dividends were paid out on the current date
|
119 |
if current_date in dividend_df['Date'].values:
|
120 |
dividend = dividend_df[dividend_df['Date'] == current_date]['Dividend'].values[0]
|
121 |
# Calculate the value increase due to dividends
|
122 |
cumulative_value += (dividend / current_price) * cumulative_value
|
123 |
|
124 |
# Update the cumulative value with the price change
|
125 |
if i < len(price_history) - 1:
|
126 |
next_price = price_history['Close'].iloc[i + 1]
|
127 |
cumulative_value *= (next_price / current_price)
|
128 |
|
129 |
# At the end of each year, record the value including dividends
|
130 |
if current_year != last_year:
|
131 |
# Append the cumulative value at the end of the previous year
|
132 |
value_data.append({'Year': last_year, 'Value Including Dividends': cumulative_value})
|
133 |
last_year = current_year
|
134 |
|
135 |
# Append the final value at the end of the last year in the dataset
|
136 |
value_data.append({'Year': last_year, 'Value Including Dividends': cumulative_value})
|
137 |
|
138 |
# Convert the accumulated list to a DataFrame
|
139 |
value_including_dividends_df = pd.DataFrame(value_data)
|
140 |
|
141 |
# Calculate the percentage increase in value including dividends
|
142 |
value_including_dividends_df['Value Increase'] = value_including_dividends_df['Value Including Dividends'].pct_change() * 100
|
143 |
|
144 |
# Get the historical dividend data
|
145 |
dividend_data = ticker.dividends
|
146 |
|
147 |
# Convert the Series to a DataFrame
|
148 |
dividend_df2 = dividend_data.reset_index()
|
149 |
|
150 |
# Rename the columns for clarity
|
151 |
dividend_df2.columns = ['Date', 'Dividend']
|
152 |
|
153 |
# Extract the year from the Date column
|
154 |
dividend_df2['Year'] = dividend_df2['Date'].dt.year
|
155 |
|
156 |
# Aggregate the annual dividends by summing them up
|
157 |
annual_dividends = dividend_df2.groupby('Year')['Dividend'].sum().reset_index()
|
158 |
|
159 |
# Calculate the year-over-year dividend increase
|
160 |
annual_dividends['Dividend Increase'] = annual_dividends['Dividend'].diff() > 0
|
161 |
|
162 |
# Calculate the cumulative number of increases
|
163 |
annual_dividends['No of Increases'] = annual_dividends['Dividend Increase'].cumsum()
|
164 |
|
165 |
# Drop the 'Dividend Increase' column if not needed in the final output
|
166 |
annual_dividends = annual_dividends.drop(columns=['Dividend Increase'])
|
167 |
|
168 |
# Get the annual income statement data to find EPS
|
169 |
income_statement = ticker.financials.T
|
170 |
|
171 |
# Extract the EPS (Earnings Per Share)
|
172 |
annual_eps = (income_statement['Net Income'] / ticker.info['sharesOutstanding']).reset_index()
|
173 |
annual_eps.columns = ['Year', 'EPS']
|
174 |
|
175 |
# Convert the index to years for the EPS DataFrame
|
176 |
annual_eps['Year'] = annual_eps['Year'].dt.year
|
177 |
|
178 |
# Align the DataFrames on the 'Year' column
|
179 |
aligned_dividends_eps = pd.merge(annual_dividends, annual_eps, on='Year', how='outer')
|
180 |
|
181 |
# Calculate the Payout Ratio
|
182 |
aligned_dividends_eps['Payout Ratio (%)'] = (aligned_dividends_eps['Dividend'] / aligned_dividends_eps['EPS']) * 100
|
183 |
|
184 |
aligned_dividends_eps.sort_values('Year', axis=0, ascending=True, inplace=True)
|
185 |
|
186 |
# Get the income statement data
|
187 |
income_statement = ticker.financials
|
188 |
|
189 |
# Transpose the data to make it easier to read
|
190 |
income_statement = income_statement.T
|
191 |
|
192 |
# Rename the columns for clarity
|
193 |
income_statement = income_statement.rename(columns={'Total Revenue': 'Revenue'})
|
194 |
income_statement = income_statement.rename(columns={'Gross Profit': 'Earnings'})
|
195 |
|
196 |
# Convert Index to Year and rename it to Year and sort by it
|
197 |
income_statement['Year'] = income_statement.index.year
|
198 |
income_statement = income_statement.sort_values(by='Year')
|
199 |
|
200 |
# Calculate Growth Columns
|
201 |
income_statement['Revenue Growth'] = income_statement['Revenue'].pct_change() * 100
|
202 |
income_statement['EBITDA Growth'] = income_statement['EBITDA'].pct_change() * 100
|
203 |
|
204 |
# Calculate Margin Columns
|
205 |
income_statement['EBITDA Margin'] = (income_statement['EBITDA']/income_statement['Revenue']).pct_change() * 100
|
206 |
|
207 |
# Calculate Gross Profit and Gross Profit Margin and Gross Profit Growth
|
208 |
income_statement['GP'] = income_statement['Revenue'] - income_statement['Cost Of Revenue']
|
209 |
income_statement['GP Margin'] = (income_statement['GP'] / income_statement['Revenue']) * 100
|
210 |
|
211 |
# Calculate Gross Profit Growth
|
212 |
income_statement['GP Growth'] = income_statement['GP'].pct_change() * 100
|
213 |
|
214 |
# Format EBITDA
|
215 |
income_statement['EBITDA MEUR'] = income_statement['EBITDA'] / 1000000
|
216 |
|
217 |
income_df = income_statement[['Year','EBITDA MEUR', 'Revenue Growth', 'GP Margin', 'GP Growth', 'EBITDA Margin', 'EBITDA Growth']]
|
218 |
|
219 |
# Get the cashflow data
|
220 |
cashflow_data = ticker.cashflow
|
221 |
|
222 |
# Transpose the data to have years as rows
|
223 |
cashflow_statement = cashflow_data.T
|
224 |
|
225 |
# Get the number of shares outstanding from the info
|
226 |
shares_outstanding = ticker.info.get('sharesOutstanding')
|
227 |
|
228 |
# Extract Cash Flow from Operations and CapEx
|
229 |
cashflow_operations = cashflow_statement['Operating Cash Flow']
|
230 |
capex = cashflow_statement['Capital Expenditure']
|
231 |
cashflow = cashflow_statement['Free Cash Flow']
|
232 |
|
233 |
# Calculate Cash Flow per Share
|
234 |
cashflow_per_share = cashflow_operations / shares_outstanding
|
235 |
|
236 |
# Calculate Free Cash Flow (FCF)
|
237 |
cashflow = cashflow_operations + capex # CapEx is typically a negative number in the cash flow statement
|
238 |
|
239 |
# Convert the 'Date' index to a year
|
240 |
cashflow.index = cashflow.index.year
|
241 |
|
242 |
# Create a DataFrame for display
|
243 |
cashflow_df = pd.DataFrame({
|
244 |
'Year': cashflow.index,
|
245 |
'Cashflow Operations': cashflow_operations.values,
|
246 |
'Cashflow per Share': cashflow_per_share,
|
247 |
#'Capital Expenditures': capex.values,
|
248 |
'Free Cashflow': cashflow.values
|
249 |
})
|
250 |
|
251 |
# Get the annual balance sheet data
|
252 |
balance_sheet = ticker.balance_sheet
|
253 |
|
254 |
# Transpose the data to have years as rows
|
255 |
balance_sheet = balance_sheet.T
|
256 |
|
257 |
# Extract Total Stockholder Equity
|
258 |
total_equity = balance_sheet['Stockholders Equity']
|
259 |
|
260 |
# Get the number of shares outstanding from the info
|
261 |
shares_outstanding = ticker.info.get('sharesOutstanding')
|
262 |
|
263 |
# Calculate Book Value per Share
|
264 |
book_value_per_share = total_equity / shares_outstanding
|
265 |
|
266 |
# Extract Total Debt and Cash Equivalents
|
267 |
total_debt = balance_sheet['Total Debt']
|
268 |
cash_and_equivalents = balance_sheet['Cash And Cash Equivalents']
|
269 |
|
270 |
# Calculate Net Financial Liabilities
|
271 |
net_financial_liabilities = total_debt - cash_and_equivalents
|
272 |
|
273 |
# Convert the index to years
|
274 |
net_financial_liabilities.index = net_financial_liabilities.index.year
|
275 |
|
276 |
# Create a DataFrame for display
|
277 |
net_financial_liabilities_df = pd.DataFrame({
|
278 |
'Year': net_financial_liabilities.index,
|
279 |
'Bookvalue per Share': book_value_per_share,
|
280 |
'Total Debt': total_debt.values,
|
281 |
'Cash': cash_and_equivalents.values,
|
282 |
'Net Financial Liabilities': net_financial_liabilities.values
|
283 |
})
|
284 |
|
285 |
# Merge DataFrames
|
286 |
df = pd.merge(pe_ratios_df, annual_dividends, on='Year', how='left')
|
287 |
df = pd.merge(df, value_including_dividends_df, on='Year', how='inner')
|
288 |
df = pd.merge(df, income_df, on='Year', how='inner')
|
289 |
df = pd.merge(df, dividend_df, on='Year', how='left')
|
290 |
df = pd.merge(df, cashflow_df, on='Year', how='inner')
|
291 |
df = pd.merge(df, net_financial_liabilities_df, on='Year', how='inner')
|
292 |
|
293 |
return company_name, df
|
294 |
gr.Markdown("# Stock Data Viewer\nEnter a stock ticker symbol to view the historical data.")
|
295 |
|
296 |
with gr.Row():
|
297 |
ticker_input = gr.Textbox(label="Enter Ticker Symbol")
|
298 |
with gr.Row():
|
299 |
submit_btn = gr.Button("Submit")
|
300 |
|
301 |
ticker_headline = gr.Markdown("")
|
302 |
|
303 |
with gr.Row():
|
304 |
data_output = gr.Dataframe()
|
305 |
def show_dataframe(ticker):
|
306 |
company_name, df = get_stock_data(ticker)
|
307 |
headline = f"### Data for {company_name} ({ticker})"
|
308 |
return headline, df
|
309 |
submit_btn.click(show_dataframe, inputs=ticker_input, outputs=[ticker_headline, data_output])
|
|
|
1 |
+
import yfinance as yf
|
2 |
# Max Rows and Columns
|
3 |
pd.set_option('display.max_columns', 500)
|
4 |
pd.set_option('display.max_rows', None)
|
5 |
|
6 |
# Two Decimals
|
7 |
pd.options.display.float_format = '{:.2f}'.format
|
8 |
|
9 |
# The stock symbol
|
10 |
symbol = ticker
|
11 |
ticker = yf.Ticker(symbol)
|
12 |
company_name = ticker.info.get("longName", "N/A")
|
13 |
|
14 |
# Get historical share prices
|
15 |
price_history = ticker.history(period='5y')
|
16 |
|
17 |
# Extract the closing prices at the end of each fiscal year
|
18 |
# We will reindex to have end-of-year dates that match the years of the income statements
|
19 |
year_end_prices = price_history.resample('A').last()['Close']
|
20 |
year_end_prices.index = year_end_prices.index.year
|
21 |
|
22 |
# Get the number of shares from the info or financials
|
23 |
shares_outstanding = ticker.info.get('sharesOutstanding')
|
24 |
|
25 |
# Get the annual income statement data
|
26 |
income_statement = ticker.financials
|
27 |
|
28 |
# Transpose the income statement to have years as rows
|
29 |
income_statement = income_statement.T
|
30 |
|
31 |
# Extract net income and calculate EPS
|
32 |
income_statement['EPS'] = income_statement['Net Income'] / shares_outstanding
|
33 |
|
34 |
# Convert the 'Date' index to a year
|
35 |
income_statement.index = income_statement.index.year
|
36 |
|
37 |
# Combine EPS and closing prices into one DataFrame
|
38 |
pe_ratios_df = pd.DataFrame({
|
39 |
'Year': income_statement.index,
|
40 |
'EPS': income_statement['EPS'],
|
41 |
'Revenue': income_statement['Total Revenue'],
|
42 |
'Closing Price': year_end_prices.reindex(income_statement.index).values
|
43 |
})
|
44 |
|
45 |
# Calculate the P/E ratio
|
46 |
pe_ratios_df['P/E Ratio'] = pe_ratios_df['Closing Price'] / pe_ratios_df['EPS']
|
47 |
|
48 |
# Calculate Market Capitalization for each year (Closing Price * Shares Outstanding)
|
49 |
pe_ratios_df['Market Cap'] = pe_ratios_df['Closing Price'] * shares_outstanding
|
50 |
|
51 |
# Calculate the P/S ratio
|
52 |
pe_ratios_df['P/S Ratio'] = pe_ratios_df['Market Cap'] / pe_ratios_df['Revenue']
|
53 |
|
54 |
# Create DataFrame with last 10 years
|
55 |
current_year = datetime.now().year
|
56 |
|
57 |
# Create a list of the last 10 years
|
58 |
years = list(range(current_year - 9, current_year + 1))
|
59 |
|
60 |
# Create a DataFrame
|
61 |
df_years = pd.DataFrame({'Year': years})
|
62 |
|
63 |
# Get the historical dividend data
|
64 |
dividend_data = ticker.dividends
|
65 |
|
66 |
# Convert the Series to a DataFrame
|
67 |
dividend_df = dividend_data.reset_index()
|
68 |
|
69 |
# Rename the columns for clarity
|
70 |
dividend_df.columns = ['Date', 'Dividend']
|
71 |
|
72 |
# Extract the year from the Date column
|
73 |
dividend_df['Year'] = dividend_df['Date'].dt.year
|
74 |
|
75 |
# Group by Year and get the last dividend of each year
|
76 |
dividend_df = dividend_df.groupby('Year').last().reset_index()
|
77 |
|
78 |
# Merge DataFrames
|
79 |
dividend_df = pd.merge(df_years, dividend_df, on='Year', how='left')
|
80 |
|
81 |
# Replace NaN with last years value
|
82 |
dividend_df['Dividend'] = dividend_df['Dividend'].ffill()
|
83 |
|
84 |
# Sort the DataFrame by Year
|
85 |
dividend_df = dividend_df.sort_values(by='Year')
|
86 |
|
87 |
# Calculate the 3-year percentage change
|
88 |
dividend_df['Dividend Growth (3y)'] = dividend_df['Dividend'].pct_change(periods=3) * 100
|
89 |
|
90 |
# Calculate the 5-year percentage change
|
91 |
dividend_df['Dividend Growth (5y)'] = dividend_df['Dividend'].pct_change(periods=5) * 100
|
92 |
|
93 |
# Calculate the 10-year percentage change
|
94 |
dividend_df['Dividend Growth (10y)'] = dividend_df['Dividend'].pct_change(periods=10) * 100
|
95 |
|
96 |
# Drop Columns
|
97 |
dividend_df = dividend_df.drop(columns=['Dividend'])
|
98 |
|
99 |
print(dividend_df)
|
100 |
|
101 |
# Get the historical stock price data for the last 10 years
|
102 |
price_history = ticker.history(period='10y')
|
103 |
|
104 |
# Initialize a list to accumulate the annual data
|
105 |
value_data = []
|
106 |
|
107 |
# Start with an initial investment value of 1 share
|
108 |
initial_value = price_history['Close'].iloc[0]
|
109 |
cumulative_value = initial_value
|
110 |
|
111 |
# Track the last year processed to ensure we only capture the final value for each year
|
112 |
last_year = price_history.index[0].year
|
113 |
|
114 |
# Iterate over each date in the price history to calculate the value including dividends
|
115 |
for i in range(len(price_history)):
|
116 |
current_date = price_history.index[i]
|
117 |
current_price = price_history['Close'].iloc[i]
|
118 |
current_year = current_date.year
|
119 |
|
120 |
# Check if any dividends were paid out on the current date
|
121 |
if current_date in dividend_df['Date'].values:
|
122 |
dividend = dividend_df[dividend_df['Date'] == current_date]['Dividend'].values[0]
|
123 |
# Calculate the value increase due to dividends
|
124 |
cumulative_value += (dividend / current_price) * cumulative_value
|
125 |
|
126 |
# Update the cumulative value with the price change
|
127 |
if i < len(price_history) - 1:
|
128 |
next_price = price_history['Close'].iloc[i + 1]
|
129 |
cumulative_value *= (next_price / current_price)
|
130 |
|
131 |
# At the end of each year, record the value including dividends
|
132 |
if current_year != last_year:
|
133 |
# Append the cumulative value at the end of the previous year
|
134 |
value_data.append({'Year': last_year, 'Value Including Dividends': cumulative_value})
|
135 |
last_year = current_year
|
136 |
|
137 |
# Append the final value at the end of the last year in the dataset
|
138 |
value_data.append({'Year': last_year, 'Value Including Dividends': cumulative_value})
|
139 |
|
140 |
# Convert the accumulated list to a DataFrame
|
141 |
value_including_dividends_df = pd.DataFrame(value_data)
|
142 |
|
143 |
# Calculate the percentage increase in value including dividends
|
144 |
value_including_dividends_df['Value Increase'] = value_including_dividends_df['Value Including Dividends'].pct_change() * 100
|
145 |
|
146 |
# Get the historical dividend data
|
147 |
dividend_data = ticker.dividends
|
148 |
|
149 |
# Convert the Series to a DataFrame
|
150 |
dividend_df2 = dividend_data.reset_index()
|
151 |
|
152 |
# Rename the columns for clarity
|
153 |
dividend_df2.columns = ['Date', 'Dividend']
|
154 |
|
155 |
# Extract the year from the Date column
|
156 |
dividend_df2['Year'] = dividend_df2['Date'].dt.year
|
157 |
|
158 |
# Aggregate the annual dividends by summing them up
|
159 |
annual_dividends = dividend_df2.groupby('Year')['Dividend'].sum().reset_index()
|
160 |
|
161 |
# Calculate the year-over-year dividend increase
|
162 |
annual_dividends['Dividend Increase'] = annual_dividends['Dividend'].diff() > 0
|
163 |
|
164 |
# Calculate the cumulative number of increases
|
165 |
annual_dividends['No of Increases'] = annual_dividends['Dividend Increase'].cumsum()
|
166 |
|
167 |
# Drop the 'Dividend Increase' column if not needed in the final output
|
168 |
annual_dividends = annual_dividends.drop(columns=['Dividend Increase'])
|
169 |
|
170 |
# Get the annual income statement data to find EPS
|
171 |
income_statement = ticker.financials.T
|
172 |
|
173 |
# Extract the EPS (Earnings Per Share)
|
174 |
annual_eps = (income_statement['Net Income'] / ticker.info['sharesOutstanding']).reset_index()
|
175 |
annual_eps.columns = ['Year', 'EPS']
|
176 |
|
177 |
# Convert the index to years for the EPS DataFrame
|
178 |
annual_eps['Year'] = annual_eps['Year'].dt.year
|
179 |
|
180 |
# Align the DataFrames on the 'Year' column
|
181 |
aligned_dividends_eps = pd.merge(annual_dividends, annual_eps, on='Year', how='outer')
|
182 |
|
183 |
# Calculate the Payout Ratio
|
184 |
aligned_dividends_eps['Payout Ratio (%)'] = (aligned_dividends_eps['Dividend'] / aligned_dividends_eps['EPS']) * 100
|
185 |
|
186 |
aligned_dividends_eps.sort_values('Year', axis=0, ascending=True, inplace=True)
|
187 |
|
188 |
# Get the income statement data
|
189 |
income_statement = ticker.financials
|
190 |
|
191 |
# Transpose the data to make it easier to read
|
192 |
income_statement = income_statement.T
|
193 |
|
194 |
# Rename the columns for clarity
|
195 |
income_statement = income_statement.rename(columns={'Total Revenue': 'Revenue'})
|
196 |
income_statement = income_statement.rename(columns={'Gross Profit': 'Earnings'})
|
197 |
|
198 |
# Convert Index to Year and rename it to Year and sort by it
|
199 |
income_statement['Year'] = income_statement.index.year
|
200 |
income_statement = income_statement.sort_values(by='Year')
|
201 |
|
202 |
# Calculate Growth Columns
|
203 |
income_statement['Revenue Growth'] = income_statement['Revenue'].pct_change() * 100
|
204 |
income_statement['EBITDA Growth'] = income_statement['EBITDA'].pct_change() * 100
|
205 |
|
206 |
# Calculate Margin Columns
|
207 |
income_statement['EBITDA Margin'] = (income_statement['EBITDA']/income_statement['Revenue']).pct_change() * 100
|
208 |
|
209 |
# Calculate Gross Profit and Gross Profit Margin and Gross Profit Growth
|
210 |
income_statement['GP'] = income_statement['Revenue'] - income_statement['Cost Of Revenue']
|
211 |
income_statement['GP Margin'] = (income_statement['GP'] / income_statement['Revenue']) * 100
|
212 |
|
213 |
# Calculate Gross Profit Growth
|
214 |
income_statement['GP Growth'] = income_statement['GP'].pct_change() * 100
|
215 |
|
216 |
# Format EBITDA
|
217 |
income_statement['EBITDA MEUR'] = income_statement['EBITDA'] / 1000000
|
218 |
|
219 |
income_df = income_statement[['Year','EBITDA MEUR', 'Revenue Growth', 'GP Margin', 'GP Growth', 'EBITDA Margin', 'EBITDA Growth']]
|
220 |
|
221 |
# Get the cashflow data
|
222 |
cashflow_data = ticker.cashflow
|
223 |
|
224 |
# Transpose the data to have years as rows
|
225 |
cashflow_statement = cashflow_data.T
|
226 |
|
227 |
# Get the number of shares outstanding from the info
|
228 |
shares_outstanding = ticker.info.get('sharesOutstanding')
|
229 |
|
230 |
# Extract Cash Flow from Operations and CapEx
|
231 |
cashflow_operations = cashflow_statement['Operating Cash Flow']
|
232 |
capex = cashflow_statement['Capital Expenditure']
|
233 |
cashflow = cashflow_statement['Free Cash Flow']
|
234 |
|
235 |
# Calculate Cash Flow per Share
|
236 |
cashflow_per_share = cashflow_operations / shares_outstanding
|
237 |
|
238 |
# Calculate Free Cash Flow (FCF)
|
239 |
cashflow = cashflow_operations + capex # CapEx is typically a negative number in the cash flow statement
|
240 |
|
241 |
# Convert the 'Date' index to a year
|
242 |
cashflow.index = cashflow.index.year
|
243 |
|
244 |
# Create a DataFrame for display
|
245 |
cashflow_df = pd.DataFrame({
|
246 |
'Year': cashflow.index,
|
247 |
'Cashflow Operations': cashflow_operations.values,
|
248 |
'Cashflow per Share': cashflow_per_share,
|
249 |
#'Capital Expenditures': capex.values,
|
250 |
'Free Cashflow': cashflow.values
|
251 |
})
|
252 |
|
253 |
# Get the annual balance sheet data
|
254 |
balance_sheet = ticker.balance_sheet
|
255 |
|
256 |
# Transpose the data to have years as rows
|
257 |
balance_sheet = balance_sheet.T
|
258 |
|
259 |
# Extract Total Stockholder Equity
|
260 |
total_equity = balance_sheet['Stockholders Equity']
|
261 |
|
262 |
# Get the number of shares outstanding from the info
|
263 |
shares_outstanding = ticker.info.get('sharesOutstanding')
|
264 |
|
265 |
# Calculate Book Value per Share
|
266 |
book_value_per_share = total_equity / shares_outstanding
|
267 |
|
268 |
# Extract Total Debt and Cash Equivalents
|
269 |
total_debt = balance_sheet['Total Debt']
|
270 |
cash_and_equivalents = balance_sheet['Cash And Cash Equivalents']
|
271 |
|
272 |
# Calculate Net Financial Liabilities
|
273 |
net_financial_liabilities = total_debt - cash_and_equivalents
|
274 |
|
275 |
# Convert the index to years
|
276 |
net_financial_liabilities.index = net_financial_liabilities.index.year
|
277 |
|
278 |
# Create a DataFrame for display
|
279 |
net_financial_liabilities_df = pd.DataFrame({
|
280 |
'Year': net_financial_liabilities.index,
|
281 |
'Bookvalue per Share': book_value_per_share,
|
282 |
'Total Debt': total_debt.values,
|
283 |
'Cash': cash_and_equivalents.values,
|
284 |
'Net Financial Liabilities': net_financial_liabilities.values
|
285 |
})
|
286 |
|
287 |
# Merge DataFrames
|
288 |
df = pd.merge(pe_ratios_df, annual_dividends, on='Year', how='left')
|
289 |
df = pd.merge(df, value_including_dividends_df, on='Year', how='inner')
|
290 |
df = pd.merge(df, income_df, on='Year', how='inner')
|
291 |
df = pd.merge(df, dividend_df, on='Year', how='left')
|
292 |
df = pd.merge(df, cashflow_df, on='Year', how='inner')
|
293 |
df = pd.merge(df, net_financial_liabilities_df, on='Year', how='inner')
|
294 |
|
295 |
return company_name, df
|
296 |
gr.Markdown("# Stock Data Viewer\nEnter a stock ticker symbol to view the historical data.")
|
297 |
|
298 |
with gr.Row():
|
299 |
ticker_input = gr.Textbox(label="Enter Ticker Symbol")
|
300 |
with gr.Row():
|
301 |
submit_btn = gr.Button("Submit")
|
302 |
|
303 |
ticker_headline = gr.Markdown("")
|
304 |
|
305 |
with gr.Row():
|
306 |
data_output = gr.Dataframe()
|
307 |
def show_dataframe(ticker):
|
308 |
company_name, df = get_stock_data(ticker)
|
309 |
headline = f"### Data for {company_name} ({ticker})"
|
310 |
return headline, df
|
311 |
submit_btn.click(show_dataframe, inputs=ticker_input, outputs=[ticker_headline, data_output])
|