Skip to content

Strategy Agent

Entry scanning, technical evaluation, signal generation, and trade state management


January 2026 Status

ACTIVE - Trend following strategy with sentiment integration

Feature Status Details
Entry Scanning ✅ Active MA20, RSI, volume criteria
Sentiment Integration ✅ Active Veto at -0.6, boost at +0.5
Trade State Machine ✅ Active SETUP → FILLED → HOLDING → CLOSED
Catalyst Scoring ✅ Active 0-100 points for position sizing
Exit Monitoring ✅ Active Stop/target detection

Overview

The Strategy Agent scans for entry candidates, evaluates technical setups, generates trading signals, and manages trade state machines.

src/agents/trading/strategy_agent.py

Responsibilities: - Scan for entry candidates (stocks meeting criteria) - Evaluate trend following setup (MA20, RSI, volume) - Generate entry/exit signals with sentiment weighting - Manage trade state machines - Monitor open positions for exit conditions - Score catalysts for position sizing


Strategy: Trend Following (3:1 R/R)

Entry Criteria

Criterion Requirement Points
Price > MA20 Uptrend confirmation Required
RSI 50-70 Momentum without overbought 1/3
Volume > 1.5x avg Confirmation of interest 1/3
ADX > 25 Strong trend (alternative to RSI) 1/3

Setup Valid: At least 2 of 3 criteria met

Exit Targets

Exit Type Calculation Description
Stop Loss Entry × 0.95 5% below entry
Profit Target Entry × 1.15 15% above entry
Risk/Reward 3:1 Minimum ratio

Event Architecture

Events Published

Event Description Data
strategy.candidate_found Potential entry detected symbol, criteria_met
strategy.entry_signal Entry criteria met symbol, entry_price, stop_price, target_price, sentiment_data
strategy.exit_signal Exit condition met symbol, reason, pnl_pct
market_data.get_quote Request quote data symbol
market_data.get_bars Request historical bars symbol, timeframe, limit

Events Subscribed

Event Handler Description
strategy.scan handle_strategy_scan Scan universe for candidates
strategy.evaluate handle_strategy_evaluate Evaluate specific symbol
position.opened handle_position_opened Track new position
market_data.quote.updated handle_market_data_quote_updated Monitor for exits
sentiment.score handle_sentiment_score Receive sentiment data

Sentiment Integration

How Sentiment Affects Trading

Sentiment Score Action Impact
< -0.6 (bearish) VETO entry Trade blocked
-0.6 to +0.5 Normal No adjustment
> +0.5 (bullish) BOOST size +25% position

Combined Score Calculation

technical_score = (criteria_met / 3) * 100  # 0-100
sentiment_adjustment = sentiment_score * 20 * confidence  # -20 to +20
combined_score = technical_score + sentiment_adjustment

Configuration

self.sentiment_veto_threshold = -0.6    # Block entries below this
self.sentiment_boost_threshold = 0.5    # Boost size above this
self.sentiment_boost_multiplier = 1.25  # 25% larger position
self.sentiment_cache_ttl_seconds = 300  # 5 minute cache

Trade State Machine

States

stateDiagram-v2
    [*] --> SETUP_DETECTED: detect_setup()
    SETUP_DETECTED --> ENTRY_APPROVED: approve_entry()
    ENTRY_APPROVED --> ORDER_PLACED: place_order()
    ORDER_PLACED --> FILLED: filled()
    FILLED --> HOLDING: set_holding()
    HOLDING --> EXIT_TRIGGERED: trigger_exit()
    EXIT_TRIGGERED --> CLOSED: close()
    CLOSED --> [*]

    SETUP_DETECTED --> [*]: invalid_setup()
    ENTRY_APPROVED --> [*]: order_rejected()
    ORDER_PLACED --> [*]: order_cancelled()

State Transitions

From To Trigger Data
SETUP_DETECTED ENTRY_APPROVED approve_entry() quantity
ENTRY_APPROVED ORDER_PLACED place_order() order_id
ORDER_PLACED FILLED filled() fill_price
FILLED HOLDING set_holding() -
HOLDING EXIT_TRIGGERED trigger_exit() reason
EXIT_TRIGGERED CLOSED close() exit_price

Catalyst Scoring System

Score tickers based on multiple catalysts (0-100 points).

Catalyst Points

