DEV Community

Cover image for ZenPNL — IDX Stock P&L + TradingView Chart + News (Next.js)
0x5zen
0x5zen

Posted on

ZenPNL — IDX Stock P&L + TradingView Chart + News (Next.js)

I just shipped a small project called ZenPNL a simple, single page IDX stock dashboard that focuses on three things: chart, P&L, and news (fast, responsive, dark-first).

Live:https://zenpnl.vercel.app

GitHub:https://github.com/meryzennn/profitandloss/

> Not financial advice. Market data can be delayed depending on sources.


Why I built it

I wanted an open and go experience like stock apps:
1) Open the site -> IHSG shows by default
2) Search an IDX ticker -> chart switches instantly
3) Calculate P&L using lots (1 lot = 100 shares)
4) Scroll -> read relevant news without leaving the dashboard


Core features

TradingView chart (IDX + IHSG)

  • Uses the TradingView widget (tv.js) for a real charting feel
  • Default symbol: IHSG / IDX Composite
  • When switching symbols, the chart resets so the previous viewport doesn't stick

Lot-based P&L calculator

  • Inputs: buy/sell price, lots, buy fee %, sell fee %, sell tax %
  • Outputs: net P&L (IDR), ROI %, break-even sell price
  • Small UX helpers: quick set buy/sell = last price

News feed that points to real publishers
Google News RSS is convenient, but RSS links can lead to redirects and sometimes weird/non-article pages.
So I implemented a resolver that:

  • prioritizes the publisher domain from RSS source
  • aggressively filters junk (ads/scripts/assets/spec pages)
  • validates final URLs as real HTML articles

Result: the news list shows actual publisher sources (e.g., local finance media) instead of news.google.com / random pages.

Dark-first UI + micro-interactions

  • Dark mode by default (better for charts)
  • Shimmer loading states for news
  • Subtle hover/press animations to feel app-like

Tech stack

  • Next.js App Router + TypeScript
  • Tailwind CSS
  • SWR for client-side fetching + caching
  • Route Handlers for API normalization:
    • Yahoo search & chart meta for Last / Prev Close
    • Google News RSS -> resolve to publisher URLs

Design choice: Last vs Close

To keep the price card easy to understand:

  • Main price uses Yahoo Last (regularMarketPrice)
  • Change badge uses Last vs Prev Close

This tends to match what users expect from stock apps and feels closer to live than strictly following candle close.


Hard parts (the annoying ones)

  • TradingView + hydration: the widget is client-only DOM injection, so the container ID must be stable to avoid mismatch issues.
  • RSS resolution: extracting clean publisher URLs from aggregated feeds is trickier than it looks (redirect chains, embedded URLs, junk endpoints).

What I'd like to improve next

  • Watchlist (localStorage)
  • Better market ticker (gainers/losers) if I find a stable IDX feed
  • Smarter news relevance (query tuning per ticker to avoid ambiguous keywords)

If you have feedback on the UI/UX or know good IDX-friendly data sources, I'd love suggestions.

Links again: https://zenpnl.vercel.app/ | https://github.com/meryzennn/profitandloss/

Top comments (0)