QuantumLearner commited on
Commit
eda34ec
·
verified ·
1 Parent(s): f169387

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +445 -178
app.py CHANGED
@@ -20,13 +20,12 @@ def interpret_growth_metrics(df, metric_list, section_title):
20
  """
21
  Generate a dynamic and formatted interpretation.
22
  It covers recent values, comparisons, summary statistics,
23
- and tangible insights specific to the section.
24
  """
25
  existing_cols = [m for m in metric_list if m in df.columns]
26
  if not existing_cols or df.empty:
27
- return f"**{section_title}**: Data is not available."
28
 
29
- # Drop rows with all NaNs in these columns.
30
  df_valid = df[['date'] + existing_cols].dropna(subset=existing_cols, how='all')
31
  if df_valid.empty:
32
  return f"**{section_title}**: No valid data entries."
@@ -48,14 +47,13 @@ def interpret_growth_metrics(df, metric_list, section_title):
48
  max_vals = values_only.max()
49
  std_vals = values_only.std()
50
 
51
- # Build the interpretation text with clear sections.
52
  text = f"##### {section_title}\n\n"
53
  text += "**Recent Data:**\n"
54
  text += f"- **Latest Record Date:** {latest_date.date()}\n"
55
  for col in existing_cols:
56
  latest_val = latest_row[col]
57
  if pd.isna(latest_val):
58
- text += f"- **{col}:** Data missing in the latest record.\n"
59
  else:
60
  text += f"- **{col}:** {latest_val:.2f}\n"
61
 
@@ -65,7 +63,7 @@ def interpret_growth_metrics(df, metric_list, section_title):
65
  latest_val = latest_row[col]
66
  prior_val = prior_row[col]
67
  if pd.isna(latest_val) or pd.isna(prior_val):
68
- text += f"- **{col}:** Comparison not possible due to missing data.\n"
69
  else:
70
  diff = latest_val - prior_val
71
  if diff > 0:
@@ -73,7 +71,7 @@ def interpret_growth_metrics(df, metric_list, section_title):
73
  elif diff < 0:
74
  text += f"- **{col}:** Decreased by {abs(diff):.2f}.\n"
75
  else:
76
- text += f"- **{col}:** Remained the same.\n"
77
 
78
  text += "\n**Historical Summary:**\n"
79
  for col in existing_cols:
@@ -81,205 +79,474 @@ def interpret_growth_metrics(df, metric_list, section_title):
81
  f"Min = {min_vals[col]:.2f}, Max = {max_vals[col]:.2f}, "
82
  f"Std Dev = {std_vals[col]:.2f}.\n")
83
 
84
- # Section-specific final interpretation.
85
  text += "\n**Final Interpretation:**\n"
86
- if "Profitability" in section_title:
87
- text += ("- Rising revenue, gross profit, EBIT, operating income, or net income "
88
- "suggests better market performance and stronger operations. "
89
- "A decline might mean increased costs or reduced sales. "
90
- "Stable figures show consistency in performance.\n")
91
- elif "EPS" in section_title:
92
- text += ("- Increases in EPS imply higher earnings per share, which may attract investors. "
93
- "A drop can hint at dilution or rising costs. "
94
- "Stable EPS reflects steady earnings.\n")
95
- elif "Share Count" in section_title:
96
- text += ("- An increase in share count may result from issuing new shares or stock-based compensation, "
97
- "which can dilute value. "
98
- "A decrease may reflect share buybacks, often seen as positive.\n")
99
- elif "Dividend" in section_title:
100
- text += ("- Growing dividend figures indicate higher cash returns to shareholders "
101
- "and may reflect a strong cash position. "
102
- "Declining dividends can signal caution or cash retention.\n")
103
- elif "Cash Flow" in section_title:
104
- text += ("- An increase in cash flow points to efficient operations and solid liquidity. "
105
- "A decrease may reveal issues with cash generation or higher working capital needs. "
106
- "Steady cash flow suggests stability.\n")
107
- elif any(keyword in section_title for keyword in ["Revenue", "Net Income", "Operating Cash Flow", "Shareholders’ Equity"]):
108
- text += ("- Sustained long-term growth is a positive sign of company strength. "
109
- "Declines over several years may indicate underlying challenges. "
110
- "Stable trends show reliable performance over time.\n")
111
- elif "Balance Sheet" in section_title:
112
- text += ("- Increases in assets and book value per share typically indicate financial strength. "
113
- "However, rising receivables, inventory, or debt should be analyzed for efficiency issues. "
114
- "Balance sheet trends require careful review.\n")
115
- elif "Expense" in section_title:
116
- text += ("- Higher R&D expenses may point to investments in future growth, while rising SGA expenses "
117
- "could indicate increased operating costs. "
118
- "Stable expenses are a sign of controlled costs.\n")
119
- else:
120
- text += ("- Review these trends with your own analysis to understand what the changes mean.\n")
121
-
122
  return text
