The economic story is old and simple: a company priced cheaply relative to what it actually earns should, on average, out-earn one priced richly for the same earnings, buy a dollar of profit for seventy cents, not for a dollar-forty. Fama and French's foundational work (1992, 1993) documented this value premium across decades of US equity data and made "cheapness relative to fundamentals" a first-class, separately-priced dimension of return, distinct from a stock's market beta. The cleanest implementation is an earnings yield: net income divided by price. A high earnings yield means you are paying little price for each rupee or dollar of earnings, cheap; a low earnings yield means you are paying a lot: expensive. (This is the reciprocal of the more familiar P/E ratio, and yield is generally the more convenient form for ranking, since a company with zero or negative earnings does not blow up a division-by-zero the way a raw P/E can.)
Advertisement
How is the earnings yield calculated?
Here is the one place this module states a simplification instead of quietly hiding it. A textbook earnings yield is net income per share over price per share, equivalently, aggregate net income over the company's full market capitalization (price × shares outstanding). This program's bundled fundamentals datasets carry aggregate net income, total assets, and total liabilities, but, deliberately, to keep the teaching data lean, no shares-outstanding field. This module's earnings_yield therefore computes net income ÷ price directly, which is only a valid per-share-consistent ratio under the explicit, stated assumption that every company in the ranking is being treated as if it had the same, arbitrary share count (so that whatever constant it is, it cancels identically for every name and never distorts the ranking, even though it would distort any claim about the ratio's absolute size). A real desk never makes this simplification, it pulls actual shares outstanding or market capitalization from its data vendor, and Common Mistake #1 returns to exactly this trap.
Which fundamentals row goes with a price date?
Before any of that, though, notice what "as of 2 June 2025" actually required: joining a price, which exists every trading day, to a fundamentals figure, which exists only four times a year at most (this program's bundled data carries one fiscal-year figure per company per year). The join rule is not "use whichever fiscal year the calendar says we are closest to", it is use the most recent fundamentals row whose filed_date is on or before the as-of date, and no other. This program's bundled US fundamentals show FY2025 filed on 2025-05-18; an as-of date of 2 June 2025 falls after that filing, so FY2025 is the correct, legitimately knowable row to use. Move the as-of date backward to, say, 1 May 2025, two and a half weeks before the filing, and the correct row instantly becomes FY2024 instead, filed a full year earlier on 2024-05-17, even though FY2025 already existed in the underlying data by then. Using FY2025 on a 1 May 2025 as-of date would be using information the market could not yet have had, a small, easy-to-miss look-ahead bias, and precisely the discipline QD1.01 owns and this module inherits without re-deriving (Common Mistake #2 returns to this directly, with the concrete size of the error this exact mis-join would cause).
Worked example: the cheapest and most expensive stocks
With that stated, here is the real, computed cross-section. As of 2 June 2025 (the trading day nearest this program's bundled fundamentals' most recent filing, filed_date 2025-05-18) the three cheapest and three most expensive names in the US universe (us-eod price joined to sec-fundamentals net income) read:
| Ticker | Net income | Price | Earnings yield |
|---|---|---|---|
| BLUSTM | 35.02 | 51.96 | 0.6740 |
| CRSTNE | 100.62 | 156.96 | 0.6411 |
| BRPEAK | 43.44 | 76.34 | 0.5690 |
| ⋯ | |||
| CLRRDG | 38.13 | 222.50 | 0.1714 |
| GOLDFD | 14.85 | 102.90 | 0.1443 |
| STNHVN | 11.73 | 90.71 | 0.1293 |
And in the India universe (nse-eod joined to india-fundamentals), same date:
| Ticker | Net income | Price | Earnings yield |
|---|---|---|---|
| CHANDANI | 376.23 | 485.56 | 0.7748 |
| VASANTI | 210.75 | 313.89 | 0.6714 |
| PIPPAL | 347.71 | 664.42 | 0.5233 |
| ⋯ | |||
| NEELKANTH | 70.27 | 351.48 | 0.1999 |
| TARANG | 161.60 | 987.68 | 0.1636 |
| SARASWATI | 116.45 | 861.40 | 0.1352 |
This module's code pack exercise QD1.02-e01 grades exactly this function, earnings_yield(net_income, price), against the full 15-name US and 15-name India cross-sections above (R6: a hidden test on each market).