Skip to content

Micro-Cap Momentum + Earnings Deployment Guide

Date: 2025-11-03 Strategy: Momentum Breakout with Earnings Overlay Account: Alpaca Paper ($99,000) Status: ✅ READY TO DEPLOY


What You're Deploying

Base Strategy: Momentum Breakout (Validated Oct 31)

  • Sharpe Ratio: 0.49 ✅ (target: >0.30)
  • Win Rate: 52.8% ✅ (target: >40%)
  • Max Drawdown: 1.8% ✅ (target: <20%)
  • Total Return: 96.3% over 18 months (validation period)
  • Total Trades: 36 trades

New Feature: Earnings Overlay (Added Today)

  • Pre-Earnings Reduction: Automatically reduce position by 50% at 7 days before earnings
  • Data Source: yfinance API (real-time earnings dates)
  • Risk Mitigation: Prevents earnings gap risk (ChatGPT lost 45% partly due to this)

Configuration

  • Symbols: 12 micro-cap stocks (PLTR, SOFI, RIOT, MARA, PLUG, BLNK, CHPT, QS, OPEN, CLOV, SKLZ, WISH)
  • Capital Allocation: $19,800 (20% of $99k paper account)
  • Max Positions: 3 concurrent
  • Position Size: $414 per trade (optimized)
  • Stop Loss: 10% hard stop, 20% trailing stop
  • Entry Criteria: 16-day breakout + 3x volume + RSI >61

Pre-Deployment Checklist

1. Verify Infrastructure

# Check Redis (message bus)
docker ps | grep redis
# Should show: trading-redis container running

# Check Alpaca credentials
grep ALPACA_PAPER ~/.env
# Should show: ALPACA_PAPER_API_KEY and ALPACA_PAPER_SECRET_KEY

# Check yfinance (for earnings data)
uv run python3 -c "import yfinance; print('yfinance OK')"
# Should print: yfinance OK

2. Verify Configuration Files

# Check micro_cap config is enabled
cat trading_agents/config/channel_configs/micro_cap.yaml | grep "enabled:"
# Should show: enabled: true

# Check portfolio config points to correct file
cat trading_agents/config/portfolio_config.yaml | grep -A 10 "micro_cap:"
# Should show: enabled: true, config_file: "channel_configs/micro_cap.yaml"

3. Test Earnings Calendar

# Test earnings data provider
uv run python3 tools/catalyst_data_providers.py
# Should show earnings dates for PLTR, AAPL, TSLA

Deployment Options

Run the strategy manually to observe behavior before automation.

Step 1: Dry Run (no real orders)

cd trading_agents
uv run python3 -c "
from orchestrator.portfolio_manager import PortfolioManager
pm = PortfolioManager(paper=True, dry_run=True)
pm.run_single_scan(channels=['micro_cap'])
"

Expected output: - Scans 12 symbols for entry signals - Logs any positions that would be entered - Shows calculated stop losses and targets - NO ORDERS PLACED (dry run)

Step 2: Live Paper Trading (real orders in paper account)

uv run python3 -c "
from orchestrator.portfolio_manager import PortfolioManager
pm = PortfolioManager(paper=True, dry_run=False)
pm.run_single_scan(channels=['micro_cap'])
"

Expected behavior: - Places real orders in Alpaca paper account - Sets stop losses automatically - Monitors positions for exits - Logs all actions to logs/trading/micro_cap.log

Option B: Automated Mode (After Manual Testing)

Run continuously during market hours.

Create LaunchAgent (~/Library/LaunchAgents/com.trading.micro_cap.plist):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.trading.micro_cap</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/uv</string>
        <string>run</string>
        <string>python3</string>
        <string>/Users/bertfrichot/mem-agent-mcp/trading_agents/orchestrator/portfolio_manager.py</string>
        <string>--paper</string>
        <string>--channels</string>
        <string>micro_cap</string>
    </array>
    <key>StartCalendarInterval</key>
    <array>
        <!-- Run every 5 minutes during trading hours (9:35 AM - 3:55 PM ET) -->
        <dict><key>Hour</key><integer>9</integer><key>Minute</key><integer>35</integer></dict>
        <dict><key>Hour</key><integer>9</integer><key>Minute</key><integer>40</integer></dict>
        <!-- Add more 5-minute intervals as needed -->
    </array>
    <key>StandardOutPath</key>
    <string>/tmp/micro_cap_trading.log</string>
    <key>StandardErrorPath</key>
    <string>/tmp/micro_cap_trading_error.log</string>
