---
id: "US-ML-027"
title: "HISTORIA DE USUARIO"
type: "User Story"
status: "Done"
priority: "Media"
epic: "OQI-006"
project: "trading-platform"
story_points: 3
created_date: "2025-12-05"
updated_date: "2026-01-04"
---

# HISTORIA DE USUARIO

**Version:** 1.0.0
**Fecha:** 2025-12-05
**Uso:** Definicion de historia de usuario

---

## US-ML-027: Integracion ICT/SMC para Killzones y OTE

### Metadata

| Campo | Valor |
|-------|-------|
| **ID** | US-ML-027 |
| **Epica** | OQI-006A - Estrategia AMD y Modelos ML Avanzados |
| **Modulo** | ml-signals |
| **Prioridad** | P1 |
| **Story Points** | 13 |
| **Sprint** | Sprint 10 |
| **Estado** | Ready |
| **Asignado a** | ML-Engineer / Frontend-Developer |

---

### Historia de Usuario

**Como** trader que sigue conceptos ICT (Inner Circle Trader) y Smart Money,
**quiero** ver Killzones, zonas OTE (Optimal Trade Entry), y estructura de mercado (BOS/CHOCH) en el chart,
**para** identificar momentos optimos de entrada basados en timing de sesion y niveles de Fibonacci institucionales.

### Descripcion Detallada

**ICT Concepts Implementados:**

1. **Killzones (Sesiones de Alta Volatilidad):**
   - London Killzone: 02:00 - 05:00 EST (mayor movimiento forex)
   - New York Killzone: 08:30 - 11:00 EST (mayor volatilidad)
   - Asian Session: 19:00 - 02:00 EST (consolidacion, setups)
   - London Close: 11:00 - 14:00 EST (reversion)

2. **OTE Zones (Optimal Trade Entry):**
   - Fibonacci levels 61.8% - 79% del swing reciente
   - Premium Zone (>50%): Mejor para shorts
   - Discount Zone (<50%): Mejor para longs
   - Equilibrium (50%): Punto de decision

3. **Market Structure (SMC):**
   - BOS (Break of Structure): Confirmacion de tendencia
   - CHOCH (Change of Character): Posible reversion
   - Higher Highs/Lows: Tendencia alcista
   - Lower Highs/Lows: Tendencia bajista

### Mockups/Wireframes

```
+----------------------------------------------------------+
|                    TRADING CHART                          |
+----------------------------------------------------------+
|  SESSION: [London KZ] Active | NY in 3h 15m              |
|  +-------------------------------------------------------+
|  |                                                       |
|  |  PREMIUM ZONE (Sell Area)                             |
|  |  ================================================ 79% |
|  |  ------------------------------------------------ 70.5%
|  |  ================================================ 62% |
|  |  OTE ZONE (Optimal Entry)                             |
|  |                                                       |
|  |        /\   [BOS]                                     |
|  |       /  \    /\                                      |
|  |      /    \  /  \  <-- Current                        |
|  |     /      \/    \                                    |
|  |    /   [CHOCH]    \                                   |
|  |   /                 \_____                            |
|  |                                                       |
|  |  ================================================ 50% |
|  |  EQUILIBRIUM                                          |
|  |                                                       |
|  |  DISCOUNT ZONE (Buy Area)                             |
|  |  ================================================ 38% |
|  |  ------------------------------------------------ 23.6%
|  |  ================================================ 0%  |
|  +-------------------------------------------------------+
|                                                          |
|  [x] Show OTE  [x] Show Killzones  [x] Show BOS/CHOCH   |
+----------------------------------------------------------+
```

---

### Criterios de Aceptacion

**Escenario 1: Visualizacion de Killzones**
```gherkin
DADO que estoy viendo el chart
CUANDO la hora actual esta dentro de una Killzone
ENTONCES veo un indicador de sesion activa en el header
Y el fondo del chart tiene un color sutil distintivo
Y veo el tiempo restante de la Killzone
```