123
 
124
  # ----------------------------
125
- # App header and description
126
- # ----------------------------
127
- st.title("Key Financial Growth")
128
- st.markdown("""
129
- This dashboard shows key financial growth metrics.
130
- Metrics are grouped by category for side-by-side comparison.
131
- Use the sidebar to set inputs and click **Run Analysis**.
132
- """)
133
-
134
- # ----------------------------
135
- # Sidebar inputs
136
- # ----------------------------
137
- st.sidebar.header("Inputs")
138
- with st.sidebar.expander("Settings", expanded=True):
139
- symbol = st.text_input("Company Symbol", value="AAPL", help="Enter the company's stock symbol (e.g., AAPL).")
140
- period = st.selectbox("Period", options=["annual", "quarter"], help="Choose to view quarterly or annual data.")
141
-
142
- run_button = st.sidebar.button("Run Analysis")
143
-
144
- # ----------------------------
145
- # Main Analysis and Visualization
146
  # ----------------------------
147
- if run_button:
 
 
 
 
 
148
  url = f"https://financialmodelingprep.com/api/v3/financial-growth/{symbol}?period={period}&apikey={API_KEY}"
149
  try:
150
  response = requests.get(url)
151
  response.raise_for_status()
152
  data = response.json()
153
-
154
  if not data:
155
- st.error("No data returned. Check the symbol or period.")
156
- else:
157
- df = pd.DataFrame(data)
158
- if "date" in df.columns:
159
- df['date'] = pd.to_datetime(df['date'], errors='coerce')
160
- df.sort_values("date", inplace=True)
161
- st.success("Data loaded successfully!")
162
- st.write("Each section below shows a chart and its interpretation.")
163
-
164
- # 1. Income Statement – Profitability Metrics
165
- st.subheader("1. Income Statement – Profitability Metrics")
166
- profitability_vars = ["revenueGrowth", "grossProfitGrowth", "ebitgrowth", "operatingIncomeGrowth", "netIncomeGrowth"]
167
- try:
168
- fig1 = px.line(df, x="date", y=profitability_vars, title="Profitability Metrics")
169
- fig1.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
170
- st.plotly_chart(fig1, use_container_width=True)
171
- except Exception:
172
- st.error("Error generating the Profitability Metrics chart.")
173
- with st.expander("Interpretation"):
174
- interp_text = interpret_growth_metrics(df, profitability_vars, "Profitability Metrics")
175
- st.markdown(interp_text)
176
 
177
- # 2. Earnings Per Share Metrics
178
- st.subheader("2. Earnings Per Share Metrics")
179
- eps_vars = ["epsgrowth", "epsdilutedGrowth"]
180
- try:
181
- fig2 = px.line(df, x="date", y=eps_vars, title="EPS Metrics")
182
- fig2.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
183
- st.plotly_chart(fig2, use_container_width=True)
184
- except Exception:
185
- st.error("Error generating the EPS Metrics chart.")
186
- with st.expander("Interpretation"):
187
- interp_text = interpret_growth_metrics(df, eps_vars, "EPS Metrics")
188
- st.markdown(interp_text)
189
 
190
- # 3. Share Count Adjustments
191
- st.subheader("3. Share Count Adjustments")
192
- share_vars = ["weightedAverageSharesGrowth", "weightedAverageSharesDilutedGrowth"]
193
- try:
194
- fig3 = px.line(df, x="date", y=share_vars, title="Share Count Adjustments")
195
- fig3.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
196
- st.plotly_chart(fig3, use_container_width=True)
197
- except Exception:
198
- st.error("Error generating the Share Count Adjustments chart.")
199
- with st.expander("Interpretation"):
200
- interp_text = interpret_growth_metrics(df, share_vars, "Share Count Adjustments")
201
- st.markdown(interp_text)
 
 
 
202
 
203
- # 4. Dividend Metric
204
- st.subheader("4. Dividend Metric")
205
- try:
206
- fig4 = px.line(df, x="date", y=["dividendsperShareGrowth"], title="Dividend per Share Growth")
207
- fig4.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
208
- st.plotly_chart(fig4, use_container_width=True)
209
- except Exception:
210
- st.error("Error generating the Dividend Metric chart.")
211
- with st.expander("Interpretation"):
212
- interp_text = interpret_growth_metrics(df, ["dividendsperShareGrowth"], "Dividend Growth")
213
- st.markdown(interp_text)
 
214
 
