robinhood-options-mobile

Multi-Indicator Automatic Trading System

Overview

The multi-indicator automatic trading system correlates 19 technical indicators to generate trade signals.

This system provides a comprehensive multi-factor analysis approach combining price action, momentum, trend, volume, and volatility indicators. It uses a Weighted Signal Strength system where indicators are weighted by importance (Price Movement > Momentum/Trend > Others) to calculate a final Signal Strength score (0-100).

Signal Discovery & Filtering

Users can explore trade signals in the Search tab using advanced filtering options:

  1. Signal Strength: Filter by Strong (70-100), Moderate (50-69), or Weak (0-49) signals.
  2. Indicator States: Filter by specific indicator states using a 4-way toggle (Off/BUY/SELL/HOLD). For example, you can search for “RSI: BUY” and “MACD: BUY” to find specific momentum setups.
  3. Sorting: Sort results by Signal Strength (default) or Timestamp to find the most relevant or most recent signals.

Note: Signal Strength and Indicator filters are exclusive. Selecting one type clears the other to ensure clear, non-conflicting results.

Signal Strength Calculation

The system uses a weighted scoring model to determine the overall strength of a trade signal. Not all indicators are created equal; some provide earlier or more reliable signals than others.

Weight Distribution:

  1. Critical (Weight 2.0):
    • Price Movement: Patterns and candlestick formations are the most direct reflection of market sentiment and often precede other indicators.
  2. High Impact (Weight 1.5):
    • Momentum: RSI and momentum signals.
    • Trend: MACD and Ichimoku.
  3. Standard Impact (Weight 1.2):
    • Trend Confirmation: ADX, Market Direction.
    • Support/Resistance: Fibonacci Retracements, Pivot Points, VWAP.
    • Volatility: Bollinger Bands.
  4. Supporting (Weight 1.0):
    • Volume/Volatility: Volume, ATR, OBV, Chaikin Money Flow.
    • Momentum/Trend: Stochastic, Williams %R, CCI, Parabolic SAR, ROC.

Formula:

$SignalStrength = \frac{WeightedScore + TotalWeight}{2 \times TotalWeight} \times 100$

The final score (0-100) reflects the net positive influence of all indicators. A score $\ge 70$ is considered a Strong BUY, while a score $\le 30$ is a Strong SELL.

Sparkline Context:

The multi-indicator result includes a sparkline series (last 80 closes) used to render quick trend previews in signal cards.

The 19 Technical Indicators

1. Price Movement (Multi-Pattern Detection)

Purpose: Identifies and scores multiple bullish and bearish chart patterns (classic and candlestick) from recent price action to produce a directional signal with confidence.

Implementation: detectChartPattern() in technical-indicators.ts

Supported Patterns:

Signals:

Confidence Scoring: Each detected pattern is assigned a confidence (0–1). Candlestick patterns like Engulfing and Hammer/Shooting Star are assigned high confidence (0.60-0.65) as they often signal immediate reversals.

Key Heuristics:

Metadata Returned:

{
   "selectedPattern": "ascending_triangle",
   "confidence": 0.63,
   "patterns": [
      {"key": "ascending_triangle", "confidence": 0.63, "direction": "bullish"},
      {"key": "breakout", "confidence": 0.60, "direction": "bullish"}
   ],
   "ma5": 101.2,
   "ma10": 100.8,
   "ma20": 99.9,
   "slope": 0.15
}

Action Threshold: Only patterns with confidence ≥ 0.60 generate BUY/SELL; otherwise the system issues a HOLD with an “emerging” reason.

Advantages vs Previous Version:

Fallback: If no actionable pattern found, a neutral summary of price and MAs is returned.

2. Momentum (RSI - Relative Strength Index)

Purpose: Measures the momentum and identifies overbought/oversold conditions, with divergence detection for early reversal signals.

Implementation: evaluateMomentum() and computeRSI() in technical-indicators.ts

Signals:

Configuration:

Technical Details:

3. Market Direction (Moving Average Crossovers)

Purpose: Evaluates overall market trend using SPY or QQQ index.

Implementation: evaluateMarketDirection() in technical-indicators.ts

Signals:

Configuration:

4. Volume (Volume Oscillator)

Purpose: Confirms price moves with volume analysis.

Implementation: evaluateVolume() in technical-indicators.ts

Signals:

5. MACD (Moving Average Convergence Divergence)

Purpose: Trend-following momentum indicator.

Implementation: evaluateMACD() in technical-indicators.ts

Signals:

6. Bollinger Bands

Purpose: Measures volatility and potential overbought/oversold conditions.

Implementation: evaluateBollingerBands() in technical-indicators.ts

Signals:

7. Stochastic Oscillator

Purpose: Momentum indicator comparing a particular closing price of a security to a range of its prices over a certain period of time.

Implementation: evaluateStochastic() in technical-indicators.ts

Signals:

8. ATR (Average True Range)

Purpose: Measures market volatility.

Implementation: evaluateATR() in technical-indicators.ts

Signals:

9. OBV (On-Balance Volume)

Purpose: Uses volume flow to predict changes in stock price.

Implementation: evaluateOBV() in technical-indicators.ts

Signals:

10. VWAP (Volume Weighted Average Price)

Purpose: Provides the average price a stock has traded at throughout the day, based on both volume and price.

Implementation: evaluateVWAP() in technical-indicators.ts

Signals:

11. ADX (Average Directional Index)

Purpose: Measures the strength of a trend.

Implementation: evaluateADX() in technical-indicators.ts

Signals:

12. Williams %R

Purpose: Momentum indicator that measures overbought and oversold levels.

Implementation: evaluateWilliamsR() in technical-indicators.ts

Signals:

13. Ichimoku Cloud

Purpose: Comprehensive indicator that defines support and resistance, identifies trend direction, gauges momentum, and provides trading signals.

Implementation: evaluateIchimokuCloud() in technical-indicators.ts

Signals:

14. CCI (Commodity Channel Index)

Purpose: Momentum-based oscillator used to identify cyclical trends and overbought/oversold levels.

Implementation: evaluateCCI() in technical-indicators.ts

Signals:

15. Parabolic SAR (Stop and Reverse)

Purpose: Trend-following indicator that highlights potential reversals and sets trailing stop levels.

Implementation: evaluateParabolicSAR() in technical-indicators.ts

Signals:

16. ROC (Rate of Change)

Purpose: Momentum oscillator measuring the percentage change in price over a given period.

Implementation: evaluateROC() in technical-indicators.ts

Parameters:

Signals:

17. Chaikin Money Flow (CMF)

Purpose: Combines price and volume to measure buying and selling pressure.

Implementation: evaluateChaikinMoneyFlow() in technical-indicators.ts

Signals:

18. Fibonacci Retracements

Purpose: Identifies potential support and resistance levels based on recent high/low range.

Implementation: evaluateFibonacciRetracements() in technical-indicators.ts

Signals:

19. Pivot Points

Purpose: Uses the previous period’s high, low, and close to project support and resistance levels.

Implementation: evaluatePivotPoints() in technical-indicators.ts

Variants Supported:

Signals:

20. TTM Squeeze (Visualization)

Purpose: Visualizes volatility compression and momentum.

Implementation: Chart overlay/indicator.

Signals:

Signal Strength Score

Purpose: Quantifies overall indicator alignment on a 0-100 scale.

Calculation:

signalStrength = ((buyCount - sellCount + totalIndicators) / (2 × totalIndicators)) × 100

Interpretation:

Use Cases:

How It Works

