#!/bin/bash # monitor_paper_trading.sh - Real-time monitoring for paper trading # Created: 2025-10-14 # Usage: ./scripts/monitor_paper_trading.sh set -euo pipefail # Colors GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' RED='\033[0;31m' NC='\033[0m' # Database connection DB_URL="postgresql://foxhunt:foxhunt_dev_password@localhost:5432/foxhunt" # Clear screen and show header clear echo -e "${BLUE}=========================================" echo "Ensemble Paper Trading - Live Monitor" echo "=========================================${NC}" echo "Press Ctrl+C to exit" echo "" # Monitoring loop (refresh every 10 seconds) while true; do echo -e "${BLUE}[$(date +%H:%M:%S)] Updating metrics...${NC}" echo "" # Service Health echo -e "${YELLOW}━━━ Service Health ━━━${NC}" HEALTH=$(curl -s http://localhost:8081/health 2>/dev/null || echo '{"status":"offline"}') STATUS=$(echo "$HEALTH" | jq -r '.status // "offline"') MODE=$(echo "$HEALTH" | jq -r '.ensemble.mode // "unknown"') MODELS=$(echo "$HEALTH" | jq -r '.ensemble.models[]? // empty' | tr '\n' ', ' | sed 's/,$//') if [ "$STATUS" = "healthy" ]; then echo -e " Status: ${GREEN}✅ $STATUS${NC}" else echo -e " Status: ${RED}❌ $STATUS${NC}" fi echo -e " Mode: $MODE" echo -e " Models: $MODELS" echo "" # Today's Performance echo -e "${YELLOW}━━━ Today's Performance ━━━${NC}" psql "$DB_URL" -t -c " SELECT COUNT(*) AS trades, SUM(CASE WHEN pnl > 0 THEN 1 ELSE 0 END) AS wins, (SUM(CASE WHEN pnl > 0 THEN 1 ELSE 0 END)::FLOAT / NULLIF(COUNT(*), 0) * 100)::NUMERIC(5,2) AS win_rate, SUM(pnl)::NUMERIC(10,2) AS total_pnl, AVG(ensemble_confidence)::NUMERIC(4,3) AS avg_confidence, AVG(disagreement_rate)::NUMERIC(4,3) AS avg_disagreement FROM paper_trading_predictions WHERE DATE(timestamp) = CURRENT_DATE AND executed = TRUE; " | while read -r trades wins win_rate pnl confidence disagreement; do trades=$(echo "$trades" | xargs) wins=$(echo "$wins" | xargs) win_rate=$(echo "$win_rate" | xargs) pnl=$(echo "$pnl" | xargs) confidence=$(echo "$confidence" | xargs) disagreement=$(echo "$disagreement" | xargs) echo " Total Trades: $trades" echo " Winning Trades: $wins" if (( $(echo "$win_rate > 52" | bc -l) )); then echo -e " Win Rate: ${GREEN}$win_rate%${NC} (Target: >52%)" else echo -e " Win Rate: ${YELLOW}$win_rate%${NC} (Target: >52%)" fi if (( $(echo "$pnl > 0" | bc -l) )); then echo -e " Total P&L: ${GREEN}\$${pnl}${NC}" else echo -e " Total P&L: ${RED}\$${pnl}${NC}" fi echo " Avg Confidence: $confidence" echo " Avg Disagreement: $disagreement" done echo "" # Per-Symbol Performance echo -e "${YELLOW}━━━ Per-Symbol Performance (Today) ━━━${NC}" psql "$DB_URL" -t -c " SELECT symbol, COUNT(*) AS trades, SUM(pnl)::NUMERIC(10,2) AS pnl FROM paper_trading_predictions WHERE DATE(timestamp) = CURRENT_DATE AND executed = TRUE GROUP BY symbol ORDER BY pnl DESC; " | while read -r symbol trades pnl; do symbol=$(echo "$symbol" | xargs) trades=$(echo "$trades" | xargs) pnl=$(echo "$pnl" | xargs) if [ -n "$symbol" ]; then if (( $(echo "$pnl > 0" | bc -l) )); then echo -e " $symbol: $trades trades, ${GREEN}\$${pnl}${NC}" else echo -e " $symbol: $trades trades, ${RED}\$${pnl}${NC}" fi fi done echo "" # Model Weights echo -e "${YELLOW}━━━ Current Model Weights ━━━${NC}" psql "$DB_URL" -t -c " SELECT AVG(dqn_weight)::NUMERIC(4,3) AS dqn_weight, AVG(ppo_weight)::NUMERIC(4,3) AS ppo_weight FROM paper_trading_predictions WHERE timestamp > NOW() - INTERVAL '1 hour' AND executed = TRUE; " | while read -r dqn_weight ppo_weight; do dqn_weight=$(echo "$dqn_weight" | xargs) ppo_weight=$(echo "$ppo_weight" | xargs) if [ -n "$dqn_weight" ]; then echo " DQN: ${dqn_weight} ($(echo "$dqn_weight * 100" | bc)%)" echo " PPO: ${ppo_weight} ($(echo "$ppo_weight * 100" | bc)%)" else echo " No data yet" fi done echo "" # High Disagreement Events echo -e "${YELLOW}━━━ High Disagreement Events (Last Hour) ━━━${NC}" HIGH_DISAGREEMENT=$(psql "$DB_URL" -t -c " SELECT COUNT(*) FROM paper_trading_predictions WHERE disagreement_rate > 0.5 AND timestamp > NOW() - INTERVAL '1 hour'; " | xargs) if [ "$HIGH_DISAGREEMENT" -gt 0 ]; then echo -e " ${YELLOW}⚠️ $HIGH_DISAGREEMENT events${NC}" else echo -e " ${GREEN}✅ 0 events${NC}" fi echo "" # Circuit Breaker Status echo -e "${YELLOW}━━━ Circuit Breaker Status ━━━${NC}" TRIGGERS=$(psql "$DB_URL" -t -c " SELECT COUNT(*) FROM paper_trading_circuit_breaker_log WHERE DATE(timestamp) = CURRENT_DATE AND resolved_at IS NULL; " | xargs) if [ "$TRIGGERS" -gt 0 ]; then echo -e " ${RED}❌ $TRIGGERS active triggers${NC}" else echo -e " ${GREEN}✅ No triggers${NC}" fi echo "" # Success Criteria Progress echo -e "${YELLOW}━━━ Success Criteria (7-Day Rolling) ━━━${NC}" # Calculate Sharpe ratio SHARPE=$(psql "$DB_URL" -t -c "SELECT calculate_sharpe_ratio('ES.FUT', 7);" | xargs) if [ -n "$SHARPE" ] && [ "$SHARPE" != "null" ]; then if (( $(echo "$SHARPE > 1.5" | bc -l) )); then echo -e " Sharpe Ratio: ${GREEN}$SHARPE${NC} (Target: >1.5) ✅" else echo -e " Sharpe Ratio: ${YELLOW}$SHARPE${NC} (Target: >1.5)" fi else echo " Sharpe Ratio: N/A (insufficient data)" fi # Calculate 7-day win rate WIN_RATE_7D=$(psql "$DB_URL" -t -c " SELECT (SUM(CASE WHEN pnl > 0 THEN 1 ELSE 0 END)::FLOAT / NULLIF(COUNT(*), 0) * 100)::NUMERIC(5,2) FROM paper_trading_predictions WHERE timestamp >= NOW() - INTERVAL '7 days' AND executed = TRUE; " | xargs) if [ -n "$WIN_RATE_7D" ]; then if (( $(echo "$WIN_RATE_7D > 52" | bc -l) )); then echo -e " Win Rate: ${GREEN}${WIN_RATE_7D}%${NC} (Target: >52%) ✅" else echo -e " Win Rate: ${YELLOW}${WIN_RATE_7D}%${NC} (Target: >52%)" fi else echo " Win Rate: N/A (insufficient data)" fi # Calculate max drawdown MAX_DD=$(psql "$DB_URL" -t -c "SELECT calculate_max_drawdown('ES.FUT', 7);" | xargs) if [ -n "$MAX_DD" ] && [ "$MAX_DD" != "null" ]; then if (( $(echo "$MAX_DD > -10" | bc -l) )); then echo -e " Max Drawdown: ${GREEN}${MAX_DD}%${NC} (Target: <-10%) ✅" else echo -e " Max Drawdown: ${RED}${MAX_DD}%${NC} (Target: <-10%)" fi else echo " Max Drawdown: N/A (insufficient data)" fi echo "" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo "Refreshing in 10 seconds..." echo "" sleep 10 clear echo -e "${BLUE}=========================================" echo "Ensemble Paper Trading - Live Monitor" echo "=========================================${NC}" echo "Press Ctrl+C to exit" echo "" done