Skip to content

Latest commit

 

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fintel — AI Financial Research Agent

A production-grade AI-powered stock research platform built with FastAPI, LangGraph, GPT-4o, and a fully responsive dark UI. Analyze any stock ticker, get deterministic buy/sell/hold decisions backed by a normalized multi-factor scoring engine, real-time technical indicators, fundamental data, news sentiment, and an AI chat assistant — all deployed on AWS EC2.

Python FastAPI Docker GPT-4o AWS EC2 Mobile Ready

🚀 Live Demo

👉 fintel.rajkumarai.dev — deployed on AWS EC2

Portfolio: rajkumarai.dev


What Makes This Different

Most AI financial tools let the LLM decide whether to buy or sell. This system does not. The investment decision is made entirely by a deterministic scoring engine — GPT-4o only explains the decision in plain English. This eliminates hallucination risk from the most critical part of the pipeline.


Features

Scoring Engine

  • Normalized scoring — scores are computed as (actual / max_possible) × 100, so stocks with missing data are judged fairly on what's available rather than penalized
  • Three-component model — Technical (0–25), Fundamental (0–40), Sentiment (0–15), minus a Volatility penalty (0–10)
  • Decision thresholds — BUY ≥ 70%, HOLD 40–69%, SELL < 40%, operating on the normalized score
  • Conflict detection — when technical and fundamental signals sharply disagree (variance > 0.15) and the score sits in the 35–55 borderline zone, the system overrides to HOLD to avoid a false signal
  • Time horizon adaptation — weight profiles for short_term (amplifies technicals), long_term (amplifies fundamentals), and default (balanced)
  • Confidence scoring — 5-factor model: data completeness, missing data penalty, signal agreement, signal consistency bonus, volatility/uncertainty penalty

Analysis

  • Live market data — real OHLCV price history via Alpha Vantage TIME_SERIES_DAILY (last 100 trading days)
  • Technical indicators — MA50, MA200, RSI, volatility, 1Y price change, golden cross / death cross detection
  • Fundamental data — revenue growth, profit margin, P/E ratio, debt-to-equity, EPS via Alpha Vantage
  • News sentiment — real-time news via Tavily API, scored by GPT-4o into positive / neutral / negative

Portfolio Mode

  • Multi-ticker ranking — submit a list of tickers and receive a ranked table sorted by normalized score
  • Allocation percentages — portfolio allocation is distributed proportionally among BUY and HOLD positions; SELL and INSUFFICIENT_DATA positions receive 0%

AI Chat Assistant

  • Full analysis context — after running an analysis, the chat assistant receives the complete result: recommendation, normalized score, all component scores, fundamentals (P/E, EPS, revenue growth, profit margin, FCF), reasoning, news summary, risk assessment, key factors, and data gaps
  • Pronoun resolution — when you ask "why is it a buy?" or "compare it with MSFT", the backend automatically resolves "it" and "this stock" to the currently analyzed ticker using keyword detection
  • Dynamic suggestion chips — chips update after every analysis based on the result: "Why BUY/SELL/HOLD?", "Signal conflict?" (when technical and fundamental signals disagree), "Compare {TICKER}", "Key risks", and "Data gaps?" (when incomplete data was detected)
  • Smart compare pre-fill — clicking "Compare" sets the input to "Compare {TICKER} with " and focuses the cursor, prompting you to type the second ticker rather than auto-sending a hardcoded pair
  • Company name display — the chat panel header shows the full company name alongside the ticker symbol after analysis completes

Infrastructure

  • Redis caching — analysis results cached for 15 minutes to minimize API calls
  • Session memory — chat history persisted per session in Redis
  • Fully mobile responsive — tab-based layout on mobile with Analysis and Chat panels switchable via bottom tab bar

Tech Stack

Layer Technology
Backend FastAPI + Uvicorn
AI Orchestration LangGraph + LangChain
LLM OpenAI GPT-4o
Market Data Alpha Vantage TIME_SERIES_DAILY
Fundamental Data Alpha Vantage API
News Tavily Search API
Caching & Sessions Redis
Data Validation Pydantic v2
Logging Structlog (structured JSON)
Frontend Vanilla JS + Chart.js
Containerization Docker + Docker Compose
Cloud AWS EC2 (Ubuntu 24.04)

Architecture

LangGraph StateGraph Pipeline

The orchestrator is a compiled LangGraph StateGraph with 9 nodes. Market data is fetched first (sequential), then fundamental data and news are fetched in parallel (fan-out), before converging back for the scoring and decision nodes (fan-in).

User Request
     │
     ▼
FastAPI REST API
     │
     ▼
LangGraph StateGraph (orchestrator.py)
     │
     ├─ dispatch               → validates input, sets initial state
     │
     ├─ fetch_market_data      → Alpha Vantage TIME_SERIES_DAILY (OHLCV)
     │
     ├─ [parallel fan-out] ───────────────────────────────────┐
     │    fetch_fundamental_data → Alpha Vantage OVERVIEW       │
     │    fetch_news             → Tavily + GPT-4o sentiment    │
     └────────────────────────────────────────────────────────┘
          │ [fan-in: both branches merge into compute_indicators]
          ▼
     compute_indicators        → MA50, MA200, RSI, volatility, trend
          │
     [conditional edge: abort to END if market data failed]
          │
     compute_scores            → deterministic multi-factor scoring
          │
     make_decision             → BUY / HOLD / SELL (no LLM)
          │
     generate_explanation      → GPT-4o writes plain English summary
          │
     apply_guardrails          → INSUFFICIENT_DATA override if needed
          │
          ▼
Redis Cache (TTL: 15 min) → JSON Response → Frontend

