Metadata-Version: 2.4
Name: alo-invest
Version: 0.1.0
Summary: Autonomous investment intelligence from the terminal — research, backtest, and trade via a conversational agent powered by the Claude Agent SDK.
Project-URL: Homepage, https://alo-invest.vercel.app
Project-URL: Documentation, https://alo-invest.vercel.app/pricing
Author-email: Giu <ge@alomana.com>
License: Alo Invest — Proprietary License
        
        Copyright (c) 2026 Alomana. All rights reserved.
        
        This software is licensed, not sold. Subject to an active subscription or
        free trial and to the Alo Invest Terms of Service
        (https://alo-invest.vercel.app/terms), Alomana grants you a personal,
        non-exclusive, non-transferable, revocable license to install and use the
        software for your own investment research.
        
        You may not copy (except as reasonably necessary to install and run the
        software), modify, distribute, sublicense, sell, or create derivative
        works from the software, and you may not remove or circumvent its license
        enforcement.
        
        The software's source code is visible as a consequence of how Python is
        distributed. Visibility is not a grant of rights: all rights not expressly
        granted above are reserved by Alomana.
        
        Third-party open-source components bundled as dependencies remain under
        their own licenses.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. SEE THE
        TERMS OF SERVICE FOR THE FULL DISCLAIMER AND LIMITATION OF LIABILITY.
License-File: LICENSE
Keywords: agent,ai,alpaca,claude,investing,trading
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.11
Requires-Dist: alpaca-py>=0.38.0
Requires-Dist: ccxt>=4.0.0
Requires-Dist: claude-agent-sdk>=0.1.75
Requires-Dist: click>=8.1.0
Requires-Dist: matplotlib>=3.7.0
Requires-Dist: numpy>=1.24.0
Requires-Dist: pandas>=2.0.0
Requires-Dist: prompt-toolkit>=3.0.0
Requires-Dist: pydantic-settings>=2.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: pyyaml>=6.0.0
Requires-Dist: requests>=2.31.0
Requires-Dist: rich>=13.0.0
Requires-Dist: seaborn>=0.12.0
Requires-Dist: yfinance>=0.2.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# Alo Invest

Autonomous investment intelligence from the terminal. Research companies, build and backtest strategies, deploy to paper trading — through a conversational agent powered by the Claude Agent SDK. Or schedule the daily investor cycle and let it run the book autonomously, inside walls enforced by code.

---

## Quick start

```bash
git clone <repo>
cd alo-invest
cp .env.example .env   # add your API keys
uv run alo-invest
```

That's it. `uv run` handles the virtual environment and dependencies automatically.

### API keys

Add keys to `.env` (see `.env.example`):

| Key | Required | What it enables |
|-----|----------|-----------------|
| `ANTHROPIC_API_KEY` | Yes | Powers the agent |
| `ALPACA_API_KEY` + `ALPACA_SECRET_KEY` | For trading/data | Real-time quotes, OHLCV bars, paper trading |
| `PERPLEXITY_API_KEY` | For research | News, sentiment, analyst views |
| `TAVILY_API_KEY` | For research | Deep research, SEC filings, document extraction |
| `BINANCE_API_KEY` + `BINANCE_SECRET_KEY` | For crypto | Spot trading, futures, account balances |
| `BINANCE_TESTNET` | For crypto paper trading | Routes all Binance orders to testnet (set `true`) |
| `NTFY_TOPIC` | For push notifications | Daily memos and kill-switch alerts pushed to your phone via [ntfy.sh](https://ntfy.sh) |

The CLI warns on startup if optional keys are missing. `ANTHROPIC_API_KEY` is required — the agent won't start without it. Binance price and OHLCV data work without keys; only account and order tools require them.

See [CRYPTO.md](CRYPTO.md) for full crypto and paper trading setup.

---

## How it works

Alo Invest runs an agentic loop via the Claude Agent SDK. You give it a goal — it plans the steps, calls tools, reads results, and iterates until done.

### Data sources

| Source | What it provides | Speed |
|--------|-----------------|-------|
| **Alpaca MCP** | Real-time quotes, OHLCV bars, account, positions, order placement | Instant |
| **Binance MCP** | Crypto prices, OHLCV bars, spot trading, USDT-margined futures, funding rates | Instant |
| **Fundamentals CLI** | Market cap, P/E, margins, sector, revenue, beta (via yfinance) | ~1-2s |
| **Perplexity MCP** | News, catalysts, analyst views, sentiment | 2-3s |
| **Tavily MCP** | Deep research, SEC filings, URL extraction | 5-10s |
| **Backtest engine** | Strategy simulation with integrity checks (uses yfinance for historical data) | Varies |

The agent knows which source to use for what — it won't web-search for a crypto price when Binance can return it instantly.

### Workspace vs Portfolio

**Workspace** (always active, defaults to cwd):
- Where files, strategies, backtests, and charts are saved

**Portfolio** (optional, `--portfolio ~/alo-invest`):
- Adds: `INVEST.md` rules, `config/*.yaml` constraints injected into the system prompt
- Adds: memory persistence, audit logs, paper trading via Alpaca

```bash
# Initialize a portfolio when you're ready for trading
uv run alo-invest init ~/alo-invest
uv run alo-invest --portfolio ~/alo-invest

# Set this to skip --portfolio every time
export ALO_INVEST_PORTFOLIO=~/alo-invest
```

After `init`, the portfolio holds (everything the agent reads or writes lives here):

```
config/              risk, universe, budgets YAML (sha256-stamped)
skills/              your overrides + cohort siblings from /strategy-factory
strategies/          draft, active, rejected — runnable .py files
backtests/runs/      backtest result JSON
reports/             daily, weekly, regime, strategy (cohort memos)
data/                market cache, portfolio positions, watch tripwires,
                     factory exploration map
proposals/           pending, approved, executed
audit/               JSONL log of every tool call and decision
theses/              long-form research notes
```

Cohort memos from `/strategy-factory` land in `reports/strategy/`; the
exploration map the factory reads and appends is at
`data/factory/exploration.yaml`.

---

## Modes

```bash
uv run alo-invest                        # paper mode (default) — can submit paper orders
uv run alo-invest --mode research        # research only — orders blocked
uv run alo-invest --mode live            # live trading (use with care)
```

---

## Autonomous mode

Schedule the daily investor cycle and the agent runs an investor's routine unattended — review the book, grade its own predictions, assess every playbook's track record, reweight the portfolio, research one idea, and send you the daily memo as a notification:

```bash
uv run alo-invest schedule install --portfolio ~/alo-invest --at 09:00
uv run alo-invest schedule status
uv run alo-invest schedule remove
```

Scheduled runs are **paper-only by construction** — there is no flag to make the loop trade live. Live access is earned later, once the prediction journal shows the autonomous operator is well-calibrated.

### Publishing to the public site

`alo-invest publish run` snapshots the live Alpaca paper account + portfolio state into `docs/content/public/` (three JSON files: `latest.json`, `nav-history.json`, `trades-30d.json`). Those are the only files the Next.js site reads — push them and Vercel rebuilds with real data:

```bash
# Snapshot locally — eyeball before publishing
uv run alo-invest publish run --portfolio ~/alo-invest

# Snapshot + git commit + push (Vercel rebuilds automatically)
uv run alo-invest publish run --portfolio ~/alo-invest --push
```

The publisher is conservative-by-default. It only ever writes the three allowlisted files; never thesis text from predictions, audit logs, API keys, draft strategies, dossier internals, or watcher state.

**Live prices without publishing (recommended).** Set `ALPACA_API_KEY` and `ALPACA_SECRET_KEY` as environment variables on the Vercel project (paper keys, server-side only — never shipped to the browser). The live pages then fetch NAV, positions, the equity curve, and fills straight from Alpaca at render time, revalidated at most once a minute. No background process anywhere: nothing runs on your machine, and Vercel only fetches when someone loads the page. The committed JSON stays as the fallback (keys absent, Alpaca down) and remains the only source for cycle-derived state — funnel counts, prediction grade, strategy attribution, options max-loss — which updates whenever a cycle publishes. See `docs/lib/alpaca.ts` and the overlay in `docs/lib/public-data.ts`.

**Scheduled publishing (alternative).** If you'd rather not put broker keys on Vercel, `publish install` schedules snapshot + push as a launchd job on your machine — no model, no tokens, push script idempotent:

```bash
uv run alo-invest publish install --portfolio ~/alo-invest --at 17:00   # daily after the close
uv run alo-invest publish install --portfolio ~/alo-invest --every 30  # or intraday
uv run alo-invest publish status
uv run alo-invest publish remove
```

**Stop publishing.** Three levels, depending on what you want to keep:

```bash
# 1. Stop automatic publishing (and optionally the autonomous loop)
uv run alo-invest publish remove
uv run alo-invest schedule remove

# 2. Take the site offline immediately by reverting the public snapshot
#    Restores whatever was in git for those files (the seed data, or the last good cycle)
git checkout HEAD -- docs/content/public/
git commit -m "publish: pause public site" docs/content/public/
git push

# 3. Stop the docs site from rebuilding at all
#    Pause the project in the Vercel dashboard — pushes still happen, deploys don't
```

Removing the schedule is the right move when you're pausing the experiment. Reverting `docs/content/public/` is for when you've published something you didn't mean to (a draft cycle, a bad day you want to roll back). Pausing in Vercel is for an extended hiatus where you don't want any new builds at all.

The architecture has three layers with different enforcement:

**1. Invariants — enforced in code.** This is the only place rules live; the model cannot route around them:

- **Pre-trade risk gate** — a hook intercepts every order-placement tool call (Alpaca and Binance) and validates universe, notional, position size, cash floor, and shorting before anything reaches a broker. Fails closed.
- **Per-domain risk budgets** (`config/budgets.yaml`) — different instruments get different walls: equities have a NAV-share cap and net-exposure band; crypto perps have a gross-notional cap, leverage ceiling, and liquidation buffer. `reduce_only` orders always pass — they can only shrink risk.
- **NAV kill-switch** — when account equity draws down past `hard_stop_pct` from its tracked peak, positions are flattened, all order flow halts on every venue, and you get notified. Only a human clears it: `alo-invest resume-trading`.
- **Config tamper guard** — risk configs are human-owned. They are hashed at approval time and verified on every order; any drift (by any path) blocks all trading until you review and run `alo-invest config-approve`.

**2. Evidence — enforced by data.** Strategies are skills, and each is a self-documenting hypothesis: YAML frontmatter declares its domain (which risk budget it inherits), regime assumptions, and falsification condition. Each playbook carries a dossier — walk-forward results, live-vs-backtest divergence, prediction journal entries tagged to it. The cycle reads every dossier before reweighting, so the investor can never pretend not to know a strategy is unproven.

**3. Judgment — the model.** Which playbook fits the regime, conviction, sizing. One portfolio, one NAV, continuous reweighting — playbooks get flagged and weighted down, not killed.

---

## CLI reference

```bash
# REPL
uv run alo-invest
uv run alo-invest --workspace ~/research
uv run alo-invest --portfolio ~/alo-invest
uv run alo-invest --think                        # extended thinking

# Resume
uv run alo-invest --resume latest
uv run alo-invest sessions

# One-shot
uv run alo-invest --prompt "analyze NVDA"

# Setup
uv run alo-invest init [directory]
uv run alo-invest doctor

# Autonomous operation
uv run alo-invest schedule install -p <portfolio> --at 09:00   # daily cycle (launchd, paper only)
uv run alo-invest schedule status
uv run alo-invest schedule remove
uv run alo-invest config-approve -p <portfolio>   # approve risk configs after editing them
uv run alo-invest resume-trading -p <portfolio>   # clear a tripped NAV kill-switch
```

---

## Skills

Skills are slash commands that encode repeatable investment workflows. Built-in skills work without a portfolio; user skills in `{portfolio}/skills/` override defaults.

| Skill | Purpose |
|-------|---------|
| `/analyze <ticker>` | Structured analysis: fundamentals, price action, news, risks, chart |
| `/crypto-analyze <symbol>` | Crypto analysis: price, funding rate, positioning, technicals, on-chain narrative, risks |
| `/funding-scan` | Scan funding rates across top perps — crowded positioning, basis trade candidates, market sentiment |
| `/basis-trade <symbol>` | Structure and execute a cash-and-carry: long spot + short perp, collect funding |
| `/backtest <file>` | Run backtest with verdict |
| `/red-team <file>` | Adversarial critique of a strategy |
| `/plan <task>` | Think through steps before executing |
| `/strategy-audit <file>` | Check for look-ahead bias, overfitting, survivorship |
| `/risk-check <file>` | Validate against portfolio risk limits |
| `/paper-deploy <file>` | Deploy strategy to Alpaca paper trading |
| `/post-mortem <name>` | Compare a deployed strategy's live performance against the backtest that justified it |
| `/scorecard` | Grade the prediction journal — hit rate, Brier score, calibration |
| `/weekly-review` | Portfolio performance review |
| `/investor-cycle` | The daily autonomous routine — safety check, review, grading, dossiers, reweighting, research, memo |

### Playbook contracts

A strategy skill can declare its hypothesis as YAML frontmatter — the contract is rendered into the prompt every time the playbook is invoked, and `playbook_dossier` ties its track record to it:

```markdown
---
name: btc-funding-harvest
domain: crypto_perps          # which risk budget it inherits
regime: positive funding, low realized volatility
falsification: 30-day funding collected minus costs goes negative
---
Playbook instructions...
```

---

## Writing strategies

Strategies are Python files with two supported interfaces:

### Weight-based (engine handles simulation)

```python
UNIVERSE = ["SPY", "QQQ", "GLD", "BIL"]
DESCRIPTION = "6-month momentum with cash filter"
CONFIG = {"normalize": True, "cost_bps": 5, "benchmark": "SPY"}

def generate_signals(prices, context=None):
    # prices: pd.DataFrame of daily close prices
    # return: pd.DataFrame of target weights
    momentum = prices.pct_change(126)
    ...
    return weights
```

### NAV-based (full control)

```python
def run(context):
    # Full control: fetch any data, model any logic
    # return: pd.Series of daily NAV starting at 1.0
    ...
    return nav
```

Run either with `/backtest strategies/draft/my_strategy.py` or ask the agent to write one for you.

---

## Configuration

### `config/policy.yaml`

```yaml
portfolio:
  objective: long_term_growth
  time_horizon_years: 5
  risk_profile: moderate
execution:
  default_mode: paper
  live_trading_enabled: false
requirements:
  backtest_before_paper: true
  risk_check_before_trade: true
  human_approval_for_live: true
```

### `config/universe.yaml`

```yaml
approved:
  etfs: [SPY, QQQ, VTI, GLD, BIL, TLT]
  equities: [AAPL, MSFT, NVDA, GOOGL]
forbidden: [TQQQ, SQQQ, UVXY]
```

### `config/risk.yaml`

```yaml
position_limits:
  max_single_position_pct: 40
  min_cash_pct: 5
drawdown_limits:
  hard_stop_pct: -20      # NAV kill-switch threshold — flatten + halt + notify
trading_limits:
  max_trade_notional_usd: 5000
  allow_short_selling: false
```

### `config/budgets.yaml`

Per-domain risk budgets — different walls for different risk physics, enforced mechanically on every order:

```yaml
domains:
  equities:
    max_pct_nav: 60              # gross equities exposure cap, % of NAV
    net_exposure_band: [0, 60]   # post-trade net exposure must stay in this band
  crypto_spot:
    max_pct_nav: 10
  crypto_perps:
    max_pct_nav: 5                    # gross perp notional cap, % of NAV
    max_leverage: 2
    min_liquidation_buffer_pct: 25    # required distance from mark to liquidation
```

**Configs are human-owned.** `init` stamps them with sha256 hashes; the risk gate verifies the stamp on every order. The agent cannot edit them, and if they drift by any other path, all order flow stops until you review and run `alo-invest config-approve`.

---

## Troubleshooting

### Alpaca DNS unreachable on macOS

If the investor cycle reports Alpaca as DNS-unreachable but `curl https://paper-api.alpaca.markets` succeeds, the issue is a stale mDNSResponder cache entry for the CNAME record. Python's `socket.getaddrinfo` hits it directly while system tools work around it.

Fix: flush the DNS cache and restart mDNSResponder.

```bash
sudo killall -HUP mDNSResponder
```

Verify with:

```bash
python3 -c "import socket; print(socket.getaddrinfo('paper-api.alpaca.markets', 443))"
```

Then run `uv run alo-invest doctor` to confirm Alpaca is green before restarting the cycle.

---

## What Alo Invest is not

- Not a live trading bot — autonomous operation is paper-only by construction; live orders require explicit `--mode live` and human approval per trade
- Not unsupervised — the autonomous cycle runs inside code-enforced walls (risk gate, domain budgets, NAV kill-switch) and reports to you daily
- Not a source of financial advice — treat all output as research, not recommendations
- Not guaranteed to beat the market — backtests don't predict future performance
