We built a full-stack decision-support platform that unifies Mamba-2 forecasting, FinBERT sentiment analysis, Monte Carlo risk simulation, portfolio optimization, and retrieval-augmented generation behind one conversational interface.
Decision support, not trade execution. We designed the platform to explain evidence, quantify uncertainty, and help users make informed decisions. It never places orders or presents itself as an autonomous investment manager.
Retail investors are surrounded by data but rarely have a coherent analytical system. Market prices live in one product, news in another, portfolio risk in a spreadsheet, and research documents in disconnected folders. The most capable forecasting, optimization, and risk tooling is still packaged for specialists.
We built the AI-Powered Personal Financial Assistant to close that gap. A user can upload a portfolio, ask a question in natural language, and receive an answer grounded in saved holdings, historical prices, financial news, probabilistic risk analysis, and private documents. The experience is simple; the engineering underneath it is deliberately not.
Our system brings together five complementary forms of intelligence:
| Capability | What the user experiences | What happens underneath |
|---|---|---|
| Conversational financial research | Ask questions without learning a query language | GPT-compatible tool calling selects a deterministic analytical workflow |
| Stock direction forecasting | Explore five-day UP, NEUTRAL, or DOWN scenarios |
A four-layer Mamba-2 model processes 256-step financial sequences |
| Portfolio intelligence | Receive target allocations, risk metrics, and rebalancing actions | Ledoit-Wolf covariance estimation and constrained SciPy optimization |
| Uncertainty analysis | Visualize possible price and portfolio trajectories | Vectorized Geometric Brownian Motion Monte Carlo simulation |
| Grounded document analysis | Query uploaded PDF and DOCX research | User-scoped embeddings, ChromaDB similarity search, and RAG prompt construction |
| Sentiment-aware market context | Review tagged, classified financial news | FinBERT inference with multi-provider and local fallbacks |
We chose a service-oriented modular monolith: one deployable Python application with boundaries modeled as if each analytical capability could later become an independent service. This gives us explicit contracts, dependency injection, isolated testing, and clear ownership without adding distributed-system overhead before it is needed.
The diagram below translates our general project architecture into the runtime components implemented in this repository.
flowchart TB
User([User])
Frontend["Next.js Frontend Service<br/>Chat · Portfolio · Prediction · Simulation · Market"]
Agent["Main Agent<br/>UIController · LLMInterface · AgentOrchestrator"]
User <-->|Interacts and prompts| Frontend
Frontend <-->|REST data transfer · /api/v1| Agent
subgraph Intelligence["Analytical and Intelligence Layer"]
Optimizer["Portfolio Optimizer Tool"]
Scheduler["APScheduler"]
Periodic["Periodic Data Fetching Tool"]
MonteCarlo["Monte Carlo Tool"]
Predictor["Stock Prediction Tool"]
NewsAnalysis["News Analysis Tool"]
RAGContext["RAG Context Tool"]
PriceFetcher["Price Data Fetcher"]
NewsFetcher["News Data Fetcher"]
Sentiment["FinBERT Sentiment Tagging"]
EntityTagging["Stock / Sector Tagging"]
Agent --> Optimizer
Agent --> MonteCarlo
Agent --> Predictor
Agent --> NewsAnalysis
Agent --> RAGContext
Scheduler --> Periodic
Periodic --> PriceFetcher
Periodic --> NewsFetcher
NewsAnalysis --> NewsFetcher
NewsAnalysis --> Sentiment
NewsAnalysis --> EntityTagging
NewsFetcher --> Sentiment
NewsFetcher --> EntityTagging
end
subgraph Data["Data Management and Retrieval Layer"]
DBManager["DatabaseManager"]
UserDB[("User DB<br/>Profiles · Portfolios · Settings")]
TimeSeriesDB[("PostgreSQL + TimescaleDB<br/>OHLCV · News · Sync State")]
VectorDB[("ChromaDB Vector Store<br/>News · User Documents")]
RAGModule["RAG Module"]
DBManager --> UserDB
DBManager --> TimeSeriesDB
DBManager --> VectorDB
VectorDB <-->|Cosine similarity retrieval| RAGModule
end
PriceFetcher --> TimeSeriesDB
Sentiment --> TimeSeriesDB
EntityTagging --> TimeSeriesDB
EntityTagging --> RAGModule
UserDB --> Optimizer
TimeSeriesDB --> Optimizer
TimeSeriesDB --> MonteCarlo
TimeSeriesDB --> Predictor
RAGContext --> RAGModule
RAGModule --> RAGContext
| Decision | Why we made it |
|---|---|
| Explicit composition root | main.py constructs database gateways, analytical services, orchestration, middleware, schedulers, and routers in one visible dependency graph. |
| Deterministic agency | The language model identifies intent and writes the narrative; financial calculations remain in typed Python services rather than opaque model reasoning. |
| Storage by access pattern | PostgreSQL handles transactional data, TimescaleDB accelerates time-series access, and ChromaDB handles semantic retrieval. |
| Interface-driven modules | Shared interfaces and DTOs isolate domain logic from infrastructure, making services replaceable and straightforward to test with mocks. |
| Graceful degradation | News, embeddings, sentiment, vector retrieval, and model inference have explicit fallback or failure-isolation paths. |
| Independent deployment boundaries | The Next.js frontend, FastAPI backend, PostgreSQL persistence, and optional Hugging Face inference endpoint can be deployed and scaled separately. |
The chat experience looks agentic, but the execution path remains controlled:
- The Next.js client sends an authenticated request through a centralized Axios layer.
- FastAPI middleware validates the JWT, attaches the user context, and enforces the chat rate limit.
UIControllerloads any required user or portfolio state and hands the request to the orchestration layer.LLMInterfaceexposes five schemas through the OpenAI-compatible tools API:stock_predictionportfolio_advicemonte_carlo_simulationnews_analysisrag_query
AgentOrchestratorinvokes the corresponding deterministic service and aggregates structured results, retrieved documents, news context, and source metadata.- The LLM converts that evidence into a concise, readable answer while our frontend renders specialized cards and charts for forecasts, allocations, and simulations.
This division of responsibility is central to the project: the LLM orchestrates and explains; tested financial services calculate.
Our stock prediction subsystem is much more than a model file behind an endpoint. We built the complete lifecycle:
- a configurable Mamba-2 state-space classifier with four Mamba blocks, a 256-dimensional hidden state, and a three-class
SELL / NEUTRAL / BUYoutput - 256-timestep windows with 13 active market features, including log returns, RSI, MACD histogram, ATR, volume change, OBV, Bollinger Band position/width, VWAP deviation, ADX, Williams %R, price range, and distance from SMA
- volatility-adaptive labels derived from forward returns and ATR rather than one fixed threshold across every asset
- chronological train, validation, and test splits with purge periods to reduce temporal leakage
- class weighting, label smoothing, a custom cross-entropy flip penalty, gradient clipping, OneCycle scheduling, and early stopping on macro F1
- per-ticker scalers and feature-schema checks to keep production inference numerically aligned with training
- both local PyTorch inference and remote Hugging Face inference through the same service contract
- hardware-aware contiguous tensor handling and Mamba-2 projection alignment for optimized CUDA/C++ kernels
- confidence guardrails that default weak directional signals to
NEUTRAL
The model is evaluated as a financial system, not only as a classifier. Our final backtest compares net strategy behavior with an equal-weight buy-and-hold baseline across October 2023–April 2026.
| Backtest metric | Mamba strategy (net) | Buy & hold |
|---|---|---|
| Annualized return | 15.79% | 38.01% |
| Annualized volatility | 13.12% | 29.31% |
| Sharpe ratio | 0.819 | 0.965 |
| Maximum drawdown | -11.13% | -42.53% |
The result illustrates the model's intended behavior: lower absolute return than an unusually strong buy-and-hold period, but dramatically stronger downside protection and substantially lower volatility.
Our portfolio engine turns saved holdings and historical prices into an actionable advisory bundle:
- aligns price histories and handles incomplete ticker coverage explicitly
- calculates log-return matrices and annualized statistics
- applies Ledoit-Wolf covariance shrinkage to stabilize noisy covariance estimates
- uses SciPy's SLSQP solver under full-investment and weight constraints
- selects minimum variance, maximum Sharpe, or maximum return objectives according to the user's risk tolerance
- reports expected return, volatility, Sharpe ratio, beta against SPY, 95% VaR, 95% CVaR, maximum drawdown, and a diversification score
- translates target weights into concrete
BUY,SELL, andHOLDrebalancing actions - warns when observed portfolio risk conflicts with the user's declared profile
The analytical output is reused across direct API workflows, dashboard visualizations, and natural-language portfolio conversations.
The simulation engine calibrates annualized drift and volatility from historical log returns, then generates vectorized Geometric Brownian Motion paths with NumPy. It supports both a single ticker and an entire saved portfolio.
Each result includes:
- p5, p25, p50, p75, and p95 percentile curves
- final-value distributions and representative paths
- expected return and annualized volatility
- 95% value at risk, loss probability, and maximum drawdown
- deterministic reproduction through an optional random seed
- configurable horizon and path count, capped defensively at 100,000 iterations
- insufficient-history and suspiciously narrow-band safeguards
These are not raw arrays hidden behind an endpoint. Recharts-based fan charts and portfolio cards make the uncertainty explorable in both dedicated dashboard pages and the chat workflow.
Our retrieval-augmented generation pipeline lets users build a private research layer over their own material:
PDF / DOCX / text
↓
MIME validation and text extraction
↓
512-token chunks with 50-token overlap
↓
all-MiniLM-L6-v2 embeddings (384 dimensions)
↓
ChromaDB cosine-similarity search filtered by user_id
↓
Top-k context assembly with a strict token budget
↓
Source-aware LLM response
User ownership is enforced inside vector metadata and retrieval filters, not left to prompt instructions. Deleting an account removes both relational records and user-scoped vector documents.
Financial data providers are rate-limited and occasionally unavailable, so we built the news pipeline around resilience:
AlphaVantage → NewsAPI → persisted PostgreSQL cache
Articles are normalized, tagged by stock and sector, persisted, and optionally indexed for retrieval. Sentiment runs through ProsusAI/finbert using Hugging Face inference when configured, with local model execution and a deterministic keyword classifier as fallbacks. Low-confidence and empty-text inputs resolve conservatively to NEUTRAL.
We paired the analytical depth with a responsive interface designed around how an investor actually explores a question.
- Conversational dashboard with Markdown responses, animated transitions, tool-aware result cards, and compact visual narratives
- Portfolio workspace for CSV upload, saved holdings, allocation comparisons, risk metrics, and rebalancing recommendations
- Prediction workspace with model probabilities, projected price ranges, and technical-indicator charts
- Simulation workspace with configurable scenarios and percentile fan charts
- Market and news workspace with historical price exploration and sentiment-aware headlines
- Account and settings flows for registration, authentication, profile changes, passwords, risk preferences, and full data deletion
The frontend is built with the Next.js App Router, React, TypeScript, Tailwind CSS, Axios interceptors, Recharts, Framer Motion, Lucide icons, and React Markdown.
Financial software earns trust through boundaries as much as features. We implemented:
- stateless JWT authentication using HS256 and configurable expiry
- Argon2id password hashing
- protected API routes with authenticated user context
- user-scoped access to portfolios, simulations, and vector documents
- per-user chat rate limiting
- file size and MIME-type validation
- relational constraints, cascade deletion, and user data sovereignty
- a low-temperature LLM configuration and structured tool calling
- confidence thresholds and conservative
NEUTRALdefaults - a strict advisory posture with no automated order execution
| Layer | Technologies |
|---|---|
| Frontend | Next.js 16, React 19, TypeScript 5, Tailwind CSS 4, Axios, Recharts, Framer Motion, React Markdown, Lucide React |
| API and application | Python 3.11, FastAPI, Uvicorn, Pydantic, APScheduler, Requests |
| AI orchestration | OpenAI-compatible Chat Completions and Tools APIs |
| Machine learning | PyTorch, Mamba SSM, causal-conv1d, Hugging Face Hub, FinBERT, all-MiniLM-L6-v2 |
| Quantitative analytics | NumPy, pandas, SciPy, scikit-learn, Ledoit-Wolf, SLSQP, Geometric Brownian Motion |
| Market data | AlphaVantage, NewsAPI, yfinance |
| Persistence | PostgreSQL, TimescaleDB, SQLAlchemy 2, psycopg2, ChromaDB |
| Documents | pdfplumber, python-docx, multipart uploads |
| Security | python-jose, Argon2id, JWT, RBAC-oriented ownership checks |
| Testing | pytest, pytest-asyncio, mocks, integration harnesses, manual browser workflows, Playwright tooling |
| Deployment | Render infrastructure-as-code, independent Python and Node services, Hugging Face inference |
Our final verification combined unit, integration, API, persistence, system, RAG, analytical-service, and manual browser testing.
- 163 automated tests collected
- 155 automated tests selected, with eight live-database tests isolated from the main run
- 155 selected automated tests passed with zero failures
- 16 manual end-to-end browser workflows passed
Selected measurements documented in our Final Project Report:
| Workflow | Observed result |
|---|---|
| Portfolio optimization, up to 10 holdings | < 500 ms |
| Monte Carlo, 1,000 paths over 30 days | < 3 s on CPU |
| RAG retrieval, top three chunks | < 200 ms |
| JWT middleware overhead | < 1 ms |
| News endpoint end-to-end workflow | 4.86 s |
| Stock/sector news tagging | 94.5% accuracy |
The repository currently contains 29 test files spanning APIs, middleware, orchestration, databases, RAG, news analysis, prediction, optimization, simulation, scheduling, and reporting.
AI_Financial_Assistant/
├── api/ # FastAPI routers, request models, and middleware
├── frontend/ # Next.js application and analytical dashboards
├── modules/
│ ├── core/ # UI controller, agent orchestration, scheduler
│ ├── database/ # PostgreSQL, TimescaleDB, and ChromaDB services
│ ├── nlp/ # LLM interface, FinBERT, news analysis
│ ├── rag/ # Document ingestion, embedding, and retrieval
│ └── tools/ # Prediction, optimization, simulation, market data
├── shared_kernel/ # Interfaces, DTOs, value objects, and exceptions
├── training/mamba/ # Reproducible Mamba-2 training and evaluation pipeline
├── models/ # Model artifacts, scalers, and backtest visualizations
├── scripts/ # Local startup, ingestion, and reporting utilities
├── Reports/ # Final report and low-level design
├── main.py # Application factory and dependency composition root
└── render.yaml # Reproducible cloud service definitions
- Python 3.11+
- Node.js 20.9+
- PostgreSQL with TimescaleDB
- provider credentials for the LLM and live market/news features
git clone git@github.com:Bitirme2025/AI_Financial_Assistant.git
cd AI_Financial_Assistant
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements.txtCreate a .env file with the services you want to enable:
POSTGRES_CONNECTION_STRING=postgresql://user:password@localhost:5432/financial_assistant
CHROMA_PERSIST_PATH=./chroma
LLM_MODEL_ENDPOINT=https://api.openai.com/v1/chat/completions
LLM_API_KEY=your-key
LLM_MODEL_NAME=gpt-4o
EXTERNAL_API_KEY=your-alphavantage-key
FALLBACK_NEWS_API_KEY=your-newsapi-key
HF_TOKEN=your-huggingface-token
JWT_SECRET_KEY=replace-with-a-long-random-secretApply the PostgreSQL schema:
psql "$POSTGRES_CONNECTION_STRING" \
-f modules/database/migrations/001_initial_schema.sql
psql "$POSTGRES_CONNECTION_STRING" \
-f modules/database/migrations/002_data_management_hardening.sqlbash scripts/run_app_local.sh| Service | Local URL |
|---|---|
| Frontend | http://127.0.0.1:3000 |
| Backend | http://127.0.0.1:8000 |
| Interactive API documentation | http://127.0.0.1:8000/docs |
Run the automated suite with:
pytest -vOur hosted demo uses free-tier services, so the first request may require a brief cold start.
- Final Project Report — architecture, project status, technology decisions, quantitative results, testing, and engineering reflection
- Low-Level Design — service contracts, class responsibilities, sequence diagrams, subsystem boundaries, and failure behavior
- Short Run Guide — the fastest local startup path
- Frontend Workflow Test Guide — browser flows and direct database verification
- Monte Carlo Test Guide — simulation scenarios and expected outputs
This project is released under the MIT License.