State management: AgentState is a TypedDict with Annotated reducers — operator.add for list fields (errors, tool_calls_log) and a last-writer-wins lambda for current_step, preventing conflicts when parallel branches update state simultaneously.

Scoring Engine Detail

Technical Score   (0–25)  ← MA cross, RSI, price momentum, volatility
Fundamental Score (0–40)  ← revenue growth, profit margin, P/E, D/E, EPS
Sentiment Score   (0–15)  ← news tone (positive=10, neutral=5, negative=0)
Volatility Penalty(0–10)  ← subtracted from total

normalized_score = (total / max_possible) × 100

BUY  ≥ 70%
HOLD  40–69%  (or conflict override when signals disagree in 35–55 range)
SELL < 40%

Project Structure

financial-research-agent/
├── app/
│   ├── agents/
│   │   ├── scoring_engine.py      # Deterministic multi-factor scoring
│   │   ├── portfolio_engine.py    # Multi-ticker ranking + allocation
│   │   ├── decision_agent.py      # GPT-4o explanation generator
│   │   └── orchestrator.py        # LangGraph pipeline
│   ├── api/
│   │   ├── middleware.py           # CORS + request logging
│   │   └── routes/
│   │       ├── analysis.py         # /analyze, /chat, /portfolio/rank
│   │       └── health.py           # /health/live and /health/ready
│   ├── models/
│   │   ├── agent_state.py          # LangGraph state (TypedDict)
│   │   ├── requests.py             # Pydantic request models
│   │   └── responses.py            # Pydantic response models
│   ├── services/
│   │   ├── cache_service.py        # Redis async wrapper
│   │   ├── session_service.py      # Chat history in Redis
│   │   └── validation_service.py   # Data quality checks
│   ├── tools/
│   │   ├── yfinance_tool.py        # Market data fetcher (Alpha Vantage)
│   │   └── tavily_tool.py          # News fetcher
│   ├── utils/
│   │   ├── config.py               # Pydantic BaseSettings
│   │   └── logger.py               # Structlog setup
│   └── main.py                     # FastAPI app + lifespan
├── frontend/
│   └── index.html                  # Single-page responsive UI
├── Dockerfile
├── docker-compose.yml
└── requirements.txt

API Endpoints

Method Endpoint Description
POST /api/v1/analyze Full AI analysis for a single stock ticker
POST /api/v1/chat Conversational AI assistant
POST /api/v1/portfolio/rank Rank and allocate across multiple tickers
GET /health/live Liveness check
GET /health/ready Readiness check (Redis connection)

Analyze a stock

curl -X POST http://localhost:8000/api/v1/analyze \
  -H "Content-Type: application/json" \
  -d '{"ticker": "AAPL", "include_news": true, "time_horizon": "long_term"}'

Response fields include: recommendation, normalized_score, confidence_score, conflict_detected, missing_components, time_horizon_used, score_breakdown, technical_indicators, fundamental_data, news_summary, explanation

Rank a portfolio

curl -X POST http://localhost:8000/api/v1/portfolio/rank \
  -H "Content-Type: application/json" \
  -d '{"tickers": ["AAPL", "MSFT", "TSLA", "NVDA"], "time_horizon": "default"}'

Chat

curl -X POST http://localhost:8000/api/v1/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "Why is AAPL rated HOLD?", "session_id": "session-abc123", "ticker": "AAPL"}'

Getting Started

Prerequisites

1. Clone the repo

git clone https://github.com/Rajkumar2002-Rk/financial-research-agent.git
cd financial-research-agent

2. Create your .env file

cp .env.example .env

Edit .env and fill in your API keys:

OPENAI_API_KEY=your_openai_key
TAVILY_API_KEY=your_tavily_key
ALPHA_VANTAGE_API_KEY=your_alphavantage_key
REDIS_URL=redis://redis:6379
OPENAI_MODEL=gpt-4o

3. Run with Docker

docker compose up --build

Open http://localhost:8000 in your browser.


Deployment on AWS EC2

  1. Launch an EC2 instance (Ubuntu 24.04, t2.micro or larger)
  2. Open port 8000 in your security group
  3. SSH in and install Docker:
sudo apt-get update && sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
  https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker ubuntu
  1. Clone, configure, and run:
git clone https://github.com/Rajkumar2002-Rk/financial-research-agent.git
cd financial-research-agent
nano .env
docker compose up --build -d
  1. Access at http://<your-ec2-public-ip>:8000

Environment Variables

Variable Required Description
OPENAI_API_KEY Yes OpenAI API key
TAVILY_API_KEY Yes Tavily Search API key
ALPHA_VANTAGE_API_KEY Yes Alpha Vantage API key (fundamental data)
REDIS_URL Yes Redis connection URL
OPENAI_MODEL No Model name (default: gpt-4o)
REDIS_CACHE_TTL No Cache TTL in seconds (default: 900)
REDIS_SESSION_TTL No Session TTL in seconds (default: 3600)

Known Limitations

  • Alpha Vantage free tier is limited to 25 API calls/day. Fundamental data may be unavailable for less common tickers.
  • INSUFFICIENT_DATA is returned when confidence falls below threshold (e.g., extreme volatility + negative sentiment with no fundamentals). This is intentional — the system refuses to guess.
  • Not financial advice. This is a personal portfolio project for demonstrating AI system design. Do not use it to make real investment decisions.

License

MIT

About

Stock research agent where GPT-4o never makes the investment call. A 9-node LangGraph pipeline gathers market, fundamental and news data, then a deterministic scoring engine issues BUY/HOLD/SELL with a confidence score - the model only classifies sentiment and writes the explanation.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages