Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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
|
| 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
|
| 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}:**
|
| 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}:**
|
| 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}:**
|
| 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 |
-
|
| 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 |
-
#
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 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 |
-
|
| 178 |
-
|
| 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 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
|
|
|
|
|
|
|
|
|
| 202 |
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
|
|
|
| 214 |
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 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 |
-
|
| 263 |
-
|
| 264 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 265 |
try:
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
st.plotly_chart(
|
| 269 |
except Exception:
|
| 270 |
-
st.error("Error generating
|
| 271 |
with st.expander("Interpretation"):
|
| 272 |
-
interp_text = interpret_growth_metrics(df,
|
| 273 |
st.markdown(interp_text)
|
| 274 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
except requests.exceptions.RequestException:
|
| 276 |
-
st.error("Error fetching data. Check
|
| 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)
|