← All posts

Do Healthcare Cash-Flow Margins Predict Returns? Signal Evaluation in Python

Test whether improving healthcare free-cash-flow margins were followed by stronger six-month stock returns.

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.

  1. Pull ten years of annual revenue and free cash flow
  2. Calculate free-cash-flow margin for each annual filing
  3. Measure the year-over-year change in that margin
  4. Start the forward-return clock on the filing date, not the fiscal period end
  5. 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 free-cash-flow margin inflections versus six-month forward returns
=== 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. The accruals gap between profit and cash, ranked across a large-cap index against forward returns, is put through a quintile test in an accruals anomaly study.

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.