# IBKR-Claude Auto Trading Bot

## Project Overview
Paper-trading bot that uses IBKR (Interactive Brokers) via `ib_insync` and Claude (claude-sonnet-4-6) as a risk filter gate before placing trades.

## Directory Layout
```
/Users/rafalsoltysek/
├── bot.py                  # Main entry: connects IBKR, runs strategy, calls Claude, spawns trade.py
├── scanner.py              # Scans watchlist.txt, ranks by RVOL, runs bot.py on best setup
├── strategy.py             # Evaluates daily + intraday filters, returns pass/fail + reasons
├── claude_filter.py        # Calls Claude API to APPROVE/REJECT a trade setup
├── morning_prefilter.py    # Pre-market scan: filters S&P 500 for gap + price + volume
├── monitor.py              # Position monitor: manages stops, partial profits, breakeven, exits
├── closer.py               # Force-closes all open positions at EOD
├── trade.py                # Executes a single BUY or SELL order via IBKR
├── compute_perf.py         # Performance reporting from trades.csv
├── rotate_logs.py          # Log rotation utility
├── rules.json              # Strategy parameters (source of truth)
├── watchlist.txt           # Symbols to scan (one per line, auto-generated by morning_prefilter)
├── trades.csv              # Trade log
├── .env                    # Environment variables (not committed)
└── src/
    ├── ibkr_client.py      # IBKRClient wrapper (ib_insync)
    ├── notify.py           # Desktop notifications
    └── sp500_tickers.py    # S&P 500 ticker list
```

## Strategy: "Trend Join Long"
Defined in `rules.json`. Long-only, 5-minute timeframe.

**Daily filters:**
- D1: Price above prior day high
- D2: Prior close above SMA-200
- D3: Gap ≥ 3% from prior close

**Intraday filters:**
- I1: Above pre-market high
- I2: Above today's HOD
- I3: RVOL ≥ 2.0x (14-day lookback)

**Entry window:** 10:05–15:30 ET, force close at 15:51 ET

**Exit rules:**
- Stop: LOD − 1%
- Partial profit (1/3): at 0.75R
- Breakeven: at 1.0R
- Trail after breakeven: swing low 5m (2,2)

**Risk:**
- Max risk per trade: 1% of portfolio
- Max position size: 10% of portfolio
- Max concurrent positions: 5
- Max trades per day: 5 (env: MAX_TRADES_PER_DAY)

## Price Filter
Scanner currently accepts stocks priced **$1.00–$20.00** only.

## Environment Variables (.env)
- `ANTHROPIC_API_KEY` — Claude API key
- `PAPER_TRADING=true` — enables paper mode
- `IBKR_PORT=7497` — paper port (7496 = live)
- `IBKR_HOST=127.0.0.1`
- `IBKR_CLIENT_ID=2`
- `PORTFOLIO_VALUE_USD=25000`
- `MAX_TRADE_SIZE_USD=2500`
- `MAX_TRADES_PER_DAY=5`

## Typical Daily Workflow
1. Pre-market: `python morning_prefilter.py` → writes `watchlist.txt`
2. Market open: `python scanner.py` → picks best RVOL setup → runs `bot.py`
3. During day: `python monitor.py` → manages open positions
4. EOD: `python closer.py` → force-closes all positions
5. After close: `python compute_perf.py` → prints P&L report

## Key Design Decisions
- Claude is a **blocking gate**: trade does not execute if Claude rejects
- `bot.py --check-only` runs filters without trading
- `bot.py --claude-only` runs through Claude approval but skips order placement
- Paper vs live is enforced by port number check (hard abort on mismatch)
