# CV6 AI Trading OS — Architecture Gap Report
**Date:** 2026-07-01  
**Spec:** Architecture Freeze V2  
**Reviewer:** Claude (AI Agent)  
**Status:** REVIEW — awaiting approval before any implementation

---

## Legend
| Symbol | Meaning |
|--------|---------|
| ✅ EXISTS | Fully implemented and wired |
| 🟡 PARTIAL | Exists but incomplete or not fully wired |
| ❌ MISSING | Not implemented at all |
| 🔴 CONFLICT | Duplicate or contradicting logic found |

---

## 1. User Configuration Layer

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| Total capital input | ✅ EXISTS | `autonomous_config.py` → `total_capital` | |
| Capital % per style (INTRADAY/SWING/FNO/SCALPING/LONG_TERM) | ✅ EXISTS | `autonomous_config.py` → `capital_allocation` | |
| Per-style broker assignment | ✅ EXISTS | `autonomous_config.py` → `broker_allocation` | |
| Risk limits (daily/weekly/monthly loss) | ✅ EXISTS | `autonomous_config.py` + `risk_guard.py` | |
| Max drawdown % | ✅ EXISTS | `autonomous_config.py` → `max_drawdown_pct` | |
| Trading time window (start/end) | ✅ EXISTS | `autonomous_config.py` → `trading_start/end` | |
| AI model selection + mode | ✅ EXISTS | `autonomous_config.py` → `enabled_ai_models`, `ai_mode` | |
| Kill switch toggle | ✅ EXISTS | `risk_guard.py` + exposed in `/autonomous/config` | |
| Paper / Real mode toggle | ✅ EXISTS | `autonomous_config.py` → `mode` | |
| F&O enabled toggle | ✅ EXISTS | `autonomous_config.py` → `fno_enabled` | |
| F&O moneyness + option type | ✅ EXISTS | `autonomous_config.py` → `fno_moneyness`, `fno_option_type` | |
| Auto square-off time (configurable) | 🟡 PARTIAL | Uses `trading_end` - 5 min; no dedicated UI input for sq-off time | Spec wants separate square-off time |
| Scan interval | ✅ EXISTS | `autonomous_config.py` → `scan_interval_seconds` | |

---

## 2. Capital Allocation Layer

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| Independent capital pool per style | ✅ EXISTS | `capital_pool.py` → `CapitalPool` | |
| No cross-pool borrowing | ✅ EXISTS | Each `CapitalPool.available_capital` is independent | |
| Per-pool P&L tracking | ✅ EXISTS | `CapitalPool.realized_pnl`, `unrealized_pnl` | |
| Per-pool daily loss tracking | ✅ EXISTS | `CapitalPool.daily_loss` | |
| Per-pool trade count | ✅ EXISTS | `CapitalPool.daily_trades` | |
| `CapitalPoolManager` summary endpoint | ✅ EXISTS | `/autonomous/pools` | |

---

## 3. Multi-Broker Allocation

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| Per-style broker routing | ✅ EXISTS | `broker_allocator.py` → `BrokerAllocator.get_broker()` | |
| Failover to next available broker | ✅ EXISTS | `BrokerAllocator.mark_failed()` + `_FALLBACK_ORDER` | |
| Product type per style (INTRADAY/DELIVERY/CARRYFORWARD) | ✅ EXISTS | `BrokerAllocator.get_product_type()` | |
| Broker adapters: Angel One | ✅ EXISTS | `broker/angel_one.py` | |
| Broker adapters: AliceBlue | ✅ EXISTS | `broker/aliceblue.py` | |
| Broker adapters: Upstox | ✅ EXISTS | `broker/upstox.py` | |
| Broker adapters: Zerodha | ✅ EXISTS | `broker/zerodha.py` | |
| Broker adapters: Dhan | ✅ EXISTS | `broker/dhan.py` | |
| Broker adapters: Shoonya, Fyers, MStock | ✅ EXISTS | `broker/shoonya.py`, `fyers.py`, `mstock.py` | |
| Broker factory pattern | ✅ EXISTS | `broker/broker_factory.py` + `broker_manager.py` | |
| Real order execution via broker APIs | 🟡 PARTIAL | Broker adapter files exist but autonomous engine uses `mode=PAPER` by default; real execution path exists but not tested |

