A free, community-first tracker for the Philippine Stock Exchange (PSE) — built to fill gaps that existing PH tools (PSE EQUIP, Investagrams/Rival, broker platforms, TradingView) either don't cover or gate behind paywalls. Read-only and informational only: no brokerage functionality, no real-time intraday claims, no stock picks or buy/sell signals.
Full product/technical planning brief: docs/PLANNING.md.
| Route | What it does |
|---|---|
/ |
PSEi market map — a treemap heatmap sized by market cap, colored by day's % change, grouped by PSE's 6 sectors |
/daily |
Redirects to today's market recap (/daily/[date]) — PSEi close, top movers, foreign flow, shareable per-day OG card |
/stocks/[ticker] |
Per-company page: price/%change, market-cap/sector rank, closing-price chart, profile, disclosures, dividend history, news mentions, and its own RSS feed |
/news |
PH business news headlines, auto-tagged by PSE ticker |
/dividends |
Dividend-yield screener across all PSE-listed stocks |
/calendar |
Dividend & corporate actions calendar (ex-date/record/payment dates, plain-language explainers) |
/compare |
Overlay closing-price performance across multiple tickers on one chart |
/block-sales |
Large negotiated "cross" trades from PSE's daily Quotation Report |
/disclosures |
PSE Edge filings distilled into a per-company digest |
/offerings |
IPO / follow-on / rights offer tracker with subscription countdowns — unlinked from nav/sitemap for now, still mock-only (see "Data sources") |
/foreign-flow |
Index-level (weekly) and per-stock (daily) net foreign buying/selling |
/dca |
Cost-averaging calculator — simulate DCA into a stock or an equal-weighted market proxy |
/charts |
Interactive candlestick charts via TradingView's free embed (NASDAQ names only — see "Data sources") |
Several features now run on real data scraped from public PSE Edge pages/PDFs; others still run on fabricated sample data pending a legally-sound real source — see "Data sources" below for exactly which is which.
- Frontend: Next.js 16 (App Router) + React 19, Tailwind CSS. Server Components with
ISR (
export const revalidate) rather than client-side fetching, except the DCA calculator and Charts page's interactive client components. The DCA calculator fetches a real Route Handler (apps/web/app/api/history/route.ts) for historical prices rather than running its simulation over purely client-generated data. - Database: Postgres via Neon (serverless) + Drizzle ORM.
- ETL: standalone
tsxscripts inetl/, scheduled via GitHub Actions (see.github/workflows/) — no long-running server, no app-triggered fetches. - Monorepo: pnpm workspaces + Turborepo.
apps/web Next.js app (all routes, UI components)
packages/db Drizzle schema, Neon client, query helpers
packages/sources/* One pluggable *Source interface + mock implementation per feature
packages/treemap-layout Pure layout + color math for the market map (no React/DOM)
etl Scheduled fetch jobs (tsx, no build step)
docs/PLANNING.md Original planning brief + running execution log
Every data feature follows the same pattern: a packages/sources/<feature> package
defines a small interface (e.g. QuoteSource, DisclosureSource) plus a Mock* class
that fabricates realistic sample data; a packages/db schema table; an etl/jobs/*.ts
script that upserts into Postgres; and a page in apps/web/app/*. Swapping a mock for a
real feed means writing a new class against the same interface — no caller changes.
pnpm install
pnpm dev # starts apps/web on localhost:3000No DATABASE_URL is required to run the app locally — every page falls back to sample
data when the database isn't configured or hasn't been populated yet (see
apps/web/lib/quotes.ts for the pattern).
To wire up a real database:
export DATABASE_URL=postgres://... # a Neon connection string
pnpm db:generate # generate a Drizzle migration from packages/db/src/schema.ts
pnpm db:push # apply it
pnpm --filter @pseye/etl fetch-quotes # populate a table locally, e.g.In production, each etl/jobs/*.ts script runs on its own schedule via GitHub Actions
(hourly for quotes/market-snapshot on trading days, daily for everything else) — see
.github/workflows/.
Other useful commands:
pnpm build # turbo run build across all packages
pnpm lint # eslint (apps/web)
pnpm typecheck # tsc --noEmit across all packages| Variable | Purpose |
|---|---|
NEXT_PUBLIC_SITE_URL |
Canonical site origin used for metadata/OG URLs and the sitemap; falls back to https://pseye.vercel.app in production, http://localhost:3000 in dev. |
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION |
Google Search Console's HTML-tag verification token (Search Console → Add property → HTML tag method). Omitted entirely from the page's <head> when unset. |
Each feature is designed so a Mock*Source can be swapped for a real one without
touching any caller (one small *Source interface per feature in packages/sources/*).
Current status per feature:
| Feature | Status | Source |
|---|---|---|
| Quotes (market map, DCA anchor price) | Real | PSE Edge per-company "Stock Data" pages |
| Historical quotes (DCA) | Real | PSE Edge's own price-chart JSON endpoint |
| News | Real | RSS feeds |
| Disclosures | Real | PSE Edge's announcements search |
| Corporate actions (dividends) | Real | PSE Edge's dividends & rights listing |
| Foreign flow — index-level | Real | PSE's free weekly Market Watch PDF |
| Foreign flow — per-stock rankings | Real | PSE's free daily Quotation Report PDF (the "Net Foreign Buying/(Selling)" column, top/bottom 10 by value) |
| Block sales | Real | PSE's free daily Quotation Report PDF (BLOCK SALES table) |
| Offerings / IPO tracker | Sample data | the one free feed found ("Listing Applicants") is currently empty and lacks the subscription-window dates this feature needs; re-investigated twice, no viable source found |
| Charts (TradingView embed) | Real, but NASDAQ only | TradingView's free widgets refuse PSE-listed symbols (verified) |
PSE's published reports (Monthly Report, Market Watch PDF, daily Quotation Report)
restrict reproduction/redistribution, and true real-time market data is a licensed, paid
product — every real source above reads a public page/PDF for delayed/EOD figures, not a
licensed feed, and none of it re-hosts PSE's documents themselves. See docs/PLANNING.md's
execution log for the full reasoning, what was investigated for the still-mock features,
and why.
No brokerage or trading functionality. No real-time intraday data claims (delayed/EOD is expected). No reproducing full news articles or PSE's PDF reports verbatim. No financial advice, stock picks, or buy/sell signals.