# Stock-Only Best Ideas + IBKR Command Center

Monitor live signals for the **8-sleeve stock/ETF book** (tactical AW, CM dip, QS actionable-4, vol edge, MA slope, Johansen, TSMOM, SH hedge) against your **Interactive Brokers** account.

**UI:** `stock_command_center.html` (repo root)  
**Snapshot:** `RenTech/data/logs/stock_command_center_snapshot.json`  
**Live signals:** `RenTech/data/logs/live_stock_only_signals.json`

> **Recommend-only:** this stack does **not** place orders. It compares model targets to IB positions and lists ADD / REMOVE / HOLD actions for you to execute in TWS.

## Prerequisites

1. **TWS or IB Gateway** logged in (paper default port **7497**, live **7496**).
2. **API enabled** in TWS → Settings → API → Enable ActiveX and Socket Clients.
3. Python deps: `ib_insync` (already in `.venv`).
4. **Client ID 3** in `RenTech/live/config/live_stock_only.json` (VRP uses 1, legacy fund signals use 2).

## Daily workflow

```bash
cd /Users/robzingale/trading_bot

# 1) Pull IB account + compute all sleeve signals
PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.live.run_stock_only_signals --fund-scale 1.5

# 2) Merge into UI snapshot (reads live_stock_only_signals.json)
PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.monitor.build_stock_command_center_snapshot --live-signals

# 3) Serve dashboard
python -m http.server 8080
# → http://localhost:8080/stock_command_center.html
```

### One-shot refresh (signals + snapshot)

```bash
cd /Users/robzingale/trading_bot && PYTHONUNBUFFERED=1 \
  .venv/bin/python -m RenTech.live.run_stock_only_signals --fund-scale 1.5 && \
  PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.monitor.build_stock_command_center_snapshot --live-signals
```

### Offline (no TWS)

Yahoo-only signals; no IB position reconciliation:

```bash
PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.live.run_stock_only_signals --offline --fund-scale 1.5
PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.monitor.build_stock_command_center_snapshot --live-signals
```

## What each sleeve uses

| Sleeve | Live data | Signal source |
|--------|-----------|---------------|
| Tactical AW | IB daily bars | `TacticalAllWeatherManager` |
| Vol Edge | Yahoo VIX/VIX3M + SPY | `evrp_boc` rules → SVIX / VIXY |
| TSMOM | IB bars (8 ETFs) | 3/6/12m momentum weights |
| MA slope top-10 | Yahoo S&P 500 panel | `MaSlopeCrossSectional` rebalance log |
| MA inverse SH | IB SPY + SH | `MaSlopeInverseSleeve` regime |
| Johansen ETF | Yahoo triplet legs | Johansen eigenvector + z-score units |
| CM dip SP100 | Yahoo scan | Prior-session −3% candidates + limit prices |
| QS actionable-4 | IB/Yahoo SPY | Turnaround Tue, O/N 3-down, 1st-of-month, O/N 10d-low |

## Sizing

Sleeve budget = **fund_weight × fund_scale × IB net liquidation**.

Default weights match `FUND_WEIGHT_TABLE_STOCK_VOL_EDGE_MA_SLOPE` in `combine_best_ideas_stack.py` (same as your 1.5× presentation book).

## CM dip IBKR automation (recommend-only first)

Sized at **sleeve / 10** (~$1,275 on $50k × 1.5). Skips new DAY limits when ≥10 dips are open.

```bash
# Paper Gateway 7497, client_id 5 — tickets only
cd /Users/robzingale/trading_bot && PYTHONUNBUFFERED=1 .venv/bin/python \
  -m RenTech.live.run_stock_book_ibkr --recommend-only --force-entry-now

# After validating RenTech/data/logs/stock_book_cm_dip_recommendation.json:
# .venv/bin/python -m RenTech.live.run_stock_book_ibkr --live --force-entry-now
```

Config: `RenTech/live/config/live_stock_book_cm_dip.json` (`recommend_only: true`). Live port: set `broker.port` to **7496**.

## Shareable Today Trades (Stage A)

Read-only enter/exit page for a friend: see `RenTech/monitor/TODAY_TRADES.md`.

```bash
PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.monitor.build_today_trades_snapshot \
  --nav 50000 --fund-scale 1.5 --held AMZN,QCOM,AXP,...
TODAY_TRADES_PASSWORD='share-me' .venv/bin/python -m RenTech.monitor.serve_today_trades --host 0.0.0.0 --port 8765
# → http://YOUR_IP:8765/today_trades.html
```

## Safety

- **`RenTech/live/config/KILL_SWITCH`** — if this file exists, UI shows halt; do not add risk.
- **`recommend_only: true`** in config — no order transmission from this module.
- MA slope top-N and dip scans use **Yahoo** (slow on first run); IB used for account + core ETFs.

## Backtest reference

Snapshot loads combined fund CSV from the latest stock-only run (default prefix `stock_only_ma_slope_fund15_2011_*`). Regenerate after combine:

```bash
cd /Users/robzingale/trading_bot && PYTHONUNBUFFERED=1 \
  .venv/bin/python RenTech/strategy_stack/combine_best_ideas_stack.py \
  --stock-only --fund-scale 1.5 \
  --start 2011-01-03 --end 2026-06-18 --capital 100000 \
  --out-prefix RenTech/data/logs/stock_only_ma_slope_fund15_2011
```

Then rebuild snapshot with `--fund-daily` if your CSV path differs.
