feat: OpenBB Investment Analysis API
REST API wrapping OpenBB SDK for stock data, sentiment analysis, technical indicators, macro data, and rule-based portfolio analysis. - Stock data via yfinance (quote, profile, metrics, financials, historical, news) - News sentiment via Alpha Vantage (per-article, per-ticker scores) - Analyst data via Finnhub (recommendations, insider trades, upgrades) - Macro data via FRED (Fed rate, CPI, GDP, unemployment, treasury yields) - Technical indicators via openbb-technical (RSI, MACD, SMA, EMA, Bollinger) - Rule-based portfolio analysis engine (BUY_MORE/HOLD/SELL) - Stock discovery (gainers, losers, active, undervalued, growth) - 102 tests, all passing
This commit is contained in:
254
README.md
Normal file
254
README.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# OpenBB Investment Analysis API
|
||||
|
||||
REST API wrapping OpenBB SDK, providing stock data query, sentiment analysis, technical indicators, macro data, and rule-based investment analysis for US and Swedish markets. Designed to be called by OpenClaw (or any AI assistant) — the API returns structured data, all LLM reasoning happens on the caller side.
|
||||
|
||||
## API Keys
|
||||
|
||||
### Required: None
|
||||
|
||||
The core functionality uses **yfinance** (free, no API key). The API works without any keys configured.
|
||||
|
||||
### Recommended Free Keys
|
||||
|
||||
| Provider | Env Variable | How to Get | What It Unlocks | Free Limit |
|
||||
|----------|-------------|------------|-----------------|------------|
|
||||
| **Finnhub** | `INVEST_API_FINNHUB_API_KEY` | https://finnhub.io/register | Insider trades, analyst upgrades, recommendation trends | 60 calls/min |
|
||||
| **FRED** | `INVEST_API_FRED_API_KEY` | https://fred.stlouisfed.org/docs/api/api_key.html | Macro data: Fed rate, CPI, GDP, unemployment, treasury yields | 120 calls/min |
|
||||
| **Alpha Vantage** | `INVEST_API_ALPHAVANTAGE_API_KEY` | https://www.alphavantage.co/support/#api-key | News sentiment scores (bullish/bearish per article per ticker) | 25 calls/day |
|
||||
|
||||
### Optional Paid Keys (for higher quality data)
|
||||
|
||||
| Provider | Env Variable | What It Adds |
|
||||
|----------|-------------|--------------|
|
||||
| **FMP** | `OBB_FMP_API_KEY` | More granular financials, earnings transcripts (250 calls/day free) |
|
||||
| **Intrinio** | `OBB_INTRINIO_API_KEY` | Institutional-grade fundamentals |
|
||||
| **Tiingo** | `OBB_TIINGO_TOKEN` | Reliable historical price data |
|
||||
| **Benzinga** | `OBB_BENZINGA_API_KEY` | Real-time news, analyst ratings |
|
||||
|
||||
### Configuration
|
||||
|
||||
Set environment variables before starting, or add to a `.env` file:
|
||||
|
||||
```bash
|
||||
export INVEST_API_FINNHUB_API_KEY=your_finnhub_key
|
||||
export INVEST_API_FRED_API_KEY=your_fred_key
|
||||
export INVEST_API_ALPHAVANTAGE_API_KEY=your_alphavantage_key
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Create conda environment
|
||||
|
||||
```bash
|
||||
conda env create -f environment.yml
|
||||
conda activate openbb-invest-api
|
||||
```
|
||||
|
||||
### 2. Start the server
|
||||
|
||||
```bash
|
||||
python main.py
|
||||
```
|
||||
|
||||
Server starts at `http://localhost:8000`. Visit `http://localhost:8000/docs` for Swagger UI.
|
||||
|
||||
### 3. Test it
|
||||
|
||||
```bash
|
||||
# Health check
|
||||
curl http://localhost:8000/health
|
||||
|
||||
# US stock quote
|
||||
curl http://localhost:8000/api/v1/stock/AAPL/quote
|
||||
|
||||
# Swedish stock quote
|
||||
curl http://localhost:8000/api/v1/stock/VOLV-B.ST/quote
|
||||
|
||||
# Sentiment analysis (requires Finnhub + Alpha Vantage keys)
|
||||
curl http://localhost:8000/api/v1/stock/AAPL/sentiment
|
||||
|
||||
# News sentiment with per-article scores (requires Alpha Vantage key)
|
||||
curl http://localhost:8000/api/v1/stock/AAPL/news-sentiment
|
||||
|
||||
# Technical indicators
|
||||
curl http://localhost:8000/api/v1/stock/AAPL/technical
|
||||
|
||||
# Macro overview (requires FRED key)
|
||||
curl http://localhost:8000/api/v1/macro/overview
|
||||
|
||||
# Portfolio analysis
|
||||
curl -X POST http://localhost:8000/api/v1/portfolio/analyze \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"holdings":[{"symbol":"AAPL","shares":100,"buy_in_price":150},{"symbol":"VOLV-B.ST","shares":50,"buy_in_price":250}]}'
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Health
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/health` | Health check |
|
||||
|
||||
### Stock Data (yfinance, no key needed)
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/v1/stock/{symbol}/quote` | Current price and volume |
|
||||
| GET | `/api/v1/stock/{symbol}/profile` | Company overview (sector, industry, description) |
|
||||
| GET | `/api/v1/stock/{symbol}/metrics` | Key ratios (PE, PB, ROE, EPS, etc.) |
|
||||
| GET | `/api/v1/stock/{symbol}/financials` | Income statement + balance sheet + cash flow |
|
||||
| GET | `/api/v1/stock/{symbol}/historical?days=365` | Historical OHLCV data |
|
||||
| GET | `/api/v1/stock/{symbol}/news` | Recent company news |
|
||||
| GET | `/api/v1/stock/{symbol}/summary` | Aggregated: quote + profile + metrics + financials |
|
||||
|
||||
### Sentiment & Analyst Data (Finnhub + Alpha Vantage, free keys)
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/v1/stock/{symbol}/sentiment` | Aggregated: news sentiment + recommendations + upgrades |
|
||||
| GET | `/api/v1/stock/{symbol}/news-sentiment?limit=30` | News articles with per-ticker sentiment scores (Alpha Vantage) |
|
||||
| GET | `/api/v1/stock/{symbol}/insider-trades` | Insider transactions (CEO/CFO buys and sells) |
|
||||
| GET | `/api/v1/stock/{symbol}/recommendations` | Monthly analyst buy/hold/sell counts |
|
||||
| GET | `/api/v1/stock/{symbol}/upgrades` | Recent analyst upgrades and downgrades |
|
||||
|
||||
### Technical Analysis (local computation, no key needed)
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/v1/stock/{symbol}/technical` | RSI, MACD, SMA, EMA, Bollinger Bands + signal interpretation |
|
||||
|
||||
### Macro Economics (FRED, free key)
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/v1/macro/overview` | Key indicators: Fed rate, treasury yields, CPI, unemployment, GDP, VIX |
|
||||
| GET | `/api/v1/macro/series/{series_id}?limit=30` | Any FRED time series by ID |
|
||||
|
||||
### Portfolio Analysis (no key needed)
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| POST | `/api/v1/portfolio/analyze` | Rule-based analysis of holdings (max 50) |
|
||||
|
||||
Request body:
|
||||
```json
|
||||
{
|
||||
"holdings": [
|
||||
{"symbol": "AAPL", "shares": 100, "buy_in_price": 150.0},
|
||||
{"symbol": "VOLV-B.ST", "shares": 50, "buy_in_price": 250.0}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Response includes per-holding: current price, P&L, key metrics, analyst target price, and a rule-engine recommendation (BUY_MORE / HOLD / SELL) with confidence level and reasons.
|
||||
|
||||
### Stock Discovery (no key needed)
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/v1/discover/gainers` | Top gainers |
|
||||
| GET | `/api/v1/discover/losers` | Top losers |
|
||||
| GET | `/api/v1/discover/active` | Most active |
|
||||
| GET | `/api/v1/discover/undervalued` | Undervalued large caps |
|
||||
| GET | `/api/v1/discover/growth` | Growth tech stocks |
|
||||
|
||||
## Rule Engine
|
||||
|
||||
The portfolio analysis endpoint uses a rule-based engine (no LLM) that scores each holding on four signals:
|
||||
|
||||
| Signal | BUY_MORE (+1) | HOLD (0) | SELL (-1) |
|
||||
|--------|---------------|----------|-----------|
|
||||
| Price vs analyst target | >15% upside | -10% to +15% | >10% downside |
|
||||
| PE ratio | < 15 | 15 - 35 | > 35 or negative |
|
||||
| Revenue growth | > 10% YoY | 0 - 10% | Negative |
|
||||
| P&L vs cost basis | Loss > 20% | -20% to +50% | Profit > 50% |
|
||||
|
||||
Scores are summed. Total >= 2 = BUY_MORE, <= -2 = SELL, otherwise HOLD. Confidence is HIGH/MEDIUM/LOW based on how many signals agree.
|
||||
|
||||
## Configuration
|
||||
|
||||
All settings are configurable via environment variables with the `INVEST_API_` prefix:
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `INVEST_API_HOST` | `0.0.0.0` | Server bind address |
|
||||
| `INVEST_API_PORT` | `8000` | Server port |
|
||||
| `INVEST_API_CORS_ORIGINS` | `["http://localhost:3000"]` | Allowed CORS origins (JSON array) |
|
||||
| `INVEST_API_LOG_LEVEL` | `info` | Logging level |
|
||||
| `INVEST_API_DEBUG` | `false` | Enable debug mode (auto-reload) |
|
||||
| `INVEST_API_FINNHUB_API_KEY` | _(empty)_ | Finnhub API key for analyst data |
|
||||
| `INVEST_API_FRED_API_KEY` | _(empty)_ | FRED API key for macro data |
|
||||
| `INVEST_API_ALPHAVANTAGE_API_KEY` | _(empty)_ | Alpha Vantage API key for news sentiment |
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
openbb-invest-api/
|
||||
├── main.py # FastAPI app entry point
|
||||
├── config.py # Settings (env-based)
|
||||
├── models.py # Pydantic request/response models
|
||||
├── mappers.py # Dict-to-model mapping functions
|
||||
├── openbb_service.py # OpenBB SDK wrapper (async)
|
||||
├── finnhub_service.py # Finnhub REST client (insider, analyst data)
|
||||
├── alphavantage_service.py # Alpha Vantage REST client (news sentiment)
|
||||
├── macro_service.py # FRED macro data via OpenBB
|
||||
├── technical_service.py # Technical indicators via openbb-technical
|
||||
├── analysis_service.py # Rule engine for portfolio analysis
|
||||
├── routes.py # Core stock data + portfolio + discovery routes
|
||||
├── routes_sentiment.py # Sentiment & analyst routes (Finnhub + Alpha Vantage)
|
||||
├── routes_macro.py # Macro economics routes (FRED)
|
||||
├── routes_technical.py # Technical analysis routes
|
||||
├── environment.yml # Conda environment
|
||||
├── pyproject.toml # Project metadata
|
||||
└── tests/ # 102 tests
|
||||
├── test_models.py
|
||||
├── test_mappers.py
|
||||
├── test_openbb_service.py
|
||||
├── test_finnhub_service.py
|
||||
├── test_analysis_service.py
|
||||
├── test_routes.py
|
||||
├── test_routes_sentiment.py
|
||||
├── test_alphavantage_service.py
|
||||
├── test_routes_macro.py
|
||||
└── test_routes_technical.py
|
||||
```
|
||||
|
||||
## Running Tests
|
||||
|
||||
```bash
|
||||
conda activate openbb-invest-api
|
||||
python -m pytest tests/ -v
|
||||
```
|
||||
|
||||
## Swedish Stocks
|
||||
|
||||
Swedish stocks are supported via the `.ST` suffix (Stockholm exchange):
|
||||
- `VOLV-B.ST` (Volvo)
|
||||
- `ERIC-B.ST` (Ericsson)
|
||||
- `HM-B.ST` (H&M)
|
||||
- `SEB-A.ST` (SEB)
|
||||
- `SAND.ST` (Sandvik)
|
||||
|
||||
## Integration with OpenClaw
|
||||
|
||||
This API is designed to be called by OpenClaw as an MCP tool or HTTP data source. OpenClaw sends requests to this API to fetch structured stock data and rule-based analysis, then uses its LLM to generate natural language investment advice.
|
||||
|
||||
Example OpenClaw workflow:
|
||||
1. User asks: "Should I buy more AAPL?"
|
||||
2. OpenClaw calls `GET /api/v1/stock/AAPL/summary` for fundamental data
|
||||
3. OpenClaw calls `GET /api/v1/stock/AAPL/sentiment` for news/analyst sentiment
|
||||
4. OpenClaw calls `GET /api/v1/stock/AAPL/technical` for technical signals
|
||||
5. OpenClaw calls `GET /api/v1/macro/overview` for market context
|
||||
6. OpenClaw calls `POST /api/v1/portfolio/analyze` with user's holdings
|
||||
7. OpenClaw's LLM synthesizes all structured data into a personalized recommendation
|
||||
|
||||
## Data Sources
|
||||
|
||||
| Source | Cost | Key Required | Data Provided |
|
||||
|--------|------|-------------|---------------|
|
||||
| **yfinance** | Free | No | Quotes, fundamentals, financials, historical prices, news, discovery |
|
||||
| **Finnhub** | Free | Yes (free registration) | Insider trades, analyst recommendations, upgrades/downgrades |
|
||||
| **Alpha Vantage** | Free | Yes (free registration) | News sentiment scores (bullish/bearish per ticker per article), 25 req/day |
|
||||
| **FRED** | Free | Yes (free registration) | Fed rate, treasury yields, CPI, unemployment, GDP, VIX, 800K+ economic series |
|
||||
| **openbb-technical** | Free | No (local computation) | RSI, MACD, SMA, EMA, Bollinger Bands |
|
||||
Reference in New Issue
Block a user