# Technical Documentation: AI4Finance-Foundation/FinRobot

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/AI4Finance-Foundation/FinRobot)

### Overview (`README.md`)

# FinRobot: An Open-Source AI Agent Platform for Financial Applications using Large Language Models
[](https://pepy.tech/project/finrobot)
[](https://pepy.tech/project/finrobot)
[](https://discord.gg/trsr8SXpW5)
[](https://www.python.org/downloads/)
[](https://pypi.org/project/finrobot/)





[](https://github.com/AI4Finance-Foundation/FinRobot/releases/tag/desktop-v0.1.0)

<div align="center">
<img align="center" src=figs/logo_white_background.jpg width="40%"/>
</div>

**FinRobot** is an open-source **agentic AI framework for financial decision intelligence**. It combines foundation models with financial tools, quantitative models, deterministic computation, and multi-agent workflows to build decision-grade financial applications.

Its core principle is simple: **models reason, software computes, agents orchestrate, and systems verify.** Models can be replaced; the surrounding financial infrastructure — tools, workflows, validation, provenance, and evaluation — is what makes the system reliable.

Unlike the single-model paradigm of [**FinGPT**](https://github.com/AI4Finance-Foundation/FinGPT), FinRobot supports end-to-end agentic workflows for **equity research, quantitative trading, risk analysis, investment banking, private equity, wealth management, and other high-stakes financial decisions**.

[Whitepaper on arXiv](https://arxiv.org/abs/2405.14767) · [Official Academic Page](https://ai4finance.org/research/finrobot-open-source-ai-agent.html)


[](https://discord.gg/trsr8SXpW5)

---

## Where to start

FinRobot is three projects sharing one financial domain layer. They are not three versions of the same thing competing for your attention — they serve different purposes.

| Directory | Version | What it is | Use it for |
|:---|:---|:---|:---|
| **[`finrobot_desktop/`](./finrobot_desktop/)** | V2 | **Production** — the real agent system. Native desktop research workstation on PydanticAI + FastAPI + React/Tauri | Actual research work. This is the one to use if you want output you can act on |
| **[`finrobot_equity/`](./finrobot_equity/)** | V1 | **Web app** — a self-hosted report generator with a FastAPI interface | Standing up a browser-based service that turns a ticker into a shareable HTML/PDF report |
| **[`finrobot_autogen/`](./finrobot_autogen/)** | V0 | **Educational** — the original AutoGen library, the codebase behind the whitepaper | Learning how financial agents are wired together, teaching, and reproducing the paper. Not intended for production use |

`pip install finrobot` installs the V0 package. Its source moved into `finrobot_autogen/`, but the import name did not change — every existing `from finrobot... import ...` keeps working.

---

## 🧬 Architecture Evolution

FinRobot evolves alongside the rapid development of AI-agent frameworks. Rather than being tied to a single agent stack, each generation explores how emerging agent architectures can improve financial analysis, research, and decision-making.

| Version | Agent Framework | Project | Maturity | Focus |
|---|---|---|---|---|
| **V0** | AutoGen | [`finrobot_autogen/`](./finrobot_autogen/) | Educational / reference | The original FinRobot multi-agent architecture for financial applications |
| **V1** | OpenAI Agents SDK | [`finrobot_equity/`](./finrobot_equity/) | Self-hosted web app | Equity-research agents, financial analysis, valuation, and automated report generation |
| **V2** | PydanticAI | [`finrobot_desktop/`](./finrobot_desktop/) | **Production** — also hosted at [finrobot.ai/v2](https://finrobot.ai/v2) | Structured, type-safe agent workflows for professional equity research |
| **V3** | DeepSeek-Harness | FinRobot V3 | In development | More autonomy inside the same verification constraints |

All three are open source. **V2 is the production system** — the deterministic compute engine, the provenance guarantees, and the agent orchestration described below all live there. V0 is kept because it is small enough to read and learn from, not because it is the recommended way to run research today.

> **Our philosophy:** FinRobot is not defined by any single agent framework. We continuously adopt, evaluate, and evolve with state-of-the-art agent architectures while keeping the financial domain layer — tools, workflows, deterministic computation, and decision-making capabilities — at the core.

---

## 🧮 Deterministic compute, LLM narration

A design principle that runs through every generation: **deterministic financial computation** and **LLM-based narration** stay strictly separate.

All financial numbers are produced by pure-Python compute operators, not by the language model. The LLM handles reasoning, synthesis, explanation, and report writing, while valuation outputs — DCF, DDM, LBO, WACC, comparable-company analysis, Monte Carlo simulation — are calculated through deterministic code paths with full provenance.

```
Numbers are code-calculated.
Narratives are LLM-assisted.
Every output is provenance-tracked.
```

---

## 🚀 FinRobot Desktop v0.1.0

A native desktop equity research cockpit powered by a production-grade multi-agent architecture. It takes analysts from market data and company filings to valuation, debate, synthesis, and investment-committee-style reports in one traceable workflow.

<div align="center">
<img src="figs/desktop-cockpit.png" width="92%" alt="FinRobot Desktop — the research cockpit: enter a ticker to open a fully traceable AI research desk"/>
</div>

<table>
<tr>
<td width="50%"><img src="figs/desktop-workspace.png" alt="Stock workspace: live market data on the left, the AI research verdict and valuation instruments on the right"/></td>
<td width="50%"><img src="figs/desktop-report.png" alt="A 13-chapter equity research report with its price target, confidence level and chapter navigation"/></td>
</tr>
<tr>
<td><b>Stock workspace</b> — live market data pulled independently of any AI report, beside the research verdict and the DCF / DDM / LBO / comps instruments.</td>
<td><b>Research report</b> — 13 chapters, a 12-month target with its range, model confidence, and the data caveats the audit operators raised.</td>
</tr>
</table>

<div align="center">
<img src="figs/desktop-dcf.png" width="92%" alt="DCF forecast table labelled code-computed, with WACC, terminal growth and tax rate, next to the LLM's narrative"/>
</div>

<p align="center"><i>The design principle, visible in the product: the DCF table is labelled <b>code-computed</b> — a ten-year forecast from pure-Python operators — while the paragraph beside it is the LLM reading those numbers back across all three valuation methods.</i></p>

👉 **Latest release:** [FinRobot Desktop v0.1.0](https://github.com/AI4Finance-Foundation/FinRobot/releases/tag/desktop-v0.1.0)

For macOS Apple Silicon (M1/M2/M3 or later), download `FinRobot_0.1.0_aarch64.dmg` and drag **FinRobot** into **Applications**. Intel Mac builds are not available in this release.

The app is not yet Apple-notarized, so on first launch macOS may report that it is "damaged." Run this once in Terminal, then open it normally:

```bash
xattr -cr /Applications/FinRobot.app
```

### Multi-agent architecture

A **Lead Agent** orchestrates specialized research agents through a pipeline-driven execution engine: five role-based sub-agents for data, analysis, modeling, synthesis, and reporting, plus three debate agents for the bull case, bear case, and judgment.

```
User Research Request
        ↓
Lead Agent / Orchestrator
        ↓
Data Agent → Analysis Agent → Modeling Agent → Synthesis Agent → Report Agent
        ↓
Bull Agent ↔ Bear Agent → Judge Agent
        ↓
Traceable Investment Research Output
```

### Codebase snapshot

| Layer | What it includes |
|---|---|
| **Full-stack system** | ~184k lines across a Python backend, React/Tauri desktop frontend, Rust shell, and tests |
| **Agent runtime** | 9 agents: lead orchestrator, 5 role-based pipeline agents, 3 debate agents |
| **Research pipelines** | 7 pipelines — company research, DCF, comps, LBO, DDM, earnings, IC memo |
| **Deterministic compute** | 32 pure-Python operators (26 valuation/analysis + 6 audit) and 7 coordinators |
| **Data infrastructure** | 7 providers with failover — FMP, Finnhub, yfinance, SEC EDGAR, Adanos, NewsAggregator, FX |
| **Skills** | 56 analyst playbooks across equity research, investment banking, private equity, and wealth management |
| **Product stack** | PydanticAI, FastAPI, SQLite, React 19, Vite 6, Zustand, Tauri/Rust, Recharts |

Full details in [`finrobot_desktop/README.md`](./finrobot_desktop/README.md).

---

## Getting started

### V2 — the desktop app, a local web UI, or the CLI

Three ways to run the same engine.

**Desktop app** — download the [release](https://github.com/AI4Finance-Foundation/FinRobot/releases/tag/desktop-v0.1.0) (macOS Apple Silicon).

**Local web UI** — the same interface in a browser, no `.dmg` and no Rust toolchain, so it also works on Intel Macs, Linux, and Windows:

```bash
cd finrobot_desktop
uv sync                        # backend dependencies
(cd desktop && npm install)    # frontend dependencies — one time

./dev.sh                       # → open http://localhost:5173
```

`dev.sh` runs the FastAPI backend on `:8321` and a Vite server on `:5173` that proxies the API to it; `Ctrl+C` stops both. Note that it first frees those two ports, so quit FinRobot.app if it is open, and that the local API is unauthenticated in browser mode — details in [`finrobot_desktop/README.md`](./finrobot_desktop/README.md).

**CLI** — after `uv sync` in `finrobot_desktop/`:

```bash
finrobot research AAPL          # full 13-chapter research artifact
finrobot dcf MSFT               # DCF valuation (auto-switches to DDM where appropriate)
finrobot comps NVDA --peers AMD,INTC
finrobot ic-memo TSLA
finrobot ask AAPL "How exposed is the gross margin to tariffs?"
```

Building the Tauri desktop shell is covered in [`finrobot_desktop/README.md`](./finrobot_desktop/README.md).

### V1 — the equity research web app

```bash
cp finrobot_equity/core/config/config.ini.example finrobot_equity/core/config/config.ini
# edit config.ini: fmp_api_key, openai_api_key, (optional) adanos_api_key

chmod +x finrobot_equity/deploy.sh
./finrobot_equity/deploy.sh start          # → http://127.0.0.1:8001
```

| Command | Description |
|:---|:---|
| `./finrobot_equity/deploy.sh start` | Start the web app (auto-installs dependencies) |
| `./finrobot_equity/deploy.sh stop` | Stop the application |
| `./finrobot_equity/deploy.sh restart` | Restart the application |
| `./finrobot_equity/deploy.sh status` | Check running status |
| `./finrobot_equity/deploy.sh install` | Install/update dependencies only |

If `deploy.sh` doesn't work in your environment:

```bash
python3 -m venv venv && source venv/bin/activate
pip install -r finrobot_equity/requirements.txt
python finrobot_equity/run_web_app.py
```

A two-step CLI pipeline is available as well — see [`finrobot_equity/README.md`](./finrobot_equity/README.md).

**Example reports:**
[NVDA](https://ai4finance-foundation.github.io/FinRobot/finrobot_equity/core/output/NVDA_Equity_Research_Report.html) ·
[MSFT](https://ai4finance-foundation.github.io/FinRobot/finrobot_equity/core/output/MSFT_Equity_Research_Report.html) ·
[TSLA](https://ai4finance-foundation.github.io/FinRobot/finrobot_equity/core/output/TSLA_Equity_Research_Report.html) ·
[META](https://ai4finance-foundation.github.io/FinRobot/finrobot_equity/core/output/META_Equity_Research_Report.html) ·
[COP](https://ai4finance-foundation.github.io/FinRobot/finrobot_equity/core/output/COP_Equity_Research_Report.html)

### V0 — the AutoGen framework

**1. Create an environment** (Python 3.10 or 3.11):

```bash
conda create --name finrobot python=3.10
conda activate finrobot
```

**2. Install** — from PyPI, or from source at the **repository root** (`setup.py` maps the `finrobot` package to `finrobot_autogen/finrobot`, so installing from inside that directory won't work):

```bash
git clone https://github.com/AI4Finance-Foundation/FinRobot.git
cd FinRobot
pip install -e .          # or: pip install -U finrobot
```

**3. Configure keys** — both files go in `finrobot_autogen/`, which is where the notebooks look for them. Copy rather than rename: the `*_sample` files are tracked, and your filled-in copies are gitignored.

```bash
cd finrobot_autogen
cp OAI_CONFIG_LIST_sample OAI_CONFIG_LIST     # OpenAI / Azure OpenAI endpoints
cp config_api_keys_sample config_api_keys     # Finnhub, FMP, SEC, Reddit, …
```

**4. Run a tutorial** from `finrobot_autogen/tutorials_beginner/` or `tutorials_advanced/`:

```
agent_annual_report.ipynb        # 10-K → formatted PDF annual report
agent_fingpt_forecaster.ipynb    # market forecast from news + financials
agent_trade_strategist.ipynb     # strategy writing and backtesting
lmm_agent_mplfinance.ipynb       # multimodal agent reading a candlestick chart
lmm_agent_opt_smacross.ipynb     # multimodal SMA-crossover tuning
```

The agent library, workflow types, and full tutorial index are in [`finrobot_autogen/README.md`](./finrobot_autogen/README.md).

---

## Repository layout

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

## 🎬 FinRobot Pro — your personal AI-powered equity research assistant

🌐 https://finrobot.ai/

<div align="center">
  <a href="https://www.youtube.com/watch?v=ebgPiJINi-k" target="_blank">
    <img src="https://github.com/user-attachments/assets/de3b9f9c-50aa-49f0-82c6-3d2b938f4670" width="90%" />
  </a>
</div>

<p align="center">
  ▶️ Click the image above to watch the demo video, or see the short preview below.
</p>

https://github.com/user-attachments/assets/93ec0f1e-e28b-4474-a0bf-a79e0c12f0ff

[FinRobot Pro](https://finrobot.ai/) is an AI-powered equity research platform that automates professional stock analysis using large language models and AI agents:

- **Automated report generation** — professional equity research reports on demand
- **Financial analysis** — income statements, balance sheets, and cash flows
- **Valuation analysis** — P/E, EV/EBITDA multiples, and peer comparison
- **Risk assessment** — comprehensive investment risk evaluation

---

## Research foundation

### The FinRobot ecosystem

<div align="center">
<img align="center" src="https://github.com/AI4Finance-Foundation/FinRobot/assets/31713746/6b30d9c1-35e5-4d36-a138-7e2769718f62" width="90%"/>
</div>

The overall framework is organized into four layers, each addressing a specific aspect of financial AI processing:

1. **Financial AI Agents Layer** — includes Financial Chain-of-Thought (CoT) prompting to strengthen complex analysis and decision-making. Market Forecasting Agents, Document Analysis Agents, and Trading Strategies Agents use CoT to break financial problems into logical steps, aligning their algorithms and domain expertise with evolving market dynamics.
2. **Financial LLMs Algorithms Layer** — configures and applies models tuned to specific domains and global market analysis.
3. **LLMOps and DataOps Layers** — a multi-source integration strategy that selects the most suitable LLM for each financial task across a range of state-of-the-art models.
4. **Multi-source LLM Foundation Models Layer** — supports plug-and-play use of general and specialized LLMs.

### Agent workflow

1. **Perception** — captures and interprets multimodal financial data from market feeds, news, and economic indicators, structuring it for analysis.
2. **Brain** — the core processing unit: consumes perception output with LLMs and applies Financial CoT to generate structured instructions.
3. **Action** — executes those instructions with tools, turning analysis into outcomes: trades, portfolio adjustments, reports, or alerts.

### Smart Scheduler

The Smart Scheduler ensures model diversity and selects the most appropriate LLM for each task.

- **Director Agent** — orchestrates task assignment, allocating work based on performance metrics and task suitability.
- **Agent Registration** — manages registration and tracks agent availability for efficient allocation.
- **Agent Adaptor** — tailors agent functionality to specific tasks.
- **Task Manager** — stores and manages general and fine-tuned LLM-based agents for different financial tasks, updated periodically.

---

## AI Agent papers

+ [Stanford University + Microsoft Research] [Agent AI: Surveying the Horizons of Multimodal Interaction](https://arxiv.org/abs/2401.03568)
+ [Stanford University] [Generative Agents: Interactive Simulacra of Human Behavior](https://arxiv.org/abs/2304.03442)
+ [Fudan NLP Group] [The Rise and Potential of Large Language Model Based Agents: A Survey](https://arxiv.org/abs/2309.07864)
+ [Fudan NLP Group] [LLM-Agent-Paper-List](https://github.com/WooooDyy/LLM-Agent-Paper-List)
+ [Tsinghua University] [Large Language Models Empowered Agent-based Modeling and Simulation: A Survey and Perspectives](https://arxiv.org/abs/2312.11970)
+ [Renmin University] [A Survey on Large Language Model-based Autonomous Agents](https://arxiv.org/pdf/2308.11432.pdf)
+ [Nanyang Technological University] [FinAgent: A Multimodal Foundation Agent for Financial Trading: Tool-Augmented, Diversified, and Generalist](https://arxiv.org/abs/2402.18485)

## AI Agent open-source frameworks & tools

+ [AutoGPT (183k stars)](https://github.com/Significant-Gravitas/AutoGPT): autonomous AI agent platform.
+ [Dify (134k stars)](https://github.com/langgenius/dify): LLM app development platform with workflow orchestration and RAG.
+ [LangChain (130k stars)](https://github.com/langchain-ai/langchain): framework for building context-aware LLM applications.
+ [MetaGPT (65.6k stars)](https://github.com/geekan/MetaGPT): multi-agent framework with role-based collaboration.
+ [AutoGen (56k stars)](https://github.com/microsoft/autogen): framework for multi-agent LLM applications with tools and human interaction.
+ [CrewAI (46.6k stars)](https://github.com/joaomdmoura/crewAI): framework for orchestrating collaborative AI agents.
+ [ChatDev (31.7k stars)](https://github.com/OpenBMB/ChatDev): multi-agent framework for software development tasks.
+ [FastGPT (27.4k stars)](https://github.com/labring/FastGPT): knowledge-based LLM platform with workflow support.
+ [Langfuse (23.4k stars)](https://github.com/langfuse/langfuse): open-source LLM observability and evaluation platform.
+ [BabyAGI (22.2k stars)](https://github.com/yoheinakajima/babyagi): task-driven experimental autonomous agent framework.
+ [SuperAGI (17.3k stars)](https://github.com/TransformerOptimus/SuperAGI): developer-focused autonomous agent framework.
+ [CAMEL (16.4k stars)](https://github.com/camel-ai/camel): framework for cooperative and communicative AI agents.
+ [Bisheng (11.2k stars)](https://github.com/dataelement/bisheng): enterprise open-source LLM application platform.

## Citing FinRobot

```bibtex
@article{yang2024finrobot,
  title   = {FinRobot: An Open-Source AI Agent Platform for Financial Applications using Large Language Models},
  author  = {Yang, Hongyang and Zhang, Boyu and Wang, Neng and Guo, Cheng and Zhang, Xiaoli and Lin, Likun and Wang, Junlin and Zhou, Tianyu and Guan, Mao and Zhang, Runjia and Wang, Christina Dan},
  journal = {arXiv preprint arXiv:2405.14767},
  year    = {2024},
  doi     = {10.48550/arXiv.2405.14767},
  url     = {https://arxiv.org/abs/2405.14767}
}

@inproceedings{zhou2024finrobot,
  title     = {FinRobot: {AI} Agent for Equity Research and Valuation with Large Language Models},
  author    = {Tianyu Zhou and Pinqiao Wang and Yilin Wu and Hongyang Yang},
  booktitle = {ICAIF 2024: The 1st Workshop on Large Language Models and Generative AI for Finance},
  year      = {2024}
}

@inproceedings{han2024enhancing,
  title     = {Enhancing Investment Analysis: Optimizing AI-Agent Collaboration in Financial Research},
  author    = {Han, Xuewen and Wang, Neng and Che, Shangkun and Yang, Hongyang and Zhang, Kunpeng and Xu, Sean Xin},
  booktitle = {ICAIF 2024: Proceedings of the 5th ACM International Conference on AI in Finance},
  pages     = {538--546},
  year      = {2024}
}
```

## License

Apache 2.0 — see [LICENSE](./LICENSE). Trademark usage is covered by [TRADEMARK_POLICY.md](./TRADEMARK_POLICY.md).

**Disclaimer**: The code and documents provided here are released under the Apache-2.0 license. They should not be construed as financial advice or recommendations for live trading. Exercise caution and consult qualified financial professionals before any trading or investment decisions.

<div align="center">
<img align="center" width="30%" alt="image" src="https://github.com/AI4Finance-Foundation/FinGPT/assets/31713746/e0371951-1ce1-488e-aa25-0992dafcc139">
</div>

---

### Overview (`finrobot_autogen/README.md`)

# FinRobot V0 — AutoGen Multi-Agent Framework

> **Educational.** The original FinRobot: a library of role-based financial agents, data-source wrappers, and analysis tools built on [Microsoft AutoGen](https://github.com/microsoft/autogen).

This is the codebase behind the [FinRobot whitepaper](https://arxiv.org/abs/2405.14767), kept in the repository for **learning and reference** — teaching, coursework, reproducing the paper, and understanding how financial agents are wired together. The agent definitions, the tool-registration pattern, and the data plumbing are all small enough to read end to end, which is exactly why it is worth keeping.

**It is not the production system.** There is no deterministic compute layer here, no provenance tracking, and no guarantee that a number in the output was computed rather than generated — the agents call tools and the LLM writes the result. For research you intend to act on, use [`finrobot_desktop/`](../finrobot_desktop/) (V2), where financial figures come from pure-Python operators and every one is traceable. For a self-hosted report-generating web service, use [`finrobot_equity/`](../finrobot_equity/) (V1).

---

## What's in here

| Layer | Module | What it does |
|:---|:---|:---|
| **Agents** | `finrobot/agents/agent_library.py` | 10 predefined roles (system message + toolkit), keyed by name |
| | `finrobot/agents/workflow.py` | Ready-made conversation topologies — single-agent, RAG, multi-agent, leader-led |
| | `finrobot/agents/prompts.py` | Shared prompt fragments, including the financial chain-of-thought scaffolds |
| **Tools** | `finrobot/toolkits.py` | Registers plain Python functions (or whole classes) as AutoGen tools |
| **Data** | `finrobot/data_source/` | Finnhub, FMP, yfinance, SEC EDGAR, Reddit, FinNLP |
| **Capabilities** | `finrobot/functional/` | Statement analysis, charting, quantitative backtesting, PDF reports, RAG |

### Agent roles

`agent_library.library` is a dict keyed by role name. Each entry carries a `profile` (system message) and a `toolkits` list:

```
Software_Developer    Data_Analyst      Programmer       Accountant
Statistician          IT_Specialist     Financial_Analyst
Artificial_Intelligence_Engineer        Market_Analyst   Expert_Investor
```

`Expert_Investor` is the most fully equipped — it carries the SEC-report, charting, text-length and PDF-building toolkits used by the annual-report tutorial.

### Workflows

`finrobot/agents/workflow.py` wraps AutoGen's `ConversableAgent` plumbing so you don't hand-roll group chats:

| Class | Shape |
|:---|:---|
| `SingleAssistant` | One assistant + one user proxy executor |
| `SingleAssistantRAG` | Same, with a retrieval-augmented proxy over your documents |
| `SingleAssistantShadow` | Assistant paired with a "shadow" agent that gets an expanded toolkit mid-conversation |
| `MultiAssistant` | A group chat across several library roles |
| `MultiAssistantWithLeader` | A group chat where one designated agent orchestrates the rest |

### Tool registration

`register_toolkits` is the seam between plain Python and the agent layer. It takes a list of functions — or a class, via `register_tookits_from_cls` — and binds them to a caller/executor pair, so the LLM proposes the call and a separate proxy actually executes it:

```python
from finrobot.toolkits import register_toolkits
from finrobot.data_source import FMPUtils

register_toolkits([FMPUtils.get_sec_report], assistant, user_proxy)
```

### Data sources

| Module | Source | Needs a key |
|:---|:---|:---|
| `finnhub_utils.py` | Finnhub — quotes, company news, basic financials | Yes |
| `fmp_utils.py` | Financial Modeling Prep — statements, ratios, SEC report URLs | Yes |
| `sec_utils.py`, `filings_src/`, `marker_sec_src/` | SEC EDGAR filings and 10-K parsing | Yes (`SEC_API_KEY`) |
| `yfinance_utils.py` | Yahoo Finance — prices, history | No |
| `reddit_utils.py` | Reddit sentiment | Yes |
| `finnlp_utils.py` | [FinNLP](https://github.com/AI4Finance-Foundation/FinNLP) — news and social data | Varies |
| `earnings_calls_src/` | Earnings-call transcripts | Varies |

`FinNLP/` is a git submodule. Fetch it with `git submodule update --init --recursive` if the directory is empty.

---

## Install

The package is published and imported as `finrobot`, but its source now lives under `finrobot_autogen/`. `setup.py` at the **repository root** maps the two, so install from the root — not from this directory:

```bash
conda create --name finrobot python=3.10   # 3.10 or 3.11
conda activate finrobot

cd /path/to/FinRobot      # repo root
pip install -e .
```

Or from PyPI:

```bash
pip install -U finrobot
```

Either way the import name is unchanged:

```python
from finrobot.agents.workflow import SingleAssistant
```

## Configure

Both config files live in **this directory** (`finrobot_autogen/`) — that's where the tutorial notebooks look for them (`../OAI_CONFIG_LIST` relative to `tutorials_*/`).

**1. LLM endpoints** — copy the sample and fill in your key:

```bash
cp OAI_CONFIG_LIST_sample OAI_CONFIG_LIST
```

It is an AutoGen config list, so it holds several entries — OpenAI and Azure OpenAI deployments — and agents select one by model name.

**2. Data API keys:**

```bash
cp config_api_keys_sample config_api_keys
```

```json
{
  "FINNHUB_API_KEY": "...",
  "FMP_API_KEY": "...",
  "SEC_API_KEY": "...",
  "REDDIT_CLIENT_ID": "...",
  "REDDIT_CLIENT_SECRET": "...",
  "TWITTER_BEARER_TOKEN": "..."
}
```

Load them into the environment with `finrobot.utils.register_keys_from_json("config_api_keys")`. Only fill in the keys for the data sources you actually use — the others can stay as placeholders.

Both `OAI_CONFIG_LIST` and `config_api_keys` are gitignored. The `*_sample` files are the ones under version control; never commit the filled-in copies.

---

## Tutorials

Run these from their own directory so the `../OAI_CONFIG_LIST` paths resolve.

### Beginner — `tutorials_beginner/`

| Notebook | What it builds |
|:---|:---|
| `agent_annual_report.ipynb` | `Expert_Investor` reads a 10-K and produces a formatted PDF annual report |
| `agent_fingpt_forecaster.ipynb` | Market forecast agent over news + basic financials |
| `agent_rag_qa.ipynb`, `agent_rag_qa_up.ipynb` | RAG question-answering over your own documents |
| `agent_rag_earnings_call_sec_filings.ipynb` | RAG across earnings-call transcripts and SEC filings |
| `ollama function call.ipynb`, `ollama stock chart.ipynb` | The same patterns against a local model via Ollama |

### Advanced — `tutorials_advanced/`

| Notebook | What it builds |
|:---|:---|
| `agent_trade_strategist.ipynb` | Strategy agent that writes and backtests trading logic |
| `agent_annual_report.ipynb` | The annual-report workflow with the full toolkit wired up |
| `agent_fingpt_forecaster.ipynb` | Forecaster with a richer data pipeline |
| `agent_openbb.ipynb` | OpenBB as an agent tool provider |
| `lmm_agent_mplfinance.ipynb` | Multimodal agent that *looks at* a rendered candlestick chart |
| `lmm_agent_opt_smacross.ipynb` | Multimodal agent that tunes an SMA-crossover strategy from chart feedback |

The two `lmm_*` notebooks need a vision-capable model configured in `OAI_CONFIG_LIST`.

## Experiments

`experiments/` holds less polished multi-agent studies — treat them as research code, not a supported API:

- `investment_group.py` — a group of analyst agents debating a position
- `multi_factor_agents.py` — factor construction and evaluation
- `portfolio_optimization.py` — portfolio construction agent
- `quantitative_investment_group_config.json` — the group configuration those scripts read

`agent_builder_demo.py` at this level shows AutoGen's agent-builder generating a team from a task description, and `test_module.py` is a smoke test over the data-source wrappers.

`report/` contains sample inputs and generated outputs (Microsoft's 2023 annual report and 10-K, an NVDA report) used by the tutorials.

## Status

V0 is stable and kept working, but it is maintained as teaching material, not as a product — active development happens in V1 and V2. Read this generation for the concepts, then build on:

- [`finrobot_desktop/`](../finrobot_desktop/) — **production**: desktop app and CLI, PydanticAI, deterministic compute engine
- [`finrobot_equity/`](../finrobot_equity/) — **web app**: self-hosted equity research report generator

## License

Apache 2.0 — see [LICENSE](../LICENSE).

---

### Overview (`finrobot_desktop/README.md`)

# FinRobot Desktop — V2

> **The production FinRobot.** Investment-bank-grade equity research in a desktop app: deterministic finance numbers plus LLM narrative, with every figure traceable back to a function call.

FinRobot Desktop is an open-source equity research workstation for analysts, quantitative researchers, and active investors. A single `research` run produces a 13-chapter artifact — Cover, Investment Thesis, Company Overview, Financial Analysis, Valuation, Recent News, Sensitivity, Catalysts, Technical & Advanced, Competitive Landscape, Financial Data, Ownership & Governance, Disclaimer.

**The core bet: numbers are computed by code, judgment is supplied by the LLM.** The model never emits a figure that cannot be traced back to a call in `finrobot/engine/compute/`.

This is V2 in the [FinRobot version lineage](../README.md), and it is the generation meant for real work. What makes it the production system rather than a larger demo:

- **32 deterministic operators** compute every financial figure in pure Python — the LLM narrates them, it does not produce them.
- **6 audit operators** check the narrative back against the numbers and flag drift before a report ships.
- **A typed pipeline runtime** with per-step validators and retry, rather than an open-ended agent conversation.
- **7 data providers behind failover**, with response validation that rejects malformed payloads before they reach the compute layer.
- **237 test files**, property-based tests, and CI across Python 3.11/3.12 and Node 22/24.

The other two generations serve different purposes: [`finrobot_equity/`](../finrobot_equity/) (V1) is a self-hosted web app for browser-based report generation, and [`finrobot_autogen/`](../finrobot_autogen/) (V0) is the educational AutoGen library behind the whitepaper.

---

<div align="center">
<img src="../figs/desktop-cockpit.png" width="92%" alt="The research cockpit: enter a ticker to open a fully traceable AI research desk"/>
</div>

<table>
<tr>
<td width="50%"><img src="../figs/desktop-workspace.png" alt="Stock workspace"/></td>
<td width="50%"><img src="../figs/desktop-report.png" alt="13-chapter research report"/></td>
</tr>
<tr>
<td><b>Stock workspace</b> — live market data pulled independently of any AI report, beside the research verdict and the valuation instruments.</td>
<td><b>Research report</b> — 13 chapters, a 12-month target with its range, model confidence, and the caveats the audit operators raised.</td>
</tr>
</table>

## How it works

The app ships as a single `.app` containing two binaries that talk over local HTTP:

- **`finrobot-desktop`** — the Tauri shell: native window, menu bar, and the React UI.
- **`finrobot-server`** — a self-contained Python backend (FastAPI + PydanticAI + the deterministic compute engine), launched automatically in the background on `127.0.0.1:8321`.

You never start anything by hand. Opening the app boots the backend; quitting it shuts the backend down. No Python, no `uv`, and no source tree are required on the user's machine.

## Architecture

```
                       Tauri shell (Rust) ── React 19 UI
                                 │  HTTP  127.0.0.1:8321
                       FastAPI routes ── PydanticAI agents
                                 │
          ┌──────────────────────┼──────────────────────┐
     pipelines              compute engine          data layer
  (7 workflows)      (32 pure-Python operators)   (7 providers,
                                                   with failover)
                                 │
                          artifact store (SQLite)
```

### Agents

Nine agents, each defined by a markdown instruction file in `finrobot/engine/agents/instructions/`:

| Group | Agents | Role |
|:---|:---|:---|
| Pipeline | `data`, `analysis`, `modeling`, `synthesis`, `report` | The main research chain — gather, interpret, model, reconcile, write |
| Debate | `bull`, `bear`, `judge` | Argue the long and short case, then adjudicate |
| Orchestration | lead agent (`factory.py`, `orchestrator.py`) | Routes the request and sequences the rest |

Because instructions are plain markdown, changing an agent's behavior does not require touching Python.

### Pipelines

Seven workflows in `finrobot/engine/pipelines/`, each a sequence of typed steps with validators and retry:

| Pipeline | CLI | Output |
|:---|:---|:---|
| `equity_research.py` | `finrobot research` | Full 13-chapter research artifact |
| `dcf.py` | `finrobot dcf` | Discounted cash flow valuation |
| `ddm.py` | `finrobot ddm` | Dividend discount model |
| `lbo.py` | `finrobot lbo` | Leveraged buyout model |
| `comps.py` | `finrobot comps` | Comparable-company analysis |
| `earnings_analysis.py` | `finrobot earnings` | Earnings review |
| `ic_memo.py` | `finrobot ic-memo` | Investment-committee memo |

`finrobot dcf` automatically falls back to DDM for companies where a dividend model is the more defensible approach; pass `--force-dcf` to override.

<div align="center">
<img src="../figs/desktop-financials.png" width="92%" alt="Financial analysis chapter: profit cascade from revenue through EBITDA to net income"/>
</div>

<p align="center"><i>The <code>equity_research</code> pipeline's financial-analysis chapter — profit cascade from revenue to net income, with margins.</i></p>

### Deterministic compute

`finrobot/engine/compute/` is the part the LLM is not allowed to improvise around:

- **26 operators** — `dcf`, `ddm`, `lbo`, `multiples`, `monte_carlo`, `sotp`, `residual_income`, `peer_screen`, `forward_estimates`, `fx_normalize`, `ownership`, `catalyst`, `signal`, and their seed variants.
- **6 audit operators** — `currency_caliber`, `ev_bridge`, `narrative_divergence`, `narrative_numeric_grounding`, `sector_sign`, `ttm_period`. These check the *narrative* against the numbers and flag drift.
- **7 coordinators** — assemble operator inputs from the data layer (`extractor`, `historical_extractor`, `segment_extractor`, `market`, `news`, `dcf_seed`, `technical_payload`).

Everything here is pure Python with no model in the loop, which is what makes the numbers reproducible and the provenance checkable.

<div align="center">
<img src="../figs/desktop-dcf.png" width="92%" alt="DCF forecast table labelled code-computed, next to the LLM narrative"/>
</div>

<div align="center">
<img src="../figs/desktop-valuation.png" width="92%" alt="Football-field valuation triangulation and the explicit-period assumptions behind the DCF"/>
</div>

<p align="center"><i>Top: the DCF table is labelled <b>code-computed</b> — ten years from pure-Python operators — while the paragraph beside it is the LLM reading those numbers back.<br/>Bottom: the football field triangulates three methods — DCF, forward-P/E comps and EV/EBITDA. They diverged 2.6x here, so the point target was withheld and only the range ships; each assumption still states the basis it came from.</i></p>

### Data layer

Seven providers in `finrobot/engine/data/providers/`, behind a common interface with health tracking and automatic failover:

`yfinance` · `edgar` (SEC) · `fmp` · `finnhub` · `adanos` (retail sentiment) · `news_aggregator` · `fx`

Supporting pieces: response caching, a symbol index, quote batching, SEC holdings sync, and a validator that rejects malformed provider payloads before they reach the compute engine.

<div align="center">
<img src="../figs/desktop-data-sources.png" width="92%" alt="Data source settings showing each provider's health state"/>
</div>

<p align="center"><i>Each provider carries a health state — always on, saved, optional, cooling down — which is what the failover reads when a source stops answering.</i></p>

### Skills

`skills/` holds **56** analyst playbooks as `SKILL.md` files, grouped by desk:

| Category | Count | Category | Count |
|:---|:---|:---|:---|
| `financial-analysis` | 11 | `equity-research` | 9 |
| `private-equity` | 10 | `investment-banking` | 9 |
| `partner-lseg` | 8 | `wealth-management` | 6 |
| `partner-spglobal` | 3 | | |

Browse them from the CLI with `finrobot skill list` and `finrobot skill search <query>`. Attribution for third-party material is in `skills/ATTRIBUTION.md`.

---

## Install (macOS, Apple Silicon)

1. Download `FinRobot_<version>_aarch64.dmg` from the [Releases](../../releases) page (or build it yourself — see below).
2. Open the `.dmg` and drag **FinRobot** into `Applications`.
3. **First open** — the app is not yet code-signed, so Gatekeeper will block a plain double-click. Either right-click the app → **Open** → **Open**, or clear the quarantine flag once:
   ```bash
   xattr -dr com.apple.quarantine /Applications/FinRobot.app
   ```
4. **First run** — open **Settings** and paste your own LLM API key (DeepSeek / OpenAI / Anthropic). FinRobot orchestrates *your* LLM account; it does not ship a key. Until a key is set, the app opens fine but analysis requests return a "configure your API key" notice instead of running.

Running an analysis needs internet access (market data from yfinance / SEC EDGAR / optional FMP, plus your LLM provider). Launching the app and browsing existing reports does not.

Intel Macs, Windows, and Linux are not covered by the current release; on those platforms, run from source.

## Use from the command line

Installing the Python package gives you a `finrobot` CLI independent of the desktop shell:

```bash
uv sync                          # or: pip install -e .
finrobot research AAPL           # full research artifact
finrobot dcf MSFT                # DCF (auto-switches to DDM where appropriate)
finrobot comps NVDA --peers AMD,INTC
finrobot ic-memo TSLA
finrobot ask AAPL "How exposed is the gross margin to tariffs?"
finrobot backtest ...            # needs the `backtest` extra
finrobot serve                   # run the backend on its own
```

Most commands accept `--model` to pick the LLM (e.g. `anthropic:claude-sonnet-4-6`) and `--lang en|zh` to set the output language.

Four notebooks in `tutorials/` cover the same ground interactively: equity research, DCF valuation, backtesting, and RAG Q&A.

## Run in a browser

The same backend and the same UI can run as a local web service, with no `.dmg` and no Rust toolchain — useful on Intel Macs, Linux, and Windows, where there is no desktop build.

**Prerequisites:** [`uv`](https://docs.astral.sh/uv/) and Node 20+. Python 3.11+.

```bash
cd finrobot_desktop
uv sync                        # backend dependencies
(cd desktop && npm install)    # frontend dependencies — one time

./dev.sh                       # → open http://localhost:5173
```

A bare `uv sync` installs the base dependencies and **removes** any extras already in the environment, so if you have been working with `--extra dev` or `--extra package`, sync with those flags instead of dropping them:

```bash
uv sync --extra dev            # keeps pytest / ruff / mypy installed
```

`dev.sh` starts two processes and wires them together:

```
  Vite dev server  :5173   ← you open this in the browser
        │  proxies /api, /chat, /health, /openapi.json
        ▼
  finrobot serve   :8321   ← FastAPI backend, run from source
```

It waits for the backend's `/openapi.json` to answer before starting the frontend, and prints the backend log path (`/tmp/finrobot-backend.log`) if startup fails. `Ctrl+C` stops both. Backend edits need a restart of the script; frontend edits hot-reload.

Configure your LLM API key from the **Settings** page in the browser UI, exactly as in the desktop app — keys are stored in the OS keychain, not in a `.env` file.

Two things to know before you run it:

- **`dev.sh` first kills whatever is listening on :8321 and :5173.** If FinRobot.app is open, that includes its bundled backend. Quit the app first.
- **In browser mode the local API is unauthenticated.** The desktop shell mints a per-launch capability token and the backend enforces it; a plain browser has no Tauri IPC to read that token from, so the backend starts with the auth middleware as a no-op (see `finrobot/auth.py`). It still binds loopback only, but any other process on the machine can reach `:8321` while it runs — including `/api/settings`, which holds your keys. Prefer the desktop app on a shared machine.

`finrobot serve` on its own exposes only the JSON API — it does not serve the UI, so the Vite server is what makes the browser version work. There is currently no static production build for browser use either: `npm run build` emits assets for the desktop bundle, and `npm run preview` has no proxy configured, so its `/api` calls would not reach the backend.

## Build from source

Prerequisites: [`uv`](https://docs.astral.sh/uv/), Node 20+, a Rust toolchain, and the Tauri CLI (`cargo install tauri-cli` → `cargo tauri`). Python 3.11+.

```bash
uv sync --extra package            # backend deps + pyinstaller (for the sidecar)
bash desktop/src-tauri/sidecar/build.sh
                                   # freeze finrobot-server into desktop/src-tauri/binaries/

cd desktop
cargo tauri dev                    # run the desktop app (debug)
cargo tauri build                  # produce FinRobot.app + .dmg under desktop/src-tauri/target/release/bundle/
```

`build.sh` freezes the backend into a PyInstaller sidecar, so a plain `cd desktop && cargo tauri dev` runs against that **frozen** binary — backend edits won't show up until you re-run `build.sh`. For a live edit loop (backend source + frontend HMR, no re-freezing) use `dev.sh`:

```bash
./dev.sh            # browser shell  → http://localhost:5173  (see "Run in a browser")
./dev.sh --app      # desktop shell  → Tauri native window, live backend
```

`--app` sets `FINROBOT_DEV_LIVE_BACKEND=1` so the Tauri shell skips spawning the bundled sidecar; the WebView then talks through the Vite proxy to the source-tree backend `dev.sh` started. Or run just the backend with hot reload: `finrobot serve --reload`.

## Development

```bash
uv sync --extra dev
pytest tests/                                          # 237 test files; live-network tests are skipped by default
pytest tests/ --cov=finrobot --cov-report=term-missing
ruff check . && mypy finrobot                          # also wired into .pre-commit-config.yaml
```

Layout:

```
finrobot_desktop/
├── finrobot/              # Python backend
│   ├── engine/            #   agents, pipelines, compute, data, skills
│   ├── routes/            #   FastAPI endpoints (runs, artifacts, valuation, …)
│   ├── artifact/          #   report storage, contracts, semantic diff (SQLite)
│   ├── audit/ obs/        #   provenance checks and observability
│   ├── cli.py server.py   #   CLI and ASGI entry points
│   └── sdk.py             #   programmatic API
├── desktop/               # Tauri shell + React 19 / Vite 6 / Zustand / Recharts
├── skills/                # 56 analyst playbooks (SKILL.md)
├── tutorials/             # 4 notebooks
├── tests/                 # pytest suite, incl. Hypothesis property tests
└── scripts/               # maintenance and build tooling
```

CI (`.github/workflows/desktop-ci.yml`) runs the backend on Python 3.11 / 3.12 and the frontend on Node 22 / 24.

For deeper reference: `finrobot/engine/instructions.md` describes the engine's contracts, `finrobot/engine/agents/instructions/*.md` holds each agent's brief, and `finrobot/sdk.py` is the programmatic entry point.

## License

Apache 2.0 — see [LICENSE](./LICENSE).

---

### Overview (`finrobot_equity/README.md`)

# FinRobot Equity — V1

> **A self-hosted web app.** AI-powered equity research report generator: fetches financial data, runs LLM-based analysis, and produces professional multi-page HTML/PDF reports — from a browser or a single command.

This is V1 in the [FinRobot version lineage](../README.md). It is a **web service you deploy**, not a desktop application and not a framework — you run `./deploy.sh start`, open a browser, and people on your network get a form that turns a ticker into a report. That narrow shape is the point: one job, done through a UI.

Where it sits relative to the others:

- **[`finrobot_desktop/`](../finrobot_desktop/) (V2)** is the production agent system — a deeper research pipeline, a deterministic compute engine, and full numeric provenance. Choose it when the analysis itself matters most.
- **This project (V1)** is the choice when *browser access* matters most: a shared internal tool, a demo, a hosted deployment behind your own auth.
- **[`finrobot_autogen/`](../finrobot_autogen/) (V0)** is educational — the AutoGen library behind the whitepaper.

### Example output

[NVDA](https://ai4finance-foundation.github.io/FinRobot/finrobot_equity/core/output/NVDA_Equity_Research_Report.html) ·
[MSFT](https://ai4finance-foundation.github.io/FinRobot/finrobot_equity/core/output/MSFT_Equity_Research_Report.html) ·
[TSLA](https://ai4finance-foundation.github.io/FinRobot/finrobot_equity/core/output/TSLA_Equity_Research_Report.html) ·
[META](https://ai4finance-foundation.github.io/FinRobot/finrobot_equity/core/output/META_Equity_Research_Report.html) ·
[COP](https://ai4finance-foundation.github.io/FinRobot/finrobot_equity/core/output/COP_Equity_Research_Report.html)

The same files are checked in under `core/output/`.

<div align="center">
<img src="../figs/equity-webapp.png" width="92%" alt="The web interface: ticker, comparables, report components and enhanced-analysis toggles on the left; run status on the right"/>
</div>

<p align="center"><i>The interface you deploy — enter a ticker, pick the peers and the sections you want, and generate.</i></p>

<div align="center">
<img src="../figs/equity-report.png" width="92%" alt="Generated equity research report: rating, price target, key metrics and the investment thesis"/>
</div>

<p align="center"><i>And what comes out: a standalone HTML report with a rating, a price target, the key multiples, and the thesis behind them.</i></p>

---

## Quick start

### 1. Configure API keys

From the repository root:

```bash
cp finrobot_equity/core/config/config.ini.example finrobot_equity/core/config/config.ini
```

```ini
[API_KEYS]
fmp_api_key    = YOUR_FMP_API_KEY       # https://financialmodelingprep.com/developer
openai_api_key = YOUR_OPENAI_API_KEY    # https://platform.openai.com/account/api-keys
adanos_api_key = YOUR_ADANOS_API_KEY    # optional — enables Retail Sentiment Insights
```

`config.ini` is gitignored; `config.ini.example` is the file under version control.

With `adanos_api_key` set, the pipeline adds an optional **Retail Sentiment Insights** layer on top of the news workflow — structured snapshots of public retail activity across Reddit, X.com, and Polymarket.

### 2. Run the web app

From this directory:

```bash
chmod +x deploy.sh
./deploy.sh start
```

Then open `http://127.0.0.1:8001`.

If `deploy.sh` doesn't work in your environment, start it by hand:

```bash
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python run_web_app.py           # --host / --port / --no-reload are available
```

### 3. Or run the two-step CLI pipeline

```bash
# Step 1 — fetch data, forecast, and generate the narrative sections
python finrobot_equity/core/src/generate_financial_analysis.py \
    --company-ticker NVDA \
    --company-name "NVIDIA Corporation" \
    --config-file finrobot_equity/core/config/config.ini \
    --peer-tickers AMD INTC \
    --generate-text-sections

# Step 2 — render the HTML report from step 1's outputs
python finrobot_equity/core/src/create_equity_report.py \
    --company-ticker NVDA \
    --company-name "NVIDIA Corporation" \
    --analysis-csv output/NVDA/analysis/financial_metrics_and_forecasts.csv \
    --ratios-csv   output/NVDA/analysis/ratios_raw_data.csv \
    --tagline-file             output/NVDA/analysis/tagline.txt \
    --company-overview-file    output/NVDA/analysis/company_overview.txt \
    --investment-overview-file output/NVDA/analysis/investment_overview.txt \
    --valuation-overview-file  output/NVDA/analysis/valuation_overview.txt \
    --risks-file               output/NVDA/analysis/risks.txt \
    --competitor-analysis-file output/NVDA/analysis/competitor_analysis.txt \
    --major-takeaways-file     output/NVDA/analysis/major_takeaways.txt \
    --peer-ev-ebitda-csv       output/NVDA/analysis/peer_ev_ebitda_comparison.csv \
    --enable-text-regeneration \
    --config-file finrobot_equity/core/config/config.ini
```

`generate_pdf_report.py` turns the HTML into a PDF as an optional third step. `core/src/Run.ipynb` walks the same pipeline in a notebook.

---

## How it works

```
┌─────────────────────────────────┐     ┌──────────────────────────────┐
│  generate_financial_analysis.py │     │  create_equity_report.py     │
│                                 │     │                              │
│  1. Fetch data from FMP API     │────>│  1. Load analysis outputs    │
│  2. Process financial metrics   │     │  2. Auto-fetch market data   │
│  3. Generate 3-year forecasts   │     │  3. Generate charts          │
│  4. Run peer comparison         │     │  4. Render HTML report       │
│  5. AI text generation          │     │  5. Validate & regenerate    │
│                                 │     │                              │
│  Output: CSV + JSON + TXT       │     │  Output: multi-page HTML     │
└─────────────────────────────────┘     └──────────────────────────────┘
```

<div align="center">
<img src="../figs/equity-charts.png" width="92%" alt="Report section pairing computed charts with the AI-written valuation analysis"/>
</div>

<p align="center"><i>Each section pairs figures computed from the FMP data — revenue/EBITDA trajectory, EPS against the P/E multiple — with the paragraph an agent wrote about them.</i></p>

Step 1 is deterministic up to the last stage: the statements, ratios, forecasts, and peer multiples are computed from FMP data before any model is called. Step 2 can optionally re-run the narrative agents (`--enable-text-regeneration`) when a section fails validation.

### The agents

Eight section writers in `core/src/modules/equity_agents/`, coordinated by `agent_manager.py`:

| Agent | Section it writes |
|:---|:---|
| `tagline_agent` | One-line thesis for the cover |
| `company_overview_agent` | Business description |
| `investment_overview_agent` | Investment thesis |
| `valuation_overview_agent` | Valuation discussion |
| `risks_agent` | Risk assessment |
| `competitor_analysis_agent` | Competitive landscape |
| `major_takeaways_agent` | Key takeaways |
| `news_summary_agent` | News summary |

Each agent receives the already-computed numbers as context, so the narrative describes the model's output rather than inventing figures.

### Layout

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

## Reference

### Deployment commands

Run from this directory, or from the repo root as `./finrobot_equity/deploy.sh …` — the script resolves its own paths either way.

| Command | Description |
|:---|:---|
| `./deploy.sh start` | Start the web application (auto-installs dependencies) |
| `./deploy.sh stop` | Stop the application |
| `./deploy.sh restart` | Restart the application |
| `./deploy.sh status` | Check running status and recent logs |
| `./deploy.sh install` | Install/update dependencies only |

`deploy.gcloud.sh` covers Google Cloud Run deployment. The `Dockerfile` and `.dockerignore` stay at the repo root: the container imports the app as `finrobot_equity.web_app.main`, so the build context has to be the root with `finrobot_equity/` as a subdirectory under it.

### Environment variables

| Variable | Default | Description |
|:---|:---|:---|
| `WEB_HOST` | `127.0.0.1` | Server bind address (read by `deploy.sh`) |
| `WEB_PORT` | `8001` | Server port (read by `deploy.sh`) |
| `DATABASE_URL` | local SQLite | Database connection string |
| `GITHUB_CLIENT_ID` | — | GitHub OAuth client ID |
| `GITHUB_CLIENT_SECRET` | — | GitHub OAuth client secret |
| `FINROBOT_ADMIN_EMAIL` | `admin@finrobot.com` | Initial admin account |
| `FINROBOT_ADMIN_EMAILS` | — | Additional admin emails (comma-separated) |
| `FINROBOT_ADMIN_PASSWORD` | random | Initial admin password — printed on first start if unset |
| `ADANOS_API_KEY` | — | Retail sentiment key (alternative to `config.ini`) |
| `ADANOS_BASE_URL` | provider default | Override the retail sentiment endpoint |

### External services

| Service | Required | Purpose |
|:---|:---|:---|
| [Financial Modeling Prep](https://financialmodelingprep.com/developer) | Yes | Financial data, market metrics, peer comparison |
| [OpenAI](https://platform.openai.com/) | Yes | Narrative generation for report sections |
| Adanos Finance API | No | Retail sentiment across Reddit, X.com, Polymarket |

### Tests

```bash
pytest finrobot_equity/core/tests/
```

## License

Apache 2.0 — see [LICENSE](../LICENSE).

---

### Overview (`finrobot_desktop/finrobot/engine/data/datasets/README.md`)

# Damodaran Industry Datasets

DCF input fallback when ticker-level data is missing — keyed on yfinance
`industry` strings, with `industry_defaults.py` doing the lookup.

## Files

| File | Source URL | Updated |
|---|---|---|
| `damodaran_capex_2026-01.xls` | https://pages.stern.nyu.edu/~adamodar/pc/datasets/capex.xls | 2026-01-05 |
| `damodaran_margin_2026-01.xls` | https://pages.stern.nyu.edu/~adamodar/pc/datasets/margin.xls | 2026-01-05 |
| `damodaran_taxrate_2026-01.xls` | https://pages.stern.nyu.edu/~adamodar/pc/datasets/taxrate.xls | 2026-01-05 |
| `damodaran_betas_2026-01.xls` | https://pages.stern.nyu.edu/~adamodar/pc/datasets/betas.xls | 2026-01-05 |
| `industry_medians.csv` | derived from the four xls files | regenerated by `build_industry_medians.py` |
| `build_industry_medians.py` | one-shot merge script | — |

`industry_medians.csv` is the runtime artifact — `industry_defaults.py` loads
it and never touches the raw xls files. Keep the xls files in-repo so the CSV
is reproducible.

## Updating

Damodaran refreshes datasets twice a year (Jan + Jul). To refresh:

```bash
cd finrobot/engine/data/datasets

# 1. Download the new xls files (rename TAG to the new date)
for n in capex margin taxrate betas; do
  curl -sLo damodaran_${n}_YYYY-MM.xls \
    https://pages.stern.nyu.edu/~adamodar/pc/datasets/${n}.xls
done

# 2. Update TAG constant in build_industry_medians.py

# 3. Regenerate the CSV
uv run python build_industry_medians.py

# 4. Verify against last release
git diff industry_medians.csv | head

# 5. Re-run the test suite — schema regressions surface in test_industry_defaults.py
uv run pytest tests/unit/test_industry_defaults.py -v
```

## Derived ratios in `industry_medians.csv`

| Field | How it's computed |
|---|---|
| `capex_pct_revenue` | `Net Cap Ex/Sales + da_pct_revenue` (CapEx = NetCapEx + Depreciation) |
| `da_pct_revenue` | `EBITDA/Sales − Pre-tax Unadjusted Operating Margin` (Op Income = EBITDA − D&A) |
| `ebitda_pct_revenue` | EBITDA/Sales (direct from margin.xls) |
| `effective_tax_rate` | "Aggregate tax rate" across money-making firms (taxrate.xls, accrual basis) |
| `levered_beta` | Equity beta (raw, levered) — from the 5y average in betas.xls |
| `debt_equity` | Industry-average D/E ratio (betas.xls) |

All values are clipped to DCF-sane ranges (e.g. tax 5–40%, beta 0.3–2.5) in
the build script. See header comment in `build_industry_medians.py`.

## Why xls files instead of just the CSV?

Damodaran publishes xls only — the CSV is our derived artifact. Keeping the
raw files in-repo means:

1. The CSV is **reproducible** from primary sources.
2. Reviewers can audit which column we used (e.g. accrual vs cash tax rate).
3. Future refreshes can diff the xls files first to spot Damodaran schema
   changes before re-running the build script.

The four xls files total ≈230 KB — tolerable.

---

--- METRICS ---
- Files Extracted: 5
- Estimated Token Budget: ~14261 tokens
- Canonical Reference: https://codewiki.google/github.com/AI4Finance-Foundation/FinRobot