215
- # 5. Cash Flow Metrics
216
- st.subheader("5. Cash Flow Metrics")
217
- cashflow_vars = ["operatingCashFlowGrowth", "freeCashFlowGrowth"]
218
- try:
219
- fig5 = px.line(df, x="date", y=cashflow_vars, title="Cash Flow Metrics")
220
- fig5.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
221
- st.plotly_chart(fig5, use_container_width=True)
222
- except Exception:
223
- st.error("Error generating the Cash Flow Metrics chart.")
224
- with st.expander("Interpretation"):
225
- interp_text = interpret_growth_metrics(df, cashflow_vars, "Cash Flow Metrics")
226
- st.markdown(interp_text)
227
 
228
- # 6. Multi-Year Growth Metrics (Per Share Basis)
229
- st.subheader("6. Multi-Year Growth Metrics (Per Share Basis)")
230
- multi_year_groups = {
231
- "Revenue Growth": ["tenYRevenueGrowthPerShare", "fiveYRevenueGrowthPerShare", "threeYRevenueGrowthPerShare"],
232
- "Operating Cash Flow Growth": ["tenYOperatingCFGrowthPerShare", "fiveYOperatingCFGrowthPerShare", "threeYOperatingCFGrowthPerShare"],
233
- "Net Income Growth": ["tenYNetIncomeGrowthPerShare", "fiveYNetIncomeGrowthPerShare", "threeYNetIncomeGrowthPerShare"],
234
- "Shareholders’ Equity Growth": ["tenYShareholdersEquityGrowthPerShare", "fiveYShareholdersEquityGrowthPerShare", "threeYShareholdersEquityGrowthPerShare"],
235
- "Dividend per Share Growth": ["tenYDividendperShareGrowthPerShare", "fiveYDividendperShareGrowthPerShare", "threeYDividendperShareGrowthPerShare"]
236
- }
237
- for subgroup, vars_list in multi_year_groups.items():
238
- st.markdown(f"**{subgroup}**")
239
- try:
240
- fig = px.line(df, x="date", y=vars_list, title=subgroup)
241
- fig.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
242
- st.plotly_chart(fig, use_container_width=True)
243
- except Exception:
244
- st.error(f"Error generating chart for {subgroup}.")
245
- with st.expander("Interpretation"):
246
- interp_text = interpret_growth_metrics(df, vars_list, subgroup)
247
- st.markdown(interp_text)
248
-
249
- # 7. Balance Sheet Metrics
250
- st.subheader("7. Balance Sheet Metrics")
251
- balance_vars = ["receivablesGrowth", "inventoryGrowth", "assetGrowth", "bookValueperShareGrowth", "debtGrowth"]
252
- try:
253
- fig7 = px.line(df, x="date", y=balance_vars, title="Balance Sheet Metrics")
254
- fig7.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
255
- st.plotly_chart(fig7, use_container_width=True)
256
- except Exception:
257
- st.error("Error generating the Balance Sheet Metrics chart.")
258
- with st.expander("Interpretation"):
259
- interp_text = interpret_growth_metrics(df, balance_vars, "Balance Sheet Metrics")
260
- st.markdown(interp_text)
261
 
262
- # 8. Expense Metrics
263
- st.subheader("8. Expense Metrics")
264
- expense_vars = ["rdexpenseGrowth", "sgaexpensesGrowth"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  try:
266
- fig8 = px.line(df, x="date", y=expense_vars, title="Expense Metrics")
267
- fig8.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
268
- st.plotly_chart(fig8, use_container_width=True)
269
  except Exception:
270
- st.error("Error generating the Expense Metrics chart.")
271
  with st.expander("Interpretation"):
272
- interp_text = interpret_growth_metrics(df, expense_vars, "Expense Metrics")
273
  st.markdown(interp_text)
274
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275
  except requests.exceptions.RequestException:
276
- st.error("Error fetching data. Check your connection and inputs.")
277
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
 
 
279
  hide_streamlit_style = """
280
  <style>
281
  #MainMenu {visibility: hidden;}
282
  footer {visibility: hidden;}
283
  </style>
284
  """
285
- st.markdown(hide_streamlit_style, unsafe_allow_html=True)
 
20
  """
21
  Generate a dynamic and formatted interpretation.
22
  It covers recent values, comparisons, summary statistics,
23
+ and insights for the section.
24
  """
25
  existing_cols = [m for m in metric_list if m in df.columns]
26
  if not existing_cols or df.empty:
27
+ return f"**{section_title}**: Data not available."
28
 
 
29
  df_valid = df[['date'] + existing_cols].dropna(subset=existing_cols, how='all')
30
  if df_valid.empty:
31
  return f"**{section_title}**: No valid data entries."
 
47
  max_vals = values_only.max()
48
  std_vals = values_only.std()
49
 
 
50
  text = f"##### {section_title}\n\n"
51
  text += "**Recent Data:**\n"
52
  text += f"- **Latest Record Date:** {latest_date.date()}\n"
53
  for col in existing_cols:
54
  latest_val = latest_row[col]
55
  if pd.isna(latest_val):
56
+ text += f"- **{col}:** Missing in latest record.\n"
57
  else:
58
  text += f"- **{col}:** {latest_val:.2f}\n"
59
 
 
63
  latest_val = latest_row[col]
64
  prior_val = prior_row[col]
65
  if pd.isna(latest_val) or pd.isna(prior_val):
66
+ text += f"- **{col}:** No comparison (missing data).\n"
67
  else:
68
  diff = latest_val - prior_val
69
  if diff > 0:
 
71
  elif diff < 0:
72
  text += f"- **{col}:** Decreased by {abs(diff):.2f}.\n"
73
  else:
74
+ text += f"- **{col}:** No change.\n"
75
 
76
  text += "\n**Historical Summary:**\n"
77
  for col in existing_cols:
 
79
  f"Min = {min_vals[col]:.2f}, Max = {max_vals[col]:.2f}, "
80
  f"Std Dev = {std_vals[col]:.2f}.\n")