Catalyst Points Criteria
FDA Approval 25 Within 90 days, >50% probability
Earnings Beat 25 30-60 days out, >10% surprise expected
M&A Activity 20 13D filings, rumors, strategic buyers
Product Launch 15 Announced within 60 days
Insider Buying 15 >10% shares bought in 90 days
Analyst Upgrade 15 Initiation, upgrade, or target raise >20%
Technical Breakout 10 52-week high, volume surge

Usage

score = agent.score_catalyst_stack("AAPL", {
    "earnings_date": datetime(2025, 1, 30),
    "earnings_surprise_est": 0.15,  # 15% expected beat
    "has_13d_filing": False,
    "has_ma_rumors": True,
    "analyst_upgrades": 2,
    "current_price": 175.50,
    "price_52w_high": 180.00,
    "volume_ratio": 3.5
})

# score = 60 (M&A + Analyst + Technical)

Entry Requirement

  • Minimum 2-3 catalysts (score > 50)
  • Higher scores = larger position sizes

Error Handling

Sentiment API Failures

Error Type Fallback Behavior Timeout
API timeout Use cached sentiment 30s
API unavailable Default to neutral (0.0) 3 retries
Parse error Log error, use neutral None
Rate limit Use cached data 60s backoff
def get_sentiment_with_fallback(self, symbol):
    try:
        sentiment = self.sentiment_api.get(symbol, timeout=30)
        self.sentiment_cache[symbol] = sentiment
        return sentiment
    except (TimeoutError, ConnectionError):
        cached = self.sentiment_cache.get(symbol)
        if cached and not self._is_cache_expired(cached):
            return cached
        return {"score": 0.0, "confidence": 0.0}  # Neutral fallback

Market Data Failures

Error Type Action Recovery
Quote unavailable Skip symbol in scan Retry next cycle
Historical data missing Use available bars Continue with partial data
Price feed delay Use last known price Mark as stale

Performance Metrics

Strategy Performance (Backtest 2024)

Metric Value Benchmark
Win Rate 68% >60% target
Avg R/R 2.8:1 3:1 target
Max Drawdown -12% <15% limit
Sharpe Ratio 1.45 >1.0 target
Total Return +34% SPY: +26%

Real-Time Monitoring

# Performance tracking
self.metrics = {
    "signals_generated": 0,
    "signals_executed": 0,
    "sentiment_vetos": 0,
    "avg_processing_time_ms": 0,
    "cache_hit_rate": 0.0
}

Alerts Configuration

Alert Threshold Action
Processing time > 5s Critical Notify DevOps
Cache hit rate < 80% Warning Check Redis
Sentiment API failures > 10% Warning Check API status

Usage Examples

Initialize Agent

from src.agents.trading.strategy_agent import StrategyAgent

agent = StrategyAgent(
    redis_host="172.200.3.164",
    redis_port=6379,
    redis_db=0,
    sentiment_api_url="https://api.sentiment.corbie.ai",
    cache_ttl=300
)

agent.start()

Scan Universe

agent.publish_event(
    event="strategy.scan",
    data={
        "symbols": ["AAPL", "MSFT", "GOOGL", "NVDA", "TSLA"]
    }
)

Evaluate Specific Symbol

agent.publish_event(
    event="strategy.evaluate",
    data={
        "symbol": "AAPL",
        "current_price": 175.50,
        "ma20": 172.00,
        "rsi": 58,
        "volume": 85000000,
        "avg_volume": 50000000
    }
)

# If criteria met, publishes:
# strategy.entry_signal with:
# - entry_price: 175.50
# - stop_price: 166.73 (5% below)
# - target_price: 201.83 (15% above)
# - risk_reward_ratio: 3.0
# - sentiment_score, sentiment_confidence
# - position_size_multiplier

Get Active Trades

trades = agent.get_active_trades()
# Returns Dict[str, TradeStateMachine] for HOLDING/EXIT_TRIGGERED states

for symbol, trade in trades.items():
    print(f"{symbol}: {trade.state.value}")
    print(f"  Entry: ${trade.data.entry_price:.2f}")
    print(f"  Stop: ${trade.data.stop_price:.2f}")

Entry Signal Flow

graph TD
    A[strategy.evaluate] --> B{Price > MA20?}
    B -->|No| C[Reject: Below MA]
    B -->|Yes| D{RSI 50-70?}
    D --> E{Volume > 1.5x?}
    E --> F{2+ Criteria Met?}
    F -->|No| G[Reject: Insufficient Criteria]
    F -->|Yes| H{Get Sentiment}
    H --> I{API Available?}
    I -->|No| J[Use Cache/Neutral]
    I -->|Yes| K{Score < -0.6?}
    J --> K
    K -->|Yes| L[VETO: Bearish Sentiment]
    K -->|No| M{Score > +0.5?}
    M -->|Yes| N[Apply 1.25x Multiplier]
    M -->|No| O[Normal Size]
    N --> P[Publish Entry Signal]
    O --> P