</dict>
</plist>

Load LaunchAgent:

launchctl load ~/Library/LaunchAgents/com.trading.micro_cap.plist
launchctl start com.trading.micro_cap

Monitor Logs:

tail -f /tmp/micro_cap_trading.log
tail -f logs/trading/micro_cap.log


Monitoring

Real-Time Monitoring

Check Alpaca Paper Account:

# View current positions
uv run python3 tools/portfolio_fetcher.py

# View recent orders
uv run python3 -c "
from alpaca.trading.client import TradingClient
import os
client = TradingClient(os.getenv('ALPACA_PAPER_API_KEY'), os.getenv('ALPACA_PAPER_SECRET_KEY'), paper=True)
orders = client.get_orders()
for order in orders[:10]:
    print(f'{order.symbol}: {order.side} {order.qty} @ {order.filled_avg_price}')
"

Check Redis State:

# Check capital allocation
docker exec trading-redis redis-cli GET capital:micro_cap:available
docker exec trading-redis redis-cli GET capital:micro_cap:used

# Expected:
# available: 19800 (initially)
# used: 0 (or current position value)

Daily Checklist

Morning (before market open - 9:00 AM ET): - [ ] Check overnight news for symbols (earnings, FDA, M&A) - [ ] Verify Alpaca paper account is accessible - [ ] Check Redis is running (docker ps | grep redis) - [ ] Review yesterday's trades in logs

During Market Hours (9:35 AM - 3:55 PM ET): - [ ] Monitor active positions every 2-3 hours - [ ] Check for entry signals (should see in logs) - [ ] Verify stop losses are set correctly - [ ] Watch for earnings-related position reductions

After Market Close (4:00 PM ET): - [ ] Calculate daily P&L - [ ] Review all trades executed - [ ] Check for any errors in logs - [ ] Update trading journal (optional but recommended)

Weekly Review

Performance Metrics:

# Run analysis on paper trading results
uv run python3 tools/trading_analytics.py --account paper --days 7

# Expected metrics after 1 week:
# - Sharpe Ratio: ~0.40-0.60 (target: 0.49)
# - Win Rate: ~50-55% (target: 52.8%)
# - Max Drawdown: < 5% (target: 1.8%)
# - Total Trades: 1-3 (depends on market conditions)


Expected Behavior

Entry Signals

  • Scans 12 symbols every 5 minutes
  • Enters when: price > 16-day high AND volume > 3x average AND RSI > 61
  • Position size: $414 (can buy 1-50+ shares depending on price)
  • Max 3 concurrent positions

Stop Loss Management

  • Sets 10% hard stop immediately after entry
  • Updates to 20% trailing stop as price rises
  • Exits after 9 days if position is unprofitable

Earnings Overlay (NEW)

  • Checks yfinance for upcoming earnings daily
  • If earnings in 7 days: sells 50% of position automatically
  • Logs: {symbol}: Earnings in {days} days. Reducing position by 50%

Exit Signals

  • Stop hit: Immediate market sell
  • Trailing stop hit: Market sell
  • Time stop (9 days): Market sell if unprofitable
  • Pre-earnings: Limit sell 50% at current_price * 0.99

Troubleshooting

No Entry Signals for Days

Normal: Strategy is selective. In backtest, averaged 2 trades/month.

Check: 1. Are any symbols meeting breakout criteria?

uv run python3 -c "
from tools.yfinance_loader import YFinanceDataLoader
loader = YFinanceDataLoader()
bars = loader.load_bars(['PLTR'], '2025-11-01', '2025-11-03')
print(bars['PLTR'].tail())
"

  1. Is market volatile enough? (Strategy works best in trending markets)

Earnings Data Not Loading

Symptoms: Log shows catalyst_data_providers not available

Fix:

uv add yfinance
uv run python3 tools/catalyst_data_providers.py  # Test

Orders Not Executing

Check Alpaca Connection:

uv run python3 -c "
from alpaca.trading.client import TradingClient
import os
client = TradingClient(os.getenv('ALPACA_PAPER_API_KEY'), os.getenv('ALPACA_PAPER_SECRET_KEY'), paper=True)
account = client.get_account()
print(f'Account status: {account.status}')
print(f'Buying power: ${account.buying_power}')
"

Expected: - status: ACTIVE - buying_power: >$19,800

Redis Connection Error

Symptoms: redis.exceptions.ConnectionError

Fix:

# Start Redis container
docker start trading-redis