81
 
 
82
  text += "\n**Final Interpretation:**\n"
83
+ text += "- Track these changes over time to see if they align with expectations.\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  return text
85
 
86
  # ----------------------------
87
+ # Pages
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  # ----------------------------
89
+ def show_financial_growth(symbol, period):
90
+ """
91
+ Original page.
92
+ Calls /financial-growth/ endpoint.
93
+ Uses the existing sections of analysis.
94
+ """
95
  url = f"https://financialmodelingprep.com/api/v3/financial-growth/{symbol}?period={period}&apikey={API_KEY}"
96
  try:
97
  response = requests.get(url)
98
  response.raise_for_status()
99
  data = response.json()
 
100
  if not data:
101
+ st.error("No data returned. Check symbol or period.")
102
+ return
103
+ df = pd.DataFrame(data)
104
+ if "date" in df.columns:
105
+ df["date"] = pd.to_datetime(df["date"], errors="coerce")
106
+ df.sort_values("date", inplace=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
+ st.success("Data loaded successfully.")
109
+ st.write("Below are key growth metrics. Expand each section for interpretation.")
 
 
 
 
 
 
 
 
 
 
110
 
111
+ # 1. Income Statement – Profitability Metrics
112
+ st.subheader("1. Profitability")
113
+ profitability_vars = [
114
+ "revenueGrowth", "grossProfitGrowth", "ebitgrowth",
115
+ "operatingIncomeGrowth", "netIncomeGrowth"
116
+ ]
117
+ try:
118
+ fig1 = px.line(df, x="date", y=profitability_vars, title="Profitability Metrics")
119
+ fig1.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
120
+ st.plotly_chart(fig1, use_container_width=True)
121
+ except Exception:
122
+ st.error("Could not plot Profitability Metrics.")
123
+ with st.expander("Interpretation"):
124
+ interp_text = interpret_growth_metrics(df, profitability_vars, "Profitability Metrics")
125
+ st.markdown(interp_text)
126
 
127
+ # 2. EPS
128
+ st.subheader("2. Earnings Per Share")
129
+ eps_vars = ["epsgrowth", "epsdilutedGrowth"]
130
+ try:
131
+ fig2 = px.line(df, x="date", y=eps_vars, title="EPS Metrics")
132
+ fig2.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
133
+ st.plotly_chart(fig2, use_container_width=True)
134
+ except Exception:
135
+ st.error("Could not plot EPS Metrics.")
136
+ with st.expander("Interpretation"):
137
+ interp_text = interpret_growth_metrics(df, eps_vars, "EPS Metrics")
138
+ st.markdown(interp_text)
139
 
140
+ # 3. Share Count
141
+ st.subheader("3. Share Count")
142
+ share_vars = ["weightedAverageSharesGrowth", "weightedAverageSharesDilutedGrowth"]
143
+ try:
144
+ fig3 = px.line(df, x="date", y=share_vars, title="Share Count Adjustments")
145
+ fig3.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
146
+ st.plotly_chart(fig3, use_container_width=True)
147
+ except Exception:
148
+ st.error("Could not plot Share Count.")
149
+ with st.expander("Interpretation"):
150
+ interp_text = interpret_growth_metrics(df, share_vars, "Share Count Adjustments")
151
+ st.markdown(interp_text)
152
 
153
+ # 4. Dividend
154
+ st.subheader("4. Dividend per Share")
155
+ try:
156
+ fig4 = px.line(df, x="date", y=["dividendsperShareGrowth"], title="Dividend Growth")
157
+ fig4.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
158
+ st.plotly_chart(fig4, use_container_width=True)
159
+ except Exception:
160
+ st.error("Could not plot Dividend Growth.")
161
+ with st.expander("Interpretation"):
162
+ interp_text = interpret_growth_metrics(df, ["dividendsperShareGrowth"], "Dividend Growth")
163
+ st.markdown(interp_text)
164
+
165
+ # 5. Cash Flow
166
+ st.subheader("5. Cash Flow")
167
+ cashflow_vars = ["operatingCashFlowGrowth", "freeCashFlowGrowth"]
168
+ try:
169
+ fig5 = px.line(df, x="date", y=cashflow_vars, title="Cash Flow Metrics")
170
+ fig5.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
171
+ st.plotly_chart(fig5, use_container_width=True)
172
+ except Exception:
173
+ st.error("Could not plot Cash Flow Metrics.")
174
+ with st.expander("Interpretation"):
175
+ interp_text = interpret_growth_metrics(df, cashflow_vars, "Cash Flow Metrics")
176
+ st.markdown(interp_text)
 
 
 
 
 
 
 
 
 
177
 
178
+ # 6. Multi-Year Growth
179
+ st.subheader("6. Multi-Year Growth (Per Share)")
180
+ multi_year_groups = {
181
+ "Revenue Growth": [
182
+ "tenYRevenueGrowthPerShare", "fiveYRevenueGrowthPerShare",
183
+ "threeYRevenueGrowthPerShare"
184
+ ],
185
+ "Operating Cash Flow Growth": [
186
+ "tenYOperatingCFGrowthPerShare", "fiveYOperatingCFGrowthPerShare",
187
+ "threeYOperatingCFGrowthPerShare"
188
+ ],
189
+ "Net Income Growth": [
190
+ "tenYNetIncomeGrowthPerShare", "fiveYNetIncomeGrowthPerShare",
191
+ "threeYNetIncomeGrowthPerShare"
192
+ ],
193
+ "Shareholders’ Equity Growth": [
194
+ "tenYShareholdersEquityGrowthPerShare", "fiveYShareholdersEquityGrowthPerShare",
195
+ "threeYShareholdersEquityGrowthPerShare"
196
+ ],
197
+ "Dividend per Share Growth": [
198
+ "tenYDividendperShareGrowthPerShare", "fiveYDividendperShareGrowthPerShare",
199
+ "threeYDividendperShareGrowthPerShare"
200
+ ]
201
+ }
202
+ for subgroup, vars_list in multi_year_groups.items():
203
+ st.markdown(f"**{subgroup}**")
204
  try:
205
+ fig = px.line(df, x="date", y=vars_list, title=subgroup)
206
+ fig.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
207
+ st.plotly_chart(fig, use_container_width=True)
208
  except Exception:
209
+ st.error(f"Error generating chart for {subgroup}.")
210
  with st.expander("Interpretation"):
211
+ interp_text = interpret_growth_metrics(df, vars_list, subgroup)
212
  st.markdown(interp_text)
213
 
214
+ # 7. Balance Sheet
215
+ st.subheader("7. Balance Sheet")
216
+ balance_vars = ["receivablesGrowth", "inventoryGrowth", "assetGrowth",
217
+ "bookValueperShareGrowth", "debtGrowth"]
218
+ try:
219
+ fig7 = px.line(df, x="date", y=balance_vars, title="Balance Sheet Metrics")
220
+ fig7.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
221
+ st.plotly_chart(fig7, use_container_width=True)
222
+ except Exception:
223
+ st.error("Could not plot Balance Sheet Metrics.")
224
+ with st.expander("Interpretation"):
225
+ interp_text = interpret_growth_metrics(df, balance_vars, "Balance Sheet Metrics")
226
+ st.markdown(interp_text)
227
+
228
+ # 8. Expense
229
+ st.subheader("8. Expense")
230
+ expense_vars = ["rdexpenseGrowth", "sgaexpensesGrowth"]
231
+ try:
232
+ fig8 = px.line(df, x="date", y=expense_vars, title="Expense Metrics")
233
+ fig8.update_layout(xaxis_title="Date", yaxis_title="Growth Rate", legend_title="Metric")
234
+ st.plotly_chart(fig8, use_container_width=True)
235
+ except Exception:
236
+ st.error("Could not plot Expense Metrics.")
237
+ with st.expander("Interpretation"):
238
+ interp_text = interpret_growth_metrics(df, expense_vars, "Expense Metrics")
239
+ st.markdown(interp_text)
240
+
241
+ except requests.exceptions.RequestException:
242
+ st.error("Error fetching data. Check connection and inputs.")
243
+
244
+ def show_balance_sheet_growth(symbol, period):
245
+ """
246
+ Page for balance sheet growth.
247
+ Calls /balance-sheet-statement-growth/ endpoint.
248
+ Displays asset, liability, equity, and debt growth.
249
+ """
250
+ url = f"https://financialmodelingprep.com/api/v3/balance-sheet-statement-growth/{symbol}?period={period}&apikey={API_KEY}"
251
+ try:
252
+ r = requests.get(url)
253
+ r.raise_for_status()
254
+ data = r.json()
255
+ if not data:
256
+ st.error("No data returned. Check symbol or period.")
257
+ return
258
+ df = pd.DataFrame(data)
259
+ if "date" in df.columns:
260
+ df["date"] = pd.to_datetime(df["date"], errors="coerce")
261
+ df.sort_values("date", inplace=True)
262
+
263
+ st.success("Data loaded successfully.")
264
+ st.write("These sections show balance sheet growth metrics.")
265
+
266
+ # Assets
267
+ st.subheader("1. Asset Growth")
268
+ asset_vars = [
269
+ "growthCashAndCashEquivalents", "growthShortTermInvestments",
270
+ "growthCashAndShortTermInvestments", "growthNetReceivables",
271
+ "growthInventory", "growthTotalCurrentAssets",
272
+ "growthPropertyPlantEquipmentNet", "growthTotalNonCurrentAssets",
273
+ "growthTotalAssets"
274
+ ]
275
+ try:
276
+ fig_a = px.line(df, x="date", y=asset_vars, title="Asset Growth")
277
+ fig_a.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
278
+ st.plotly_chart(fig_a, use_container_width=True)
279
+ except Exception:
280
+ st.error("Could not plot Asset Growth.")
281
+ with st.expander("Interpretation"):
282
+ interp_text = interpret_growth_metrics(df, asset_vars, "Asset Growth")
283
+ st.markdown(interp_text)
284
+
285
+ # Liabilities
286
+ st.subheader("2. Liability Growth")
287
+ liability_vars = [
288
+ "growthAccountPayables", "growthShortTermDebt", "growthTaxPayables",
289
+ "growthTotalCurrentLiabilities", "growthLongTermDebt",
290
+ "growthTotalNonCurrentLiabilities", "growthTotalLiabilities"
291
+ ]
292
+ try:
293
+ fig_l = px.line(df, x="date", y=liability_vars, title="Liability Growth")
294
+ fig_l.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
295
+ st.plotly_chart(fig_l, use_container_width=True)
296
+ except Exception:
297
+ st.error("Could not plot Liability Growth.")
298
+ with st.expander("Interpretation"):
299
+ interp_text = interpret_growth_metrics(df, liability_vars, "Liability Growth")
300
+ st.markdown(interp_text)
301
+
302
+ # Equity
303
+ st.subheader("3. Equity Growth")
304
+ equity_vars = [
305
+ "growthCommonStock", "growthRetainedEarnings",
306
+ "growthAccumulatedOtherComprehensiveIncomeLoss",
307
+ "growthTotalStockholdersEquity"
308
+ ]
309
+ try:
310
+ fig_e = px.line(df, x="date", y=equity_vars, title="Equity Growth")
311
+ fig_e.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
312
+ st.plotly_chart(fig_e, use_container_width=True)
313
+ except Exception:
314
+ st.error("Could not plot Equity Growth.")
315
+ with st.expander("Interpretation"):
316
+ interp_text = interpret_growth_metrics(df, equity_vars, "Equity Growth")
317
+ st.markdown(interp_text)
318
+
319
+ # Debt
320
+ st.subheader("4. Debt Metrics")
321
+ debt_vars = [
322
+ "growthTotalDebt", "growthNetDebt"
323
+ ]
324
+ try:
325
+ fig_d = px.line(df, x="date", y=debt_vars, title="Debt Metrics")
326
+ fig_d.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
327
+ st.plotly_chart(fig_d, use_container_width=True)
328
+ except Exception:
329
+ st.error("Could not plot Debt Metrics.")
330
+ with st.expander("Interpretation"):
331
+ interp_text = interpret_growth_metrics(df, debt_vars, "Debt Metrics")
332
+ st.markdown(interp_text)
333
+
334
+ except requests.exceptions.RequestException:
335
+ st.error("Error fetching data. Check connection and inputs.")
336
+
337
+ def show_income_growth(symbol, period):
338
+ """
339
+ Page for income statement growth.
340
+ Calls /income-statement-growth/ endpoint.
341
+ Groups items into profitability, expenses, net, etc.
342
+ """
343
+ url = f"https://financialmodelingprep.com/api/v3/income-statement-growth/{symbol}?period={period}&apikey={API_KEY}"
344
+ try:
345
+ r = requests.get(url)
346
+ r.raise_for_status()
347
+ data = r.json()
348
+ if not data:
349
+ st.error("No data returned. Check symbol or period.")
350
+ return
351
+ df = pd.DataFrame(data)
352
+ if "date" in df.columns:
353
+ df["date"] = pd.to_datetime(df["date"], errors="coerce")
354
+ df.sort_values("date", inplace=True)
355
+
356
+ st.success("Data loaded successfully.")
357
+ st.write("These sections show income statement growth metrics.")
358
+
359
+ # Profitability
360
+ st.subheader("1. Profitability")
361
+ profitability_vars = [
362
+ "growthRevenue", "growthGrossProfit", "growthOperatingIncome",
363
+ "growthNetIncome", "growthEBITDA"
364
+ ]
365
+ try:
366
+ fig_p = px.line(df, x="date", y=profitability_vars, title="Profitability Growth")
367
+ fig_p.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
368
+ st.plotly_chart(fig_p, use_container_width=True)
369
+ except Exception:
370
+ st.error("Could not plot Profitability Growth.")
371
+ with st.expander("Interpretation"):
372
+ interp_text = interpret_growth_metrics(df, profitability_vars, "Profitability Growth")
373
+ st.markdown(interp_text)
374
+
375
+ # Expense
376
+ st.subheader("2. Expense")
377
+ expense_vars = [
378
+ "growthCostOfRevenue", "growthOperatingExpenses",
379
+ "growthResearchAndDevelopmentExpenses", "growthSellingAndMarketingExpenses"
380
+ ]
381
+ try:
382
+ fig_e = px.line(df, x="date", y=expense_vars, title="Expense Growth")
383
+ fig_e.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
384
+ st.plotly_chart(fig_e, use_container_width=True)
385
+ except Exception:
386
+ st.error("Could not plot Expense Growth.")
387
+ with st.expander("Interpretation"):
388
+ interp_text = interpret_growth_metrics(df, expense_vars, "Expense Growth")
389
+ st.markdown(interp_text)
390
+
391
+ # Net and Tax
392
+ st.subheader("3. Net and Tax Metrics")
393
+ net_tax_vars = [
394
+ "growthIncomeBeforeTax", "growthIncomeTaxExpense",
395
+ "growthNetIncome", "growthNetIncomeRatio"
396
+ ]
397
+ try:
398
+ fig_n = px.line(df, x="date", y=net_tax_vars, title="Net Income and Tax Growth")
399
+ fig_n.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
400
+ st.plotly_chart(fig_n, use_container_width=True)
401
+ except Exception:
402
+ st.error("Could not plot Net Income/Tax Growth.")
403
+ with st.expander("Interpretation"):
404
+ interp_text = interpret_growth_metrics(df, net_tax_vars, "Net Income/Tax Growth")
405
+ st.markdown(interp_text)
406
+
407
+ # EPS
408
+ st.subheader("4. EPS Growth")
409
+ eps_vars = ["growthEPS", "growthEPSDiluted"]
410
+ try:
411
+ fig_eps = px.line(df, x="date", y=eps_vars, title="EPS Growth")
412
+ fig_eps.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
413
+ st.plotly_chart(fig_eps, use_container_width=True)
414
+ except Exception:
415
+ st.error("Could not plot EPS Growth.")
416
+ with st.expander("Interpretation"):
417
+ interp_text = interpret_growth_metrics(df, eps_vars, "EPS Growth")
418
+ st.markdown(interp_text)
419
+
420
  except requests.exceptions.RequestException:
421
+ st.error("Error fetching data. Check connection and inputs.")
422
 
423
+ def show_cashflow_growth(symbol, period):
424
+ """
425
+ Page for cash flow statement growth.
426
+ Calls /cash-flow-statement-growth/ endpoint.
427
+ Groups items into operating, investing, financing metrics.
428
+ """
429
+ url = f"https://financialmodelingprep.com/api/v3/cash-flow-statement-growth/{symbol}?period={period}&apikey={API_KEY}"
430
+ try:
431
+ r = requests.get(url)
432
+ r.raise_for_status()
433
+ data = r.json()
434
+ if not data:
435
+ st.error("No data returned. Check symbol or period.")
436
+ return
437
+ df = pd.DataFrame(data)
438
+ if "date" in df.columns:
439
+ df["date"] = pd.to_datetime(df["date"], errors="coerce")
440
+ df.sort_values("date", inplace=True)
441
+
442
+ st.success("Data loaded successfully.")
443
+ st.write("These sections show cash flow statement growth metrics.")
444
+
445
+ # Operating
446
+ st.subheader("1. Operating Activities")
447
+ operating_vars = [
448
+ "growthNetIncome", "growthDepreciationAndAmortization",
449
+ "growthChangeInWorkingCapital", "growthNetCashProvidedByOperatingActivites",
450
+ "growthOperatingCashFlow"
451
+ ]
452
+ try:
453
+ fig_op = px.line(df, x="date", y=operating_vars, title="Operating Cash Flow Growth")
454
+ fig_op.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
455
+ st.plotly_chart(fig_op, use_container_width=True)
456
+ except Exception:
457
+ st.error("Could not plot Operating CF Growth.")
458
+ with st.expander("Interpretation"):
459
+ interp_text = interpret_growth_metrics(df, operating_vars, "Operating CF Growth")
460
+ st.markdown(interp_text)
461
+
462
+ # Investing
463
+ st.subheader("2. Investing Activities")
464
+ investing_vars = [
465
+ "growthInvestmentsInPropertyPlantAndEquipment", "growthAcquisitionsNet",
466
+ "growthPurchasesOfInvestments", "growthSalesMaturitiesOfInvestments",
467
+ "growthNetCashUsedForInvestingActivites"
468
+ ]
469
+ try:
470
+ fig_inv = px.line(df, x="date", y=investing_vars, title="Investing Cash Flow Growth")
471
+ fig_inv.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
472
+ st.plotly_chart(fig_inv, use_container_width=True)
473
+ except Exception:
474
+ st.error("Could not plot Investing CF Growth.")
475
+ with st.expander("Interpretation"):
476
+ interp_text = interpret_growth_metrics(df, investing_vars, "Investing CF Growth")
477
+ st.markdown(interp_text)
478
+
479
+ # Financing
480
+ st.subheader("3. Financing Activities")
481
+ financing_vars = [
482
+ "growthDebtRepayment", "growthCommonStockRepurchased",
483
+ "growthDividendsPaid", "growthNetCashUsedProvidedByFinancingActivities"
484
+ ]
485
+ try:
486
+ fig_fin = px.line(df, x="date", y=financing_vars, title="Financing Cash Flow Growth")
487
+ fig_fin.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
488
+ st.plotly_chart(fig_fin, use_container_width=True)
489
+ except Exception:
490
+ st.error("Could not plot Financing CF Growth.")
491
+ with st.expander("Interpretation"):
492
+ interp_text = interpret_growth_metrics(df, financing_vars, "Financing CF Growth")
493
+ st.markdown(interp_text)
494
+
495
+ # Free Cash Flow
496
+ st.subheader("4. Free Cash Flow")
497
+ fcf_vars = ["growthFreeCashFlow"]
498
+ try:
499
+ fig_fcf = px.line(df, x="date", y=fcf_vars, title="Free Cash Flow Growth")
500
+ fig_fcf.update_layout(xaxis_title="Date", yaxis_title="Growth", legend_title="Metric")
501
+ st.plotly_chart(fig_fcf, use_container_width=True)
502
+ except Exception:
503
+ st.error("Could not plot Free Cash Flow Growth.")
504
+ with st.expander("Interpretation"):
505
+ interp_text = interpret_growth_metrics(df, fcf_vars, "Free Cash Flow Growth")
506
+ st.markdown(interp_text)
507
+
508
+ except requests.exceptions.RequestException:
509
+ st.error("Error fetching data. Check connection and inputs.")
510
+
511
+ # ----------------------------
512
+ # Main
513
+ # ----------------------------
514
+ st.title("Company Growth Rates with Multi-Page Analysis")
515
+ st.markdown("""
516
+ This app provides four pages:
517
+ 1. Financial Growth
518
+ 2. Balance Sheet Growth
519
+ 3. Income Growth
520
+ 4. Cash Flow Growth
521
+
522
+ Use the radio button below to switch between them.
523
+ Enter your symbol and period in the sidebar, then click **Run**.
524
+ """)
525
+
526
+ page = st.radio("Select Page",
527
+ ["Financial Growth", "Balance Sheet Growth", "Income Growth", "Cash Flow Growth"],
528
+ index=0)
529
+
530
+ st.sidebar.header("Inputs")
531
+ symbol = st.sidebar.text_input("Company Symbol", value="AAPL")
532
+ period = st.sidebar.selectbox("Period", options=["annual", "quarter"])
533
+ run_button = st.sidebar.button("Run")
534
+
535
+ if run_button:
536
+ if page == "Financial Growth":
537
+ show_financial_growth(symbol, period)
538
+ elif page == "Balance Sheet Growth":
539
+ show_balance_sheet_growth(symbol, period)
540
+ elif page == "Income Growth":
541
+ show_income_growth(symbol, period)
542
+ elif page == "Cash Flow Growth":
543
+ show_cashflow_growth(symbol, period)
544
 
545
+ # Hide Streamlit style
546
  hide_streamlit_style = """
547
  <style>
548
  #MainMenu {visibility: hidden;}
549
  footer {visibility: hidden;}
550
  </style>
551
  """
552
+ st.markdown(hide_streamlit_style, unsafe_allow_html=True)