Signal Generation Flow

  1. Data Collection
    • Fetch historical prices and volumes for the target symbol
    • Fetch market index (SPY/QQQ) data
    • Minimum 30-60 periods of data required
  2. Indicator Evaluation
    • Each of the 19 indicators is evaluated independently
    • Each returns: { signal: "BUY"|"SELL"|"HOLD", reason: string, value: number }
  3. Multi-Indicator Correlation
    • Function: evaluateAllIndicators() in technical-indicators.ts
    • Checks if ALL 19 indicators signal BUY
    • Returns allGreen: true only when all 19 are BUY
  4. Trade Decision
    • Alpha agent (alpha-agent.ts) calls multi-indicator evaluation
    • If allGreen = false: No trade (HOLD)
    • If allGreen = true: Generate trade proposal
    • RiskGuard agent performs final risk assessment
  5. Trade Execution
    • Trade proposal sent to risk assessment
    • If approved: Trade is executed
    • Results stored in Firestore under agentic_trading/signals_{symbol}

Code Flow

agentic-trading.ts (getMarketData with OHLCV)
         ↓
alpha-agent.ts (handleAlphaTask)
         ↓
technical-indicators.ts (evaluateAllIndicators)
         ↓
    ┌────┴────┬────────┬───────────┬──────────┬───────────┐
    ↓         ↓        ↓           ↓          ↓           ↓
  Price   Momentum  Market     Volume     MACD      Bollinger
Movement  (RSI+Div) Direction                        Bands
    ↓         ↓        ↓           ↓          ↓           ↓
    └────┬────┴────────┴───────────┴──────────┴───────────┘
         ↓
    ┌────┴────┬─────────┬────────┬────────┬────────┐
    ↓         ↓         ↓        ↓        ↓        ↓
Stochastic  ATR       OBV      VWAP     ADX   Williams%R
    ↓         ↓         ↓        ↓        ↓        ↓
    └────┬────┴─────────┴────────┴────────┴────────┘
         ↓
  All 19 Green? + Signal Strength Score
         ↓
    Yes → Trade Proposal → RiskGuard → Execute
    No  → HOLD (with strength score for analytics)

Configuration

Backend Configuration (Firebase Functions)

File: functions/src/agentic-trading.ts

Default configuration:

{
  smaPeriodFast: 10,
  smaPeriodSlow: 30,
  tradeQuantity: 1,
  maxPositionSize: 100,
  maxPortfolioConcentration: 0.5,
  rsiPeriod: 14,
  marketIndexSymbol: "SPY"
}

Stored in Firestore: agentic_trading/config

Frontend Configuration (Flutter App)

File: lib/widgets/agentic_trading_settings_widget.dart

Configurable parameters:

Updating Configuration

Via Mobile App:

  1. Navigate to Agentic Trading Settings
  2. Modify desired parameters
  3. Tap “Save Settings”
  4. Changes are persisted to Firestore

Via Firebase Console:

  1. Open Firestore database
  2. Navigate to agentic_trading/config document
  3. Modify fields directly
  4. Changes take effect on next trade evaluation

Firestore Indexes

For optimal performance with server-side filtering, deploy the following indexes:

Required Indexes:

  1. Composite index for filtered queries by signal type and timestamp
  2. Single-field index for timestamp ordering

Deployment:

firebase deploy --only firestore:indexes

Configuration File: firebase/firestore.indexes.json

These indexes enable efficient server-side filtering of trade signals by signal type, date range, and ordering by timestamp.

Intraday Trading

Overview

The system supports multiple trading intervals for different time horizons:

Interval Selection

Users can select their preferred interval in the mobile app using a SegmentedButton:

// Fetch hourly signal
await provider.fetchTradeSignal(symbol, interval: '1h');

// Fetch 15-minute signal
await provider.fetchTradeSignal(symbol, interval: '15m');

// Fetch daily signal (default)
await provider.fetchTradeSignal(symbol, interval: '1d');

Market Hours Intelligence

The system automatically filters signals based on market hours with DST awareness:

Implementation:

Backend Cron Jobs

Hourly Cron (agenticTradingIntradayCronJob):

15-Minute Cron (agenticTrading15mCronJob):

End-of-Day Cron (agenticTradingCron):

Signal Storage Schema

Daily signals (backward compatible):

agentic_trading/signals_<SYMBOL>

Intraday signals:

agentic_trading/signals_<SYMBOL>_<INTERVAL>

Examples:

Cache Strategy

Interval-specific cache TTLs optimize performance:

Cache staleness is checked before fetching new data from Yahoo Finance API.

Data Fetching

The getMarketData() function accepts interval parameters:

await getMarketData(
  symbol,
  smaPeriodFast,
  smaPeriodSlow,
  interval,  // '15m', '30m', '1h', '1d'
  range      // '1d', '5d', '1mo', '1y', etc.
);

Yahoo Finance API provides OHLCV data for all supported intervals.

Real-Time Signal Updates

Overview

Trade signals now update in real-time using Firestore snapshot listeners, eliminating the need for manual refresh or polling.

Implementation

Previous Approach (Deprecated):

// One-time fetch - missed backend updates
final snapshot = await query.get();
_tradeSignals = snapshot.docs.map(...).toList();
notifyListeners();

Current Approach:

// Real-time listener - automatically updates on changes
_tradeSignalsSubscription = query.snapshots().listen((snapshot) {
  _tradeSignals = snapshot.docs.map(...).toList();
  notifyListeners(); // Fires on every Firestore update
});

Subscription Lifecycle

Setup:

StreamSubscription<QuerySnapshot<Map<String, dynamic>>>? _tradeSignalsSubscription;

Cleanup:

@override
void dispose() {
  _tradeSignalsSubscription?.cancel();
  super.dispose();
}

Server Data Prioritization

The system intelligently handles cached vs server data:

  1. Initial fetch: Requests server data explicitly with Source.server
  2. First snapshot: If from cache, waits up to 1 second for server data
  3. Server arrival: Immediately processes server data when available
  4. Fallback: Uses cached data if server doesn’t respond within 1 second
  5. Subsequent updates: Processes all snapshots in real-time

Benefits

Monitoring Trade Signals

Firebase Firestore

Trade signals are stored in:

Document structure:

{
  "timestamp": 1234567890000,
  "symbol": "AAPL",
  "interval": "1h",
  "signal": "BUY" | "SELL" | "HOLD",
  "reason": "All 19 indicators are GREEN - Strong BUY signal",
  "multiIndicatorResult": {
    "allGreen": true,
    "overallSignal": "BUY",
    "indicators": {
         "priceMovement": {
            "signal": "BUY",
            "reason": "Ascending Triangle pattern (conf 63%)",
            "value": 0.63,
            "metadata": {
               "selectedPattern": "ascending_triangle",
               "confidence": 0.63,
               "patterns": [ {"key": "ascending_triangle", "confidence": 0.63} ],
               "ma5": 101.2,
               "ma10": 100.8,
               "ma20": 99.9,
               "slope": 0.15
            }
         },
      "momentum": {
        "signal": "BUY",
        "reason": "RSI indicates oversold condition...",
        "value": 28.5,
        "metadata": { "rsi": 28.5, ... }
      },
      "marketDirection": {
        "signal": "BUY",
        "reason": "Market bullish: 10-day MA crossed above...",
        "value": 3.2,
        "metadata": { ... }
      },
      "volume": {
        "signal": "BUY",
        "reason": "High volume with price increase...",
        "value": 1.8,
        "metadata": { ... }
      }
    }
  },
  "currentPrice": 450.25,
  "config": { ... },
  "proposal": { ... },
  "assessment": { ... }
}

Firestore Indexes

Required composite indexes for optimized queries (configured in firebase/firestore.indexes.json):

Signal type + timestamp:

{
  "collectionGroup": "signals",
  "queryScope": "COLLECTION",
  "fields": [
    {"fieldPath": "signal", "order": "ASCENDING"},
    {"fieldPath": "timestamp", "order": "DESCENDING"}
  ]
}

Interval + timestamp:

{
  "collectionGroup": "signals",
  "queryScope": "COLLECTION",
  "fields": [
    {"fieldPath": "interval", "order": "ASCENDING"},
    {"fieldPath": "timestamp", "order": "DESCENDING"}
  ]
}

Deploy indexes with: firebase deploy --only firestore:indexes

Server-Side Filtering

The fetchAllTradeSignals() function in AgenticTradingProvider supports optional server-side filtering:

Parameters:

Query Limits:

Example Usage:

// Fetch only BUY signals with limit
await agenticTradingProvider.fetchAllTradeSignals(
  signalType: 'BUY',
  limit: 50,
);

// Fetch signals for specific symbols
await agenticTradingProvider.fetchAllTradeSignals(
  symbols: ['AAPL', 'MSFT', 'GOOGL'],
  limit: 100,
);

// Fetch all signals (backward compatible)
await agenticTradingProvider.fetchAllTradeSignals();

Performance Benefits:

Note: For symbol lists exceeding 30 items, client-side filtering is automatically applied as a fallback due to Firestore’s whereIn limitation.

Mobile App UI

Agentic Trading Settings Screen

The Agentic Trading Settings screen displays:

Search Tab - Trade Signals Section

The Search tab includes a Trade Signals section with filtering capabilities and market status indicators:

Market Status Display:

Filter UI:

Signal Display:

State Synchronization:

Automated Execution (Cron Jobs)

Daily Cron Job

File: functions/src/agentic-trading-cron.ts

Schedule: Every weekday at 4:00 PM ET (after market close)

Process:

  1. Scans all documents in agentic_trading collection
  2. For each chart_{SYMBOL} document:
    • Loads configuration
    • Calls performTradeProposal() with symbol and interval: '1d'
    • Multi-indicator evaluation runs
    • Trade executed if all indicators are green and risk check passes
  3. Results stored in agentic_trading/signals_{SYMBOL}

Intraday Cron Jobs

File: functions/src/agentic-trading-intraday-cron.ts

Hourly Schedule: 30 9-16 * * mon-fri (every hour at 30 minutes past, during market hours)

15-Minute Schedule: 15,30,45,0 9-16 * * mon-fri (every 15 minutes during market hours)

Process:

  1. Scans all documents in agentic_trading collection
  2. For each chart_{SYMBOL} document:
    • Loads configuration
    • Calls performTradeProposal() with symbol and appropriate interval
    • Multi-indicator evaluation runs
    • Trade executed if all indicators are green and risk check passes
  3. Results stored in agentic_trading/signals_{SYMBOL}_{INTERVAL}

Deployment:

cd src/robinhood_options_mobile/functions
firebase deploy --only functions:agenticTradingIntradayCronJob,functions:agenticTrading15mCronJob

Monitoring:

Testing

Manual Testing via Mobile App

  1. Navigate to Agentic Trading Settings
  2. Enable “Enable Agentic Trading”
  3. Configure parameters (optional)
  4. Tap “Initiate Test Trade Proposal”
  5. Review indicator status display
  6. Check if all 19 indicators are green

Testing Individual Indicators

You can test individual indicators by:

  1. Price Movement: Review 20+ periods of price data
  2. Momentum: Check RSI calculation with 14+ periods
  3. Market Direction: Verify MA crossovers on SPY/QQQ
  4. Volume: Analyze volume relative to 20-period average

Example Test Scenarios

Scenario 1: Strong Bullish Signal

Scenario 2: Mixed Signals

Scenario 3: Bearish Signal

Best Practices

Configuration Tuning

  1. Conservative Approach:
    • RSI period: 14-20 (longer period = smoother)
    • SMA fast/slow: 10/30 or 20/50
    • Requires strong signals from all indicators
  2. Aggressive Approach:
    • RSI period: 7-10 (shorter period = more sensitive)
    • SMA fast/slow: 5/15 or 8/21
    • More frequent signals but higher false positives
  3. Market Index Selection:
    • Use SPY for broad market correlation
    • Use QQQ for tech-heavy portfolios

