🧠 All Projects
šŸ“

Hedge Sprint 2 Spec: Strategy Ensemble System

P3 - Low
Spec Hedge

Hedge Sprint 2: Strategy Ensemble System

Priority: CRITICAL — Core value prop of Hedge
Owner: Bob coordinating, Atlas (backend), Kai (frontend)


Architecture Overview

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                      STRATEGY LIBRARY                           │
│  [MA Crossover] [RSI(2)] [MACD+RSI] [Bollinger] [Momentum] ...  │
│  [HMM Regime] [VIX Overlay] [Sector Rotation] [Gap Fill] ...    │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                           │
                           ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                   NIGHTLY SIGNAL SCANNER                        │
│  Run ALL strategies against ALL tickers in screener universe    │
│  → Store: {ticker, strategy, signal, confidence, reasoning}     │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                           │
                           ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                 COMPOSITE SCORING ENGINE                        │
│  composite = Ī£(signal Ɨ confidence Ɨ regime_weight) / N         │
│  Rank all tickers by composite score                            │
│  Filter by current HMM regime                                   │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                           │
                           ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                   AI OPPORTUNITY FINDER                         │
│  Mode 1: "Analyze AAPL" → All strategy signals + reasoning      │
│  Mode 2: "Scan watchlist" → Top 10 ranked opportunities         │
│  Mode 3: "401k rebalance" → Monthly fund rotation suggestions   │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Phase 1: Strategy Library (Atlas)

Database Schema

-- Strategy definitions (templates + user customized)
CREATE TABLE strategy_definitions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name TEXT NOT NULL,
    slug TEXT UNIQUE NOT NULL,  -- 'rsi_2_mean_reversion'
    description TEXT,
    category TEXT NOT NULL,  -- 'trend', 'mean_reversion', 'momentum', 'regime', 'risk_mgmt'
    timeframe TEXT NOT NULL,  -- 'intraday', 'daily', 'weekly', 'monthly'
    complexity TEXT NOT NULL,  -- 'easy', 'medium', 'hard'
    parameters JSONB NOT NULL DEFAULT '{}',  -- configurable params
    default_params JSONB NOT NULL DEFAULT '{}',
    is_system BOOLEAN DEFAULT true,  -- system template vs user-created
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Strategy signals (generated by scanner)
CREATE TABLE strategy_signals (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    ticker TEXT NOT NULL,
    strategy_id UUID REFERENCES strategy_definitions(id),
    signal TEXT NOT NULL,  -- 'LONG', 'SHORT', 'NEUTRAL'
    confidence DECIMAL(5,2) NOT NULL,  -- 0-100
    reasoning TEXT,
    price_at_signal DECIMAL(12,2),
    generated_at TIMESTAMPTZ DEFAULT NOW(),
    expires_at TIMESTAMPTZ,  -- signal validity
    UNIQUE(ticker, strategy_id, generated_at::date)
);

-- Composite scores (aggregated)
CREATE TABLE composite_scores (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    ticker TEXT NOT NULL,
    score DECIMAL(5,2) NOT NULL,  -- -100 to +100
    regime TEXT,  -- current HMM regime when scored
    signal_count INTEGER,
    bullish_count INTEGER,
    bearish_count INTEGER,
    top_signals JSONB,  -- [{strategy, signal, confidence}]
    scored_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(ticker, scored_at::date)
);

CREATE INDEX idx_signals_ticker ON strategy_signals(ticker);
CREATE INDEX idx_signals_date ON strategy_signals(generated_at);
CREATE INDEX idx_composite_score ON composite_scores(score DESC);

10 Core Strategy Implementations

Each strategy must implement:

class BaseStrategy:
    def generate_signal(self, ticker: str, data: pd.DataFrame) -> Signal:
        """Returns Signal(direction, confidence, reasoning)"""
        pass
    
    def backtest(self, ticker: str, start_date, end_date) -> BacktestResult:
        """Returns performance metrics"""
        pass
# Strategy Class Name Key Parameters
1 Dual MA Crossover DualMAStrategy fast_period=9, slow_period=21
2 RSI(2) Mean Reversion RSI2Strategy period=2, oversold=10, overbought=90
3 MACD + RSI Combo MACDRSIStrategy macd_fast=12, macd_slow=26, rsi_period=14
4 Bollinger Band Reversion BollingerStrategy period=20, std_dev=2
5 ETF Momentum Rotation MomentumRotationStrategy lookback=63, top_n=3
6 Opening Range Breakout ORBStrategy range_minutes=30
7 ATR Trailing Stop (Turtle) TurtleStrategy atr_period=20, atr_mult=2
8 VIX Risk Overlay VIXOverlayStrategy low_vix=15, high_vix=25
9 Gap Fill GapFillStrategy min_gap_pct=1.0
10 200-Day SMA Timing SMA200Strategy period=200
11 HMM Regime HMMRegimeStrategy (existing)

API Endpoints

GET  /api/strategies/library          - List all strategy definitions
GET  /api/strategies/library/{slug}   - Get strategy details + params
POST /api/strategies/library/{slug}/backtest  - Run backtest
     body: {ticker, start_date, end_date, params}

GET  /api/strategies/signals/{ticker} - Get all signals for ticker
GET  /api/strategies/signals/latest   - Get today's signals (all tickers)
POST /api/strategies/scan             - Trigger manual scan
     body: {tickers: [...], strategies: [...]}

GET  /api/strategies/composite/{ticker}  - Get composite score for ticker
GET  /api/strategies/composite/top       - Top N by composite score
GET  /api/strategies/composite/opportunities - AI-filtered opportunities

Phase 2: Nightly Scanner (Atlas)

Scanner Service

class NightlyScanner:
    async def run(self):
        """Run after market close (4:30 PM PT)"""
        # 1. Get universe from screener_stocks
        tickers = await self.get_screener_universe()
        
        # 2. Get current HMM regime
        regime = await self.hmm_detector.predict("SPY")
        
        # 3. Run each strategy against each ticker
        for ticker in tickers:
            data = await self.fetch_price_data(ticker)
            for strategy in self.strategies:
                signal = strategy.generate_signal(ticker, data)
                await self.store_signal(ticker, strategy, signal)
        
        # 4. Calculate composite scores
        await self.calculate_composites(regime)
        
        # 5. Notify user of opportunities
        await self.send_summary()

Composite Scoring Formula

def calculate_composite(ticker, signals, regime):
    total_score = 0
   

Created: Wed, Feb 18, 2026, 8:28 PM by bob

Updated: Wed, Feb 18, 2026, 8:28 PM

Last accessed: Wed, Apr 1, 2026, 11:52 PM

ID: e66f83fe-25d5-49ce-b4e3-b97d4b17b075