---

## 4. Three Independent Trading Engines

### 4a. Intraday Engine

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| **Separate Intraday Engine module** | ❌ MISSING | Currently handled as `style="INTRADAY"` inside monolithic `autonomous_engine.py` | Spec requires independent module |
| Auto square-off at configurable time | 🟡 PARTIAL | `position_monitor.py` → `_is_eod()` triggers 5 min before `trading_end` | Hard-coded 5-min window; spec wants configurable sq-off time e.g. "3:10 PM" |
| Intraday strategies (VWAP, EMA, Supertrend) | 🟡 PARTIAL | `smart_scanner.py` Stage 3 scores using these signals, but no separate intraday strategy module | |
| No re-entry after SL within same day | ❌ MISSING | No re-entry prevention logic exists | |
| Intraday-specific position sizing | ✅ EXISTS | `BrokerAllocator.calculate_position_size()` + `rr_map["INTRADAY"]` | |
| INTRADAY product type | ✅ EXISTS | `BrokerAllocator.get_product_type("INTRADAY")` → "INTRADAY" | |

### 4b. Swing Engine

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| **Separate Swing Engine module** | ❌ MISSING | Currently handled as `style="SWING"` inside `autonomous_engine.py` | Spec requires independent module |
| Exit on target hit | ✅ EXISTS | `position_monitor.py` → `TARGET_HIT` | |
| Exit on stop loss hit | ✅ EXISTS | `position_monitor.py` → `STOPPED_OUT` | |
| Exit on AI signal reversal | ❌ MISSING | No re-analysis of open swing positions by AI | |
| Exit on trend change (EMA cross / Supertrend flip) | ❌ MISSING | No indicator re-check on existing swing positions | |
| NOT time-based exit (no EOD for swing) | ✅ EXISTS | `position_monitor.py` only EOD-closes `INTRADAY` and `SCALPING` styles | |
| Swing product type (CARRYFORWARD) | ✅ EXISTS | `BrokerAllocator.get_product_type("SWING")` → "CARRYFORWARD" | |
| Multi-day hold with carry-forward | ✅ EXISTS | Capital pool tracks position; no EOD close for SWING | |
| Weekly profit booking | ❌ MISSING | No weekly profit-taking logic | |

### 4c. F&O Engine

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| **F&O Engine module** | 🟡 PARTIAL | `fno_engine.py` exists with BSM + Greeks + chain analysis | NOT integrated into autonomous trading loop |
| Independent F&O scanner | ❌ MISSING | FnoEngine does chain analysis on demand; no autonomous scanning of F&O opportunities | |
| Option chain with OI/PCR/MaxPain | ✅ EXISTS | `fno_engine.py` → `get_option_chain()`, `calc_pcr()`, `calc_max_pain()` | Uses BSM simulation, not live broker data |
| Strike selection (ATM/ITM/OTM/delta) | ✅ EXISTS | `fno_engine.py` → `select_strike()` | |
| Greeks (delta/gamma/theta/vega/rho) | ✅ EXISTS | `fno_engine.py` → `BSM.greeks()` | |
| Lot size calculation | ✅ EXISTS | `fno_engine.py` → `LOT_SIZES` dict (30+ symbols) | |
| Margin calculation | ✅ EXISTS | `fno_engine.py` → `calc_margin()` | |
| OI analysis (resistance/support levels) | ✅ EXISTS | `fno_engine.py` → `oi_analysis()` | |
| F&O auto-trade integration in autonomous engine | ❌ MISSING | `autonomous_engine._phase_execute()` does NOT call FnoEngine when `fno_enabled=True` | |
| Real option chain from broker API | ❌ MISSING | `fno_engine._build_chain()` uses BSM simulation, not live data | |

---