Risk Management

The multi-indicator system works best when combined with:

Monitoring

Regularly review:

Troubleshooting

No Trades Being Generated

Check:

  1. Is agentic trading enabled in settings?
  2. Are all 19 indicators rarely aligning?
  3. Review Firestore signals_{SYMBOL} for indicator status
  4. Check Firebase Functions logs for errors
  5. Verify market data is being fetched (Yahoo Finance API working)
  6. Ensure Firestore indexes are deployed for signal queries

Signals Not Showing in Search View

Check:

  1. Verify signals exist in Firestore agentic_trading/signals_{SYMBOL}
  2. Check if filters are too restrictive (try “All” filter)
  3. Verify fetchAllTradeSignals() is being called
  4. Check provider is properly connected with Consumer widget
  5. Review Firebase Functions logs for query errors
  6. Ensure Firestore indexes are deployed and active

Too Many False Signals

Solutions:

  1. Increase RSI period for smoother signals
  2. Increase SMA periods for market direction
  3. Add additional filters (e.g., minimum price change threshold)
  4. Tighten volume requirements

Indicators Not Updating

Check:

  1. Firebase Functions are deployed and running
  2. Cron job is executing (check logs)
  3. Yahoo Finance API is accessible
  4. Firestore has chart data cached

Future Enhancements

Potential improvements:

  1. Additional Indicators:
    • ✅ MACD (Moving Average Convergence Divergence) - IMPLEMENTED
    • ✅ Bollinger Bands - IMPLEMENTED
    • ✅ Stochastic Oscillator - IMPLEMENTED
    • ✅ ATR (Average True Range) - IMPLEMENTED
    • ✅ OBV (On-Balance Volume) - IMPLEMENTED
    • ✅ VWAP (Volume Weighted Average Price) - IMPLEMENTED v3
    • ✅ ADX (Average Directional Index) - IMPLEMENTED v3
    • ✅ Williams %R - IMPLEMENTED v3
    • ✅ RSI Divergence Detection - IMPLEMENTED v3
    • ✅ Ichimoku Cloud - IMPLEMENTED
    • ✅ Fibonacci Retracements - IMPLEMENTED
    • ✅ Parabolic SAR - IMPLEMENTED
    • ✅ Chaikin Money Flow - IMPLEMENTED
    • ✅ Rate of Change (ROC) - IMPLEMENTED
  2. Machine Learning:
    • Pattern recognition using historical data
    • Adaptive indicator weighting
    • Predictive models for indicator correlation
  3. Backtesting:
    • Historical performance analysis
    • Strategy optimization
    • Parameter tuning based on past data
  4. Advanced Risk Management:
    • Dynamic position sizing
    • Correlation analysis across portfolio
    • Volatility-adjusted indicators
  5. Real-time Monitoring:
    • Intraday signal generation
    • WebSocket connections for live data
    • Push notifications for trade signals

References

Recent Improvements (v2)

The technical indicators module has been improved for accuracy, robustness, and edge-case handling:

Bollinger Bands Precision

OBV Robustness

Pattern Detection Accuracy

Code Quality

Recent Improvements (v3)

New Indicators Added

VWAP (Volume Weighted Average Price)

ADX (Average Directional Index)

Williams %R

Enhanced RSI with Divergence Detection

Signal Strength Scoring System

System Expansion

Code Quality

Custom Indicators

The system now supports Custom Indicators, allowing users to extend the analysis capabilities beyond the core 19 indicators.

Support

For questions or issues:

  1. Check Firebase Functions logs
  2. Review Firestore documents
  3. Test individual indicators manually
  4. Consult the codebase:
    • functions/src/technical-indicators.ts
    • functions/src/alpha-agent.ts
    • functions/src/agentic-trading.ts