diff options
| author | Tyler <tyler@tylerhoang.xyz> | 2026-03-30 19:09:45 -0700 |
|---|---|---|
| committer | Tyler <tyler@tylerhoang.xyz> | 2026-03-30 19:09:45 -0700 |
| commit | 92b7eae36866c3424f44b4b6a653833a65df91a9 (patch) | |
| tree | 1ab8d86c74b741d5e1b2e8df2caa6de0b0bc9464 /components/valuation.py | |
| parent | 8f6199a97c592e68f812d952b41942603723e2ed (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.py | 47 |
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)), ]), ] |
