The Quality Score follows the Quality Minus Junk (QMJ) score of Asness, Frazzini and Pedersen (2019): a company is of high quality when it is profitable, growing, safe and pays out to its shareholders. Every measure is ranked across the tickers given in each period and turned into a z-score, each of the four components is the z-score of the average of its measures, and the Quality Score is the z-score of their sum. A positive score is a higher quality than the average of the tickers given.

The measures are as follows (a higher value is a higher quality, so the measures marked “low” enter with a minus sign):

\[\text{Profitability:}\;\; \text{Gross Profits to Assets} ((\text{Revenue} - \text{Cost of Goods Sold}) / \text{Total Assets},\; \text{Novy-Marx}\; 2013),\;\; \text{Return on Equity},\;\; \text{Return on Assets},\;\; \text{Cash Flow to Assets} ((\text{Operating Cash Flow} - \text{Capital Expenditure}) / \text{Total Assets}),\;\; \text{Gross Margin and low accruals} ((\text{Operating Cash Flow} - \text{Net Income}) / \text{Total Assets})\]
  • Growth: the change in Gross Profits to Assets, Return on Equity, Return on Assets, Cash Flow to Assets and Gross Margin over growth_years
\[\text{Safety:}\;\; \text{low Beta (of the period's returns against the benchmark)},\;\; \text{low leverage} (\text{Total Debt} / \text{Total Assets}),\;\; \text{low Ohlson O-Score},\;\; \text{high Altman Z-Score and low earnings volatility (the standard deviation of the Return on Equity over growth\_years)}\] \[\text{Payout:}\;\; \text{low equity issuance (-ln of the change in the diluted shares over a year)},\;\; \text{low debt issuance} (- \text{ln of the change in Total Debt over}\; a \;\text{year}) \text{and the net payout ratio} ((\text{Dividends} + \text{Share Repurchases} - \text{Shares Issued}) / \text{Net Income})\]

Also known as: QMJ, Quality Minus Junk, quality factor, quality composite.

Quality Score (QMJ) in Python or via the MCP

Install the Finance Toolkit with:

pip install financetoolkit -U

Then call get_quality_score as shown below.

from financetoolkit import Toolkit

toolkit = Toolkit(
    ["AAPL", "MSFT", "GOOGL", "META", "NVDA", "INTC", "IBM", "ORCL"],
    api_key="FINANCIAL_MODELING_PREP_KEY",
    start_date="2016-01-01",
    end_date="2025-12-31",
)

toolkit.models.get_quality_score().xs("Quality Score", level=1)

Or, after setting up the Finance Toolkit MCP, ask:

How did Apple, Microsoft, Alphabet, Meta, Nvidia, Intel, IBM and Oracle rank on a Quality Minus Junk quality score from 2020 to 2025?

Which returns:

  2020 2021 2022 2023 2024 2025
AAPL 0.6124 1.0206 1.4289 0.6124 0.6124 1.3363
GOOGL -1.0206 0.2041 0.6124 1.0206 1.0206 0.8018
IBM -1.4289 -0.6124 -0.6124 -0.6124 -0.6124 -0.2673
INTC -0.6124 -1.0206 -1.4289 -1.4289 -1.4289 -1.3363
META 1.4289 1.4289 0.2041 -0.2041 0.2041 0.2673
MSFT 1.0206 0.6124 1.0206 0.2041 -0.2041 -0.8018
NVDA 0.2041 -0.2041 -0.2041 1.4289 1.4289 nan
ORCL -0.2041 -1.4289 -1.0206 -1.0206 -1.0206 nan

Parameters

get_quality_score accepts the following parameters.

ParameterTypeDescriptionExample
growth_yearsintThe number of years over which the growth and the earnings volatility are measured. Defaults to 5, as in the paper.5, as in the paper
trailingint | NoneSum the flows over this many periods. Defaults to None, which is 4 for quarterly data (a trailing twelve months) and 1 otherwise.4
roundingint | NoneThe number of decimals to round the results to. Defaults to None, which uses the rounding of the Toolkit (4 unless set otherwise).2
show_columnslist[str] | NoneThe periods to show. Defaults to None, all periods.None, all periods
Share