aboutsummaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/data_service.py24
-rw-r--r--services/valuation_service.py15
2 files changed, 36 insertions, 3 deletions
diff --git a/services/data_service.py b/services/data_service.py
index 67f2e7b..bfd1290 100644
--- a/services/data_service.py
+++ b/services/data_service.py
@@ -684,3 +684,27 @@ def get_free_cash_flow_series(ticker: str) -> pd.Series:
return (op + capex).dropna()
except KeyError:
return pd.Series(dtype=float)
+
+
+@st.cache_data(ttl=3600)
+def get_free_cash_flow_ttm(ticker: str) -> float | None:
+ """Return trailing-twelve-month free cash flow from quarterly cash flow statements."""
+ t = yf.Ticker(ticker.upper())
+ cf_q = t.quarterly_cashflow
+ if cf_q is None or cf_q.empty:
+ return None
+
+ if "Free Cash Flow" in cf_q.index:
+ vals = cf_q.loc["Free Cash Flow"].iloc[:4].dropna()
+ if len(vals) == 4:
+ return float(vals.sum())
+
+ try:
+ op = cf_q.loc["Operating Cash Flow"].iloc[:4].dropna()
+ capex = cf_q.loc["Capital Expenditure"].iloc[:4].dropna()
+ if len(op) == 4 and len(capex) == 4:
+ return float((op + capex).sum())
+ except KeyError:
+ return None
+
+ return None
diff --git a/services/valuation_service.py b/services/valuation_service.py
index 357c679..1230aa5 100644
--- a/services/valuation_service.py
+++ b/services/valuation_service.py
@@ -50,6 +50,7 @@ def run_dcf(
terminal_growth: float = 0.03,
projection_years: int = 5,
growth_rate_override: float | None = None,
+ base_fcf_override: float | None = None,
total_debt: float = 0.0,
cash_and_equivalents: float = 0.0,
preferred_equity: float = 0.0,
@@ -78,7 +79,7 @@ def run_dcf(
historical_growth = compute_historical_growth_rate(fcf_series)
growth_rate = historical_growth if historical_growth is not None else 0.05
- base_fcf = float(historical[-1])
+ base_fcf = float(base_fcf_override) if base_fcf_override is not None else float(historical[-1])
if base_fcf <= 0:
return {
"error": (
@@ -136,6 +137,8 @@ def run_ev_ebitda(
ebitda: float,
total_debt: float,
total_cash: float,
+ preferred_equity: float,
+ minority_interest: float,
shares_outstanding: float,
target_multiple: float,
) -> dict:
@@ -149,11 +152,13 @@ def run_ev_ebitda(
implied_ev = ebitda * target_multiple
net_debt = (total_debt or 0.0) - (total_cash or 0.0)
- equity_value = implied_ev - net_debt
+ other_claims = (preferred_equity or 0.0) + (minority_interest or 0.0)
+ equity_value = implied_ev - net_debt - other_claims
return {
"implied_ev": implied_ev,
"net_debt": net_debt,
+ "other_claims": other_claims,
"equity_value": equity_value,
"implied_price_per_share": equity_value / shares_outstanding,
"target_multiple_used": target_multiple,
@@ -164,6 +169,8 @@ def run_ev_revenue(
revenue: float,
total_debt: float,
total_cash: float,
+ preferred_equity: float,
+ minority_interest: float,
shares_outstanding: float,
target_multiple: float,
) -> dict:
@@ -177,11 +184,13 @@ def run_ev_revenue(
implied_ev = revenue * target_multiple
net_debt = (total_debt or 0.0) - (total_cash or 0.0)
- equity_value = implied_ev - net_debt
+ other_claims = (preferred_equity or 0.0) + (minority_interest or 0.0)
+ equity_value = implied_ev - net_debt - other_claims
return {
"implied_ev": implied_ev,
"net_debt": net_debt,
+ "other_claims": other_claims,
"equity_value": equity_value,
"implied_price_per_share": equity_value / shares_outstanding,
"target_multiple_used": target_multiple,