**Escenario 2: Visualizacion de zonas OTE**
```gherkin
DADO que hay un swing reciente identificable
CUANDO activo el indicador OTE
ENTONCES veo lineas horizontales en niveles Fibonacci (23.6%, 38.2%, 50%, 61.8%, 70.5%, 79%)
Y la zona 61.8%-79% esta sombreada como "OTE Zone"
Y veo labels de "Premium" (>50%) y "Discount" (<50%)
```

**Escenario 3: Deteccion de BOS**
```gherkin
DADO que hay una estructura de mercado definida
CUANDO el precio rompe un high/low estructural
ENTONCES se marca el punto de BOS con un icono y label
Y se dibuja una linea desde el swing roto
Y el color indica la direccion (verde=bullish, rojo=bearish)
```

**Escenario 4: Deteccion de CHOCH**
```gherkin
DADO que hay una tendencia establecida
CUANDO el precio hace un cambio de caracter (rompe tendencia)
ENTONCES se marca el punto de CHOCH con icono distintivo
Y se muestra alerta "Posible Reversion"
Y se actualiza la estructura de mercado
```

**Escenario 5: Countdown de Killzone**
```gherkin
DADO que no estoy en una Killzone
CUANDO veo el indicador de sesion
ENTONCES veo "Proxima: London KZ en 2h 30m"
Y el countdown se actualiza cada minuto
```

**Escenario 6: Configuracion de timezone**
```gherkin
DADO que estoy en una zona horaria diferente a EST
CUANDO configuro mi timezone local
ENTONCES las Killzones se muestran en mi hora local
Y los tiempos estan correctamente convertidos
```

### Criterios Adicionales

- [ ] Toggle individual para cada indicador (OTE, KZ, BOS/CHOCH)
- [ ] Colores personalizables para cada elemento
- [ ] Historial de BOS/CHOCH de ultimas 24h
- [ ] Alertas cuando precio entra en OTE zone durante Killzone
- [ ] Compatible con multiples timeframes

---

### Tareas Tecnicas

**Backend (FastAPI):**
- [ ] BE-ML-060: Endpoint GET /api/ml/ict/killzones/current
- [ ] BE-ML-061: Endpoint GET /api/ml/ict/ote/levels
- [ ] BE-ML-062: Endpoint GET /api/ml/smc/structure
- [ ] BE-ML-063: WebSocket para BOS/CHOCH en real-time

**ML/Feature Engineering:**
- [ ] ML-060: Implementar KillzoneDetector
- [ ] ML-061: Implementar OTECalculator (Fibonacci levels)
- [ ] ML-062: Implementar StructureAnalyzer (BOS/CHOCH)
- [ ] ML-063: Features ICT/SMC para modelos (15 features)

**Frontend:**
- [ ] FE-ML-060: Componente KillzoneIndicator
- [ ] FE-ML-061: Componente OTEZonesOverlay
- [ ] FE-ML-062: Componente StructureMarkers (BOS/CHOCH)
- [ ] FE-ML-063: Componente SessionCountdown
- [ ] FE-ML-064: Store ictStore (Zustand)
- [ ] FE-ML-065: Integracion con TradingView chart

**Tests:**
- [ ] TEST-ML-060: Unit tests KillzoneDetector
- [ ] TEST-ML-061: Unit tests OTECalculator
- [ ] TEST-ML-062: Unit tests StructureAnalyzer
- [ ] TEST-ML-063: E2E tests visualizacion

---

### Dependencias

**Depende de:**
- [ ] OQI-003: Trading Charts basico - Estado: In Progress
- [ ] Swing High/Low detection implementado - Estado: Done

**Bloquea:**
- [ ] US-ML-024: Score de confluencia (factor ICT/SMC)

---

### Notas Tecnicas

**Endpoints involucrados:**
| Metodo | Endpoint | Descripcion |
|--------|----------|-------------|
| GET | /api/ml/ict/killzones/current | Killzone actual |
| GET | /api/ml/ict/ote/levels | Niveles Fibonacci OTE |
| GET | /api/ml/smc/structure | Estructura de mercado |
| WS | /ws/ml/ict | Stream de actualizaciones |

