Pulse AI is a full-stack stock intelligence dashboard that combines:
- real-time or cached stock price retrieval from Alpha Vantage,
- technical anomaly detection using a Python microservice,
- AI-generated market commentary using Google Gemini,
- portfolio tracking with live mark-to-market calculations,
- watchlist management with mini sparkline previews.
The project is split into three major parts:
- Frontend – React + Vite dashboard UI
- Node.js backend – Express API + MongoDB persistence
- Python backend – FastAPI service for anomaly detection and AI insight generation
flowchart LR
U[User] --> F[React Frontend]
F -->|GET /api/stocks/:ticker| E[Express API]
F -->|GET /api/insights/:ticker| E
F -->|GET/POST/DELETE portfolio| E
F -->|GET/POST/DELETE watchlist| E
E --> M[(MongoDB)]
E --> A[Alpha Vantage API]
E -->|POST /api/anomaly| P[FastAPI Service]
E -->|POST /api/insights| P
P --> D[Anomaly Engine]
P --> G[Gemini LLM Client]
D --> P
G --> P
P --> E
E --> F
Pulse-AI-Stock-Intelligence-Dashboard/
├── backend/
│ ├── express/
│ │ ├── index.js
│ │ ├── models/
│ │ │ ├── CatchedPrices.js
│ │ │ ├── Portfolio.js
│ │ │ └── Watchlist.js
│ │ ├── routes/
│ │ │ ├── insights.js
│ │ │ ├── portfolio.js
│ │ │ ├── stocks.js
│ │ │ └── watchlist.js
│ │ ├── services/
│ │ │ └── alphaVantage.js
│ │ └── scripts/
│ │ └── seedCache.js
│ └── python/
│ ├── main.py
│ ├── routers/
│ │ ├── anomaly.py
│ │ └── insights.py
│ └── services/
│ ├── anomaly_engine.py
│ └── llm_client.py
├── frontend/
│ └── src/
│ ├── App.jsx
│ ├── utils/api.js
│ └── components/
│ ├── AIInsightCard.jsx
│ ├── AnomalyTable.jsx
│ ├── KPICard.jsx
│ ├── PortfolioPieChart.jsx
│ ├── PortfolioTracker.jsx
│ ├── StockChart.jsx
│ └── WatchlistSidebar.jsx
└── README.md
The frontend is built with React + Vite and acts as the main user-facing dashboard.
frontend/src/main.jsxbootstraps the React app.frontend/src/App.jsxis the central container for the dashboard.frontend/src/utils/api.jsdefines Axios API helpers.
- Search for a ticker and trigger analysis
- Show KPI cards for latest price, daily change, anomaly count, and data source
- Render a price chart with anomaly markers
- Display AI-generated market insight
- Manage a user watchlist
- Manage portfolio holdings and allocation visualization
This is the orchestration layer for the UI.
It:
- stores the selected ticker,
- triggers stock fetch and AI insight fetch,
- manages loading and error states,
- switches between Dashboard and Portfolio tabs,
- passes data into presentational components.
Uses Recharts to render the closing-price trend for the last 30 trading days.
It also:
- formats dates for chart labels,
- shows OHLC + volume in a custom tooltip,
- highlights anomaly dates with red
ReferenceDotmarkers.
Displays:
- trend classification,
- risk level,
- 2-sentence summary,
- price target hint,
- key observation.
If the Gemini call fails or quota is hit, the backend may return a computed fallback insight, which this card still renders.
Renders anomaly rows with:
- date,
- close price,
- % move,
- z-score,
- severity,
- direction.
Supports:
- add ticker,
- remove ticker,
- select ticker for dashboard analysis,
- quick performance preview with mini sparklines.
Supports:
- add holding,
- remove holding,
- fetch latest holding metrics,
- compute and display overall P&L summary,
- render a portfolio allocation pie chart.
Uses Recharts PieChart to visualize holding allocation by current value.
The Node.js backend is the main API gateway between the frontend, MongoDB, Alpha Vantage, and the FastAPI service.
backend/express/index.js
- Expose REST endpoints for stock analysis, insights, portfolio, and watchlist
- Connect to MongoDB with Mongoose
- Fetch market data from Alpha Vantage
- Forward price data to FastAPI for anomaly detection and AI insights
- Persist watchlist, portfolio, and cached prices
/api/stocks→ stock price retrieval + anomaly analysis/api/insights→ AI insight generation/api/portfolio→ portfolio CRUD + enrichment/api/watchlist→ watchlist CRUD + enrichment/health→ service health check
Flow:
- Validate ticker symbol.
- Fetch daily prices using
getDailyPrices(). - Slice the latest 30 trading days.
- Send those prices to FastAPI
/api/anomaly. - Return prices + anomaly result to frontend.
Note: In the current code, the anomaly response is called but not assigned back into the anamolies array, so the frontend may receive an empty anomaly list even if FastAPI detects anomalies. This is an implementation gap worth fixing.
Flow:
- Fetch the latest daily prices.
- Normalize numeric fields.
- Send the last 30 days to FastAPI
/api/insights. - Return structured AI insight data.
- If FastAPI fails, return a safe fallback response.
This route is more defensive and better instrumented than the stock route.
Provides:
GET /api/portfolio→ returns holdings and aggregated summaryPOST /api/portfolio→ adds a holdingDELETE /api/portfolio/:id→ removes a holding
For each stored holding, the route fetches the latest market data and computes:
- current price,
- current value,
- total cost,
- P&L,
- P&L percentage.
Provides:
GET /api/watchlist→ list watchlist items with price, day change, sparkline dataPOST /api/watchlist→ add or upsert a tickerDELETE /api/watchlist/:ticker→ remove a ticker
backend/express/services/alphaVantage.js
- Call Alpha Vantage daily time-series endpoint
- Transform raw API response into normalized objects
- Cache the result in MongoDB
- Return demo data when API quota/rate limit is reached
{
date,
open,
high,
low,
close,
volume
}If Alpha Vantage returns a Note or Information field, the code switches to generated demo price data. This prevents the UI from completely failing when API limits are hit.
Stores cached daily prices by ticker.
Intended behavior:
- one document per ticker,
- TTL-based auto-expiry after about 1 hour.
Stores:
- ticker,
- shares,
- buy price,
- buy date,
- timestamp.
Stores unique tickers for the user watchlist.
The Python service handles the analytics/AI side of the platform.
backend/python/main.py
/api/anomaly/api/insights/health
Because Python is a natural fit for analytics logic, statistical processing, and AI/ML integration. The Express service uses it like a specialized analytics engine.
backend/python/routers/anomaly.pybackend/python/services/anomaly_engine.py
- Receive ticker + price series from Express.
- Compute day-over-day percent changes.
- Calculate mean and standard deviation of changes.
- Compute z-score for each day.
- Flag days with
|z-score| > 2.0as anomalies. - Mark severity:
MEDIUMif|z| > 2HIGHif|z| > 3
- Classify direction:
SPIKE UPDROP DOWN
Each anomaly may contain:
- date
- close
- prev_close
- pct_change
- z_score
- severity
- direction
- reason
backend/python/routers/insights.pybackend/python/services/llm_client.py
- Receive ticker + recent prices.
- Re-run anomaly detection for context.
- Compute summary features:
- start price,
- end price,
- overall change,
- 30-day high,
- 30-day low,
- average volume.
- Build a structured prompt.
- Send prompt to Google Gemini.
- Expect a JSON-only response.
- Parse JSON and return to Express.
- If parsing fails or quota is exceeded, return a fallback computed insight.
{
"trend": "Bullish | Bearish | Neutral",
"risk_level": "Low | Medium | High",
"price_target_hint": "brief one-line price expectation",
"summary": "2-sentence explanation",
"key_observation": "specific pattern insight"
}flowchart TD
A[Express sends ticker + prices] --> B[FastAPI insights router]
B --> C[Run anomaly detection]
C --> D[Compute price summary metrics]
D --> E[Build Gemini prompt]
E --> F[Call Gemini model]
F --> G{Valid JSON returned?}
G -- Yes --> H[Parse structured insight]
G -- No --> I[Fallback insight or raw response]
H --> J[Return insight to Express]
I --> J
sequenceDiagram
participant User
participant Frontend
participant Express
participant MongoDB
participant AlphaVantage
participant FastAPI
participant Gemini
User->>Frontend: Enter ticker and click Analyze
Frontend->>Express: GET /api/stocks/:ticker
Express->>MongoDB: Check cached prices
alt Cache hit
MongoDB-->>Express: Cached prices
else Cache miss
Express->>AlphaVantage: Fetch daily prices
AlphaVantage-->>Express: Time series data
Express->>MongoDB: Save cache
end
Express->>FastAPI: POST /api/anomaly
FastAPI-->>Express: Anomaly results
Express-->>Frontend: Prices + anomalies
Frontend->>Express: GET /api/insights/:ticker
Express->>FastAPI: POST /api/insights
FastAPI->>Gemini: Generate stock insight
Gemini-->>FastAPI: Structured JSON insight
FastAPI-->>Express: Insight response
Express-->>Frontend: Insight payload
Frontend-->>User: Chart, KPI cards, anomalies, AI summary
GET /api/stocks/:tickerGET /api/insights/:ticker
GET /api/portfolioPOST /api/portfolioDELETE /api/portfolio/:id
GET /api/watchlistPOST /api/watchlistDELETE /api/watchlist/:ticker
GET /health
POST /api/anomalyPOST /api/insightsGET /health
- React
- Vite
- Axios
- Recharts
- react-sparklines
- Tailwind CSS
- Node.js
- Express
- Mongoose
- MongoDB
- Axios
- FastAPI
- Pydantic
- Google Generative AI SDK
- python-dotenv
- Alpha Vantage
- Google Gemini