# Or create if doesn't exist
docker run -d --name trading-redis -p 6379:6379 redis:latest


Safety Features

Automatic Halt Conditions

  • 20% Drawdown: All trading stops automatically
  • Manual Resume Only: Requires explicit approval to resume
  • Alert Channels: Publishes to risk_alerts and portfolio.halt

Position Limits

  • Max Position Value: $1,000 (hard cap)
  • Max Positions: 3 concurrent
  • Max Channel Exposure: 20% of portfolio ($19,800)

Stop Losses

  • Hard Stop: 10% below entry (immediate exit)
  • Trailing Stop: 20% below peak (locks in profits)
  • Time Stop: Exit after 9 days if unprofitable

Earnings Protection (NEW)

  • 7-Day Warning: Reduce 50% at 7 days before earnings
  • Gap Risk: Prevents overnight earnings gaps
  • Re-Entry: Can re-enter after earnings if signals present

Rollback Plan

If strategy shows unexpected behavior:

Step 1: Immediate Stop

# Disable channel
sed -i '' 's/enabled: true/enabled: false/' trading_agents/config/portfolio_config.yaml

# Stop LaunchAgent (if running)
launchctl stop com.trading.micro_cap

Step 2: Close All Positions

uv run python3 -c "
from alpaca.trading.client import TradingClient
import os
client = TradingClient(os.getenv('ALPACA_PAPER_API_KEY'), os.getenv('ALPACA_PAPER_SECRET_KEY'), paper=True)
positions = client.get_all_positions()
for pos in positions:
    if pos.symbol in ['PLTR', 'SOFI', 'RIOT', 'MARA', 'PLUG', 'BLNK', 'CHPT', 'QS', 'OPEN', 'CLOV', 'SKLZ', 'WISH']:
        client.close_position(pos.symbol)
        print(f'Closed {pos.symbol}')
"

Step 3: Analyze Failure - Review logs: logs/trading/micro_cap.log - Check trades in Alpaca dashboard - Compare to backtest expectations - Identify root cause (bug vs market regime change)


Success Criteria (1-Week Validation)

After 5 trading days, check:

Criterion Target Action if Failed
Sharpe Ratio > 0.0 Investigate negative trades
Win Rate > 40% Review entry logic
Max Drawdown < 10% Check stop loss execution
Total Trades >= 1 Normal (low activity week possible)
Strategy Errors 0 Fix bugs before continuing

If all criteria met → Continue paper trading for 4 more weeks (total: 1 month)

If any failed → Debug, fix, and restart 1-week validation


Next Steps After 1 Month

If Validation Successful (Sharpe >0.30, Win Rate >50%)

  1. Consider Live Trading (small scale):
  2. Allocate $500-1000 in Alpaca live account
  3. Test with 1-2 positions max
  4. Monitor for 2 weeks before scaling up

  5. Layer in SEC/FDA Data (if desired):

  6. Implement Form 4 insider trading detection
  7. Add Schedule 13D activist investor tracking
  8. Gradually transition to catalyst-based entries

If Validation Unsuccessful

  1. Analyze failure mode (strategy vs execution)
  2. Re-optimize parameters on recent data
  3. Consider alternative strategies (catalyst-only, hybrid, etc.)

Files Modified (Today)

Configuration

  • trading_agents/config/portfolio_config.yaml (enabled micro_cap, added earnings overlay)

Code

  • trading_agents/position_management_agent.py (integrated yfinance earnings data)

New Tools

  • tools/catalyst_data_providers.py (earnings calendar integration)

Documentation

  • DEPLOY_MICRO_CAP.md (this file)

Support & Monitoring

Logs: - Strategy logs: logs/trading/micro_cap.log - Portfolio logs: logs/trading/portfolio_manager.log - System logs: /tmp/micro_cap_trading.log

Dashboards (if using Grafana): - Portfolio performance: http://localhost:3000/d/portfolio - Risk metrics: http://localhost:3000/d/risk - Jaeger traces: http://localhost:16686

Quick Commands:

# Check current positions
uv run python3 tools/portfolio_fetcher.py

# View recent trades
tail -100 logs/trading/micro_cap.log | grep "Position opened\|Position closed"

# Check earnings calendar for all symbols
uv run python3 tools/catalyst_data_providers.py


Deployment Date: 2025-11-03 Strategy Version: Momentum Breakout v1.0 + Earnings Overlay v1.0 Expected Go-Live: User discretion (ready immediately) Risk Level: LOW (paper trading, validated strategy)

🎯 Ready to deploy when you are!