**Componentes UI:**
- `KillzoneIndicator`: Indicador de sesion en header
- `OTEZonesOverlay`: Overlay de zonas Fibonacci
- `StructureMarkers`: Marcadores BOS/CHOCH en chart
- `SessionCountdown`: Countdown a proxima Killzone

**Response Schemas:**

```typescript
// Killzones
interface KillzoneStatus {
  current_session: 'london' | 'new_york' | 'asian' | 'london_close' | null;
  is_active: boolean;
  time_remaining_seconds: number | null;
  next_session: {
    name: string;
    starts_in_seconds: number;
  };
  session_strength: number;  // 0-1 (volatilidad historica)
}

// OTE Levels
interface OTELevels {
  swing_high: number;
  swing_low: number;
  swing_direction: 'bullish' | 'bearish';
  levels: {
    fib_0: number;      // 0%
    fib_236: number;    // 23.6%
    fib_382: number;    // 38.2%
    fib_50: number;     // 50% (Equilibrium)
    fib_618: number;    // 61.8%
    fib_705: number;    // 70.5%
    fib_79: number;     // 79%
    fib_100: number;    // 100%
  };
  ote_zone: {
    low: number;        // 61.8%
    high: number;       // 79%
  };
  current_price_position: 'premium' | 'discount' | 'equilibrium' | 'ote';
}

// Market Structure
interface MarketStructure {
  trend: 'bullish' | 'bearish' | 'ranging';
  recent_swings: SwingPoint[];
  bos_events: StructureBreak[];
  choch_events: StructureBreak[];
  current_range: {
    high: number;
    low: number;
  };
}

interface SwingPoint {
  type: 'high' | 'low';
  price: number;
  timestamp: string;
  index: number;
}

interface StructureBreak {
  type: 'bos' | 'choch';
  direction: 'bullish' | 'bearish';
  price: number;
  timestamp: string;
  broken_level: number;
  significance: 'minor' | 'major';
}
```

**Killzone Schedule (EST):**
```python
KILLZONES = {
    'asian': {
        'start': '19:00',
        'end': '02:00',
        'description': 'Asian Session - Consolidation',
        'typical_behavior': 'ranging'
    },
    'london': {
        'start': '02:00',
        'end': '05:00',
        'description': 'London Killzone - High Volatility',
        'typical_behavior': 'breakout'
    },
    'new_york': {
        'start': '08:30',
        'end': '11:00',
        'description': 'NY Killzone - Highest Volatility',
        'typical_behavior': 'continuation_or_reversal'
    },
    'london_close': {
        'start': '11:00',
        'end': '14:00',
        'description': 'London Close - Reversion',
        'typical_behavior': 'mean_reversion'
    }
}
```

**OTE Calculation:**
```python
class OTECalculator:
    FIB_LEVELS = [0, 0.236, 0.382, 0.5, 0.618, 0.705, 0.79, 1.0]

    def calculate_levels(self, swing_high: float, swing_low: float) -> OTELevels:
        range_size = swing_high - swing_low

        levels = {}
        for level in self.FIB_LEVELS:
            # Para retracement: desde high hacia low
            levels[f'fib_{int(level*1000)}'] = swing_high - (range_size * level)

        return OTELevels(
            swing_high=swing_high,
            swing_low=swing_low,
            levels=levels,
            ote_zone={
                'low': levels['fib_618'],
                'high': levels['fib_79']
            }
        )

    def get_price_position(self, current_price: float, levels: OTELevels) -> str:
        fib_position = (levels.swing_high - current_price) / (levels.swing_high - levels.swing_low)

        if 0.618 <= fib_position <= 0.79:
            return 'ote'
        elif fib_position < 0.5:
            return 'premium'
        elif fib_position > 0.5:
            return 'discount'
        else:
            return 'equilibrium'
```

