Appearance
Market panel
The Market panel is the primary surface for instrument analysis. It pulls live quotes from Finnhub and EOD prices plus fundamentals from EODHD, all proxied through the Atlas backend so API keys stay server-side. Implemented in frontend/src/components/MarketPanel/index.jsx.

Data sources
- Finnhub (backend/services/finnhub.py) — live equity quotes, instrument search, intraday OHLC.
- EODHD (backend/services/eodhd.py) — end-of-day prices, fundamentals (P/E, EBITDA, ROIC, EPS — see glossary), historical history, dividends.
Both sources are exposed through backend/routes/market.py. The frontend never calls these providers directly; this is enforced by the project's secrets handling rules.
Views
The panel switches between five views via the tab strip (portfolioTabs.jsx):
| View | File | What it shows |
|---|---|---|
| Portfolio | PortfolioPriceView.jsx | Holdings table with cost basis, market value, P/L, weight |
| Candlestick | PortfolioCandlestickView.jsx | OHLC candles for the selected symbol with volume bars |
| Performance | PortfolioPerformanceView.jsx | Time-series total return vs. benchmark |
| Technical | PortfolioTechnicalView.jsx | RSI, MACD, moving averages, technical signal labels |
| Fundamental | PortfolioFundamentalView.jsx | P/E, EBITDA, ROIC, EPS, dividend yield, sector multiples |
Switching views never refetches your selection — quote and OHLC data are cached locally via useMarketData.js and useMarketOHLC.js.
Intraday vs. EOD
- Intraday — driven by Finnhub. 1-minute resolution by default. Quote updates flow in over the WebSocket channel (backend/routes/websocket.py).
- EOD — driven by EODHD. Daily bars, dividends, splits, and fundamentals fields. EOD data lags by one trading session for free-tier accounts. See Data delays & limits.
Adding a position
The + button opens AddPositionModal.jsx. Enter symbol, quantity, cost basis, and optional notes. Closed positions move to ClosedPositions.jsx for historical attribution but stop counting against the live P/L summary.
Required env
EODHD_API_KEY,EODHD_BASE_URL
Tips
- The MarketTicker strip (MarketTicker.jsx) at the top of the panel shows your watchlist symbols on a continuous loop — click any symbol to focus the panel on it.
- For quick comparison across many symbols at once, use Market dashboards instead — heatmaps and treemaps surface relative moves better than per-symbol panels.
- For per-instrument financial analysis (income, balance, cash flow, ownership, transcripts), open the Security dashboard — it loads richer data than this panel.
- The Portfolio view (default) and your overall Portfolios → My portfolio read the same store. Edits propagate both ways.
Caching
The panel caches aggressively to keep upstream usage in check:
| Data | TTL | Where |
|---|---|---|
| Live quote | ~10s (or WebSocket-driven) | Redis |
| Intraday OHLC | ~5 min | Redis + frontend hook (useMarketOHLC.js) |
| EOD bars | 1 day | Redis |
| Fundamentals | 1 day | Redis |
| Symbol metadata | 7 days | Redis |
A hard refresh (Ctrl+Shift+R) clears frontend caches; backend Redis caches refresh on TTL or restart.
View-switching cost
Switching between the five views (Portfolio / Candle / Performance / Technical / Fundamental) is free — all data fields fetch once on symbol focus and the views just re-render. So if you find yourself wanting RSI plus the income statement plus a candlestick, switching is faster than opening multiple panels.
The exception: the Fundamental view fetches a richer fundamentals payload than the other views need; first-switch cost ~200ms, then cached.
Common pitfalls
| Symptom | Likely cause | Fix |
|---|---|---|
| Quote permanently shows "delayed" | Free Finnhub tier on a delayed exchange | Upgrade Finnhub or pick a different listing |
| Fundamentals show "—" everywhere | EODHD coverage gap on this symbol | Try a major-exchange peer to confirm the panel works |
| Spike on chart that disappears on reload | One bad upstream tick | EODHD usually corrects; cache TTL is short |
| "No data" on otherwise-active ticker | Symbol typo or wrong exchange suffix | Use command bar fuzzy match instead |
| Portfolio P/L is wrong | Cost basis was entered as price-per-share, not total cost | Edit the position in AddPositionModal.jsx |
Symbol formats
EODHD and Finnhub use slightly different symbol conventions:
- US:
AAPL(no suffix). - LSE:
BARC.L(London suffix). - XETRA:
SAP.XETRA. - TSE (Tokyo):
7203.T.
The command bar fuzzy-matches on company name and resolves to the right symbol form, so most users never type the suffix manually. For programmatic access, see the API reference.