## 5. Common Services

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| Market Scanner — NSE 500+ universe | ✅ EXISTS | `smart_scanner.py` → `NSE_UNIVERSE` (~500 symbols) | |
| Market Scanner — BSE universe | ❌ MISSING | No BSE symbols in scanner | |
| Market Scanner — F&O symbols | 🟡 PARTIAL | `fno_engine.py` → `LOT_SIZES` has 30+ F&O symbols; not used in scanner | |
| Real-time prices from broker | 🟡 PARTIAL | Angel One WebSocket exists (`websocket/market_stream.py`); scanner uses **simulated/random prices** | Critical gap |
| Volume filter, circuit filter, volatility filter | ✅ EXISTS | `smart_scanner.py` Stage 1–4 + `risk_guard.py` | |
| Sector assignment per symbol | 🟡 PARTIAL | `market_scanner.py` → `ScanResult.sector = "Other"` (not populated with real sector) | |

---

## 6. AI Cost Optimization

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| 5-stage funnel (500→200→20→5→3) | ✅ EXISTS | `smart_scanner.py` → `SmartScanner.scan()` | |
| Stage 1: Volume/price pre-filter | ✅ EXISTS | `SmartScanner._stage1_prefilter()` | |
| Stage 2: Technical (EMA/RSI/MACD) | ✅ EXISTS | `SmartScanner._stage2_technical()` | |
| Stage 3: Quality (Supertrend/VWAP/Breakout) | ✅ EXISTS | `SmartScanner._stage3_quality()` | |
| Stage 4: Risk filter (circuit/volatility/sector) | ✅ EXISTS | `SmartScanner._stage4_risk()` | |
| Stage 5: AI only for top 3-5 | ✅ EXISTS | `autonomous_engine._phase_analyze()` | |
| AI Cache with TTL | ✅ EXISTS | `ai_cache.py` → `AICache` with configurable TTL | |
| AI cost per call tracking | ❌ MISSING | No token/cost tracking for AI calls | |
| AI model failover | ✅ EXISTS | `ai_consensus.py` handles unavailable models | |

---

## 7. Risk Engine

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| Kill switch (hard stop all trading) | ✅ EXISTS | `risk_guard.py` → `activate_kill_switch()` | |
| Daily loss limit | ✅ EXISTS | `risk_guard.py` → `_check_loss_limits()` + `LossTracker` | |
| Weekly loss limit | ✅ EXISTS | `risk_guard.py` → weekly tracking in `LossTracker` | |
| Monthly loss limit | ✅ EXISTS | `risk_guard.py` → monthly tracking in `LossTracker` | |
| Max drawdown % | ✅ EXISTS | `risk_guard.py` → `DrawdownTracker` | |
| Market hours check | ✅ EXISTS | `risk_guard.py` → `_check_market_hours()` | |
| Circuit filter (% move block) | ✅ EXISTS | `risk_guard.py` → `_check_circuit()` | |
| VIX threshold block | ✅ EXISTS | `risk_guard.py` → `_check_volatility()` | |
| News sentiment block | ✅ EXISTS | `risk_guard.py` → `_check_news()` | |
| Sector concentration limit | ✅ EXISTS | `risk_guard.py` → `_check_sector_exposure()` | |
| Position sizing | ✅ EXISTS | `broker_allocator.py` → `calculate_position_size()` | |
| Per-trade risk % | ✅ EXISTS | `autonomous_config.py` → `risk_pct` | |
| Post-trade P&L update to risk guard | ✅ EXISTS | `autonomous_engine._phase_monitor()` → `risk_guard.on_trade_closed()` | |

---

## 8. Order Flow

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| Entry → Risk Check → Broker API → Position | 🟡 PARTIAL | `autonomous_engine._phase_execute()` checks `risk_guard.check_entry()` then calls broker | |
| Broker order placement (PAPER mode) | ✅ EXISTS | `autonomous_engine._phase_execute()` with `mode=PAPER` simulated | |
| Broker order placement (REAL mode) | 🟡 PARTIAL | REAL mode path exists but relies on `broker_manager`; not end-to-end tested | |
| Order status polling after placement | ❌ MISSING | No order status check after initial placement; no rejection handling | |
| Partial fill handling | ❌ MISSING | No partial fill logic | |
| Order rejection handling | ❌ MISSING | No retry or fallback on order rejection | |

---

