Scoring Formulas Reference

This page documents the scoring formulas used by the portfolio optimizer to rank stocks and ETFs. Scores are normalized to 0–1 where higher is better (except for risk/danger, which are inverted). The optimizer combines these scores with your risk level to build diversified portfolios.

← How the Risk Calculator & Portfolio Optimizer Works

Common Helpers

  • clamp(value, min, max) — Restricts a value to [min, max].
  • safeNormalize(value, min, max, fallback) — Maps value to [0, 1] with (value − min) / (max − min); returns fallback if value is null/undefined/NaN.
  • safeInverseNormalize — Same as above but "lower is better": returns 1 − safeNormalize(…).
  • averageWithFallback(values, fallback) — Average of valid numbers; fallback if none valid.

Equity Scoring

Each sub-score is normalized to [0, 1]. Missing inputs use a 0.5 fallback. The final equity score combines value, growth, profitability, income, sustainability, analyst, danger, risk-adjusted score, and quality with configurable weights that depend on your risk level.

  • Value score — P/E, PEG, price-to-book, price-to-sales, enterprise-to-EBITDA (inverse: lower is better).
  • Growth score — Revenue and earnings growth (annual and quarterly).
  • Profitability score — Gross, operating, profit margins; return on equity and assets.
  • Income score — Dividend yield (normalized to [0, 0.12]).
  • Sustainability score — Growth health, margin durability, balance-sheet resilience, payout sanity.
  • Risk score — Volatility, beta, drawdown; normalized then inverted so lower risk → higher score.
  • Risk-adjusted score — Combines expected return and risk so that higher return per unit of risk gives a higher score.

ETF Scoring

ETFs are scored on danger (volatility/tracking error), risk-adjusted return, return, income (yield), cost (expense ratio), and liquidity. The final ETF score blends these with weights that align with the chosen risk level (e.g. more weight on cost and liquidity for conservative, more on return for aggressive).

Units & Normalization

Data from providers (e.g. Yahoo Finance) may use percent or decimal. The engine normalizes before scoring: yields and expense ratios are converted to decimal (e.g. 12.58% → 0.1258); returns use a rule such that values with |x| > 1 are divided by 100. Volatility and risk metrics are already in decimal form.

The exact weights and ranges are maintained in the engine code. This reference summarizes the structure; for implementation details see the repository.

Back to How It Works