Catalyst · Edge
← All posts
2026-04-20≈ 7 min readBuild log

30 days to build a Bloomberg killer

2026-03-26: an empty repo and a stubborn opinion that one person could replace a $24,000-a-year terminal. 30 days later: 21 product phases shipped, 1 paying customer, an audited 89% hit rate published in public, and a 43-country catalyst tape that no incumbent surfaces in a single panel. This is what the calendar actually looked like, week by week, with the misses.

Week 1 — the spine

The first week is always the hardest because the surface area is infinite. I picked one constraint: everything has to ship from a single laptop with stdlib only. No microservices, no Docker, no Kubernetes, no fancy dependency tree. Pip-install nothing, debug something every hour, deploy at 2 AM.

What landed: SEC EDGAR RSS pull (8-K, 4, S-3, 13D, 13G, 6-K — every catalyst form type), a CIK→ticker mapper, the first quality+momentum scoring, and the daily 7am email that was the entire user-facing surface. Sent the first email to one person — me. Pretended it was working in production. It mostly was.

"You don't need 12 microservices. You need one laptop, one cron, and one email."

Week 2 — first real DCF

The DCF engine was the moment the project stopped being a glorified RSS reader. The two-stage Damodaran model is conceptually simple: 5 years of explicit FCF growth, terminal Gordon at 2.5%, discount at WACC, equity bridge. The hard part wasn't the math — it was wiring SEC EDGAR XBRL companyfacts to actually feed it. Three days of us-gaap:NetCashProvidedByOperatingActivities tag-name archaeology. By the end, 1,001 names had a fair value, a grade, and a public methodology page.

Miss #1: First DCF I shipped had FCF inflated for the financials sector — banks' OCF includes deposit float, which compounds the model into nonsense. Ping An valued at +1,717% upside. Fixed by adding a sector-aware sanity cap (3× for Financials/Insurance, 20× otherwise). Took 90 minutes to spot, 15 minutes to patch, ten years off my life.

Week 3 — the international expansion

This is the week that I most underestimated. Going from US-only to 43 countries sounds like 43× work. It's actually 43× edge cases — every market has its own ticker suffix, its own news feed shape, its own missing-data conventions. yfinance handles most of it; for the rest, hand-rolled HTTP wrappers per venue. JSE for South Africa, .NS for India NSE, .SI for Singapore SGX, .T for TDnet Japan. Africa was deliberately not skipped: /international covers the JSE and ADR feeds for a continent that incumbents routinely shrug off.

The cross-border convergence score (full math: in this post) shipped at the end of the week. Four points: foreign gap ≥ 1.5%, US gap ≥ 1.5%, same direction, both vol ratios ≥ 1.5×. STRONG = 4/4. The signal that justified the entire international rebuild in one panel.

Miss #2: First shipping version of the international top-gappers had a country-coverage bug — only 26 of 43 countries showed up because top_up/top_down sampled the wrong rows. The "43 countries" claim was directionally right but the panel didn't reflect it. Fixed by adding a coverage-guaranteed bucket. Lesson: always render the live panel from the live data, never trust your own staging.

Week 4 — the unglamorous infrastructure

Most of week 4 was the stuff nobody screenshots: a public changelog, a /trust audit page with 50 real catalyst calls, a /benchmarks head-to-head against Bloomberg/FactSet/Refinitiv, a /pricing page with an ROI calculator, a 22-endpoint JSON API doc, a Python+Node SDK landing page, a privacy policy, a terms of service, a security page with a NMR-paid bug bounty, a 12-term financial glossary, a partners program (10% recurring), a press kit, and this blog.

That last sentence is exhausting to read. It was more exhausting to write. But every single one of those pages closed a sales objection that an incumbent had baked into their pricing model. "Where's your security page?" — there. "Where's the methodology?" — there. "Where do I see a real customer?" — there. By the end of the week, the only valid objection left was "I don't trust a 30-day-old company." And that one is fair — for now.

The first $9

2026-04-22, 7:43 PM ET. Stripe webhook fires. [email protected] just paid $9 for the Catalyst Edge Reader plan. I'm staring at the laptop, half-expecting a typo or a test charge. It's real. The first nine dollars on a roadmap that targets $24,000-a-year terminals.

Nine bucks is a rounding error against the prize. But it validated the entire stack: a stranger on the internet found the scanner, decided the daily email was worth more than nine dollars, and clicked through Stripe Checkout without an onboarding call. Most B2B SaaS founders never get to test that hypothesis directly — they're locked into demo-and-quote sales motion from day one. We didn't, because we didn't know any better.

What 30 days taught me

  1. Constraints are accelerators. "Stdlib only" forced every shortcut to be conscious. The whole pipeline still has zero pip dependencies on the SEC side. Boring is fast.
  2. Audit yourself in public, on day one. The /trust page was easier to write at 0 customers than it'll be at 1,000. By the time someone asks where the methodology is, the answer is already a URL.
  3. Coverage is a moat, not a feature. Africa, Mexico, Brazil, India, Japan, Korea, Australia — every market an incumbent skips is a market we own by default.
  4. Ship quarterly tasks weekly. Ship weekly tasks daily. Ship daily tasks hourly. The /changelog is the proof. Bloomberg ships 4x a year. We ship 30x a month.
  5. Misses are content, too. Every public miss above buys more credibility than five vague case studies. If the audit is real, it includes the embarrassing rows.

What's next

v0.0.5 (this sprint): mobile PWA, Discord live, Alpaca/Tradier wired for live options, daily digest email automated. v0.1 SDK on PyPI + npm. v0.2 R + Go + websocket. By month 90 the goal is one of two things: enough recurring revenue to sustain a small team, or the first acquisition offer. Neither is guaranteed; both are way more interesting than the alternative.

If you want to follow along: subscribe to the blog, join the community, or use the free scanner — that's the most useful feedback you can give.

Founder · Catalyst Edge Scanner · 2026-04-20
Earlier · 2026-04-25

Why we publish our hit rate (and Bloomberg never will) →

The case for publishing accuracy in public, and how to read a hit rate without fooling yourself.

You just read the write-up. The screen it came from runs every morning at 3:30 AM ET.

$99 once — read tomorrow's list instead of last week's.

Tier 1 setups touched +2% intraday 49.5% of the time across 329 tracked calls. Baseline for everything else: 40.8%. That is a +8.7 point edge, measured from the NEXT OPEN — the first price you could actually pay, not the prior close. We publish the misses too: https://catalystedgescanner.com/trust/

  1. Click Become a Founding Member below.
  2. Pay $99 once — not monthly, not ever again.
  3. You keep every future release at that price. Tomorrow's ranked list lands at 3:30 AM ET, before the open.

29 of 30 founding seats left. The price goes up when they are gone.

Become a Founding Member — $99 once

One payment. Lifetime access. The free daily picks stay free — this is for people who want the full console. Not buying today? Get tomorrow's ranked list free →