Do Healthcare Cash-Flow Margins Predict Returns? Signal Evaluation in Python
June 12, 2026
What's the question?
Free-cash-flow margin measures how much revenue turns into free cash flow after operating needs and capital spending. It is a useful quality measure because reported earnings can improve while cash generation remains weak. In healthcare, cash-flow quality matters because business models differ widely: managed care, pharmaceuticals, and diversified medical products do not convert revenue into cash at the same rate.
The question is whether improving free-cash-flow margins have been followed by better stock performance. This is not a valuation model. It is a signal test. A signal is useful if it separates stronger forward-return groups from weaker ones without relying on hindsight.
The approach
The universe is UNH, JNJ, LLY, MRK, ABBV, and PFE. Built from SEC EDGAR public filings and market data, the test uses annual filings and daily split-adjusted prices.
- Pull ten years of annual revenue and free cash flow
- Calculate free-cash-flow margin for each annual filing
- Measure the year-over-year change in that margin
- Start the forward-return clock on the filing date, not the fiscal period end
- Compare 126-trading-day returns after positive margin inflections with returns after flat or negative inflections
Using the filing date is important because it avoids treating financial statement data as known before it was publicly filed.
Code
import xfinlink as xfl
import pandas as pd
xfl.set_api_key("YOUR_API_KEY") # free at https://xfinlink.com/signup
tickers = ["UNH", "JNJ", "LLY", "MRK", "ABBV", "PFE"]
fund = xfl.fundamentals(tickers, period_type="annual", period="10y",
fields=["revenue", "free_cash_flow"])
prices = xfl.prices(tickers, start="2016-01-01", fields=["adj_close"])
pivot = prices.pivot_table(index="date", columns="ticker", values="adj_close")
events = []
for ticker, group in fund.sort_values(["ticker", "period_end"]).groupby("ticker"):
group["fcf_margin"] = group["free_cash_flow"] / group["revenue"]
group["margin_change"] = group["fcf_margin"].diff()
series = pivot[ticker].dropna()
for _, row in group.dropna(subset=["margin_change"]).iterrows():
start = series.index.searchsorted(row["filing_date"])
if start + 126 < len(series):
fwd = series.iloc[start + 126] / series.iloc[start] - 1
events.append([ticker, row["margin_change"], fwd])
events = pd.DataFrame(events, columns=["ticker", "margin_change", "forward_return"])
print(events.groupby(events["margin_change"] > 0)["forward_return"].mean())
Full script with formatting and visualisation: healthcare-margin-inflection-python.py
Output
=== Healthcare Cash-Flow Margin Inflection Signal ===
Sample: 2018-02-16 to 2025-02-27 (44 filing-date observations)
Forward horizon: 126 trading days
Positive cash-flow margin inflections: 25 observations, avg forward return 7.4%
Negative or flat inflections: 19 observations, avg forward return 4.4%
Positive-minus-negative spread: 2.9%
Correlation: cash-flow margin change vs forward return = -0.02
Latest cash-flow margin inflections by ticker:
JNJ filing=2025-02-13 FCF_margin= 21.4% margin_change= 3.3% forward_6m= 12.3%
UNH filing=2025-02-27 FCF_margin= 6.9% margin_change= -0.3% forward_6m= -35.5%
ABBV filing=2025-02-14 FCF_margin= 40.6% margin_change= -1.2% forward_6m= 7.1%
MRK filing=2025-02-25 FCF_margin= 15.2% margin_change= -9.6% forward_6m= -7.0%
LLY filing=2025-02-19 FCF_margin= 2.3% margin_change= -17.8% forward_6m= -18.6%
PFE filing=2025-02-27 FCF_margin= 9.4% margin_change= -18.9% forward_6m= -5.7%
What this tells us
Positive free-cash-flow margin inflections performed better on average. The positive group produced a 7.4% average forward return over 126 trading days, compared with 4.4% for flat or negative inflections. The spread is 2.9 percentage points.
The correlation is -0.02, which is an important qualification. Larger margin improvements did not linearly map to larger forward returns. The signal worked better as a directional quality filter than as a precise ranking variable. The latest observations show the same point. JNJ had the only positive latest cash-flow margin change and a positive forward return. UNH had only a small negative change but a very weak forward return, showing that company-specific events still dominate individual outcomes.
So what?
Cash-flow margin inflection is useful as a first screen, not as a standalone trading rule. A positive inflection says that the company is converting more revenue into cash than it did in the prior annual filing. That is a constructive quality signal. It should then be paired with valuation, balance-sheet risk, and company-specific review.
For healthcare portfolios, the practical use is monitoring deterioration. Large negative cash-flow margin changes, such as the latest LLY and PFE observations in this sample, deserve a second look before adding exposure purely because the sector is defensive.
Built with xfinlink — free financial data API for Python. pip install xfinlink
pip install xfinlink