## 9. Position Management

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| Per-pool open position tracking | ✅ EXISTS | `capital_pool.py` → `CapitalPool.positions` | |
| LTP updates per cycle | 🟡 PARTIAL | `position_monitor.monitor_pool()` called each cycle; uses `price_map` from simulated scanner | Real LTP feed not wired to monitor |
| Trailing stop loss | ✅ EXISTS | `position_monitor.py` → `TRAIL_PCT = 0.005` | |
| SL exit | ✅ EXISTS | `position_monitor.py` → `STOPPED_OUT` | |
| Target exit | ✅ EXISTS | `position_monitor.py` → `TARGET_HIT` | |
| EOD square-off (INTRADAY + SCALPING) | ✅ EXISTS | `position_monitor.py` → `_is_eod()` | |
| Swing carry-forward (NO EOD close) | ✅ EXISTS | SWING/FNO/LONG_TERM not in `intraday_styles` set | |
| Swing exit on AI re-analysis | ❌ MISSING | Open swing positions are not re-analyzed by AI | |
| Swing exit on trend reversal signal | ❌ MISSING | No indicator re-check on open swing positions | |

---

## 10. Trade Journal & Learning Engine

| Requirement | Status | Location | Notes |
|-------------|--------|----------|-------|
| TradeRecord model (30+ columns) | ✅ EXISTS | `learning_models.py` | |
| Record trade on close | ✅ EXISTS | `autonomous_engine._phase_monitor()` → `learning_service.record_trade()` | |
| Strategy performance stats | ✅ EXISTS | `learning_service.py` → `get_strategy_stats()` | |
| Style performance stats | ✅ EXISTS | `learning_service.py` → `get_style_stats()` | |
| AI accuracy tracking | ✅ EXISTS | `learning_service.py` → `get_ai_accuracy()` | |
| Time-of-day analysis | ✅ EXISTS | `learning_service.py` → `get_time_analysis()` | |
| Sector analysis | ✅ EXISTS | `learning_service.py` → `get_sector_stats()` | |
| Monthly series | ✅ EXISTS | `learning_service.py` → `get_monthly_series()` | |
| Auto-improvement suggestions | ✅ EXISTS | `learning_service.py` → `get_suggestions()` | |
| Auto-apply suggestions | ❌ MISSING | `auto_apply_suggestions` flag exists in config but logic NOT implemented | |
| LearningPage UI | ✅ EXISTS | `frontend/src/pages/LearningPage.tsx` | |

---

## 11. CONFLICTS (Must Fix Before Implementation)

### 🔴 CONFLICT #1: Dual `/risk` Router Prefix
**Problem:** Two separate routers both use `prefix="/risk"`:
- `app/risk/risk_router.py` (old) — registered in `main.py` line 174
- `app/risk_guard/risk_router.py` (new) — registered in `main.py` line 224

**Effect:** FastAPI silently stacks both routers. `GET /risk/calculate` goes to old risk engine; `GET /risk/status` goes to new risk guard. No hard crash, but the frontend `RiskManagerPage.tsx` may be calling old endpoints. Endpoints may shadow each other.

**Resolution:** Rename old router prefix to `/risk/legacy` or `/risk/position-sizing`; keep `/risk` for the new `risk_guard_router` only.

---

### 🔴 CONFLICT #2: Monolithic Engine vs. Spec's 3 Independent Engines
**Problem:** Spec requires 3 independent engines (Intraday, Swing, F&O). Currently `autonomous_engine.py` handles ALL styles in one cycle with a `style` flag. There is no per-style engine with per-style exit logic.

**Effect:**
- Swing exits only on SL/target, not on trend change or AI reversal
- F&O trading is not actually connected to the autonomous cycle even when `fno_enabled=True`
- Intraday and Swing share the same SCAN→RANK→ANALYZE→EXECUTE→MONITOR cycle with no differentiation

**Resolution:** Add `IntradayEngine`, `SwingEngine`, `FnoEngine`-as-trader as sub-orchestrators called by the master engine, each with its own exit policy.

---

