Tutorial: Production Deployment¶
Deploy your validated strategy to live trading.
Overview¶
This tutorial covers:
- Pre-deployment checklist
- Configuration for production
- Setting up daemon mode
- Connecting to brokers
- Monitoring and alerting
- Handling errors
Pre-Deployment Checklist¶
Strategy Validation¶
Bash
# 1. Run walk-forward validation
sigc run strategy.sig --walk-forward --validate
# 2. Check parameter stability
sigc run strategy.sig --walk-forward --stability-analysis
# 3. Verify recent performance
sigc run strategy.sig --from 2023-01-01
# 4. Test with realistic costs
sigc run strategy.sig --costs "tc.bps(15)"
Required Results¶
- Out-of-sample Sharpe > 0.5
- Degradation < 50%
- Stable parameters across periods
- Positive return after costs
- Max drawdown within risk tolerance
Step 1: Production Configuration¶
Create Config File¶
YAML
# config/production.yaml
# Data source
data:
source: "s3://mybucket/prices/"
format: parquet
refresh_interval: 1h
# Strategy parameters (from walk-forward optimization)
params:
lookback: 60
top_pct: 0.20
position_cap: 0.03
# Risk limits
risk:
max_position: 0.03
max_sector: 0.20
max_drawdown: 0.15
gross_exposure: 2.0
net_exposure_range: [-0.1, 0.1]
# Transaction costs
costs:
commission_bps: 5
spread_bps: 5
market_impact_bps: 2
# Safety systems
safety:
pre_trade_checks: true
max_order_size: 0.02
max_daily_turnover: 0.20
circuit_breaker:
daily_loss_limit: 0.03
position_divergence: 0.10
# Execution
execution:
broker: alpaca
paper_trading: true # Start with paper
order_type: limit
limit_offset_bps: 5
Step 2: Strategy File for Production¶
Separate Production Strategy¶
Text Only
// strategies/momentum_prod.sig
// Import production config
config: "config/production.yaml"
data:
source = config.data.source
format = parquet
// Use fixed parameters (from optimization)
signal momentum:
emit zscore(ret(prices, 60))
signal value:
emit zscore(book_to_market)
signal combined:
emit neutralize(0.6 * momentum + 0.4 * value, by=sectors)
portfolio production:
weights = rank(combined).long_short(
top = 0.20,
bottom = 0.20,
cap = 0.03
)
constraints:
gross_exposure = 2.0
net_exposure: [-0.1, 0.1]
max_sector = 0.20
max_position = 0.03
max_turnover = 0.20
costs = tc.bps(12)
// No backtest - this is live
Step 3: Set Up Daemon Mode¶
Daemon Configuration¶
YAML
# config/daemon.yaml
daemon:
enabled: true
pid_file: "/var/run/sigc/momentum.pid"
log_file: "/var/log/sigc/momentum.log"
schedule:
# Generate weights at 3:30 PM (before market close)
- cron: "30 15 * * 1-5"
action: compute_weights
timezone: "America/New_York"
# Execute at 3:55 PM
- cron: "55 15 * * 1-5"
action: execute_trades
timezone: "America/New_York"
# Retry configuration
retry:
max_attempts: 3
delay_seconds: 60
Start Daemon¶
Bash
# Start in paper trading mode first
sigc daemon start --config config/production.yaml --paper
# Check status
sigc daemon status
# View logs
tail -f /var/log/sigc/momentum.log
Step 4: Connect to Broker¶
Alpaca Configuration¶
YAML
# config/broker.yaml
broker:
name: alpaca
paper: true # Paper trading
credentials:
api_key: ${ALPACA_API_KEY}
api_secret: ${ALPACA_API_SECRET}
settings:
base_url: "https://paper-api.alpaca.markets"
data_url: "https://data.alpaca.markets"
Set Environment Variables¶
Test Connection¶
Text Only
Broker Connection Test: Alpaca (Paper)
======================================
Connection: ✓ Success
Account Status: ACTIVE
Buying Power: $100,000.00
Equity: $100,000.00
Step 5: Paper Trading Period¶
Run Paper Trading¶
Bash
# Start paper trading daemon
sigc daemon start \
--strategy strategies/momentum_prod.sig \
--config config/production.yaml \
--broker config/broker.yaml \
--paper
Monitor Paper Trading¶
Bash
# Check current positions
sigc positions
# View today's trades
sigc trades --today
# Performance summary
sigc performance --period 1w
Paper Trading Checklist¶
Run paper trading for at least 2-4 weeks:
- Trades execute correctly
- Position sizes match targets
- Costs are as expected
- No unexpected errors
- Performance tracks backtest
Step 6: Set Up Monitoring¶
Prometheus Metrics¶
YAML
# config/monitoring.yaml
monitoring:
prometheus:
enabled: true
port: 9090
metrics:
- portfolio_value
- daily_return
- position_count
- turnover
- tracking_error
Alerting Rules¶
YAML
# config/alerts.yaml
alerting:
# Slack notifications
slack:
webhook: ${SLACK_WEBHOOK_URL}
channel: "#trading-alerts"
# Alert rules
rules:
- name: "Large Drawdown"
condition: drawdown > 0.05
severity: warning
- name: "Circuit Breaker"
condition: daily_loss > 0.03
severity: critical
action: halt_trading
- name: "Execution Failure"
condition: trade_failed
severity: critical
- name: "Data Staleness"
condition: data_age > 2h
severity: warning
Enable Alerting¶
Bash
sigc daemon start \
--strategy strategies/momentum_prod.sig \
--config config/production.yaml \
--alerts config/alerts.yaml
Step 7: Go Live¶
Final Checklist¶
Text Only
Pre-Flight Checks
=================
[✓] Strategy file valid
[✓] Data source accessible
[✓] Broker connection OK
[✓] Account has sufficient capital
[✓] Risk limits configured
[✓] Alerting configured
[✓] Logging enabled
Ready for live trading.
Switch to Live¶
Bash
# Start live daemon
sigc daemon start \
--strategy strategies/momentum_prod.sig \
--config config/production.yaml \
--live
# Confirm
sigc daemon status
Step 8: Daily Operations¶
Morning Checks¶
Bash
# Check overnight status
sigc status
# Verify positions
sigc positions --compare target
# Check for alerts
sigc alerts --last 24h
End of Day¶
Bash
# Review trades
sigc trades --today
# Check P&L
sigc performance --today
# Verify reconciliation
sigc reconcile
Weekly Review¶
Bash
# Performance report
sigc report --period 1w --output reports/weekly.html
# Compare to backtest
sigc compare --backtest --period 1w
Error Handling¶
Common Errors¶
Trade Rejection:
Text Only
Error: Trade rejected - insufficient buying power
Action: Check account balance, reduce position sizes
Data Error:
Broker Connection:
Recovery Procedures¶
YAML
# config/recovery.yaml
recovery:
# Automatic recovery
auto_retry:
enabled: true
max_attempts: 3
# Manual intervention required
manual_intervention:
- circuit_breaker_triggered
- large_position_divergence
- broker_account_issue
# Notification
notify_on_recovery: true
Complete Production Setup¶
Directory Structure¶
Text Only
trading/
├── config/
│ ├── production.yaml
│ ├── daemon.yaml
│ ├── broker.yaml
│ ├── alerts.yaml
│ └── monitoring.yaml
├── strategies/
│ └── momentum_prod.sig
├── logs/
│ └── (auto-generated)
├── reports/
│ └── (auto-generated)
└── scripts/
├── start.sh
├── stop.sh
└── health_check.sh
Start Script¶
Bash
#!/bin/bash
# scripts/start.sh
# Load environment
source ~/.trading_env
# Start daemon
sigc daemon start \
--strategy strategies/momentum_prod.sig \
--config config/production.yaml \
--broker config/broker.yaml \
--alerts config/alerts.yaml \
--monitoring config/monitoring.yaml \
--live
echo "Trading daemon started"
Health Check Script¶
Bash
#!/bin/bash
# scripts/health_check.sh
# Check daemon status
STATUS=$(sigc daemon status --json | jq -r '.status')
if [ "$STATUS" != "running" ]; then
echo "CRITICAL: Daemon not running"
exit 2
fi
# Check last trade time
LAST_TRADE=$(sigc trades --last --json | jq -r '.timestamp')
# ... additional checks
echo "OK: All systems operational"
exit 0
Best Practices¶
1. Start Small¶
Begin with small position sizes, increase gradually:
YAML
# Week 1-2
max_position: 0.01 # 1% max
# Week 3-4
max_position: 0.02 # 2% max
# Month 2+
max_position: 0.03 # 3% max (target)
2. Monitor Closely Initially¶
Check multiple times per day during first week.
3. Have a Kill Switch¶
4. Keep Backups¶
Bash
# Backup configuration
cp -r config/ backup/config_$(date +%Y%m%d)/
# Backup state
sigc state export --output backup/state_$(date +%Y%m%d).json
5. Document Everything¶
Keep a trading log of: - Parameter changes - Incidents - Performance notes - Lessons learned
Next Steps¶
- Python Workflow - Advanced analysis
- Monitoring - Detailed monitoring setup
- Alerting - Alert configuration