What (One-liner)
Heuristic implementation of Porter 5+1 Forces: derives 6-force quantitative scores + 3 competitive advantages from yfinance financial report proxy signals, producing a 0-100 C score. Input for the C dimension of the BLCV composite score.
How to use
Drag blcv_compete_v1 into Canvas, fill in symbol (required) + optional peers list. When no peers, peer_comparison is null; when peers are present (<=5), fetch from yfinance individually for gross_margin comparison.
Core formulas
Porter 5+1 forces (0-1 scale):
rivalry← margin_stability heuristicthreat_new_entrants← market_cap bucket + growththreat_substitutes← revenue growth decelerationbuyer_power← COGS/Revenue trend slopesupplier_power← COGS/Revenue levelcomplementary_power← (high margin + high growth) heuristic
Competitive advantages (3 fixed):
market_position: mega_cap_leader / large_cap / mid_cap / small_cap / unknownconsumer_loyalty: (margin_stab + revenue_stab) / 2switching_cost: high / medium / low (based on stability + loyalty)
Scoring:
porter_score = max(0, 1 - avg_5_threats) + complementary × 0.1
advantage_score = loyalty × 0.4 + switching_weight × 0.3 + market_pos_weight × 0.3
c_score = (porter_score + advantage_score) / 2 × 100Assumptions & applicability
Assumptions: proxy signals (margin → rivalry, COGS → buyer/supplier power) are reasonable; market_cap USD thresholds; 5-year steady-state margin data.
Applicability: US mega-cap / large-cap, mature industries, competitive landscape assessment for long-term holding candidates.
Out of scope: Strict Porter analysis, non-US, fast-iterating industries, true multi-peer comparative.
Input / Output contract
{symbol: str, peers: list[str] | None} → {symbol, name, porter_forces{6 keys}, porter_evidence[], competitive_advantages[3], c_score, peer_comparison | null, logic_lineage}.
6 Porter forces + 3 advantages fixed schema, golden locked.
Known limitations
- Proxy-based heuristic, not canonical Porter (mappings like rivalry ← margin_stability are not academically validated)
- Proxies for threat_new_entrants / threat_substitutes are weak (relying mainly on market_cap + growth deceleration)
- Market position thresholds 500B/100B/10B USD hardcoded
- Switching cost 3-way discrete (lacking gradient)
- 50/50 porter vs advantage weight not sensitivity tested
- No cache when peer_comparison is enabled — watch yfinance quota
- Does not compare against industry baseline (cross-industry c_score is mechanically comparable but semantically dubious)
References
Porter (1979, 2008) HBR Five Forces original + Brandenburger-Nalebuff (1996) Co-opetition (6th force) + Greenwald-Kahn (2005) Competition Demystified. See frontmatter for details.
Golden Test
tests/golden/fixtures/tier2/blcv_compete/, yfinance-snapshot integration regression (peers=None path), 1e-6 tolerance. 7 tests:
matches_snapshot— deep comparison of full outputc_score_in_0_100_range— range contractdeterminism— 5 reruns byte-identicalporter_forces_has_six— 6 forces fixed keysadvantages_has_three_fixed— 3 advantages fixed dimspeers_none_skips_peer_comparison— peers=None → peer_comparison nullporter_forces_in_0_1_range— all 6 forces ∈ [0, 1] numeric contract
Peer-enabled path not tested (future work: multi-symbol snapshot infrastructure).
Changelog
- 1.0.0 (2026-04-20) — First Active (Tier 2 batch 3, yfinance snapshot regression)