### 🔴 CONFLICT #3: Simulated Prices in Scanner
**Problem:** `SmartScanner._get_universe_data()` and `MarketScanner._fetch_market_data()` generate **random/simulated LTPs** in production. This means:
- Stage 1-4 filtering uses fake price data
- Position monitor gets fake LTPs
- P&L is entirely simulated regardless of `mode=REAL`

**Effect:** Setting `mode=REAL` will place real orders at brokers but use fake prices for decision-making.

**Resolution:** Wire `smart_scanner.py` Stage 1 to Angel One's market data API (WebSocket ticks or REST snapshot) before enabling `mode=REAL`.

---

### 🔴 CONFLICT #4: Old `app/strategy/strategy_engine.py` Not Used
**Problem:** `strategy_engine.py` contains a basic score-based strategy engine. It is not called by `autonomous_engine.py` (which uses `smart_scanner.py` instead). But it is still registered via `strategy_router.py`.

**Effect:** Dead code. The `/strategy/analyze` endpoint still exists and returns results, but they are not used in any trading decision.

**Resolution:** Either retire `strategy_engine.py` or wire it as a fallback when SmartScanner is disabled.

---

## 12. Summary Matrix

| Component | Spec Requirement | Current Status |
|-----------|-----------------|----------------|
| Capital Pools | Independent per style | ✅ EXISTS |
| Multi-broker routing | Per style, with failover | ✅ EXISTS |
| Intraday Engine | Independent module, sq-off, no re-entry | 🟡 PARTIAL — no module, no re-entry |
| Swing Engine | Independent module, trend exit, AI exit | ❌ MISSING — no swing-specific exit logic |
| F&O Engine | BSM + chain + autonomous scanner | 🟡 PARTIAL — chain analysis works; no auto-trade |
| Market Scanner | Full NSE+BSE with real prices | 🟡 PARTIAL — NSE only, simulated prices |
| 5-Stage AI Funnel | Smart cost control | ✅ EXISTS |
| AI Cache | TTL-based cache | ✅ EXISTS |
| AI Consensus | Multi-model with failover | ✅ EXISTS |
| Risk Guard | Kill switch + 8-layer checks | ✅ EXISTS |
| `/risk` Router | Single unified risk endpoint | 🔴 CONFLICT — two routers on same prefix |
| Order Flow | Entry→Risk→Broker→Track | 🟡 PARTIAL — no order status polling |
| Position Monitor | SL/Target/Trail/EOD | ✅ EXISTS (INTRADAY) / 🟡 PARTIAL (Swing) |
| Trade Journal | Full record on close | ✅ EXISTS |
| Learning Engine | Stats + suggestions | ✅ EXISTS |
| Auto-apply Suggestions | Apply suggestions automatically | ❌ MISSING |
| Real LTP Feed to Engine | Live prices for decisions | ❌ MISSING |
| BSE Universe | BSE symbol scanning | ❌ MISSING |
| AI Cost Tracking | Token/cost per call | ❌ MISSING |
| Swing AI Re-exit | Re-analyze open swing on each cycle | ❌ MISSING |
| No Re-entry Logic | Block re-entry after same-day SL | ❌ MISSING |

---

## 13. Recommended Implementation Order (Post-Approval)

**Priority 1 — Critical Fixes (Conflicts must be resolved first):**
1. Fix `/risk` router conflict — rename old prefix
2. Wire real LTP feed to SmartScanner (Angel One WebSocket ticks)
3. Integrate FnoEngine into `autonomous_engine._phase_execute` when `fno_enabled=True`

**Priority 2 — Spec Gaps (Core engine completeness):**
4. Add `IntradayEngine` subclass/module with configurable sq-off time and no-re-entry logic
5. Add `SwingEngine` subclass/module with AI re-exit + trend change exit
6. Add F&O autonomous scanner (scan FnoEngine chain on F&O symbols, pick best opportunity)

**Priority 3 — Nice-to-have:**
7. Sector data for ScanResult symbols (map symbol → sector)
8. Order status polling after placement
9. Auto-apply learning suggestions
10. BSE universe support
11. AI cost/token tracking

---

*Report generated from live code inspection of D:\CV6_AI_Trading_OS — no estimated or fabricated data.*
