Metadata-Version: 2.4
Name: portfolio-rotation-mcp
Version: 0.4.0
Summary: MCP server for portfolio rotation analysis -- works with Claude, ChatGPT, Gemini, and any MCP client
Project-URL: Homepage, https://github.com/mothanaprime/Rebalance-MCP
Project-URL: Repository, https://github.com/mothanaprime/Rebalance-MCP
Project-URL: Issues, https://github.com/mothanaprime/Rebalance-MCP/issues
License-Expression: MIT
Keywords: backtest,investing,mcp,portfolio,risk,rotation,scoring
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp[cli]>=1.2.0
Requires-Dist: numpy>=1.24.0
Requires-Dist: yfinance>=0.2.30
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == 'test'
Description-Content-Type: text/markdown

# Portfolio Rotation MCP Server

[![PyPI](https://img.shields.io/pypi/v/portfolio-rotation-mcp)](https://pypi.org/project/portfolio-rotation-mcp/)
[![Python](https://img.shields.io/pypi/pyversions/portfolio-rotation-mcp)](https://pypi.org/project/portfolio-rotation-mcp/)

MCP server for portfolio rotation analysis. Score holdings and candidates across 5 dimensions, identify optimal swaps, validate with risk checks and backtests.

**Works with any MCP client**: Claude Desktop, ChatGPT, Gemini, LangChain, Cursor, Windsurf, VS Code, Ollama clients, and more.

## What It Does

You give it a portfolio and candidate tickers. It returns:

```
ROTATION SCORECARD (GARP Style)
Ticker | Thesis | Valuation | Momentum | Catalyst | Technical | Composite | Action
META   |  75ᴾ   |   80ᴬ     |   78ᴬ    |   85ᴾ    |   74ᴬ     |   78.4    | Strong Buy
AVGO   |  70ᴾ   |   72ᴬ     |   75ᴬ    |   70ᴾ    |   80ᴬ     |   73.1    | Buy
AAPL   |  70ᴾ   |   65ᴬ     |   62ᴬ    |   60ᴾ    |   68ᴬ     |   65.5    | Hold
MSFT   |  65ᴾ   |   60ᴬ     |   58ᴬ    |   55ᴾ    |   62ᴬ     |   60.2    | Hold
JPM    |  50ᴾ   |   55ᴬ     |   45ᴬ    |   40ᴾ    |   42ᴬ     |   47.4    | Watch

KEY METRICS
Ticker | P/E  | EV/EBITDA | P/FCF | ROE  | D/E | Beta | Rev Growth
META   | 22.5 |   15.2    | 18.1  | 35%  | 0.3 | 1.18 |   +22.4%
AVGO   | 28.3 |   20.1    | 25.5  | 42%  | 1.5 | 1.32 |   +15.8%

RISK DASHBOARD
Portfolio Beta: 1.05 | VaR(95%): 1.85% | CVaR(95%): 2.45%
⚠️ Technology sector: 35% (>30% limit)

SWAP RECOMMENDATIONS
Sell JPM (47.4) → Buy META (78.4) | Delta: +31.0 | Strong Swap

ALLOCATION (NORMAL regime)
Conservative: META 6% | Balanced: META 10% | Aggressive: META 15%
```

## Quick Start

```bash
# Install from PyPI
pip install portfolio-rotation-mcp

# Or run directly (no install needed)
uvx portfolio-rotation-mcp

# Set API key (optional -- falls back to yfinance without it)
export FINANCIAL_DATASETS_API_KEY=your-key
```

### Prerequisites

- Python >= 3.10
- Optional: [financial-datasets.ai](https://financial-datasets.ai) API key for premium data (without it, prices come from yfinance and financial statements are unavailable)

## 11 Tools

| Tool | Description |
|------|-------------|
| `fetch_prices` | Historical OHLCV prices (API + yfinance fallback) |
| `fetch_financials` | Income/balance/cashflow statements |
| `fetch_ff_factors` | Fama-French 5-factor + momentum data |
| `score_tickers` | 5-dimension scoring (auto + manual) |
| `analyze_risk` | Concentration, correlation, volatility, beta, VaR, CVaR |
| `compare_swaps` | Pairwise swap recommendations (delta >= 15) |
| `run_backtest` | Historical strategy simulation |
| `stress_test` | Scenario replay, Monte Carlo, factor decomposition |
| `compute_attribution` | Trade attribution and swap alpha |
| `run_pipeline` | Full 6-stage rotation analysis (regime-adaptive allocation) |
| `get_skill` | Retrieve domain knowledge (scoring rules, swap logic, risk thresholds) |

## Platform Setup

### Claude Desktop

Add to your config file:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "portfolio-rotation": {
      "command": "uvx",
      "args": ["portfolio-rotation-mcp"],
      "env": {
        "FINANCIAL_DATASETS_API_KEY": "your-key"
      }
    }
  }
}
```

Then in Claude Desktop, just say:

> My portfolio is AAPL 20%, MSFT 15%, JPM 10%. Evaluate META and AVGO as swap candidates.

Claude will automatically call the MCP tools.

### Claude Code (CLI)

```bash
claude mcp add portfolio-rotation -- uvx portfolio-rotation-mcp
```

### Cursor / Windsurf / VS Code

Add to your MCP settings (`.cursor/mcp.json`, `.windsurf/mcp.json`, or VS Code MCP config):

```json
{
  "mcpServers": {
    "portfolio-rotation": {
      "command": "uvx",
      "args": ["portfolio-rotation-mcp"],
      "env": {
        "FINANCIAL_DATASETS_API_KEY": "your-key"
      }
    }
  }
}
```

### LangChain (any model: DeepSeek, GPT, Llama, etc.)

```python
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_openai import ChatOpenAI

# Use any model -- DeepSeek, GPT, Llama, etc.
llm = ChatOpenAI(
    model="deepseek-chat",  # or "gpt-4o", etc.
    base_url="https://api.deepseek.com/v1",
    api_key="sk-...",
)

async with MultiServerMCPClient({
    "portfolio-rotation": {
        "command": "uvx",
        "args": ["portfolio-rotation-mcp"],
        "env": {"FINANCIAL_DATASETS_API_KEY": "your-key"},
    }
}) as client:
    tools = client.get_tools()
    # Create agent with tools and invoke
```

### OpenAI Agents SDK

```python
from agents import Agent
from agents.mcp import MCPServerStdio

async with MCPServerStdio(
    command="uvx",
    args=["portfolio-rotation-mcp"],
) as server:
    tools = await server.list_tools()
    agent = Agent(name="Rotation Analyst", tools=tools)
```

### Ollama + Continue / LibreChat

Configure in the MCP settings of your Ollama frontend:

```json
{
  "command": "uvx",
  "args": ["portfolio-rotation-mcp"],
  "env": {
    "FINANCIAL_DATASETS_API_KEY": "your-key"
  }
}
```

## Usage Examples

### Quick: Full Pipeline (one tool call)

Ask your AI agent:

> Analyze my portfolio: AAPL 20% (Technology), MSFT 15% (Technology), JPM 10% (Financials). Candidates: META, AVGO. Use GARP style.

The agent will call `run_pipeline` which runs all 6 stages automatically: data fetch -> scoring -> risk check -> swap comparison -> backtest -> report.

### Targeted: Score Specific Tickers

> Score AAPL, META, and AVGO. My thesis score for META is 80 and catalyst is 85.

The agent will call `fetch_prices`, then `score_tickers` with your manual overrides.

### Deep Dive: Stress Test

> Stress test my portfolio under a 2008-style crash scenario. Include Monte Carlo simulation.

The agent will call `fetch_prices`, `fetch_ff_factors`, then `stress_test`.

### Post-Trade: Attribution

> I sold INTC and bought NVDA on Jan 15 at $120. How did that swap perform?

The agent will call `fetch_prices`, then `compute_attribution` to measure swap alpha.

## Development

```bash
# Clone and install in development mode
git clone git@github.com:mothanaprime/Rebalance-MCP.git
cd Rebalance-MCP
pip install -e .

# Run the server
portfolio-rotation-mcp

# Test with MCP inspector
mcp dev src/portfolio_rotation/server.py
```

## Scoring Framework

5 dimensions, 0-100 each, weighted by investment style:

| Dimension | GARP Weight | Scoring Mode |
|-----------|------------|--------------|
| Thesis Integrity | 25% | ᴾ Auto-proxy (financial trends) or ᴹ manual override |
| Valuation Attractiveness | 25% | ᴬ Auto: P/E + PEG + EV/EBITDA + P/FCF (4-methodology blend) |
| Fundamental Momentum | 20% | ᴬ Auto (price momentum + revenue growth) |
| Catalyst Proximity | 15% | ᴾ Auto-proxy (earnings, volume, analyst targets) or ᴹ manual |
| Technical Trend | 15% | ᴬ Auto (MA crossovers, RSI, relative strength) |

**Valuation** blends up to 4 methodologies: P/E (35%), PEG (20%), EV/EBITDA (25%), P/FCF (20%). Missing methods redistribute weight. Falls back to P/E-only without balance sheet/cash flow data.

**Risk metrics**: Portfolio beta, individual stock betas, parametric VaR (95%/99%), historical VaR, CVaR (Expected Shortfall).

**Allocation**: Regime-adaptive — parameters auto-adjust for VIX level (LOW/NORMAL/ELEVATED/HIGH).

**Swap threshold**: Buy Score - Hold Score >= 15

**Style presets**: `garp` (default), `value`, `growth`, `momentum`, `event_driven` -- each has different dimension weights.

See [docs/scoring-framework.md](docs/scoring-framework.md) for full details.

## Agent Prompt

See [docs/agent-prompt.md](docs/agent-prompt.md) for a model-agnostic system prompt you can use to configure any AI agent for rotation analysis.

## Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `FINANCIAL_DATASETS_API_KEY` | No | -- | API key for [financial-datasets.ai](https://financial-datasets.ai). Without it, prices fall back to yfinance and financials are unavailable. |
| `PORTFOLIO_ROTATION_SOURCE` | No | `auto` | Data source: `auto` (API first, yfinance fallback), `api`, `financial-datasets`, or `yfinance`. Can be overridden per-call. |

## License

MIT