Exit Signal Monitoring

The agent monitors positions for:

Condition Action
Price >= Target Publish strategy.exit_signal with reason TARGET_HIT
Price <= Stop Publish strategy.exit_signal with reason STOP_HIT
def handle_market_data_quote_updated(self, message):
    if last_price >= target_price:
        trade.trigger_exit(reason="TARGET_HIT")
        self.publish_event("strategy.exit_signal", {...})

    elif last_price <= stop_price:
        trade.trigger_exit(reason="STOP_HIT")
        self.publish_event("strategy.exit_signal", {...})

Configuration Reference

Parameter Type Default Description
redis_host str "172.200.3.164" Redis host for message bus
redis_port int 6379 Redis port
redis_db int 0 Redis database number
sentiment_api_url str None Sentiment service endpoint
cache_ttl int 300 Cache TTL in seconds
max_concurrent_evaluations int 10 Parallel evaluation limit
processing_timeout_ms int 5000 Max processing time

Strategy Parameters

Parameter Default Description
stop_loss_pct 0.05 5% stop loss
profit_target_pct 0.15 15% profit target
target_risk_reward 3.0 Minimum R/R ratio
rsi_min 50 Minimum RSI for entry
rsi_max 70 Maximum RSI for entry
adx_min 25 Minimum ADX for entry
volume_multiplier 1.5 Volume vs average threshold

Sentiment Parameters

Parameter Default Description
sentiment_veto_threshold -0.6 Block entries below this
sentiment_boost_threshold 0.5 Boost position above this
sentiment_boost_multiplier 1.25 25% position increase
sentiment_cache_ttl_seconds 300 5 minute cache
sentiment_timeout_seconds 30 API call timeout
sentiment_retry_attempts 3 Max retry attempts

Troubleshooting

Common Issues

Issue Symptoms Solution
No signals generated Agent running but silent Check market data feed
High sentiment API failures Warnings in logs Verify API endpoint and auth
Redis connection errors Agent crashes Check Redis connectivity
Slow processing Timeouts in logs Scale Redis or reduce scan universe

Debug Commands

# Check agent health
agent.get_health_status()

# View sentiment cache
agent.get_sentiment_cache_stats()

# Monitor active trades
agent.get_trade_summary()

# Performance metrics
agent.get_performance_metrics()

Log Analysis

# Strategy agent logs
grep "strategy_agent" /var/log/corbie/agents.log

# Sentiment failures
grep "sentiment.*error" /var/log/corbie/agents.log

# Performance issues
grep "timeout\|slow" /var/log/corbie/agents.log

Integration Testing

With Risk Management Agent

def test_integration_risk_management():
    # Strategy generates signal
    strategy_agent.publish_event("strategy.entry_signal", signal_data)

    # Risk management validates
    assert risk_agent.last_validation_result["approved"] == True

    # Integration verified
    assert strategy_agent.pending_signals == 0

With Market Data Agent

def test_market_data_integration():
    # Request market data
    strategy_agent.request_quote("AAPL")

    # Verify data received
    assert market_data_agent.quote_requests > 0
    assert strategy_agent.last_quote_received is not None

Logging Examples

Entry Signal

INFO Entry signal: AAPL @ $175.50 | Stop: $166.73, Target: $201.83 | R/R: 3.00:1 | Sentiment: +0.35

Sentiment Veto

WARNING SENTIMENT VETO: AAPL entry blocked due to bearish sentiment (-0.72, 85% confidence)

Sentiment Boost

INFO SENTIMENT BOOST: AAPL position size +25% due to bullish sentiment (+0.65)

Target Hit

INFO Target hit: AAPL @ $201.83 (target: $201.83)

Stop Hit

INFO Stop hit: AAPL @ $166.73 (stop: $166.73)

Error Handling

ERROR Sentiment API timeout for AAPL, using cached data (5 minutes old)
WARNING High processing time: 4.2s for NVDA evaluation (limit: 5s)

See Also


Last Updated: January 10, 2026 Platform: Trend Following 3:1 R/R | Sentiment Integration | Redis Pub/Sub