What (One-liner)
BLCV batch scan: run the four-dimension BLCV analysis (V/B/C/L) over a set of tickers, synthesise with weights, sort descending, assign rank numbers, and emit the top_pick with the full ranking. The core tool for equity-pool shortlisting.
How to use
Drag blcv_equity_scan_v1 onto the Canvas, fill the required symbols list plus optional weights and optional peers_map (peers per ticker). Output is {count, top_pick, results[], logic_lineage}.
Typical usage:
scan_full(["META", "AAPL", "GOOG", "MSFT", "AMZN"])
→ count=5, top_pick="NVDA" (e.g.), ranked 1-5 by blcv_score descCore formulas
Essentially a map + sort over score_single:
for sym in symbols:
result = score_single(sym, weights, peers_map.get(sym)) # 4 dim + compose
results.append(result)
ranking = sorted(results, key=blcv_score, reverse=True) # stable sort
for i, r in enumerate(ranking):
r.rank = i + 1
top_pick = ranking[0].symbol if ranking else NoneUnderlying score_single formula (see the blcv_score_v1 card):
blcv_raw = (wB×B + wL×L + wC×C + wV×V) / Σw
if industry ∈ avoided: blcv_raw ×= 0.6
blcv_score = round(clamp(blcv_raw, 0, 100), 2)Assumptions & applicability
Assumptions: yfinance available + the four dimension analyzers' assumptions + DEFAULT_WEIGHTS + hardcoded thresholds.
Fits: US-equity shortlists, peer baskets, factor-investing ranking, quarterly reviews.
Does not fit: 100+ symbols (slow), non-US names, multi-factor attribution, time-series BLCV.
Input / Output contract
{symbols: list[str], weights?: dict, peers_map?: dict[sym, list[sym]]} → {count: int, top_pick: str | null, results: list[{symbol, rank, blcv_score, signal, dimension_scores, margin_of_safety, details, ...}], logic_lineage: list[str]}.
A per-symbol exception becomes {symbol, error, blcv_score: 0} at the ranking tail.
Known limitations
- Sequential, no concurrency — N symbols = N yfinance calls
- Failed symbols appear at the ranking tail with blcv_score=0 (not excluded) — callers must check the
errorfield - DEFAULT_WEIGHTS / industry penalty ×0.6 / signal thresholds are all hardcoded
- Stable sort keeps input order on ties → potentially confusing in UI
- No caching (two scans of the same symbol fetch twice)
- peers_map is optional → without it the C dimension's peer_comparison is null
References
Graham-Dodd (1934) batch-screening methodology + Fama-French (1992) factor-ranking framework + Asness et al. (2013) multi-factor evidence. Full citations in the frontmatter.
Golden Test
tests/golden/fixtures/tier2/blcv_equity_scan/ — a yfinance-snapshot integration regression (single-symbol wrapper path), 1e-6 tolerance, 6 tests:
matches_snapshot— deep comparison of the full outputdeterminism— 5 reruns byte-identicalrank_assignment— multi-symbol (shared snapshot → equal scores), ranks=[1,2,3] with stable sortempty_symbols— N=0 → count=0, top_pick=null, results=[]logic_lineage_format— ["BLCV full scan", "symbols=AAPL,MSFT"]result_preserves_rank_field— every result carries an integerrank
The four underlying dimensions have independent goldens (tier1/blcv_financials, tier1/blcv_business, tier2/blcv_compete, tier2/blcv_leadership) — this test focuses on the wrapper mechanics.
Changelog
- 1.0.0 (2026-04-20) — First Active (Tier 2 batch 4, batch wrapper)

