POTE/scripts/analyze_official.py
ilia 0d8d85adc1 Add complete automation, reporting, and CI/CD system
Features Added:
==============

📧 EMAIL REPORTING SYSTEM:
- EmailReporter: Send reports via SMTP (Gmail, SendGrid, custom)
- ReportGenerator: Generate daily/weekly summaries with HTML/text formatting
- Configurable via .env (SMTP_HOST, SMTP_PORT, etc.)
- Scripts: send_daily_report.py, send_weekly_report.py

🤖 AUTOMATED RUNS:
- automated_daily_run.sh: Full daily ETL pipeline + reporting
- automated_weekly_run.sh: Weekly pattern analysis + reports
- setup_cron.sh: Interactive cron job setup (5-minute setup)
- Logs saved to ~/logs/ with automatic cleanup

🔍 HEALTH CHECKS:
- health_check.py: System health monitoring
- Checks: DB connection, data freshness, counts, recent alerts
- JSON output for programmatic use
- Exit codes for monitoring integration

🚀 CI/CD PIPELINE:
- .github/workflows/ci.yml: Full CI/CD pipeline
- GitHub Actions / Gitea Actions compatible
- Jobs: lint & test, security scan, dependency scan, Docker build
- PostgreSQL service for integration tests
- 93 tests passing in CI

📚 COMPREHENSIVE DOCUMENTATION:
- AUTOMATION_QUICKSTART.md: 5-minute email setup guide
- docs/12_automation_and_reporting.md: Full automation guide
- Updated README.md with automation links
- Deployment → Production workflow guide

🛠️ IMPROVEMENTS:
- All shell scripts made executable
- Environment variable examples in .env.example
- Report logs saved with timestamps
- 30-day log retention with auto-cleanup
- Health checks can be scheduled via cron

WHAT THIS ENABLES:
==================
After deployment, users can:
1. Set up automated daily/weekly email reports (5 min)
2. Receive HTML+text emails with:
   - New trades, market alerts, suspicious timing
   - Weekly patterns, rankings, repeat offenders
3. Monitor system health automatically
4. Run full CI/CD pipeline on every commit
5. Deploy with confidence (tests + security scans)

USAGE:
======
# One-time setup (on deployed server)
./scripts/setup_cron.sh

# Or manually send reports
python scripts/send_daily_report.py --to user@example.com
python scripts/send_weekly_report.py --to user@example.com

# Check system health
python scripts/health_check.py

See AUTOMATION_QUICKSTART.md for full instructions.

93 tests passing | Full CI/CD | Email reports ready
2025-12-15 15:34:31 -05:00

142 lines
4.4 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Analyze performance of a specific official.
"""
import argparse
import logging
import sys
from pote.analytics.metrics import PerformanceMetrics
from pote.db import get_session
from pote.db.models import Official
logging.basicConfig(level=logging.INFO, format="%(message)s")
logger = logging.getLogger(__name__)
def format_pct(value):
"""Format percentage."""
return f"{float(value):+.2f}%"
def format_money(value):
"""Format money."""
return f"${float(value):,.0f}"
def main():
parser = argparse.ArgumentParser(description="Analyze official's trading performance")
parser.add_argument("name", help="Official's name (e.g., 'Nancy Pelosi')")
parser.add_argument(
"--window",
type=int,
default=90,
help="Return window in days (default: 90)",
)
parser.add_argument(
"--benchmark",
default="SPY",
help="Benchmark ticker (default: SPY)",
)
args = parser.parse_args()
with next(get_session()) as session:
# Find official
official = (
session.query(Official)
.filter(Official.name.ilike(f"%{args.name}%"))
.first()
)
if not official:
logger.error(f"Official not found: {args.name}")
logger.info("Available officials:")
for o in session.query(Official).all():
logger.info(f" - {o.name}")
sys.exit(1)
# Get performance metrics
metrics = PerformanceMetrics(session)
perf = metrics.official_performance(
official.id,
window_days=args.window,
benchmark=args.benchmark,
)
# Display results
print()
print("=" * 70)
print(f" {perf['name']} Performance Analysis")
print("=" * 70)
print()
print(f"Party: {perf['party']}")
print(f"Chamber: {perf['chamber']}")
print(f"State: {perf['state']}")
print(f"Window: {perf['window_days']} days")
print(f"Benchmark: {perf['benchmark']}")
print()
if perf.get("trades_analyzed", 0) == 0:
print("⚠️ No trades with sufficient price data to analyze")
sys.exit(0)
print("📊 TRADING ACTIVITY")
print("-" * 70)
print(f"Total Trades: {perf['total_trades']}")
print(f"Analyzed: {perf['trades_analyzed']}")
print(f"Buy Trades: {perf['buy_trades']}")
print(f"Sell Trades: {perf['sell_trades']}")
print(f"Total Value: {format_money(perf['total_value_traded'])}")
print()
print("📈 PERFORMANCE METRICS")
print("-" * 70)
print(f"Average Return: {format_pct(perf['avg_return'])}")
print(f"Median Return: {format_pct(perf['median_return'])}")
print(f"Max Return: {format_pct(perf['max_return'])}")
print(f"Min Return: {format_pct(perf['min_return'])}")
print()
print("🎯 VS MARKET ({})".format(perf['benchmark']))
print("-" * 70)
print(f"Average Alpha: {format_pct(perf['avg_alpha'])}")
print(f"Median Alpha: {format_pct(perf['median_alpha'])}")
print(f"Win Rate: {perf['win_rate']:.1%}")
print(f"Beat Market Rate: {perf['beat_market_rate']:.1%}")
print()
print("🏆 BEST/WORST TRADES")
print("-" * 70)
best = perf['best_trade']
worst = perf['worst_trade']
print(f"Best: {best['ticker']:6s} {format_pct(best['return']):>10s} ({best['date']})")
print(f"Worst: {worst['ticker']:6s} {format_pct(worst['return']):>10s} ({worst['date']})")
print()
# Signal
alpha = float(perf['avg_alpha'])
beat_rate = perf['beat_market_rate']
print("🔔 RESEARCH SIGNAL")
print("-" * 70)
if alpha > 5 and beat_rate > 0.65:
print("✅ FOLLOW_RESEARCH: Strong positive alpha with high win rate")
elif alpha > 2 and beat_rate > 0.55:
print("⭐ FOLLOW_RESEARCH: Moderate positive alpha")
elif alpha < -5 or beat_rate < 0.35:
print("🚨 AVOID_RISK: Negative alpha or poor performance")
elif perf['total_trades'] < 5:
print("👀 WATCH: Limited data, need more trades for confidence")
else:
print("📊 NEUTRAL: Performance close to market")
print()
print("=" * 70)
if __name__ == "__main__":
main()