PM Talk Series · Build Lesson 01

How to build an app that tracks % down from all-time high for any stock.

This is the right first conversation for building an ATH screener: define the decision, constrain the system, force deterministic scoring, and turn the output into a ranked grid instead of a generic stock dashboard.

The product definition

The app is not a generic stock screener. The goal is to help a user identify fundamentally strong stocks that are meaningfully below their highs and approaching attractive buy zones. That framing matters because it changes the whole build. You are no longer making a filter wall. You are making a ranked decision-support product.

Core product rule

Start with the user decision. In this case: which strong stocks are far enough below ATH to deserve attention now?

The ideal PM-to-builder conversation

Step 01 Define the ranking model before the UI

The builder should frame the product as a deterministic composite score across discount, fundamentals, and technicals, with explainable weighting and no LLM in the hot path.

Step 02 Set constraints early

Make it local-first, cheap to run, cached, explainable, and resilient to flaky data vendors. This prevents the product from turning into an expensive real-time infrastructure project.

Step 03 Surface risks honestly

All-time highs can be misleading, Fibonacci is subjective unless anchored consistently, and market data providers fail. Design around those realities before writing code.

Step 04 Split backend from app

Use a lightweight Python FastAPI backend for fetching, scoring, caching, and alerts. Use a SwiftUI iPhone app for ranked views, detail pages, and the ATH grid.

Step 05 Write the exact scoring pillars

Use three pillars: discount score, fundamental score, and technical score. Weight them 30%, 35%, and 35%. Then compute confidence from pillar agreement.

Step 06 Define “ready to buy” explicitly

A stock becomes actionable only if it is not an inverse ETF, within 3% of the next Fibonacci buy level, composite score is at least 75, and confidence is at least 60.

Step 07 Turn it into a scan-friendly grid

The ATH Grid view should use tile height to reflect percent below ATH, color to reflect setup quality, and grouping to separate Ready To Buy, Core / Long, and Inverse / Short ETFs.

What the backend should return

Identity and price context
  • ticker, company, sector, group
  • price, ath_price, pct_below_ath, pct_below_52w
  • day_change_pct, week_change_pct, month_change_pct
Scoring and actionability
  • discount_score, fundamental_score, technical_score
  • composite_score, composite_confidence, tier
  • fib_level, next_buy_level, rsi, ready_to_buy

Why the grid matters

A ranked list is good for precision. The grid is good for scanning. In this product, the grid is not visual decoration. It changes how the user sees opportunity. Tile height makes drawdown legible. Color helps separate near-high quality names from deep-discount names. Grouping keeps actionable ideas distinct from watchlist names and inverse products.

UI rule

Make the primary visual dimension the one that matters most to the decision. Here, that is % down from ATH.

What to exclude from v1

The lesson

Great prompting is not clever wording. It is clear product definition. The PM did three things correctly here: defined the user decision, constrained the architecture before build, and explicitly protected v1 from complexity traps. That is why this produces an ATH screener instead of a generic stock app.