# Intraday MA-Slope confirm_entry_4b — IBKR Paper / Live

Automated **same-day** top-10 rotation with **confirm_entry_4b** (rank at ~10:25, re-confirm at ~10:45, hold to **MOC**).

**Default:** recommend-only (writes order tickets; you review before enabling auto-trade).

## Prerequisites

1. **TWS or IB Gateway** logged into **paper** (port **7497**) or live (**7496**).
2. TWS → **Settings → API → Enable ActiveX and Socket Clients** (allow `127.0.0.1`).
3. **Market data:** delayed frozen (`market_data_type: 3`) works for signals; live/paper fills use IB.
4. Python: `ib_insync` in `.venv` (`pip install ib_insync`).
5. **Client ID 4** in `RenTech/live/config/live_ma_slope_intraday.json`  
   (VRP=1, fund platform=2, stock-only signals=3).

## Signal data

| `data_source` | Use when |
|---------------|----------|
| `alpaca_parquet` (default) | Local `SP500_1Min_Parquet_RTH_FULL` — **matches backtest** |
| `ibkr` | Fetch 5m bars from IB (slow for 500 names; pacing) |

## Phase 1 — Recommend only (start here)

```bash
cd /Users/robzingale/trading_bot

# One-shot (run during entry window ~10:40–11:05 ET)
PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.live.run_ma_slope_intraday_ibkr --recommend-only

# RTH loop (60s) — entry + MOC exit windows
PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.live.run_ma_slope_intraday_ibkr --loop --recommend-only
```

**Output:** `RenTech/data/logs/ma_slope_intraday_ibkr_recommendation.json`  
Lists target weights + proposed BUY (entry) or MOC SELL (exit) tickets.

### Smoke test (any time)

```bash
PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.live.run_ma_slope_intraday_ibkr \
  --recommend-only --force
```

## Phase 2 — Paper auto-trade

After recommendations look sane for several sessions:

```bash
# Paper TWS on 7497 — places real paper orders
PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.live.run_ma_slope_intraday_ibkr --loop --live
```

Or via platform orchestrator:

```bash
PYTHONUNBUFFERED=1 .venv/bin/python RenTech/live/run_live_platform.py \
  --config RenTech/live/config/live_ma_slope_intraday.json \
  --strategy ma_slope_intraday --live
```

## Schedule (Eastern)

| Window | Action |
|--------|--------|
| **10:40–11:05** | Compute confirm_entry_4b → **BUY** top-10 (equal weight) |
| **15:55–16:00** | **MOC SELL** all sleeve stocks (flat, no overnight) |

Cron example (loop is simpler; shown for reference):

```cron
40 10 * * 1-5 cd /Users/robzingale/trading_bot && .venv/bin/python -m RenTech.live.run_ma_slope_intraday_ibkr --recommend-only
55 15 * * 1-5 cd /Users/robzingale/trading_bot && .venv/bin/python -m RenTech.live.run_ma_slope_intraday_ibkr --recommend-only
```

## Sizing

- **Capital budget** = `capital_budget_nav_pct` × IB **Net Liquidation** (default **10%**).
- Each name gets `weight × budget` → rounded **share count** via last IB price.
- Does not use margin leverage beyond what IB allows on market orders.

## Safety

| Control | Location |
|---------|----------|
| Kill switch | `RenTech/live/config/KILL_SWITCH` (content `HALT`) |
| Recommend-only default | `risk.recommend_only: true` in config JSON |
| Pending-order block | `block_if_pending_orders: true` |
| Daily loss cap | `max_daily_loss_pct_nav: 0.02` |
| One entry / day | State file `RenTech/data/live_state/ma_slope_intraday.json` |

## Config knobs (`live_ma_slope_intraday.json`)

```json
"top_n": 10,
"max_tickers": 500,
"data_source": "alpaca_parquet",
"capital_budget_nav_pct": 0.10,
"entry_after_et": "10:40",
"entry_before_et": "11:05",
"exit_after_et": "15:55",
"exit_before_et": "16:00"
```

## Live vs backtest gaps

- **Fills:** market orders + MOC vs backtest close-to-close returns.
- **Slippage:** not modeled in live path; backtest `slippage_bps` is separate.
- **Universe:** same alphabetical ~500; IB may reject some symbols.
- **Data lag:** Alpaca parquet must include **today** for intraday signals (run download script if stale).

## Refresh Alpaca data (optional, before open)

```bash
cd /Users/robzingale/trading_bot && PYTHONUNBUFFERED=1 .venv/bin/python \
  RenTech/data_pipeline/download_alpaca_rth_minutes.py \
  --start 2025-01-02 --end today --workers 2 --resume
```

## Troubleshooting

| Issue | Fix |
|-------|-----|
| `Connection refused` | TWS running? Port 7497 paper / 7496 live? |
| `clientId already in use` | Change `client_id` in JSON |
| `waiting_confirm` | Run after ~10:45 ET (bar 14 on 5m grid) |
| `flat_signal` | No names passed confirm filter today |
| Stale signals | Extend Alpaca parquets through today |

DISCLAIMER: Prototype for paper testing. Validate fills, PDT rules, and buying power before live capital.
