AI Hedge Fund is an open-source, educational simulation of an AI-powered investment firm. It runs a team of AI "analyst" agents — each modeled on a famous investor or an analytical discipline — that read real financial data, debate a stock, and produce buy/sell/hold decisions. A risk manager sets position limits and a portfolio manager makes the final call.
Caution
This project is a proof of concept for educational and research purposes only. It does not place real trades and is not investment advice. No guarantees are provided, and the creator assumes no liability for financial losses. Always consult a licensed financial advisor before making investment decisions.
You can use AI Hedge Fund in two ways:
- Command Line Interface (CLI) — run an analysis or a historical backtest directly in your terminal. Best for automation, scripting, and power users.
- Web Application — a visual, browser-based interface where you build and run agent "flows" by dragging nodes on a canvas. Best for users who prefer a graphical experience.
This guide covers both, from first install to advanced multi-model configurations.
Table of Contents
- Quick Start
- What You Get
- Requirements
- Installation
- Running the CLI
- Choosing Analysts
- Choosing a Language Model
- Running the Backtester
- Running with Local Models (Ollama)
- Running with Docker
- Using the Web Application
- Common Tasks & Recipes
- How It Works
- Command & Flag Reference
- Environment Variables Reference
- Troubleshooting
- FAQ
1. Quick Start
If you already have Python 3.11, Poetry, and an OpenAI API key, you can be running in three steps.
# 1. Clone and enter the project
git clone https://github.com/virattt/ai-hedge-fund.git
cd ai-hedge-fund
# 2. Create your .env and add at least one LLM key + a data key
cp .env.example .env
# (edit .env — set OPENAI_API_KEY and FINANCIAL_DATASETS_API_KEY)
# 3. Install dependencies and run
poetry install
poetry run python src/main.py --ticker AAPL,MSFT,NVDA
You'll be prompted to pick your analysts and a model, then the agents run and print their signals and a final trading decision per ticker.
Analysis for AAPL
==================================================
AGENT ANALYSIS: [AAPL]
+------------------+----------+--------------+----------------------------+
| Agent | Signal | Confidence | Reasoning |
+==================+==========+==============+============================+
| Warren Buffett | BULLISH | 85% | Durable moat, strong ... |
| Cathie Wood | NEUTRAL | 60% | Innovation pipeline ... |
+------------------+----------+--------------+----------------------------+
TRADING DECISION: [AAPL]
+------------+--------+
| Action | BUY |
| Quantity | 50 |
| Confidence | 78.0% |
+------------+--------+
Note
The exact analysts, models, signals, and numbers you see depend on your selections and live data. Output is illustrative.
2. What You Get
AI Hedge Fund assembles a virtual investment committee. When you run it, the following happens for the tickers you choose:
| Stage | Who | What they do |
|---|---|---|
| Analysis | Your selected analyst agents (run in parallel) | Each fetches financial data and emits a signal: bullish, bearish, or neutral, with a confidence score and reasoning. |
| Risk control | Risk Manager | Measures each ticker's volatility and correlation, then sets a maximum position size per ticker. |
| Decision | Portfolio Manager | Combines all analyst signals with the risk limits and produces the final action and quantity for each ticker. |
The available actions a decision can take are:
| Action | Meaning |
|---|---|
buy |
Open or add to a long position |
sell |
Reduce or close a long position |
short |
Open or add to a short position |
cover |
Buy back (close) a short position |
hold |
Take no action |
Important
AI Hedge Fund simulates these decisions. It never connects to a broker and never executes a real order. The "portfolio" is an in-memory record used for analysis and backtesting only.
3. Requirements
Software
| Tool | Version | Why |
|---|---|---|
| Python | 3.11 (recommended) | The engine and backend. Python 3.13+ may cause dependency issues. |
| Poetry | latest | Python dependency and virtual-environment manager. |
| Node.js + npm | latest LTS | Required only for the web application's frontend. |
| Docker | latest | Optional — only if you run via containers. |
| Ollama | latest | Optional — only if you want to run local models instead of cloud APIs. |
API keys
You need two kinds of keys, set in a .env file:
- At least one LLM provider key — to power the agents' reasoning (e.g.
OPENAI_API_KEY,ANTHROPIC_API_KEY,GROQ_API_KEY,DEEPSEEK_API_KEY, or any other supported provider). Not required if you use Ollama local models. FINANCIAL_DATASETS_API_KEY— to fetch the financial data (prices, fundamentals, news, insider trades) that the agents analyze.
Tip
Get an LLM key from your preferred provider (e.g. platform.openai.com) and a data key from financialdatasets.ai. See the Environment Variables Reference for the full list of supported providers.
4. Installation
These steps are common to both the CLI and the web application.
Step 1 — Clone the repository
git clone https://github.com/virattt/ai-hedge-fund.git
cd ai-hedge-fund
Step 2 — Create your .env file
The repository ships a template named .env.example with every supported key. Copy it:
cp .env.example .env
Step 3 — Add your API keys
Open .env in any editor and fill in the keys you have. At minimum, set one LLM key and the data key:
# For running LLMs hosted by OpenAI (GPT 5, etc.)
OPENAI_API_KEY=your-openai-api-key
# For getting financial data to power the hedge fund
FINANCIAL_DATASETS_API_KEY=your-financial-datasets-api-key
Important
You must set at least one LLM API key (such as
OPENAI_API_KEY,GROQ_API_KEY,ANTHROPIC_API_KEY, orDEEPSEEK_API_KEY) for the hedge fund to work. If a key is missing, the agent that needs it raises an error such asOpenAI API key not found. Please make sure OPENAI_API_KEY is set in your .env file....
Step 4 — Install Poetry (if needed)
macOS / Linux
curl -sSL https://install.python-poetry.org | python3 -
Windows
Download and run the official installer from python-poetry.org, or use the macOS/Linux command inside WSL.
Step 5 — Install project dependencies
poetry install
This creates a virtual environment and installs everything the CLI needs (LangChain, LangGraph, pandas, the LLM provider clients, and more).
Tip
All later commands are prefixed with
poetry runso they execute inside that environment. If you'd rather not type the prefix each time, activate the shell withpoetry shellfirst.
5. Running the CLI
The CLI is the fastest way to get a trading decision. The entry point is src/main.py.
Basic run
poetry run python src/main.py --ticker AAPL,MSFT,NVDA
--ticker (also spelled --tickers) takes a comma-separated list of stock symbols with no spaces.
When you run this, you'll be asked two interactive questions:
- Select your AI analysts — a checkbox list. Press
Spaceto toggle each,ato toggle all, andEnterto confirm. You must pick at least one. - Select your LLM model — an arrow-key menu of supported cloud models.
After your choices, the agents run and the results are printed as tables.
Analyze a specific date range
By default the system reasons about the period leading up to today. Pin it to an exact window with --start-date and --end-date (both YYYY-MM-DD):
poetry run python src/main.py --ticker AAPL,MSFT,NVDA --start-date 2024-01-01 --end-date 2024-03-01
Warning
Dates must be in
YYYY-MM-DDformat. Anything else raisesStart date must be in YYYY-MM-DD formatorEnd date must be in YYYY-MM-DD format.
See each agent's reasoning
Add --show-reasoning to print the full chain-of-thought each agent produced, not just the final signal:
poetry run python src/main.py --ticker NVDA --show-reasoning
Skip the interactive prompts
You can pre-answer both prompts with flags, which is essential for scripting and automation:
poetry run python src/main.py \
--ticker AAPL,MSFT \
--analysts warren_buffett,cathie_wood,technical_analyst \
--model gpt-4o
--analyststakes comma-separated analyst keys (see the analyst table).--analysts-allselects every analyst and overrides--analysts.--modelselects the LLM by name and skips the model menu.
Set starting capital and shorting margin
poetry run python src/main.py --ticker AAPL --initial-cash 250000 --margin-requirement 0.5
--initial-cash(alias--initial-capital) sets the simulated starting cash. Default:100000.0.--margin-requirementsets the margin ratio required to open short positions (e.g.0.5= 50%). Default:0.0.
Visualize the agent graph
poetry run python src/main.py --ticker AAPL --show-agent-graph
This saves a diagram of the agent workflow (the wiring of analysts → risk manager → portfolio manager) as a PNG.
6. Choosing Analysts
Analysts are the heart of the system. There are two families: investor personas (each emulating a legendary investor's philosophy) and analytical specialists (each focused on one discipline). Use the key in the left column with the --analysts flag.
Investor personas
| Key | Name | Style in one line |
|---|---|---|
aswath_damodaran |
Aswath Damodaran | The Dean of Valuation — rigorous intrinsic-value analysis. |
ben_graham |
Ben Graham | The Father of Value Investing — margin of safety, undervalued names. |
bill_ackman |
Bill Ackman | The Activist Investor — bold, contrarian, pushes for change. |
cathie_wood |
Cathie Wood | The Queen of Growth — disruptive innovation and technology. |
charlie_munger |
Charlie Munger | The Rational Thinker — wonderful businesses at fair prices. |
michael_burry |
Michael Burry | The Big Short Contrarian — deep value, willing to short. |
mohnish_pabrai |
Mohnish Pabrai | The Dhandho Investor — low-risk, high-upside doubles. |
nassim_taleb |
Nassim Taleb | The Black Swan analyst — tail risk, antifragility, asymmetry. |
peter_lynch |
Peter Lynch | The 10-Bagger Investor — "buy what you know." |
phil_fisher |
Phil Fisher | The Scuttlebutt Investor — deep qualitative research. |
rakesh_jhunjhunwala |
Rakesh Jhunjhunwala | The Big Bull of India — macro-driven growth bets. |
stanley_druckenmiller |
Stanley Druckenmiller | The Macro Investor — top-down asymmetric opportunities. |
warren_buffett |
Warren Buffett | The Oracle of Omaha — durable moats, long-term ownership. |
Analytical specialists
| Key | Name | Focus |
|---|---|---|
technical_analyst |
Technical Analyst | Chart patterns, trends, and technical indicators. |
fundamentals_analyst |
Fundamentals Analyst | Financial statements and intrinsic value. |
growth_analyst |
Growth Analyst | Growth trends and growth-vs-valuation. |
news_sentiment_analyst |
News Sentiment Analyst | Sentiment derived from company news. |
sentiment_analyst |
Sentiment Analyst | Market sentiment and investor behavior. |
valuation_analyst |
Valuation Analyst | Fair-value models and valuation metrics. |
Tip
Mix personas with specialists for a richer committee. For example,
--analysts warren_buffett,cathie_wood,technical_analyst,sentiment_analystblends two opposing investment philosophies with a chart reader and a sentiment gauge.
Note
Regardless of which analysts you select, the Risk Manager and Portfolio Manager always run. They are not optional analysts — they are the final two stages that turn signals into a decision.
7. Choosing a Language Model
Each agent's reasoning is produced by a large language model (LLM). You can use a cloud provider or run models locally with Ollama.
Cloud models
When you don't pass --model, the CLI shows a menu of cloud models. To select non-interactively, pass the model name:
poetry run python src/main.py --ticker AAPL --model gpt-5.5
Supported cloud providers include OpenAI, Anthropic, DeepSeek, Groq, Google (Gemini), xAI (Grok), Kimi / Moonshot, OpenRouter, GigaChat, and Azure OpenAI. Each requires its corresponding API key in .env (see the Environment Variables Reference).
The bundled cloud model menu includes options such as:
| Display name | Model name | Provider |
|---|---|---|
| GPT-5.5 | gpt-5.5 |
OpenAI |
| Claude Opus 4.8 | claude-opus-4-8 |
Anthropic |
| Gemini 3.1 Pro | gemini-3.1-pro-preview |
|
| Grok 4.3 | grok-4.3 |
xAI |
| DeepSeek V4 Pro | deepseek-v4-pro |
DeepSeek |
| Kimi K2.6 | kimi-k2.6 |
Kimi |
Note
The model list is defined in
src/llm/api_models.jsonand may change between versions. If you pass a--modelname that isn't in the list, the CLI asks you to pick one from the menu instead.
Custom model names
If a provider offers a model not in the menu, choose the custom option (shown as -) and type the exact model name when prompted.
8. Running the Backtester
The backtester replays your agent committee day-by-day over a historical window and reports how the simulated portfolio would have performed.
Run a backtest
poetry run python src/backtester.py --ticker AAPL,MSFT,NVDA
As with the main CLI, you'll be prompted to select analysts and a model (unless you pass flags). The backtester then:
- Pre-fetches one year of price/fundamental/news data for each ticker (plus
SPYfor benchmarking). - Steps through each business day in your date range.
- Runs the full agent committee on each day and executes the resulting decisions against the simulated portfolio.
- Prints a running results table and, at the end, performance metrics.
Tip
The backtester defaults to a one-month lookback if you don't pass
--start-date. Pass an explicit range for longer studies:poetry run python src/backtester.py --ticker AAPL --start-date 2024-01-01 --end-date 2024-06-01
Reading the results
The summary reports these metrics:
| Metric | What it tells you |
|---|---|
| Portfolio Return | Total percentage gain/loss of the simulated portfolio over the window. |
| Benchmark Return | Buy-and-hold return of the S&P 500 (SPY) over the same window, for comparison. |
| Sharpe Ratio | Risk-adjusted return (excess return per unit of total volatility). Higher is better. |
| Sortino Ratio | Like Sharpe, but only penalizes downside volatility. |
| Max Drawdown | The largest peak-to-trough decline, and the date it occurred. |
| Cash / Position / Total Value | The portfolio's ending composition. |
Note
Risk-adjusted ratios use an annual risk-free rate of
4.34%and252trading days per year. Metrics only begin computing after a few days of history have accumulated.
Backtest flags
The backtester accepts the same flags as the main CLI for tickers, dates, analysts, model, capital, margin, and Ollama. (--show-reasoning and --show-agent-graph are specific to the main CLI.)
Tip
Press
Ctrl+Cduring a long backtest to interrupt gracefully — the tool will print any partial results it has computed so far before exiting.
9. Running with Local Models (Ollama)
You can run the entire committee on your own machine — no cloud LLM key required — using Ollama.
Enable Ollama
Add the --ollama flag to any CLI or backtester command:
poetry run python src/main.py --ticker AAPL,MSFT,NVDA --ollama
The CLI then shows a menu of supported local models and walks you through the rest:
- If Ollama isn't installed, it offers to install it (macOS/Linux) or open the download page (Windows).
- If the Ollama server isn't running, it starts it.
- If your chosen model isn't downloaded yet, it offers to pull it (with a progress bar).
Bundled local model menu
The local model menu includes options such as:
| Display name | Model name | Family |
|---|---|---|
| gpt-oss (20B) | gpt-oss:20b |
OpenAI |
| gpt-oss (120B) | gpt-oss:120b |
OpenAI |
| Llama 3.1 (8B) | llama3.1:latest |
Meta |
| Llama 3.3 (70B) | llama3.3:70b-instruct-q4_0 |
Meta |
| Gemma 3 (4B/12B/27B) | gemma3:4b … gemma3:27b |
|
| Qwen 3 (4B/8B/30B) | qwen3:4b … qwen3:30b-a3b |
Alibaba |
| Mistral Small 3.1 (24B) | mistral-small3.1 |
Mistral |
Warning
Larger local models (e.g. the 70B Llama) can require several gigabytes of disk and significant RAM/VRAM. Start with a small model (4B–8B) to confirm the pipeline works before pulling a large one.
Point at an existing Ollama server
If you already run Ollama elsewhere (e.g. another machine or a container), set the OLLAMA_BASE_URL environment variable so the app uses it instead of starting a local server:
OLLAMA_BASE_URL=http://192.168.1.50:11434 poetry run python src/main.py --ticker AAPL --ollama
10. Running with Docker
The docker/ directory provides a containerized way to run the CLI and backtester, with an optional bundled Ollama service. A wrapper script handles the Docker commands for you.
Using the run script
macOS / Linux
cd docker
./run.sh --ticker AAPL,MSFT,NVDA main
If you get a permission error, make it executable first: chmod +x run.sh.
Windows
cd docker
run.bat --ticker AAPL,MSFT,NVDA main
Common Docker commands
| Command | What it does |
|---|---|
./run.sh --ticker AAPL,MSFT,NVDA main |
Run the main hedge fund. |
./run.sh --ticker AAPL,MSFT,NVDA backtest |
Run the backtester. |
./run.sh --ticker AAPL --ollama main |
Run with the bundled Ollama service. |
./run.sh build |
Build the Docker image. |
./run.sh compose |
Run via Docker Compose with integrated Ollama. |
./run.sh ollama |
Start only the Ollama container. |
./run.sh pull llama3 |
Pull a model into the Ollama container. |
./run.sh help |
Show all options. |
The run script accepts the familiar flags: --ticker, --start-date, --end-date, --initial-cash, --margin-requirement, --ollama, --ollama-base-url, and --show-reasoning.
Note
Docker reads your API keys from the project-root
.envfile, which is mounted into the container automatically. You don't need to re-enter keys.
11. Using the Web Application
The web application gives you a visual, drag-and-drop interface for building and running agent flows. It has two parts that run together: a FastAPI backend and a React frontend.
Quick start (recommended)
From inside the app/ directory there's a one-line setup script that installs everything and launches both services:
macOS / Linux
cd app
./run.sh
If you get "permission denied": chmod +x run.sh && ./run.sh
Windows
cd app
run.bat
The script checks for required tools (Node.js, Python, Poetry), installs all dependencies, starts both services, and opens your browser automatically.
What you can access
Once running, open these in your browser:
| URL | What |
|---|---|
http://localhost:5173 |
The web interface (frontend). |
http://localhost:8000 |
The backend API. |
http://localhost:8000/docs |
Interactive API documentation. |
Manual setup (developers)
If you prefer to run each service yourself, in two terminals:
# Terminal 1 — backend
cd app/backend
poetry run uvicorn main:app --reload
# Terminal 2 — frontend
cd app/frontend
npm install
npm run dev
Working in the interface
The web app is organized as a node-based canvas:
- Drag agent and component nodes onto the canvas from the sidebar to assemble a flow.
- Configure models per node — you can assign different LLMs to different agents from the Settings panel.
- Manage API keys in the Settings → API Keys panel, so you don't have to edit
.envby hand. - Run the flow and watch each agent's status update live, with reasoning and JSON output panels.
- Save and reuse flows — your flow layouts and run history are stored locally by the backend.
Tip
The web app exposes the same engine as the CLI. If you've already configured
.env, the backend will pick up those keys; you can also add or override keys through the Settings page.
12. Common Tasks & Recipes
Run a quick single-stock sanity check
poetry run python src/main.py --ticker AAPL --analysts warren_buffett --model gpt-4o
Compare two investment philosophies on the same stock
poetry run python src/main.py --ticker TSLA \
--analysts warren_buffett,cathie_wood --show-reasoning
Buffett (value) and Wood (growth) often disagree — --show-reasoning lets you read why.
Run the full committee
poetry run python src/main.py --ticker AAPL,MSFT,NVDA --analysts-all
Backtest a value committee over six months
poetry run python src/backtester.py --ticker AAPL,MSFT \
--analysts ben_graham,warren_buffett,charlie_munger \
--start-date 2024-01-01 --end-date 2024-06-30 \
--model gpt-4o
Run entirely offline with a local model
poetry run python src/main.py --ticker AAPL --ollama
# then pick e.g. llama3.1:latest from the menu
Simulate a long/short strategy with margin
poetry run python src/main.py --ticker AAPL,TSLA \
--initial-cash 500000 --margin-requirement 0.5 --analysts-all
A non-zero --margin-requirement lets the portfolio manager open short positions.
13. How It Works
You don't need this section to use the tool, but it helps you interpret the output. For the full architecture, see the Admin Guide.
The committee pipeline
The system is built as a graph of agents. When you run an analysis, the flow is:
┌─────────────┐
│ start │
└──────┬──────┘
│ (fan out to every selected analyst, in parallel)
┌───────────┼───────────┬───────────────┐
▼ ▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐ ┌──────────┐
│Buffett │ │ Wood │ │ Burry │ ... │Technicals│
└───┬────┘ └───┬────┘ └───┬────┘ └────┬─────┘
└──────────┴──────────┴────────────────┘
│ (all signals collected)
▼
┌──────────────┐
│ Risk Manager │ sets max position size per ticker
└──────┬───────┘
▼
┌──────────────────┐
│ Portfolio Manager│ final action + quantity per ticker
└──────┬───────────┘
▼
┌──────────────┐
│ Decision │
└──────────────┘
What each analyst does
Every analyst agent follows the same recipe:
- Fetch data for each ticker — financial metrics, line items, prices, insider trades, and news from the Financial Datasets API.
- Score it using deterministic, philosophy-specific functions (e.g. Buffett scores fundamentals, consistency, competitive moat, pricing power, book-value growth, management quality, and intrinsic value).
- Reason with an LLM to turn those scores into a final
signal(bullish/bearish/neutral), aconfidence(0–100), and a writtenreasoning.
How the decision is made
- The Risk Manager measures each ticker's volatility and the correlation between tickers, then caps how large any single position can be.
- The Portfolio Manager receives every analyst's signal plus the risk caps. It computes which actions are even possible (you can't sell shares you don't own) and then asks the LLM to choose the final action and quantity for each ticker, respecting those limits.
Note
Data is cached in memory during a single run, so repeated requests for the same ticker/date are fast. The cache is not saved to disk — a fresh process starts with an empty cache.
14. Command & Flag Reference
Entry points
| Command | Purpose |
|---|---|
poetry run python src/main.py |
Run a one-shot trading analysis. |
poetry run python src/backtester.py |
Run a historical backtest. |
poetry run backtester |
Alternative entry point for the modular backtesting engine (defined as a Poetry script). |
Flags
| Flag | Alias | Type | Default | Applies to | Description |
|---|---|---|---|---|---|
--tickers |
--ticker |
string | — | both | Comma-separated stock symbols, e.g. AAPL,MSFT,GOOGL. |
--analysts |
string | (prompt) | both | Comma-separated analyst keys, e.g. michael_burry,warren_buffett. |
|
--analysts-all |
flag | off | both | Use all analysts; overrides --analysts. |
|
--model |
string | (prompt) | main | LLM model name, e.g. gpt-4o. |
|
--ollama |
flag | off | both | Use local Ollama models. | |
--start-date |
string | computed | both | Start date, YYYY-MM-DD. |
|
--end-date |
string | today | both | End date, YYYY-MM-DD. |
|
--initial-cash |
--initial-capital |
float | 100000.0 |
both | Starting simulated cash. |
--margin-requirement |
float | 0.0 |
both | Margin ratio for shorts (e.g. 0.5). |
|
--show-reasoning |
flag | off | main | Print each agent's full reasoning. | |
--show-agent-graph |
flag | off | main | Save the agent workflow diagram as a PNG. |
Note
If you omit
--analysts/--analysts-allor--model, the CLI prompts you interactively. The modularbacktesterentry point also prompts interactively when flags are omitted.
15. Environment Variables Reference
All variables live in your project-root .env file (copied from .env.example). You only need the keys for the providers you actually use.
Data provider (required)
| Variable | Purpose |
|---|---|
FINANCIAL_DATASETS_API_KEY |
Access to prices, fundamentals, insider trades, and news. |
LLM provider keys (set at least one)
| Variable | Provider |
|---|---|
OPENAI_API_KEY |
OpenAI |
ANTHROPIC_API_KEY |
Anthropic |
DEEPSEEK_API_KEY |
DeepSeek |
GROQ_API_KEY |
Groq |
GOOGLE_API_KEY |
Google (Gemini) |
XAI_API_KEY |
xAI (Grok) |
MOONSHOT_API_KEY / KIMI_API_KEY |
Kimi / Moonshot |
OPENROUTER_API_KEY |
OpenRouter |
GIGACHAT_API_KEY |
GigaChat |
AZURE_OPENAI_API_KEY |
Azure OpenAI |
Optional / advanced
| Variable | Purpose | Default |
|---|---|---|
OPENAI_API_BASE |
Override the OpenAI base URL (for proxies/compatible endpoints). | — |
OLLAMA_HOST |
Ollama host (used by Docker on macOS). | localhost |
OLLAMA_BASE_URL |
Full base URL of an existing Ollama server. | http://localhost:11434 |
MOONSHOT_BASE_URL / KIMI_BASE_URL |
Override Kimi endpoint (e.g. mainland-China host). | https://api.moonshot.ai/v1 |
AZURE_OPENAI_ENDPOINT |
Azure endpoint URL (required for Azure). | — |
AZURE_OPENAI_DEPLOYMENT_NAME |
Azure deployment name (required for Azure). | — |
YOUR_SITE_URL / YOUR_SITE_NAME |
Attribution headers sent with OpenRouter requests. | project URL / AI Hedge Fund |
GIGACHAT_USER / GIGACHAT_PASSWORD / GIGACHAT_CREDENTIALS |
Alternative GigaChat authentication. | — |
Tip
Anything you don't use can stay blank or be deleted from
.env. The app only validates a key when an agent actually needs that provider.
16. Troubleshooting
Error: OpenAI API key not found. Please make sure OPENAI_API_KEY is set in your .env file or provided via API keys.
Cause: You selected an OpenAI model but no OPENAI_API_KEY is set.
Solution: Add OPENAI_API_KEY=... to your .env (in the project root). The same applies to every provider — the message names the exact variable (ANTHROPIC_API_KEY, GROQ_API_KEY, DEEPSEEK_API_KEY, GOOGLE_API_KEY, XAI_API_KEY, OPENROUTER_API_KEY, etc.).
Prevention: Run cp .env.example .env and fill in keys before your first run.
Error: Start date must be in YYYY-MM-DD format / End date must be in YYYY-MM-DD format
Cause: A --start-date or --end-date value isn't in YYYY-MM-DD form.
Solution: Use four-digit year, two-digit month and day, e.g. 2024-03-01.
Error: Unsupported model provider: <name>
Cause: A model/provider combination the app doesn't recognize was requested.
Solution: Pick a model from the interactive menu, or pass a --model name that exists in the bundled model list.
Command not found: uvicorn when starting the web app
Cause: The backend's Poetry environment is incomplete. Solution:
cd app/backend
poetry env remove --all
poetry install
# or force a clean sync:
poetry install --sync
# verify:
poetry run python -c "import uvicorn; import fastapi"
Port already in use (8000 or 5173)
Cause: A previous backend/frontend process is still running.
Solution: Stop it, e.g. pkill -f "uvicorn\|vite", or change the port in the run scripts.
Permission denied running ./run.sh
Cause: The script isn't executable.
Solution: chmod +x run.sh && ./run.sh.
The analysis hangs and never finishes
Cause: LLM API calls currently have no built-in timeout, so a stalled provider request can hang the run (tracked as a known issue in the project's GitHub).
Solution: Interrupt with Ctrl+C and retry. Consider a faster/cheaper model or fewer analysts to reduce the number of calls.
Python version errors during poetry install
Cause: Python 3.13+ can have dependency-compatibility issues.
Solution: Use Python 3.11. Check your version with python --version and switch via pyenv/conda if needed.
No data / empty results for a ticker (especially ETFs)
Cause: The Financial Datasets API may not have coverage for some symbols (certain ETFs are a known gap), or your data key is missing/rate-limited.
Solution: Confirm FINANCIAL_DATASETS_API_KEY is set, try a well-known equity like AAPL, and check the symbol is supported by the data provider.
Rate limited (429). Waiting Ns before retrying...
Cause: The data API is throttling your requests. The app automatically backs off and retries (linear backoff starting around 60 seconds). Solution: No action needed — wait. To reduce throttling, analyze fewer tickers at once or shorten the date range.
17. FAQ
Q: Does this actually buy or sell stocks? No. The system only simulates decisions and tracks an in-memory portfolio. It never connects to a broker and places no real orders.
Q: Is this financial advice? No. It is an educational research project. Do not use it to make real investment decisions.
Q: Which API keys do I absolutely need?
At least one LLM provider key (or use --ollama for local models) and FINANCIAL_DATASETS_API_KEY for the financial data.
Q: Can I run it without paying for a cloud LLM?
Yes — use --ollama to run open models locally on your machine. You still need a data key for financial data.
Q: How do I pick analysts without the interactive prompt?
Pass --analysts key1,key2,... (or --analysts-all). See the analyst keys.
Q: What's the difference between src/main.py and src/backtester.py?
main.py runs a single analysis for the current/selected period. backtester.py replays the committee day-by-day over a historical window and reports performance metrics.
Q: Can different agents use different models? In the web application, yes — you can assign models per node. The CLI uses one model for the whole committee per run.
Q: What does --margin-requirement do?
It sets the cash ratio required to open short positions. With the default 0.0, the simulation effectively won't size shorts; set e.g. 0.5 to enable 50%-margin shorting.
Q: Why do I sometimes see "Error in analysis, using default" in the output? If an LLM call fails after its retries, the agent returns a safe default signal so the run can continue rather than crashing.
Q: What is the v2/ directory?
It's a work-in-progress, ground-up rebuild of the engine using quantitative methods instead of investor personas. It is not yet integrated into the main app and isn't needed for normal use. See the Admin Guide for details.
Q: Which Python version should I use? Python 3.11 is recommended. Newer versions (3.13+) may cause dependency issues.
Q: How current is the data the agents see?
The agents fetch data up to your --end-date (default: today). Choosing an earlier --end-date lets you analyze "as of" a past point in time.