**BOS/CHOCH Detection:**
```python
class StructureAnalyzer:
    def detect_bos(self, swings: List[SwingPoint], current_candle: Candle) -> Optional[StructureBreak]:
        """
        BOS: Precio rompe un swing en direccion de la tendencia
        - Bullish BOS: Rompe swing high previo
        - Bearish BOS: Rompe swing low previo
        """
        last_high = self._get_last_swing(swings, 'high')
        last_low = self._get_last_swing(swings, 'low')

        if current_candle.close > last_high.price:
            return StructureBreak(
                type='bos',
                direction='bullish',
                price=current_candle.close,
                broken_level=last_high.price
            )
        elif current_candle.close < last_low.price:
            return StructureBreak(
                type='bos',
                direction='bearish',
                price=current_candle.close,
                broken_level=last_low.price
            )

        return None

    def detect_choch(self, swings: List[SwingPoint], trend: str, current_candle: Candle) -> Optional[StructureBreak]:
        """
        CHOCH: Precio rompe estructura CONTRA la tendencia
        - Bullish CHOCH: En downtrend, rompe un high (posible reversion)
        - Bearish CHOCH: En uptrend, rompe un low (posible reversion)
        """
        if trend == 'bullish':
            # En uptrend, buscar rotura de low
            last_low = self._get_last_swing(swings, 'low')
            if current_candle.close < last_low.price:
                return StructureBreak(
                    type='choch',
                    direction='bearish',
                    price=current_candle.close,
                    broken_level=last_low.price
                )
        elif trend == 'bearish':
            # En downtrend, buscar rotura de high
            last_high = self._get_last_swing(swings, 'high')
            if current_candle.close > last_high.price:
                return StructureBreak(
                    type='choch',
                    direction='bullish',
                    price=current_candle.close,
                    broken_level=last_high.price
                )

        return None
```

**Features ICT/SMC (15 features):**
```python
ict_smc_features = [
    # OTE Features (5)
    'ote_position',           # 0-1 (0=low, 1=high del OTE zone)
    'is_in_ote_zone',         # binary
    'is_premium',             # binary (>50%)
    'is_discount',            # binary (<50%)
    'fib_level_nearest',      # Nivel Fib mas cercano (0.236, 0.382, etc.)

    # Killzone Features (5)
    'is_killzone_active',     # binary
    'killzone_type',          # categorical (0=none, 1=london, 2=ny, 3=asian, 4=close)
    'killzone_progress',      # 0-1 (% transcurrido de la KZ)
    'time_to_killzone',       # Minutos hasta proxima KZ (-1 si activa)
    'session_historical_volatility',  # Volatilidad historica de la sesion

    # Structure Features (5)
    'bos_count_bullish_20',   # Count de BOS bullish en 20 periodos
    'bos_count_bearish_20',   # Count de BOS bearish en 20 periodos
    'choch_recency',          # Periodos desde ultimo CHOCH (-1 si no hay)
    'structure_score',        # -1 (bearish) a +1 (bullish)
    'swing_strength'          # Fuerza del ultimo swing (ATR-normalized)
]
```

---

### Definition of Ready (DoR)

- [x] Historia claramente escrita (quien, que, por que)
- [x] Criterios de aceptacion definidos
- [x] Story points estimados
- [x] Dependencias identificadas
- [x] Diseno/mockup disponible
- [x] API spec disponible

### Definition of Done (DoD)

- [ ] Codigo implementado segun criterios
- [ ] Tests unitarios escritos y pasando
- [ ] Tests de integracion pasando
- [ ] Code review aprobado
- [ ] Documentacion actualizada
- [ ] Inventarios actualizados
- [ ] Traza registrada
- [ ] QA aprobado
- [ ] Desplegado en ambiente de pruebas

---

### Historial de Cambios

| Fecha | Cambio | Autor |
|-------|--------|-------|
| 2025-12-05 | Creacion | Requirements-Analyst |

---

### Notas de Implementacion

_Pendiente de desarrollo_

### Notas de QA

_Pendiente de pruebas_

---

**Creada por:** Requirements-Analyst
**Fecha:** 2025-12-05
**Ultima actualizacion:** 2025-12-05
