{"repo": "beepboop2025/economic-intelligence-agent", "files": {"src/demo.py": {"b39a0b4668b2cfb5f1e9279a01dbebfb660ba35a": {"t": 1785596454.3268187, "n": 14742, "h": "f6dba038177d56ba", "c": "#!/usr/bin/env python3\n\"\"\"\nDemo runner for Economic Intelligence Agent v2.0\nRuns a full 9-step pipeline using mock data (no API keys needed)\n\"\"\"\n\nimport os\nimport sys\nimport json\nfrom datetime import datetime\n\nfrom demo_data import generate_all_demo_data\nfrom analysis_engine import AnalysisEngine, ReportGenerator\nfrom report_generator import EnhancedReportGenerator\nfrom quant_engine import QuantEngine\nfrom risk_engine import RiskEngine\nfrom sentiment_engine import SentimentEngine\nfrom alert_engine import AlertEngine\nfrom storage import DataStore\n\n\ndef run_demo(report_format: str = \"markdown\"):\n \"\"\"Run a full demo analysis with the v2.0 pipeline\"\"\"\n\n print(\"\\n\" + \"=\" * 60)\n print(\" ECONOMIC INTELLIGENCE AGENT v2.0 - DEMO MODE\")\n print(\"=\" * 60 + \"\\n\")\n print(\"Using simulated market data for demonstration\\n\")\n\n # Step 1: Generate Demo Data\n print(\"[1/9] Generating demo market data...\")\n print(\"-\" * 40)\n\n data = generate_all_demo_data()\n\n crypto_count = len(data[\"crypto\"][\"top_coins\"])\n news_count = len(data[\"news\"])\n equity_count = len(data[\"equities\"][\"indices\"])\n bond_count = len(data[\"bonds\"][\"yields\"])\n commodity_count = len(data[\"commodities\"][\"prices\"])\n reddit_count = sum(len(v) for v in data.get(\"reddit\", {}).values())\n\n print(f\" Crypto: {crypto_count} coins\")\n print(f\" Equities: {equity_count} indices\")\n print(f\" Bonds: {bond_count} yields\")\n print(f\" Commodities: {commodity_count} items\")\n print(f\" Forex: USD + EUR rates\")\n print(f\" News: {news_count} articles\")\n print(f\" Reddit: {reddit_count} posts\")\n print(f\" GDELT: {len(data.get('gdelt', []))} articles\")\n print(f\" Events: {len(data['economic_events'])} upcoming\")\n\n # Save raw data\n os.makedirs(\"data\", exist_ok=True)\n raw_data_path = f\"data/demo_data_{datetime.now().strftime('%Y%m%d_%H%M')}.json\"\n with open(raw_data_path, \"w\") as f:\n json.dump(data, f, indent=2, default=str)\n print(f\" Raw data saved: {raw_data_path}\")\n\n # Step 2: Store\n print(\"\\n[2/9] Persisting to database...\")\n store = DataStore(\"data/economic_intelligence.db\")\n stored = 0\n for key in (\"top_coins\",):\n items = data.get(\"crypto\", {}).get(key, [])\n if items:\n stored += store.store_market_data_batch(items)\n for key in (\"indices\",):\n items = data.get(\"equities\", {}).get(key, [])\n if items:\n stored += store.store_market_data_batch(items)\n stored += store.store_market_data_batch(data.get(\"bonds\", {}).get(\"yields\", []))\n stored += store.store_market_data_batch(data.get(\"commodities\", {}).get(\"prices\", []))\n print(f\" Stored {stored} records\")\n\n # Step 3: Quant\n print(\"\\n[3/9] Running quantitative analysis...\")\n quant_engine = QuantEngine()\n quant_summary = quant_engine.generate_quant_summary(data)\n yc = quant_summary.get(\"yield_curve\", {})\n print(f\" Yield curve 2Y-10Y spread: {yc.get('spread_2y10y', 'N/A')}%\")\n print(f\" Inverted: {'Yes' if yc.get('inverted') else 'No'}\")\n\n # Step 4: Sentiment\n print(\"\\n[4/9] Analyzing sentiment...\")\n sent_engine = SentimentEngine()\n sent_summary = sent_engine.generate_sentiment_summary(data)\n fg = sent_summary.get(\"fear_greed\", {})\n print(f\" Fear/Greed: {fg.get('value', 50):.0f}/100 ({fg.get('label', 'neutral')})\")\n ns = sent_summary.get(\"news_sentiment\", {})\n print(f\" News sentiment: {ns.get('label', 'N/A')} (score: {ns.get('compound', 0):.3f})\")\n\n # Step 5: Risk\n print(\"\\n[5/9] Computing risk metrics...\")\n risk_engine = RiskEngine()\n risk_summary = risk_engine.generate_risk_summary(data)\n print(f\" Overall risk: {risk_summary.get('overall_risk_level', 'N/A').upper()}\")\n stress = risk_summary.get(\"stress_tests\", [])\n if stress:\n worst = stress[0]\n print(f\" Worst scenario: {worst['description']} ({worst['pnl_pct']:+.1f}%)\")\n\n # Step 6: LLM Analysis\n print(\"\\n[6/9] AI analysis...\")\n api_key = os.getenv(\"OPENROUTER_KEY\") or os.getenv(\"OPENAI_API_KEY\") or os.getenv(\"ANTHROPIC_API_KEY\")\n\n if not api_key:\n print(\" No LLM key — using mock analysis\")\n analysis = generate_mock_analysis(data)\n else:\n llm_config = {\n \"provider\": \"openrouter\" if os.getenv(\"OPENROUTER_KEY\") else (\"openai\" if os.getenv(\"OPENAI_API_KEY\") else \"anthropic\"),\n \"model\": \"anthropic/claude-3.5-sonnet\" if os.getenv(\"OPENROUTER_KEY\") else \"gpt-4\",\n \"api_key\": api_key,\n \"temperature\": 0.3,\n \"max_tokens\": 4000,\n }\n try:\n analyzer = AnalysisEngine(llm_config)\n analysis = analyzer.analyze_market_data(data)\n if \"error\" in analysis:\n print(f\" LLM failed: {analysis['error']}\")\n analysis = generate_mock_analysis(data)\n else:\n print(f\" Tone: {analysis.get('executive_summary', {}).get('market_tone', 'N/A').upper()}\")\n except Exception as e:\n print(f\" Analysis error: {e}\")\n analysis = generate_mock_analysis(data)\n\n # Step 7: Alerts\n print(\"\\n[7/9] Evaluating alerts...\")\n alert_engine = AlertEngine({\"channels\": [\"console\"]}, store=store)\n new_alerts = alert_engine.evaluate_and_notify(data, quant_summary, sent_summary, risk_summary)\n print(f\" {len(new_alerts)} alerts triggered\")\n\n # Step 8: Report\n print(f\"\\n[8/9] Generating {report_format} report...\")\n reporter = EnhancedReportGenerator(\"reports\")\n previous = store.get_last_analysis()\n\n if report_format == \"html\":\n report = reporter.generate_html(analysis, data, quant=quant_summary, risk=risk_summary, sentiment=sent_summary, alerts=new_alerts, previous=previous)\n elif report_format == \"json\":\n report = reporter.generate_json(analysis, data, quant=quant_summary, risk=risk_summary, sentiment=sent_summary, alerts=new_alerts)\n else:\n report = reporter.generate_markdown(analysis, data, quant=quant_summary, risk=risk_summary, sentiment=sent_summary, alerts=new_alerts, previous=previous)\n\n ts = datetime.now().strftime(\"%Y%m%d_%H%M\")\n ext = {\"markdown\": \"md\", \"html\": \"html\", \"json\": \"json\"}.get(report_format, \"md\")\n report_path = reporter.save_report(report, f\"demo_report_{ts}.{ext}\", fmt=report_format)\n print(f\" Report saved: {report_path}\")\n\n # Step 9: Archive\n print(\"\\n[9/9] Archiving analysis...\")\n es = analysis.get(\"executive_summary\", {})\n store.store_analysis(\n market_tone=es.get(\"market_tone\", \"unknown\"),\n key_theme=es.get(\"key_theme\", \"\"),\n summary=analysis,\n report_path=report_path,\n report_format=report_format,\n )\n print(\" Archived to database\")\n\n # Summary\n print(\"\\n\" + \"=\" * 60)\n print(\" DEMO ANALYSIS COMPLETE\")\n print(\"=\" * 60)\n\n print(f\"\\nMarket Tone: {es.get('market_tone', 'N/A').upper()}\")\n print(f\"Key Theme: {es.get('key_theme', 'N/A')}\")\n print(f\"Risk Level: {risk_summary.get('overall_risk_level', 'N/A').upper()}\")\n print(f\"Fear/Greed: {fg.get('value', 50):.0f}/100 ({fg.get('label', 'neutral')})\")\n print(f\"Alerts: {len(new_alerts)}\")\n\n # DB stats\n stats = store.get_stats()\n print(f\"\\nDatabase: {stats}\")\n\n # Report preview\n print(\"\\n\" + \"=\" * 60)\n print(\" REPORT PREVIEW:\")\n print(\"=\" * 60)\n lines = report.split(\"\\n\")\n preview = \"\\n\".join(lines[:50])\n print(preview + \"\\n... [Report continues — see full file]\\n\")\n\n store.close()\n return report_path\n\n\ndef generate_mock_analysis(data: dict) -> dict:\n \"\"\"Generate a mock analysis when LLM is unavailable\"\"\"\n\n btc_data = next((c for c in data[\"crypto\"][\"top_coins\"] if c.symbol == \"BTC\"), None)\n btc_price = btc_data.price if btc_data else 85000\n\n return {\n \"executive_summary\": {\n \"market_tone\": \"mixed\",\n \"key_theme\": \"Central bank divergence and crypto institutional adoption driving cross-asset volatility, with inflation concerns moderating but growth worries emerging.\",\n \"primary_risk_factors\": [\n \"Commercial real estate refinancing cliff with $1.5T debt maturing 2024-2025\",\n \"Persistent inflation forcing central banks to maintain restrictive policy longer\",\n \"Geopolitical tensions in Middle East threatening energy supply stability\",\n \"China property sector stress with potential global contagion\",\n ],\n \"primary_opportunities\": [\n \"Bitcoin ETF inflows creating structural demand floor\",\n \"Gold benefiting from fiscal dominance and de-dollarization trends\",\n \"Energy sector on supply constraints and infrastructure investment\",\n \"AI productivity boom driving technology sector earnings\",\n ],\n },\n \"market_overview\": {\n \"equities\": {\n \"trend\": \"Consolidation with rotation from mega-cap tech to value and small-caps\",\n \"key_levels\": \"S&P 500 support at 5750/5650, resistance at 5900/6000\",\n \"sentiment\": \"neutral\",\n },\n \"bonds\": {\n \"yield_trend\": \"Range-bound with 10Y Treasury 4.1-4.4%, curve steepening beginning\",\n \"curve_shape\": \"inverted\",\n \"implications\": \"Historical recession indicator, but soft landing still possible\",\n },\n \"crypto\": {\n \"market_phase\": \"accumulation\",\n \"dominance_trends\": \"BTC dominance elevated at 58% on institutional flows\",\n \"risk_appetite\": \"moderate\",\n },\n \"forex\": {\n \"dollar_strength\": \"strong\",\n \"major_moves\": \"USD/JPY near 150 intervention watch, EUR/USD testing 0.92 support\",\n \"carry_trade_activity\": \"Reduced as BoJ normalizes, unwind risk elevated\",\n },\n },\n \"key_events\": [\n {\"event\": \"Fed Chair Powell Congressional testimony\", \"impact\": \"immediate\", \"affected_assets\": [\"USD\", \"Treasuries\", \"Gold\", \"Bitcoin\"], \"market_implication\": \"Dovish tone bullish for risk assets\"},\n {\"event\": \"US Non-Farm Payrolls release\", \"impact\": \"immediate\", \"affected_assets\": [\"USD\", \"Treasuries\", \"Equities\"], \"market_implication\": \"Strong data delays rate cut expectations\"},\n {\"event\": \"ECB Rate Decision with updated projections\", \"impact\": \"delayed\", \"affected_assets\": [\"EUR\", \"European equities\"], \"market_implication\": \"Easing signals bearish for EUR\"},\n ],\n \"cross_asset_analysis\": [\n {\"observation\": \"Bitcoin and Gold decoupling from traditional risk assets\", \"assets_involved\": [\"Bitcoin\", \"Gold\", \"USD\"], \"historical_context\": \"Similar to 2020-2021 inflation hedge phase\", \"implications\": \"Treat both as distinct inflation/uncertainty hedges\"},\n {\"observation\": \"Equity-bond correlation normalizing to negative\", \"assets_involved\": [\"S&P 500\", \"10Y Treasury\"], \"historical_context\": \"Positive correlation during 2022 was anomaly\", \"implications\": \"Traditional 60/40 diversification working again\"},\n ],\n \"risk_assessment\": {\n \"systemic_risks\": [\n {\"risk\": \"CRE refinancing crisis as $1.5T debt matures into higher rates\", \"severity\": \"high\", \"probability\": \"medium\", \"trigger_events\": [\"Regional bank failures\", \"Office vacancy >25%\"]},\n {\"risk\": \"Treasury market liquidity stress amid QT\", \"severity\": \"medium\", \"probability\": \"medium\", \"trigger_events\": [\"Auction tail risks\", \"Foreign selling\"]},\n ],\n \"tail_risks\": [\n \"Middle East conflict disrupting oil above $120/bbl\",\n \"Major crypto exchange failure triggering DeFi contagion\",\n \"AI bubble burst with concentrated tech valuations\",\n ],\n \"hedging_considerations\": \"Long volatility via VIX calls, increase gold to 10-15%, maintain USD cash buffer\",\n },\n \"sector_rotation\": {\n \"current_flows\": \"Rotation from mega-cap tech to small-cap value and energy\",\n \"leading_sectors\": [\"Energy\", \"Financials\", \"Materials\", \"Utilities\"],\n \"lagging_sectors\": [\"Technology\", \"Communication Services\", \"Real Estate\"],\n \"rotation_stage\": \"mid\",\n },\n \"outlook\": {\n \"immediate_1_7_days\": f\"Range-bound. BTC consolidating ${btc_price - 3000:.0f}-${btc_price + 3000:.0f}. Dollar strong but overbought.\",\n \"short_term_1_4_weeks\": \"Directional catalyst from NFP and CPI data. Soft landing = risk-on rally.\",\n \"medium_term_1_6_months\": \"Baseline: soft landing, Fed cuts 2-3 times mid-year. Bear case: credit event.\",\n \"key_levels_to_watch\": {\n \"equities\": \"S&P 5650 support, 6000 breakout, VIX 20 fear threshold\",\n \"bonds\": \"10Y 3.8% bullish, 4.5% bearish, 2s10s flattening\",\n \"crypto\": f\"BTC ${btc_price - 5000:.0f} support, $100k psychological\",\n \"forex\": \"DXY 108 resistance, USD/JPY 150 intervention\",\n },\n \"catalysts_to_monitor\": [\n \"Fed policy pivot signals\",\n \"Inflation trajectory (CPI/PCE)\",\n \"Corporate earnings guidance\",\n \"China stimulus effectiveness\",\n \"Geopolitical escalations\",\n ],\n },\n \"trade_setups\": [\n {\"idea\": f\"Long BTC in ${btc_price - 5000:.0f}-${btc_price - 2000:.0f} accumulation zone\", \"rationale\": \"ETF inflows + halving catalyst\", \"risk_reward\": \"3:1\", \"timeframe\": \"medium\"},\n {\"idea\": \"Yield curve steepener: Long 2Y, Short 10Y\", \"rationale\": \"Curve normalization as Fed cuts\", \"risk_reward\": \"2.5:1\", \"timeframe\": \"short\"},\n {\"idea\": \"Gold long on dips to $2800-$2825\", \"rationale\": \"Fiscal dominance hedge + central bank buying\", \"risk_reward\": \"2:1\", \"timeframe\": \"short\"},\n ],\n }\n\n\nif __name__ == \"__main__\":\n import argparse\n parser = argparse.ArgumentParser(description=\"EconAgent Demo\")\n parser.add_argument(\"--format\", choices=[\"markdown\", \"html\", \"json\"], default=\"markdown\")\n args = parser.parse_args()\n\n try:\n report_path = run_demo(args.format)\n print(f\"\\nFull report: {report_path}\")\n print(\"\\nTo run with live data:\")\n print(\" 1. Get API keys from OpenRouter (free): https://openrouter.ai/\")\n print(\" 2. export OPENROUTER_KEY='your_key'\")\n print(\" 3. python src/main.py\")\n except KeyboardInterrupt:\n print(\"\\n\\nDemo interrupted\")\n except Exception as e:\n print(f\"\\nError: {e}\")\n import traceback\n traceback.print_exc()\n"}}}}