aboutsummaryrefslogtreecommitdiff
path: root/components/valuation.py
diff options
context:
space:
mode:
authorTyler <tyler@tylerhoang.xyz>2026-03-30 19:09:45 -0700
committerTyler <tyler@tylerhoang.xyz>2026-03-30 19:09:45 -0700
commit92b7eae36866c3424f44b4b6a653833a65df91a9 (patch)
tree1ab8d86c74b741d5e1b2e8df2caa6de0b0bc9464 /components/valuation.py
parent8f6199a97c592e68f812d952b41942603723e2ed (diff)
Compute all Key Ratios from raw statements, eliminating FMP ratio calls
Added compute_ttm_ratios() which derives all 16 TTM ratios directly from yfinance quarterly income statements, balance sheets, and cash flow: Valuation: P/E, P/S, P/B, EV/EBITDA, EV/Revenue Profitability: Gross/Operating/Net Margin, ROE, ROA, ROIC Leverage: D/E, Current Ratio, Quick Ratio, Interest Coverage Dividends: Yield, Payout Ratio get_key_ratios() no longer calls FMP's /ratios-ttm or /key-metrics-ttm endpoints, saving ~2 FMP API calls per ticker load (including each Comps peer). Forward P/E still comes from yfinance info dict (analyst estimate). This also fixes EV/EBITDA for all tickers (DDOG was 4998x from FMP/yfinance pre-computed values, now correctly 194x from income statement EBITDA). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'components/valuation.py')
-rw-r--r--components/valuation.py47
1 files changed, 18 insertions, 29 deletions
diff --git a/components/valuation.py b/components/valuation.py
index e77073f..7ac32f5 100644
--- a/components/valuation.py
+++ b/components/valuation.py
@@ -143,45 +143,34 @@ def _render_ratios(ticker: str):
st.info("Ratio data unavailable. Check your FMP API key.")
return
- def r(fmp_key, yf_key=None, fmt=fmt_ratio):
- val = ratios.get(fmp_key) if ratios else None
- if val is None and yf_key and info:
- val = info.get(yf_key)
+ def r(key, fmt=fmt_ratio):
+ val = ratios.get(key) if ratios else None
return fmt(val) if val is not None else "—"
- # Always compute EV/EBITDA from income statement — both FMP and yfinance's
- # pre-computed multiples use a bad EBITDA figure for many tickers.
- def _ev_ebitda() -> str:
- ev = info.get("enterpriseValue")
- ebitda = get_ebitda_from_income_stmt(ticker)
- if ev and ebitda and ebitda > 0:
- return fmt_ratio(ev / ebitda)
- return "—"
-
rows = [
("Valuation", [
- ("P/E (TTM)", r("peRatioTTM", "trailingPE")),
- ("Forward P/E", fmt_ratio(info.get("forwardPE")) if info.get("forwardPE") is not None else "—"),
- ("P/S (TTM)", r("priceToSalesRatioTTM", "priceToSalesTrailing12Months")),
- ("P/B", r("priceToBookRatioTTM", "priceToBook")),
- ("EV/EBITDA", _ev_ebitda()),
- ("EV/Revenue", r("evToSalesTTM", "enterpriseToRevenue")),
+ ("P/E (TTM)", r("peRatioTTM")),
+ ("Forward P/E", r("forwardPE")),
+ ("P/S (TTM)", r("priceToSalesRatioTTM")),
+ ("P/B", r("priceToBookRatioTTM")),
+ ("EV/EBITDA", r("enterpriseValueMultipleTTM")),
+ ("EV/Revenue", r("evToSalesTTM")),
]),
("Profitability", [
- ("Gross Margin", r("grossProfitMarginTTM", "grossMargins", fmt_pct)),
- ("Operating Margin", r("operatingProfitMarginTTM", "operatingMargins", fmt_pct)),
- ("Net Margin", r("netProfitMarginTTM", "profitMargins", fmt_pct)),
- ("ROE", r("returnOnEquityTTM", "returnOnEquity", fmt_pct)),
- ("ROA", r("returnOnAssetsTTM", "returnOnAssets", fmt_pct)),
+ ("Gross Margin", r("grossProfitMarginTTM", fmt=fmt_pct)),
+ ("Operating Margin", r("operatingProfitMarginTTM", fmt=fmt_pct)),
+ ("Net Margin", r("netProfitMarginTTM", fmt=fmt_pct)),
+ ("ROE", r("returnOnEquityTTM", fmt=fmt_pct)),
+ ("ROA", r("returnOnAssetsTTM", fmt=fmt_pct)),
("ROIC", r("returnOnInvestedCapitalTTM", fmt=fmt_pct)),
]),
("Leverage & Liquidity", [
- ("Debt/Equity", r("debtToEquityRatioTTM", "debtToEquity")),
- ("Current Ratio", r("currentRatioTTM", "currentRatio")),
- ("Quick Ratio", r("quickRatioTTM", "quickRatio")),
+ ("Debt/Equity", r("debtToEquityRatioTTM")),
+ ("Current Ratio", r("currentRatioTTM")),
+ ("Quick Ratio", r("quickRatioTTM")),
("Interest Coverage", r("interestCoverageRatioTTM")),
- ("Dividend Yield", r("dividendYieldTTM", "dividendYield", fmt_pct)),
- ("Payout Ratio", r("dividendPayoutRatioTTM", "payoutRatio", fmt_pct)),
+ ("Dividend Yield", r("dividendYieldTTM", fmt=fmt_pct)),
+ ("Payout Ratio", r("dividendPayoutRatioTTM", fmt=fmt_pct)),
]),
]