Repository Methodology

How ValueArc Works

This page documents the full pipeline: screening, growth filtering, valuation, margin of safety scoring, published outputs, and the main reasons you can end up with a lot of negative MOS values.

Pipeline

  • The screener starts with a fixed Finviz filter set in scripts/run_screener.py.
  • Each ticker then gets a 10-year price CAGR, and only names above 15% are kept for the valuation pass.
  • The filtered set gets bear, base, and bull intrinsic values from a local earnings-power model.
  • The workflow writes timestamped CSV snapshots, a stable valuearc_filtered_TODAY.csv, and metadata for the dashboard.

Current MOS Formula

The model uses:

MOS = (Intrinsic Value - Price) / Intrinsic Value

Negative values mean the modeled intrinsic value is below the current market price. That is not a math error. It is the expected output whenever the valuation assumptions are more conservative than the market.

Valuation Mechanics

Normalized EPS
Median of annual EPS history

Uses the median of available annual EPS values, with trailing EPS only as fallback.

Growth
EPS CAGR capped at 10 / 20 / 30%

Bear uses 0.5x historical EPS CAGR, base uses 1.0x, bull uses 1.5x, each with hard caps.

Discounting
Sector base rate plus quality adjustment

Uses a sector-specific base hurdle and then shifts it modestly lower or higher based on the quality multiplier.

Quality Haircut
0.60 to 1.00 multiplier

Applies penalties for EPS volatility, negative EPS frequency, and leverage.

Floor Value
80% TBV or 80% net cash

Uses the higher of conservative tangible-book-per-share or net-cash-per-share values.

Final Value
max(earnings value, floor)

The floor only prevents collapse below asset value. It does not push weak earnings names into positive MOS.

Current base discount map: Utilities 8.0%, Consumer Defensive 8.5%, Healthcare 9.0%, Real Estate 9.5%, Financials 10.0%, Communication Services 10.0%, Industrials 10.0%, Technology 10.5%, and 11.0% for higher-cyclicality or fallback sectors.
Lower-Rate Sectors
8.0% to 9.5%

Utilities, consumer defensive, healthcare, and real estate get lower base rates because their cash flows are usually steadier, more regulated, or more defensive than the broad market.

Mid-Rate Sectors
10.0% to 10.5%

Financials, communication services, industrials, and technology sit in the middle because they can still be durable businesses, but usually carry more operating leverage, cyclicality, or disruption risk.

Higher-Rate Sectors
11.0% fallback

Consumer cyclical, basic materials, energy, and unknown sectors keep the highest base hurdle because earnings are often more commodity-sensitive, cyclical, or dependent on favorable market conditions.

Why So Many Negative MOS Values

  • The model still discounts aggressively, but it no longer forces every company through one global 11% hurdle.
  • There is no perpetuity or terminal multiple, so value stops after year 20.
  • Growth assumptions are capped, which limits upside for high-quality compounders.
  • The quality multiplier only cuts value. It never rewards stability above 1.00.
  • The floor value is usually too low to offset a weak earnings valuation for most growth businesses.
  • Names are prefiltered on price CAGR, not valuation cheapness, so you are often evaluating winners at already-expensive prices.
Bottom line: the model is structurally conservative, so a broad field of negative MOS values is the normal output, not a sign that the arithmetic is broken.

More Efficient Alternatives

  • Use a shorter, clearer valuation horizon such as 5 to 10 years plus an exit multiple instead of 20 years of discounted EPS.
  • Rank on a relative score like Price / Base Value or Value / Price if the goal is ordering, not literal margin of safety interpretation.
  • Clip or winsorize extreme negative MOS values before ranking so the table remains readable.
  • Use owner earnings or free cash flow for mature firms instead of EPS when accounting noise is large.
  • This repo now applies sector-specific base discount rates and then adjusts them by quality, which should reduce some false negatives for stable sectors.
  • Separate the scoring model from the reporting model: keep conservative value estimates, but rank by base-case discount to value instead of bear-case only.
Practical recommendation: if you want fewer negative values without making the model soft, the cleanest first move is to rank on MOS_Base_% and report bear/base/bull together, while keeping bear as a stress-test metric rather than the primary screen.