{"repo": "altusrossouw/reddit-stonks", "files": {"app.py": {"9572f1123a0c8c29495e0ee8cf3d5c5f8cc5008c": {"t": 1785745407.607817, "n": 10760, "h": "f9006a62feee209f", "c": "#!/usr/bin/env python3\nimport asyncio\nimport json\nimport os\nimport re\nimport sys\nfrom datetime import datetime\n\nfrom dotenv import load_dotenv\nfrom openai import OpenAI\nfrom fastapi import FastAPI, Query\nfrom fastapi.responses import HTMLResponse, StreamingResponse\nfrom fastapi.staticfiles import StaticFiles\n\nfrom reddit_scraper import scrape_all\nfrom stock_data import fetch_stock_data, find_european_equivalents\nfrom backtest import save_pick, compute_performance\n\nload_dotenv()\n\nDEEPSEEK_API_KEY = os.getenv(\"DEEPSEEK_API_KEY\")\nDEEPSEEK_BASE_URL = \"https://api.deepseek.com/v1\"\n\nclient = OpenAI(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)\napp = FastAPI(title=\"Reddit Stonks\")\nTOP_N_TICKERS = 20\n\n\ndef extract_top_picks(analysis: str) -> list[str]:\n picks: list[str] = []\n for match in re.finditer(\n r\"\\*\\*TOP PICK:\\s*\\$?(\\w+)\\*\\*|\\*\\*RUNNER-UP:\\s*\\$?(\\w+)\\*\\*|\\*\\*WILDCARD[^*]*:\\s*\\$?(\\w+)\\*\\*\",\n analysis,\n ):\n ticker = match.group(1) or match.group(2) or match.group(3)\n if ticker:\n picks.append(ticker)\n return picks\n\n\ndef parse_confidence(analysis: str) -> int:\n m = re.search(r\"Confidence Score:\\s*(\\d+)/10\", analysis, re.IGNORECASE)\n return int(m.group(1)) if m else 0\n\n\ndef parse_top_ticker_price(ticker: str, stock_data: dict) -> float:\n sd = stock_data.get(ticker, {})\n return sd.get(\"price\", 0)\n\n\ndef build_context(reddit_data: dict, stock_data: dict, euro: bool = False) -> str:\n ticker_counts = reddit_data[\"ticker_counts\"]\n top_tickers = list(ticker_counts.keys())[:TOP_N_TICKERS]\n trends = reddit_data.get(\"trends\", {})\n\n lines = [\n f\"Analysis Date: {datetime.now().strftime('%Y-%m-%d %H:%M UTC')}\",\n f\"Total Reddit Posts Analyzed: {len(reddit_data['posts'])}\",\n \"\",\n \"=== STOCK DATA (with MOMENTUM TREND) ===\",\n ]\n\n for ticker in top_tickers:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n mentions = ticker_counts.get(ticker, 0)\n trend = trends.get(ticker, \"steady\")\n cap_str = f\"${sd['market_cap']/1e9:.1f}B\" if sd[\"market_cap\"] else \"N/A\"\n target_str = f\"${sd['target_mean']:.2f}\" if sd.get(\"target_mean\") else \"N/A\"\n short_str = f\"{sd['short_pct']*100:.1f}%\" if sd.get(\"short_pct\") else \"N/A\"\n\n lines.append(\n f\"${ticker} ({sd['short_name']}): \"\n f\"Price=${sd['price']:.2f}, \"\n f\"MktCap={cap_str}, \"\n f\"Sector={sd['sector']}, \"\n f\"1WkChange={sd['week_change_pct']:+.2f}%, \"\n f\"P/E={sd.get('pe_ratio', 'N/A')}, \"\n f\"FwdP/E={sd.get('forward_pe', 'N/A')}, \"\n f\"Beta={sd.get('beta', 'N/A')}, \"\n f\"50dMA={sd.get('fifty_day_avg', 'N/A')}, \"\n f\"200dMA={sd.get('two_hundred_day_avg', 'N/A')}, \"\n f\"Recommendation={sd['recommendation']}, \"\n f\"AnalystTarget={target_str}, \"\n f\"ShortFloat={short_str}, \"\n f\"InstOwnership={sd.get('inst_ownership', 'N/A')}, \"\n f\"VolRatio={sd['volume_ratio']}, \"\n f\"RedditMentions={mentions}, \"\n f\"MentionsTrend={trend} (rising=accelerating hype, falling=fading interest, new=first appearance, steady=same level)\"\n )\n\n trending_up = [t for t in top_tickers if trends.get(t) == \"rising\"]\n trending_down = [t for t in top_tickers if trends.get(t) == \"falling\"]\n if trending_up:\n lines.append(f\"\\nRISING mentions (more hype this week vs last): {', '.join('$'+t for t in trending_up)}\")\n if trending_down:\n lines.append(f\"FALLING mentions (less hype this week vs last): {', '.join('$'+t for t in trending_down)}\")\n\n lines.append(\"\")\n lines.append(\"=== REDDIT MENTION RANKING ===\")\n for ticker, count in list(ticker_counts.items())[:TOP_N_TICKERS]:\n trend_icon = {\"rising\": \"↑\", \"falling\": \"↓\", \"new\": \"★\", \"steady\": \"→\", \"gone\": \"✗\"}.get(trends.get(ticker, \"\"), \"\")\n lines.append(f\" ${ticker}: {count} mentions {trend_icon}\")\n\n if euro:\n lines.append(\"\")\n lines.append(\"=== NOTE ===\")\n lines.append(\"Include European exchange equivalents section in your response.\")\n\n return \"\\n\".join(lines)\n\n\nasync def run_analysis(context: str) -> str:\n system_prompt = (\n \"You are a senior quantitative analyst at a top hedge fund. \"\n \"Your specialty is combining social media sentiment analysis with \"\n \"fundamental and technical data to identify short-term trading opportunities. \"\n \"Output your analysis in clear sections with specific reasoning. \"\n \"Be concise and data-driven.\\n\\n\"\n \"CRITICAL: A stock with RISING mentions + strong fundamentals is a buy signal. \"\n \"A stock with FALLING mentions (fading hype) is a sell signal — do NOT pick these. \"\n \"A stock with RISING mentions but weak fundamentals is a hype trap — be skeptical. \"\n \"Weight fundamentals (P/E, beta, analyst consensus) at least as heavily as Reddit sentiment.\"\n )\n\n user_prompt = f\"\"\"Analyze the following data and determine which single stock has the highest probability of delivering the best return over the NEXT 7 DAYS (1 week).\n\nConsider:\n1. Reddit hype/momentum\n2. Recent price action and technical setup\n3. Valuation (P/E, forward P/E)\n4. Short squeeze potential\n5. Volume anomalies\n6. Analyst sentiment and price targets\n7. Sector momentum\n\nOutput format:\n\n**TOP PICK: $TICKER**\n- Rationale: (2-3 sentences)\n\n**RUNNER-UP: $TICKER**\n- Rationale: (1-2 sentences)\n\n**WILDCARD (High Risk/Reward): $TICKER**\n- Rationale: (1-2 sentences)\n\n**Risk Factors to Watch:**\n- (2-3 bullet points)\n\n**Confidence Score: X/10**\n- (1 sentence)\n\nDATA:\n{context}\"\"\"\n\n loop = asyncio.get_event_loop()\n try:\n response = await loop.run_in_executor(\n None,\n lambda: client.chat.completions.create(\n model=\"deepseek-v4-flash\",\n messages=[\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt},\n ],\n temperature=0.3,\n max_tokens=1200,\n ),\n )\n return response.choices[0].message.content or \"(no response)\"\n except Exception as e:\n return f\"Error calling Deepseek API: {e}\"\n\n\nasync def send_event(msg_type: str, data: dict):\n yield f\"data: {json.dumps({'type': msg_type, **data})}\\n\\n\"\n\n\nasync def event_stream(posts_per_sub: int, euro: bool):\n try:\n yield f\"data: {json.dumps({'type': 'status', 'message': 'Scraping Reddit...'})}\\n\\n\"\n\n loop = asyncio.get_event_loop()\n reddit_data = await loop.run_in_executor(None, lambda: scrape_all(limit_per_sub=posts_per_sub))\n\n ticker_count = len(reddit_data[\"ticker_counts\"])\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Found {ticker_count} unique tickers. Fetching stock data...'})}\\n\\n\"\n\n top_tickers = list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]\n stock_data = await loop.run_in_executor(None, fetch_stock_data, top_tickers)\n\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Stock data ready for {len(stock_data)} tickers. Sending to AI...'})}\\n\\n\"\n\n stock_rows = []\n for ticker in list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n stock_rows.append({\n \"ticker\": ticker,\n \"price\": sd[\"price\"],\n \"currency\": sd[\"currency\"],\n \"market_cap\": sd[\"market_cap\"],\n \"sector\": sd[\"sector\"],\n \"short_name\": sd[\"short_name\"],\n \"week_change_pct\": sd[\"week_change_pct\"],\n \"pe_ratio\": sd.get(\"pe_ratio\"),\n \"forward_pe\": sd.get(\"forward_pe\"),\n \"beta\": sd.get(\"beta\"),\n \"volume_ratio\": sd[\"volume_ratio\"],\n \"short_pct\": sd.get(\"short_pct\"),\n \"inst_ownership\": sd.get(\"inst_ownership\"),\n \"recommendation\": sd[\"recommendation\"],\n \"target_mean\": sd.get(\"target_mean\"),\n \"mentions\": reddit_data[\"ticker_counts\"].get(ticker, 0),\n \"trend\": reddit_data.get(\"trends\", {}).get(ticker, \"steady\"),\n })\n\n context = build_context(reddit_data, stock_data, euro=euro)\n analysis = await run_analysis(context)\n\n picks = extract_top_picks(analysis)\n top_ticker = picks[0] if len(picks) > 0 else \"\"\n runner_ticker = picks[1] if len(picks) > 1 else \"\"\n wildcard_ticker = picks[2] if len(picks) > 2 else \"\"\n\n save_pick(\n top_pick=top_ticker,\n top_price=parse_top_ticker_price(top_ticker, stock_data),\n runner_up=runner_ticker,\n runner_up_price=parse_top_ticker_price(runner_ticker, stock_data),\n wildcard=wildcard_ticker,\n wildcard_price=parse_top_ticker_price(wildcard_ticker, stock_data),\n confidence=parse_confidence(analysis),\n posts_scraped=len(reddit_data[\"posts\"]),\n tickers_found=len(reddit_data[\"ticker_counts\"]),\n analysis=analysis,\n )\n\n euro_data = []\n if euro:\n picks = extract_top_picks(analysis)\n for us_ticker in picks:\n eq = await loop.run_in_executor(None, find_european_equivalents, us_ticker)\n euro_data.append({\"us_ticker\": us_ticker, \"equivalents\": eq})\n\n yield f\"data: {json.dumps({'type': 'result', 'stocks': stock_rows, 'analysis': analysis, 'euro': euro_data})}\\n\\n\"\n yield f\"data: {json.dumps({'type': 'done'})}\\n\\n\"\n\n except Exception as e:\n yield f\"data: {json.dumps({'type': 'error', 'message': str(e)})}\\n\\n\"\n yield f\"data: {json.dumps({'type': 'done'})}\\n\\n\"\n\n\n@app.get(\"/api/analyze\")\nasync def analyze(\n posts: int = Query(25, ge=10, le=25),\n euro: bool = Query(False),\n):\n return StreamingResponse(\n event_stream(posts, euro),\n media_type=\"text/event-stream\",\n headers={\n \"Cache-Control\": \"no-cache\",\n \"X-Accel-Buffering\": \"no\",\n },\n )\n\n\n@app.get(\"/\")\nasync def index():\n return HTMLResponse(open(\"static/index.html\").read())\n\n\n@app.get(\"/app\")\nasync def app_page():\n return HTMLResponse(open(\"static/app.html\").read())\n\n\n@app.get(\"/track-record\")\nasync def track_record_page():\n return HTMLResponse(open(\"static/track-record.html\").read())\n\n\n@app.get(\"/api/track-record\")\nasync def track_record_api():\n loop = asyncio.get_event_loop()\n return await loop.run_in_executor(None, compute_performance)\n\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n"}, "d6fd3bd3400f7d2a5ad8be10176a2bca3a8f2aa8": {"t": 1785752902.2421706, "n": 10647, "h": "c59217cb123416c9", "c": "#!/usr/bin/env python3\nimport asyncio\nimport json\nimport os\nimport re\nimport sys\nfrom datetime import datetime\n\nfrom dotenv import load_dotenv\nfrom openai import OpenAI\nfrom fastapi import FastAPI, Query\nfrom fastapi.responses import HTMLResponse, StreamingResponse\nfrom fastapi.staticfiles import StaticFiles\n\nfrom reddit_scraper import scrape_all\nfrom stock_data import fetch_stock_data, find_european_equivalents\nfrom backtest import save_pick, compute_performance\n\nload_dotenv()\n\nDEEPSEEK_API_KEY = os.getenv(\"DEEPSEEK_API_KEY\")\nDEEPSEEK_BASE_URL = \"https://api.deepseek.com/v1\"\n\nclient = OpenAI(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)\napp = FastAPI(title=\"Reddit Stonks\")\nTOP_N_TICKERS = 20\n\n\ndef extract_top_picks(analysis: str) -> list[str]:\n picks: list[str] = []\n for match in re.finditer(\n r\"\\*\\*TOP PICK:\\s*\\$?(\\w+)\\*\\*|\\*\\*RUNNER-UP:\\s*\\$?(\\w+)\\*\\*|\\*\\*WILDCARD[^*]*:\\s*\\$?(\\w+)\\*\\*\",\n analysis,\n ):\n ticker = match.group(1) or match.group(2) or match.group(3)\n if ticker:\n picks.append(ticker)\n return picks\n\n\ndef parse_confidence(analysis: str) -> int:\n m = re.search(r\"Confidence Score:\\s*(\\d+)/10\", analysis, re.IGNORECASE)\n return int(m.group(1)) if m else 0\n\n\ndef parse_top_ticker_price(ticker: str, stock_data: dict) -> float:\n sd = stock_data.get(ticker, {})\n return sd.get(\"price\", 0)\n\n\ndef build_context(reddit_data: dict, stock_data: dict, euro: bool = False) -> str:\n ticker_counts = reddit_data[\"ticker_counts\"]\n top_tickers = list(ticker_counts.keys())[:TOP_N_TICKERS]\n trends = reddit_data.get(\"trends\", {})\n\n lines = [\n f\"Analysis Date: {datetime.now().strftime('%Y-%m-%d %H:%M UTC')}\",\n f\"Total Reddit Posts Analyzed: {len(reddit_data['posts'])}\",\n \"\",\n \"=== STOCK DATA (with MOMENTUM TREND) ===\",\n ]\n\n for ticker in top_tickers:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n mentions = ticker_counts.get(ticker, 0)\n trend = trends.get(ticker, \"steady\")\n cap_str = f\"${sd['market_cap']/1e9:.1f}B\" if sd[\"market_cap\"] else \"N/A\"\n target_str = f\"${sd['target_mean']:.2f}\" if sd.get(\"target_mean\") else \"N/A\"\n short_str = f\"{sd['short_pct']*100:.1f}%\" if sd.get(\"short_pct\") else \"N/A\"\n\n lines.append(\n f\"${ticker} ({sd['short_name']}): \"\n f\"Price=${sd['price']:.2f}, \"\n f\"MktCap={cap_str}, \"\n f\"Sector={sd['sector']}, \"\n f\"1WkChange={sd['week_change_pct']:+.2f}%, \"\n f\"P/E={sd.get('pe_ratio', 'N/A')}, \"\n f\"FwdP/E={sd.get('forward_pe', 'N/A')}, \"\n f\"Beta={sd.get('beta', 'N/A')}, \"\n f\"50dMA={sd.get('fifty_day_avg', 'N/A')}, \"\n f\"200dMA={sd.get('two_hundred_day_avg', 'N/A')}, \"\n f\"Recommendation={sd['recommendation']}, \"\n f\"AnalystTarget={target_str}, \"\n f\"ShortFloat={short_str}, \"\n f\"VolRatio={sd['volume_ratio']}, \"\n f\"RedditMentions={mentions}, \"\n f\"MentionsTrend={trend} (rising=accelerating hype, falling=fading interest, new=first appearance, steady=same level)\"\n )\n\n trending_up = [t for t in top_tickers if trends.get(t) == \"rising\"]\n trending_down = [t for t in top_tickers if trends.get(t) == \"falling\"]\n if trending_up:\n lines.append(f\"\\nRISING mentions (more hype this week vs last): {', '.join('$'+t for t in trending_up)}\")\n if trending_down:\n lines.append(f\"FALLING mentions (less hype this week vs last): {', '.join('$'+t for t in trending_down)}\")\n\n lines.append(\"\")\n lines.append(\"=== REDDIT MENTION RANKING ===\")\n for ticker, count in list(ticker_counts.items())[:TOP_N_TICKERS]:\n trend_icon = {\"rising\": \"↑\", \"falling\": \"↓\", \"new\": \"★\", \"steady\": \"→\", \"gone\": \"✗\"}.get(trends.get(ticker, \"\"), \"\")\n lines.append(f\" ${ticker}: {count} mentions {trend_icon}\")\n\n if euro:\n lines.append(\"\")\n lines.append(\"=== NOTE ===\")\n lines.append(\"Include European exchange equivalents section in your response.\")\n\n return \"\\n\".join(lines)\n\n\nasync def run_analysis(context: str) -> str:\n system_prompt = (\n \"You are a senior quantitative analyst at a top hedge fund. \"\n \"Your specialty is combining social media sentiment analysis with \"\n \"fundamental and technical data to identify short-term trading opportunities. \"\n \"Output your analysis in clear sections with specific reasoning. \"\n \"Be concise and data-driven.\\n\\n\"\n \"CRITICAL: A stock with RISING mentions + strong fundamentals is a buy signal. \"\n \"A stock with FALLING mentions (fading hype) is a sell signal — do NOT pick these. \"\n \"A stock with RISING mentions but weak fundamentals is a hype trap — be skeptical. \"\n \"Weight fundamentals (P/E, beta, analyst consensus) at least as heavily as Reddit sentiment.\"\n )\n\n user_prompt = f\"\"\"Analyze the following data and determine which single stock has the highest probability of delivering the best return over the NEXT 7 DAYS (1 week).\n\nConsider:\n1. Reddit hype/momentum\n2. Recent price action and technical setup\n3. Valuation (P/E, forward P/E)\n4. Short squeeze potential\n5. Volume anomalies\n6. Analyst sentiment and price targets\n7. Sector momentum\n\nOutput format:\n\n**TOP PICK: $TICKER**\n- Rationale: (2-3 sentences)\n\n**RUNNER-UP: $TICKER**\n- Rationale: (1-2 sentences)\n\n**WILDCARD (High Risk/Reward): $TICKER**\n- Rationale: (1-2 sentences)\n\n**Risk Factors to Watch:**\n- (2-3 bullet points)\n\n**Confidence Score: X/10**\n- (1 sentence)\n\nDATA:\n{context}\"\"\"\n\n loop = asyncio.get_event_loop()\n try:\n response = await loop.run_in_executor(\n None,\n lambda: client.chat.completions.create(\n model=\"deepseek-v4-flash\",\n messages=[\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt},\n ],\n temperature=0.3,\n max_tokens=1200,\n ),\n )\n return response.choices[0].message.content or \"(no response)\"\n except Exception as e:\n return f\"Error calling Deepseek API: {e}\"\n\n\nasync def send_event(msg_type: str, data: dict):\n yield f\"data: {json.dumps({'type': msg_type, **data})}\\n\\n\"\n\n\nasync def event_stream(posts_per_sub: int, euro: bool):\n try:\n yield f\"data: {json.dumps({'type': 'status', 'message': 'Scraping Reddit...'})}\\n\\n\"\n\n loop = asyncio.get_event_loop()\n reddit_data = await loop.run_in_executor(None, lambda: scrape_all(limit_per_sub=posts_per_sub))\n\n ticker_count = len(reddit_data[\"ticker_counts\"])\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Found {ticker_count} unique tickers. Fetching stock data...'})}\\n\\n\"\n\n top_tickers = list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]\n stock_data = await loop.run_in_executor(None, fetch_stock_data, top_tickers)\n\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Stock data ready for {len(stock_data)} tickers. Sending to AI...'})}\\n\\n\"\n\n stock_rows = []\n for ticker in list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n stock_rows.append({\n \"ticker\": ticker,\n \"price\": sd[\"price\"],\n \"currency\": sd[\"currency\"],\n \"market_cap\": sd[\"market_cap\"],\n \"sector\": sd[\"sector\"],\n \"short_name\": sd[\"short_name\"],\n \"week_change_pct\": sd[\"week_change_pct\"],\n \"pe_ratio\": sd.get(\"pe_ratio\"),\n \"forward_pe\": sd.get(\"forward_pe\"),\n \"beta\": sd.get(\"beta\"),\n \"volume_ratio\": sd[\"volume_ratio\"],\n \"short_pct\": sd.get(\"short_pct\"),\n \"recommendation\": sd[\"recommendation\"],\n \"target_mean\": sd.get(\"target_mean\"),\n \"mentions\": reddit_data[\"ticker_counts\"].get(ticker, 0),\n \"trend\": reddit_data.get(\"trends\", {}).get(ticker, \"steady\"),\n })\n\n context = build_context(reddit_data, stock_data, euro=euro)\n analysis = await run_analysis(context)\n\n picks = extract_top_picks(analysis)\n top_ticker = picks[0] if len(picks) > 0 else \"\"\n runner_ticker = picks[1] if len(picks) > 1 else \"\"\n wildcard_ticker = picks[2] if len(picks) > 2 else \"\"\n\n save_pick(\n top_pick=top_ticker,\n top_price=parse_top_ticker_price(top_ticker, stock_data),\n runner_up=runner_ticker,\n runner_up_price=parse_top_ticker_price(runner_ticker, stock_data),\n wildcard=wildcard_ticker,\n wildcard_price=parse_top_ticker_price(wildcard_ticker, stock_data),\n confidence=parse_confidence(analysis),\n posts_scraped=len(reddit_data[\"posts\"]),\n tickers_found=len(reddit_data[\"ticker_counts\"]),\n analysis=analysis,\n )\n\n euro_data = []\n if euro:\n picks = extract_top_picks(analysis)\n for us_ticker in picks:\n eq = await loop.run_in_executor(None, find_european_equivalents, us_ticker)\n euro_data.append({\"us_ticker\": us_ticker, \"equivalents\": eq})\n\n yield f\"data: {json.dumps({'type': 'result', 'stocks': stock_rows, 'analysis': analysis, 'euro': euro_data})}\\n\\n\"\n yield f\"data: {json.dumps({'type': 'done'})}\\n\\n\"\n\n except Exception as e:\n yield f\"data: {json.dumps({'type': 'error', 'message': str(e)})}\\n\\n\"\n yield f\"data: {json.dumps({'type': 'done'})}\\n\\n\"\n\n\n@app.get(\"/api/analyze\")\nasync def analyze(\n posts: int = Query(25, ge=10, le=25),\n euro: bool = Query(False),\n):\n return StreamingResponse(\n event_stream(posts, euro),\n media_type=\"text/event-stream\",\n headers={\n \"Cache-Control\": \"no-cache\",\n \"X-Accel-Buffering\": \"no\",\n },\n )\n\n\n@app.get(\"/\")\nasync def index():\n return HTMLResponse(open(\"static/index.html\").read())\n\n\n@app.get(\"/app\")\nasync def app_page():\n return HTMLResponse(open(\"static/app.html\").read())\n\n\n@app.get(\"/track-record\")\nasync def track_record_page():\n return HTMLResponse(open(\"static/track-record.html\").read())\n\n\n@app.get(\"/api/track-record\")\nasync def track_record_api():\n loop = asyncio.get_event_loop()\n return await loop.run_in_executor(None, compute_performance)\n\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n"}, "8ecfb3655ac7b4ee3a0aaf8ce65d1e8dda50bb6e": {"t": 1785752906.0325675, "n": 10131, "h": "6950f79d4a839c21", "c": "#!/usr/bin/env python3\nimport asyncio\nimport json\nimport os\nimport re\nimport sys\nfrom datetime import datetime\n\nfrom dotenv import load_dotenv\nfrom openai import OpenAI\nfrom fastapi import FastAPI, Query\nfrom fastapi.responses import HTMLResponse, StreamingResponse\nfrom fastapi.staticfiles import StaticFiles\n\nfrom reddit_scraper import scrape_all\nfrom stock_data import fetch_stock_data, find_european_equivalents\nfrom backtest import save_pick, compute_performance\n\nload_dotenv()\n\nDEEPSEEK_API_KEY = os.getenv(\"DEEPSEEK_API_KEY\")\nDEEPSEEK_BASE_URL = \"https://api.deepseek.com/v1\"\n\nclient = OpenAI(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)\napp = FastAPI(title=\"Reddit Stonks\")\nTOP_N_TICKERS = 20\n\n\ndef extract_top_picks(analysis: str) -> list[str]:\n picks: list[str] = []\n for match in re.finditer(\n r\"\\*\\*TOP PICK:\\s*\\$?(\\w+)\\*\\*|\\*\\*RUNNER-UP:\\s*\\$?(\\w+)\\*\\*|\\*\\*WILDCARD[^*]*:\\s*\\$?(\\w+)\\*\\*\",\n analysis,\n ):\n ticker = match.group(1) or match.group(2) or match.group(3)\n if ticker:\n picks.append(ticker)\n return picks\n\n\ndef parse_confidence(analysis: str) -> int:\n m = re.search(r\"Confidence Score:\\s*(\\d+)/10\", analysis, re.IGNORECASE)\n return int(m.group(1)) if m else 0\n\n\ndef parse_top_ticker_price(ticker: str, stock_data: dict) -> float:\n sd = stock_data.get(ticker, {})\n return sd.get(\"price\", 0)\n\n\ndef build_context(reddit_data: dict, stock_data: dict, euro: bool = False) -> str:\n ticker_counts = reddit_data[\"ticker_counts\"]\n top_tickers = list(ticker_counts.keys())[:TOP_N_TICKERS]\n trends = reddit_data.get(\"trends\", {})\n\n lines = [\n f\"Analysis Date: {datetime.now().strftime('%Y-%m-%d %H:%M UTC')}\",\n f\"Total Reddit Posts Analyzed: {len(reddit_data['posts'])}\",\n \"\",\n \"=== STOCK DATA (with MOMENTUM TREND) ===\",\n ]\n\n for ticker in top_tickers:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n mentions = ticker_counts.get(ticker, 0)\n trend = trends.get(ticker, \"steady\")\n cap_str = f\"${sd['market_cap']/1e9:.1f}B\" if sd[\"market_cap\"] else \"N/A\"\n target_str = f\"${sd['target_mean']:.2f}\" if sd.get(\"target_mean\") else \"N/A\"\n short_str = f\"{sd['short_pct']*100:.1f}%\" if sd.get(\"short_pct\") else \"N/A\"\n\n lines.append(\n f\"${ticker} ({sd['short_name']}): \"\n f\"Price=${sd['price']:.2f}, \"\n f\"MktCap={cap_str}, \"\n f\"Sector={sd['sector']}, \"\n f\"1WkChange={sd['week_change_pct']:+.2f}%, \"\n f\"P/E={sd.get('pe_ratio', 'N/A')}, \"\n f\"FwdP/E={sd.get('forward_pe', 'N/A')}, \"\n f\"Beta={sd.get('beta', 'N/A')}, \"\n f\"50dMA={sd.get('fifty_day_avg', 'N/A')}, \"\n f\"200dMA={sd.get('two_hundred_day_avg', 'N/A')}, \"\n f\"Recommendation={sd['recommendation']}, \"\n f\"AnalystTarget={target_str}, \"\n f\"ShortFloat={short_str}, \"\n f\"VolRatio={sd['volume_ratio']}, \"\n f\"RedditMentions={mentions}, \"\n f\"MentionsTrend={trend} (rising=accelerating hype, falling=fading interest, new=first appearance, steady=same level)\"\n )\n\n trending_up = [t for t in top_tickers if trends.get(t) == \"rising\"]\n trending_down = [t for t in top_tickers if trends.get(t) == \"falling\"]\n if trending_up:\n lines.append(f\"\\nRISING mentions (more hype this week vs last): {', '.join('$'+t for t in trending_up)}\")\n if trending_down:\n lines.append(f\"FALLING mentions (less hype this week vs last): {', '.join('$'+t for t in trending_down)}\")\n\n lines.append(\"\")\n lines.append(\"=== REDDIT MENTION RANKING ===\")\n for ticker, count in list(ticker_counts.items())[:TOP_N_TICKERS]:\n trend_icon = {\"rising\": \"↑\", \"falling\": \"↓\", \"new\": \"★\", \"steady\": \"→\", \"gone\": \"✗\"}.get(trends.get(ticker, \"\"), \"\")\n lines.append(f\" ${ticker}: {count} mentions {trend_icon}\")\n\n if euro:\n lines.append(\"\")\n lines.append(\"=== NOTE ===\")\n lines.append(\"Include European exchange equivalents section in your response.\")\n\n return \"\\n\".join(lines)\n\n\nasync def run_analysis(context: str) -> str:\n system_prompt = (\n \"You are a senior quantitative analyst at a top hedge fund. \"\n \"Your specialty is combining social media sentiment analysis with \"\n \"fundamental and technical data to identify short-term trading opportunities. \"\n \"Output your analysis in clear sections with specific reasoning. \"\n \"Be concise and data-driven.\\n\\n\"\n \"CRITICAL: A stock with RISING mentions + strong fundamentals is a buy signal. \"\n \"A stock with FALLING mentions (fading hype) is a sell signal — do NOT pick these. \"\n \"A stock with RISING mentions but weak fundamentals is a hype trap — be skeptical. \"\n \"Weight fundamentals (P/E, beta, analyst consensus) at least as heavily as Reddit sentiment.\"\n )\n\n user_prompt = f\"\"\"Analyze the following data and determine which single stock has the highest probability of delivering the best return over the NEXT 7 DAYS (1 week).\n\nConsider:\n1. Reddit hype/momentum\n2. Recent price action and technical setup\n3. Valuation (P/E, forward P/E)\n4. Short squeeze potential\n5. Volume anomalies\n6. Analyst sentiment and price targets\n7. Sector momentum\n\nOutput format:\n\n**TOP PICK: $TICKER**\n- Rationale: (2-3 sentences)\n\n**RUNNER-UP: $TICKER**\n- Rationale: (1-2 sentences)\n\n**WILDCARD (High Risk/Reward): $TICKER**\n- Rationale: (1-2 sentences)\n\n**Risk Factors to Watch:**\n- (2-3 bullet points)\n\n**Confidence Score: X/10**\n- (1 sentence)\n\nDATA:\n{context}\"\"\"\n\n loop = asyncio.get_event_loop()\n try:\n response = await loop.run_in_executor(\n None,\n lambda: client.chat.completions.create(\n model=\"deepseek-v4-flash\",\n messages=[\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt},\n ],\n temperature=0.3,\n max_tokens=1200,\n ),\n )\n return response.choices[0].message.content or \"(no response)\"\n except Exception as e:\n return f\"Error calling Deepseek API: {e}\"\n\n\nasync def event_stream(posts_per_sub: int, euro: bool):\n yield f\"data: {json.dumps({'type': 'status', 'message': 'Scraping Reddit...'})}\\n\\n\"\n\n loop = asyncio.get_event_loop()\n reddit_data = await loop.run_in_executor(None, lambda: scrape_all(limit_per_sub=posts_per_sub))\n\n ticker_count = len(reddit_data[\"ticker_counts\"])\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Found {ticker_count} unique tickers. Fetching stock data...'})}\\n\\n\"\n\n top_tickers = list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]\n stock_data = await loop.run_in_executor(None, fetch_stock_data, top_tickers)\n\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Stock data ready for {len(stock_data)} tickers. Sending to AI...'})}\\n\\n\"\n\n stock_rows = []\n for ticker in list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n stock_rows.append({\n \"ticker\": ticker,\n \"price\": sd[\"price\"],\n \"currency\": sd[\"currency\"],\n \"market_cap\": sd[\"market_cap\"],\n \"sector\": sd[\"sector\"],\n \"short_name\": sd[\"short_name\"],\n \"week_change_pct\": sd[\"week_change_pct\"],\n \"pe_ratio\": sd.get(\"pe_ratio\"),\n \"forward_pe\": sd.get(\"forward_pe\"),\n \"beta\": sd.get(\"beta\"),\n \"volume_ratio\": sd[\"volume_ratio\"],\n \"short_pct\": sd.get(\"short_pct\"),\n \"recommendation\": sd[\"recommendation\"],\n \"target_mean\": sd.get(\"target_mean\"),\n \"mentions\": reddit_data[\"ticker_counts\"].get(ticker, 0),\n \"trend\": reddit_data.get(\"trends\", {}).get(ticker, \"steady\"),\n })\n\n context = build_context(reddit_data, stock_data, euro=euro)\n analysis = await run_analysis(context)\n\n picks = extract_top_picks(analysis)\n top_ticker = picks[0] if len(picks) > 0 else \"\"\n runner_ticker = picks[1] if len(picks) > 1 else \"\"\n wildcard_ticker = picks[2] if len(picks) > 2 else \"\"\n\n save_pick(\n top_pick=top_ticker,\n top_price=parse_top_ticker_price(top_ticker, stock_data),\n runner_up=runner_ticker,\n runner_up_price=parse_top_ticker_price(runner_ticker, stock_data),\n wildcard=wildcard_ticker,\n wildcard_price=parse_top_ticker_price(wildcard_ticker, stock_data),\n confidence=parse_confidence(analysis),\n posts_scraped=len(reddit_data[\"posts\"]),\n tickers_found=len(reddit_data[\"ticker_counts\"]),\n analysis=analysis,\n )\n\n euro_data = []\n if euro:\n picks = extract_top_picks(analysis)\n for us_ticker in picks:\n eq = await loop.run_in_executor(None, find_european_equivalents, us_ticker)\n euro_data.append({\"us_ticker\": us_ticker, \"equivalents\": eq})\n\n yield f\"data: {json.dumps({'type': 'result', 'stocks': stock_rows, 'analysis': analysis, 'euro': euro_data})}\\n\\n\"\n yield f\"data: {json.dumps({'type': 'done'})}\\n\\n\"\n\n\n@app.get(\"/api/analyze\")\nasync def analyze(\n posts: int = Query(25, ge=10, le=25),\n euro: bool = Query(False),\n):\n return StreamingResponse(\n event_stream(posts, euro),\n media_type=\"text/event-stream\",\n headers={\n \"Cache-Control\": \"no-cache\",\n \"X-Accel-Buffering\": \"no\",\n },\n )\n\n\n@app.get(\"/\")\nasync def index():\n return HTMLResponse(open(\"static/index.html\").read())\n\n\n@app.get(\"/app\")\nasync def app_page():\n return HTMLResponse(open(\"static/app.html\").read())\n\n\n@app.get(\"/track-record\")\nasync def track_record_page():\n return HTMLResponse(open(\"static/track-record.html\").read())\n\n\n@app.get(\"/api/track-record\")\nasync def track_record_api():\n loop = asyncio.get_event_loop()\n return await loop.run_in_executor(None, compute_performance)\n\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n"}, "0bdc2cae393221e85a62ba359cd05a27d58ed3af": {"t": 1785752907.2961493, "n": 8877, "h": "2b839d2a0bb67986", "c": "#!/usr/bin/env python3\nimport asyncio\nimport json\nimport os\nimport re\nimport sys\nfrom datetime import datetime\n\nfrom dotenv import load_dotenv\nfrom openai import OpenAI\nfrom fastapi import FastAPI, Query\nfrom fastapi.responses import HTMLResponse, StreamingResponse\nfrom fastapi.staticfiles import StaticFiles\n\nfrom reddit_scraper import scrape_all\nfrom stock_data import fetch_stock_data, find_european_equivalents\nfrom backtest import save_pick, compute_performance\n\nload_dotenv()\n\nDEEPSEEK_API_KEY = os.getenv(\"DEEPSEEK_API_KEY\")\nDEEPSEEK_BASE_URL = \"https://api.deepseek.com/v1\"\n\nclient = OpenAI(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)\napp = FastAPI(title=\"Reddit Stonks\")\nTOP_N_TICKERS = 20\n\n\ndef extract_top_picks(analysis: str) -> list[str]:\n picks: list[str] = []\n for match in re.finditer(\n r\"\\*\\*TOP PICK:\\s*\\$?(\\w+)\\*\\*|\\*\\*RUNNER-UP:\\s*\\$?(\\w+)\\*\\*|\\*\\*WILDCARD[^*]*:\\s*\\$?(\\w+)\\*\\*\",\n analysis,\n ):\n ticker = match.group(1) or match.group(2) or match.group(3)\n if ticker:\n picks.append(ticker)\n return picks\n\n\ndef parse_confidence(analysis: str) -> int:\n m = re.search(r\"Confidence Score:\\s*(\\d+)/10\", analysis, re.IGNORECASE)\n return int(m.group(1)) if m else 0\n\n\ndef parse_top_ticker_price(ticker: str, stock_data: dict) -> float:\n sd = stock_data.get(ticker, {})\n return sd.get(\"price\", 0)\n\n\ndef build_context(reddit_data: dict, stock_data: dict, euro: bool = False) -> str:\n ticker_counts = reddit_data[\"ticker_counts\"]\n top_tickers = list(ticker_counts.keys())[:TOP_N_TICKERS]\n\n lines = [\n f\"Analysis Date: {datetime.now().strftime('%Y-%m-%d %H:%M UTC')}\",\n f\"Total Reddit Posts Analyzed: {len(reddit_data['posts'])}\",\n \"\",\n \"=== STOCK DATA ===\",\n ]\n\n for ticker in top_tickers:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n mentions = ticker_counts.get(ticker, 0)\n cap_str = f\"${sd['market_cap']/1e9:.1f}B\" if sd[\"market_cap\"] else \"N/A\"\n target_str = f\"${sd['target_mean']:.2f}\" if sd.get(\"target_mean\") else \"N/A\"\n short_str = f\"{sd['short_pct']*100:.1f}%\" if sd.get(\"short_pct\") else \"N/A\"\n\n lines.append(\n f\"${ticker} ({sd['short_name']}): \"\n f\"Price=${sd['price']:.2f}, \"\n f\"MktCap={cap_str}, \"\n f\"Sector={sd['sector']}, \"\n f\"1WkChange={sd['week_change_pct']:+.2f}%, \"\n f\"P/E={sd.get('pe_ratio', 'N/A')}, \"\n f\"FwdP/E={sd.get('forward_pe', 'N/A')}, \"\n f\"Beta={sd.get('beta', 'N/A')}, \"\n f\"50dMA={sd.get('fifty_day_avg', 'N/A')}, \"\n f\"200dMA={sd.get('two_hundred_day_avg', 'N/A')}, \"\n f\"Recommendation={sd['recommendation']}, \"\n f\"AnalystTarget={target_str}, \"\n f\"ShortFloat={short_str}, \"\n f\"VolRatio={sd['volume_ratio']}, \"\n f\"RedditMentions={mentions}\"\n )\n\n lines.append(\"\")\n lines.append(\"=== REDDIT MENTION RANKING ===\")\n for ticker, count in list(ticker_counts.items())[:TOP_N_TICKERS]:\n lines.append(f\" ${ticker}: {count} mentions\")\n\n if euro:\n lines.append(\"\")\n lines.append(\"=== NOTE ===\")\n lines.append(\"Include European exchange equivalents section in your response.\")\n\n return \"\\n\".join(lines)\n\n\nasync def run_analysis(context: str) -> str:\n system_prompt = (\n \"You are a senior quantitative analyst at a top hedge fund. \"\n \"Your specialty is combining social media sentiment analysis with \"\n \"fundamental and technical data to identify short-term trading opportunities. \"\n \"Output your analysis in clear sections with specific reasoning. \"\n \"Be concise and data-driven.\"\n )\n\n user_prompt = f\"\"\"Analyze the following data and determine which single stock has the highest probability of delivering the best return over the NEXT 7 DAYS (1 week).\n\nConsider:\n1. Reddit hype/momentum\n2. Recent price action and technical setup\n3. Valuation (P/E, forward P/E)\n4. Short squeeze potential\n5. Volume anomalies\n6. Analyst sentiment and price targets\n7. Sector momentum\n\nOutput format:\n\n**TOP PICK: $TICKER**\n- Rationale: (2-3 sentences)\n\n**RUNNER-UP: $TICKER**\n- Rationale: (1-2 sentences)\n\n**WILDCARD (High Risk/Reward): $TICKER**\n- Rationale: (1-2 sentences)\n\n**Risk Factors to Watch:**\n- (2-3 bullet points)\n\n**Confidence Score: X/10**\n- (1 sentence)\n\nDATA:\n{context}\"\"\"\n\n loop = asyncio.get_event_loop()\n try:\n response = await loop.run_in_executor(\n None,\n lambda: client.chat.completions.create(\n model=\"deepseek-v4-flash\",\n messages=[\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt},\n ],\n temperature=0.3,\n max_tokens=1200,\n ),\n )\n return response.choices[0].message.content or \"(no response)\"\n except Exception as e:\n return f\"Error calling Deepseek API: {e}\"\n\n\nasync def event_stream(posts_per_sub: int, euro: bool):\n yield f\"data: {json.dumps({'type': 'status', 'message': 'Scraping Reddit...'})}\\n\\n\"\n\n loop = asyncio.get_event_loop()\n reddit_data = await loop.run_in_executor(None, lambda: scrape_all(limit_per_sub=posts_per_sub))\n\n ticker_count = len(reddit_data[\"ticker_counts\"])\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Found {ticker_count} unique tickers. Fetching stock data...'})}\\n\\n\"\n\n top_tickers = list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]\n stock_data = await loop.run_in_executor(None, fetch_stock_data, top_tickers)\n\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Stock data ready for {len(stock_data)} tickers. Sending to AI...'})}\\n\\n\"\n\n stock_rows = []\n for ticker in list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n stock_rows.append({\n \"ticker\": ticker,\n \"price\": sd[\"price\"],\n \"currency\": sd[\"currency\"],\n \"market_cap\": sd[\"market_cap\"],\n \"sector\": sd[\"sector\"],\n \"short_name\": sd[\"short_name\"],\n \"week_change_pct\": sd[\"week_change_pct\"],\n \"pe_ratio\": sd.get(\"pe_ratio\"),\n \"forward_pe\": sd.get(\"forward_pe\"),\n \"beta\": sd.get(\"beta\"),\n \"volume_ratio\": sd[\"volume_ratio\"],\n \"short_pct\": sd.get(\"short_pct\"),\n \"recommendation\": sd[\"recommendation\"],\n \"target_mean\": sd.get(\"target_mean\"),\n \"mentions\": reddit_data[\"ticker_counts\"].get(ticker, 0),\n })\n\n context = build_context(reddit_data, stock_data, euro=euro)\n analysis = await run_analysis(context)\n\n picks = extract_top_picks(analysis)\n top_ticker = picks[0] if len(picks) > 0 else \"\"\n runner_ticker = picks[1] if len(picks) > 1 else \"\"\n wildcard_ticker = picks[2] if len(picks) > 2 else \"\"\n\n save_pick(\n top_pick=top_ticker,\n top_price=parse_top_ticker_price(top_ticker, stock_data),\n runner_up=runner_ticker,\n runner_up_price=parse_top_ticker_price(runner_ticker, stock_data),\n wildcard=wildcard_ticker,\n wildcard_price=parse_top_ticker_price(wildcard_ticker, stock_data),\n confidence=parse_confidence(analysis),\n posts_scraped=len(reddit_data[\"posts\"]),\n tickers_found=len(reddit_data[\"ticker_counts\"]),\n analysis=analysis,\n )\n\n euro_data = []\n if euro:\n picks = extract_top_picks(analysis)\n for us_ticker in picks:\n eq = await loop.run_in_executor(None, find_european_equivalents, us_ticker)\n euro_data.append({\"us_ticker\": us_ticker, \"equivalents\": eq})\n\n yield f\"data: {json.dumps({'type': 'result', 'stocks': stock_rows, 'analysis': analysis, 'euro': euro_data})}\\n\\n\"\n yield f\"data: {json.dumps({'type': 'done'})}\\n\\n\"\n\n\n@app.get(\"/api/analyze\")\nasync def analyze(\n posts: int = Query(25, ge=10, le=25),\n euro: bool = Query(False),\n):\n return StreamingResponse(\n event_stream(posts, euro),\n media_type=\"text/event-stream\",\n headers={\n \"Cache-Control\": \"no-cache\",\n \"X-Accel-Buffering\": \"no\",\n },\n )\n\n\n@app.get(\"/\")\nasync def index():\n return HTMLResponse(open(\"static/index.html\").read())\n\n\n@app.get(\"/app\")\nasync def app_page():\n return HTMLResponse(open(\"static/app.html\").read())\n\n\n@app.get(\"/track-record\")\nasync def track_record_page():\n return HTMLResponse(open(\"static/track-record.html\").read())\n\n\n@app.get(\"/api/track-record\")\nasync def track_record_api():\n loop = asyncio.get_event_loop()\n return await loop.run_in_executor(None, compute_performance)\n\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n"}, "71136da4fd60da53fe38c64e72765079e5fb670c": {"t": 1785752908.5688648, "n": 7521, "h": "01b3699020e2185a", "c": "#!/usr/bin/env python3\nimport asyncio\nimport json\nimport os\nimport re\nimport sys\nfrom datetime import datetime\n\nfrom dotenv import load_dotenv\nfrom openai import OpenAI\nfrom fastapi import FastAPI, Query\nfrom fastapi.responses import HTMLResponse, StreamingResponse\nfrom fastapi.staticfiles import StaticFiles\n\nfrom reddit_scraper import scrape_all\nfrom stock_data import fetch_stock_data, find_european_equivalents\n\nload_dotenv()\n\nDEEPSEEK_API_KEY = os.getenv(\"DEEPSEEK_API_KEY\")\nDEEPSEEK_BASE_URL = \"https://api.deepseek.com/v1\"\n\nclient = OpenAI(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)\napp = FastAPI(title=\"Reddit Stonks\")\nTOP_N_TICKERS = 20\n\n\ndef extract_top_picks(analysis: str) -> list[str]:\n picks: list[str] = []\n for match in re.finditer(\n r\"\\*\\*TOP PICK:\\s*\\$?(\\w+)\\*\\*|\\*\\*RUNNER-UP:\\s*\\$?(\\w+)\\*\\*|\\*\\*WILDCARD[^*]*:\\s*\\$?(\\w+)\\*\\*\",\n analysis,\n ):\n ticker = match.group(1) or match.group(2) or match.group(3)\n if ticker:\n picks.append(ticker)\n return picks\n\n\ndef build_context(reddit_data: dict, stock_data: dict, euro: bool = False) -> str:\n ticker_counts = reddit_data[\"ticker_counts\"]\n top_tickers = list(ticker_counts.keys())[:TOP_N_TICKERS]\n\n lines = [\n f\"Analysis Date: {datetime.now().strftime('%Y-%m-%d %H:%M UTC')}\",\n f\"Total Reddit Posts Analyzed: {len(reddit_data['posts'])}\",\n \"\",\n \"=== STOCK DATA ===\",\n ]\n\n for ticker in top_tickers:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n mentions = ticker_counts.get(ticker, 0)\n cap_str = f\"${sd['market_cap']/1e9:.1f}B\" if sd[\"market_cap\"] else \"N/A\"\n target_str = f\"${sd['target_mean']:.2f}\" if sd.get(\"target_mean\") else \"N/A\"\n short_str = f\"{sd['short_pct']*100:.1f}%\" if sd.get(\"short_pct\") else \"N/A\"\n\n lines.append(\n f\"${ticker} ({sd['short_name']}): \"\n f\"Price=${sd['price']:.2f}, \"\n f\"MktCap={cap_str}, \"\n f\"Sector={sd['sector']}, \"\n f\"1WkChange={sd['week_change_pct']:+.2f}%, \"\n f\"P/E={sd.get('pe_ratio', 'N/A')}, \"\n f\"FwdP/E={sd.get('forward_pe', 'N/A')}, \"\n f\"Beta={sd.get('beta', 'N/A')}, \"\n f\"50dMA={sd.get('fifty_day_avg', 'N/A')}, \"\n f\"200dMA={sd.get('two_hundred_day_avg', 'N/A')}, \"\n f\"Recommendation={sd['recommendation']}, \"\n f\"AnalystTarget={target_str}, \"\n f\"ShortFloat={short_str}, \"\n f\"VolRatio={sd['volume_ratio']}, \"\n f\"RedditMentions={mentions}\"\n )\n\n lines.append(\"\")\n lines.append(\"=== REDDIT MENTION RANKING ===\")\n for ticker, count in list(ticker_counts.items())[:TOP_N_TICKERS]:\n lines.append(f\" ${ticker}: {count} mentions\")\n\n if euro:\n lines.append(\"\")\n lines.append(\"=== NOTE ===\")\n lines.append(\"Include European exchange equivalents section in your response.\")\n\n return \"\\n\".join(lines)\n\n\nasync def run_analysis(context: str) -> str:\n system_prompt = (\n \"You are a senior quantitative analyst at a top hedge fund. \"\n \"Your specialty is combining social media sentiment analysis with \"\n \"fundamental and technical data to identify short-term trading opportunities. \"\n \"Output your analysis in clear sections with specific reasoning. \"\n \"Be concise and data-driven.\"\n )\n\n user_prompt = f\"\"\"Analyze the following data and determine which single stock has the highest probability of delivering the best return over the NEXT 7 DAYS (1 week).\n\nConsider:\n1. Reddit hype/momentum\n2. Recent price action and technical setup\n3. Valuation (P/E, forward P/E)\n4. Short squeeze potential\n5. Volume anomalies\n6. Analyst sentiment and price targets\n7. Sector momentum\n\nOutput format:\n\n**TOP PICK: $TICKER**\n- Rationale: (2-3 sentences)\n\n**RUNNER-UP: $TICKER**\n- Rationale: (1-2 sentences)\n\n**WILDCARD (High Risk/Reward): $TICKER**\n- Rationale: (1-2 sentences)\n\n**Risk Factors to Watch:**\n- (2-3 bullet points)\n\n**Confidence Score: X/10**\n- (1 sentence)\n\nDATA:\n{context}\"\"\"\n\n loop = asyncio.get_event_loop()\n try:\n response = await loop.run_in_executor(\n None,\n lambda: client.chat.completions.create(\n model=\"deepseek-v4-flash\",\n messages=[\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt},\n ],\n temperature=0.3,\n max_tokens=1200,\n ),\n )\n return response.choices[0].message.content or \"(no response)\"\n except Exception as e:\n return f\"Error calling Deepseek API: {e}\"\n\n\nasync def event_stream(posts_per_sub: int, euro: bool):\n yield f\"data: {json.dumps({'type': 'status', 'message': 'Scraping Reddit...'})}\\n\\n\"\n\n loop = asyncio.get_event_loop()\n reddit_data = await loop.run_in_executor(None, lambda: scrape_all(limit_per_sub=posts_per_sub))\n\n ticker_count = len(reddit_data[\"ticker_counts\"])\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Found {ticker_count} unique tickers. Fetching stock data...'})}\\n\\n\"\n\n top_tickers = list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]\n stock_data = await loop.run_in_executor(None, fetch_stock_data, top_tickers)\n\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Stock data ready for {len(stock_data)} tickers. Sending to AI...'})}\\n\\n\"\n\n stock_rows = []\n for ticker in list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n stock_rows.append({\n \"ticker\": ticker,\n \"price\": sd[\"price\"],\n \"currency\": sd[\"currency\"],\n \"market_cap\": sd[\"market_cap\"],\n \"sector\": sd[\"sector\"],\n \"short_name\": sd[\"short_name\"],\n \"week_change_pct\": sd[\"week_change_pct\"],\n \"pe_ratio\": sd.get(\"pe_ratio\"),\n \"forward_pe\": sd.get(\"forward_pe\"),\n \"beta\": sd.get(\"beta\"),\n \"volume_ratio\": sd[\"volume_ratio\"],\n \"short_pct\": sd.get(\"short_pct\"),\n \"recommendation\": sd[\"recommendation\"],\n \"target_mean\": sd.get(\"target_mean\"),\n \"mentions\": reddit_data[\"ticker_counts\"].get(ticker, 0),\n })\n\n context = build_context(reddit_data, stock_data, euro=euro)\n analysis = await run_analysis(context)\n\n euro_data = []\n if euro:\n picks = extract_top_picks(analysis)\n for us_ticker in picks:\n eq = await loop.run_in_executor(None, find_european_equivalents, us_ticker)\n euro_data.append({\"us_ticker\": us_ticker, \"equivalents\": eq})\n\n yield f\"data: {json.dumps({'type': 'result', 'stocks': stock_rows, 'analysis': analysis, 'euro': euro_data})}\\n\\n\"\n yield f\"data: {json.dumps({'type': 'done'})}\\n\\n\"\n\n\n@app.get(\"/api/analyze\")\nasync def analyze(\n posts: int = Query(25, ge=5, le=100),\n euro: bool = Query(False),\n):\n return StreamingResponse(\n event_stream(posts, euro),\n media_type=\"text/event-stream\",\n headers={\n \"Cache-Control\": \"no-cache\",\n \"X-Accel-Buffering\": \"no\",\n },\n )\n\n\n@app.get(\"/\")\nasync def index():\n return HTMLResponse(open(\"static/index.html\").read())\n\n\n@app.get(\"/app\")\nasync def app_page():\n return HTMLResponse(open(\"static/app.html\").read())\n\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n"}, "d800fbee4541e2413fdcffa39a33b86e14df1ef3": {"t": 1785752910.7957227, "n": 7517, "h": "ab3d4feebf2e008b", "c": "#!/usr/bin/env python3\nimport asyncio\nimport json\nimport os\nimport re\nimport sys\nfrom datetime import datetime\n\nfrom dotenv import load_dotenv\nfrom openai import OpenAI\nfrom fastapi import FastAPI, Query\nfrom fastapi.responses import HTMLResponse, StreamingResponse\nfrom fastapi.staticfiles import StaticFiles\n\nfrom reddit_scraper import scrape_all\nfrom stock_data import fetch_stock_data, find_european_equivalents\n\nload_dotenv()\n\nDEEPSEEK_API_KEY = os.getenv(\"DEEPSEEK_API_KEY\")\nDEEPSEEK_BASE_URL = \"https://api.deepseek.com/v1\"\n\nclient = OpenAI(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)\napp = FastAPI(title=\"Reddit Stonks\")\nTOP_N_TICKERS = 20\n\n\ndef extract_top_picks(analysis: str) -> list[str]:\n picks: list[str] = []\n for match in re.finditer(\n r\"\\*\\*TOP PICK:\\s*\\$?(\\w+)\\*\\*|\\*\\*RUNNER-UP:\\s*\\$?(\\w+)\\*\\*|\\*\\*WILDCARD[^*]*:\\s*\\$?(\\w+)\\*\\*\",\n analysis,\n ):\n ticker = match.group(1) or match.group(2) or match.group(3)\n if ticker:\n picks.append(ticker)\n return picks\n\n\ndef build_context(reddit_data: dict, stock_data: dict, euro: bool = False) -> str:\n ticker_counts = reddit_data[\"ticker_counts\"]\n top_tickers = list(ticker_counts.keys())[:TOP_N_TICKERS]\n\n lines = [\n f\"Analysis Date: {datetime.now().strftime('%Y-%m-%d %H:%M UTC')}\",\n f\"Total Reddit Posts Analyzed: {len(reddit_data['posts'])}\",\n \"\",\n \"=== STOCK DATA ===\",\n ]\n\n for ticker in top_tickers:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n mentions = ticker_counts.get(ticker, 0)\n cap_str = f\"${sd['market_cap']/1e9:.1f}B\" if sd[\"market_cap\"] else \"N/A\"\n target_str = f\"${sd['target_mean']:.2f}\" if sd.get(\"target_mean\") else \"N/A\"\n short_str = f\"{sd['short_pct']*100:.1f}%\" if sd.get(\"short_pct\") else \"N/A\"\n\n lines.append(\n f\"${ticker} ({sd['short_name']}): \"\n f\"Price=${sd['price']:.2f}, \"\n f\"MktCap={cap_str}, \"\n f\"Sector={sd['sector']}, \"\n f\"1WkChange={sd['week_change_pct']:+.2f}%, \"\n f\"P/E={sd.get('pe_ratio', 'N/A')}, \"\n f\"FwdP/E={sd.get('forward_pe', 'N/A')}, \"\n f\"Beta={sd.get('beta', 'N/A')}, \"\n f\"50dMA={sd.get('fifty_day_avg', 'N/A')}, \"\n f\"200dMA={sd.get('two_hundred_day_avg', 'N/A')}, \"\n f\"Recommendation={sd['recommendation']}, \"\n f\"AnalystTarget={target_str}, \"\n f\"ShortFloat={short_str}, \"\n f\"VolRatio={sd['volume_ratio']}, \"\n f\"RedditMentions={mentions}\"\n )\n\n lines.append(\"\")\n lines.append(\"=== REDDIT MENTION RANKING ===\")\n for ticker, count in list(ticker_counts.items())[:TOP_N_TICKERS]:\n lines.append(f\" ${ticker}: {count} mentions\")\n\n if euro:\n lines.append(\"\")\n lines.append(\"=== NOTE ===\")\n lines.append(\"Include European exchange equivalents section in your response.\")\n\n return \"\\n\".join(lines)\n\n\nasync def run_analysis(context: str) -> str:\n system_prompt = (\n \"You are a senior quantitative analyst at a top hedge fund. \"\n \"Your specialty is combining social media sentiment analysis with \"\n \"fundamental and technical data to identify short-term trading opportunities. \"\n \"Output your analysis in clear sections with specific reasoning. \"\n \"Be concise and data-driven.\"\n )\n\n user_prompt = f\"\"\"Analyze the following data and determine which single stock has the highest probability of delivering the best return over the NEXT 7 DAYS (1 week).\n\nConsider:\n1. Reddit hype/momentum\n2. Recent price action and technical setup\n3. Valuation (P/E, forward P/E)\n4. Short squeeze potential\n5. Volume anomalies\n6. Analyst sentiment and price targets\n7. Sector momentum\n\nOutput format:\n\n**TOP PICK: $TICKER**\n- Rationale: (2-3 sentences)\n\n**RUNNER-UP: $TICKER**\n- Rationale: (1-2 sentences)\n\n**WILDCARD (High Risk/Reward): $TICKER**\n- Rationale: (1-2 sentences)\n\n**Risk Factors to Watch:**\n- (2-3 bullet points)\n\n**Confidence Score: X/10**\n- (1 sentence)\n\nDATA:\n{context}\"\"\"\n\n loop = asyncio.get_event_loop()\n try:\n response = await loop.run_in_executor(\n None,\n lambda: client.chat.completions.create(\n model=\"deepseek-chat\",\n messages=[\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt},\n ],\n temperature=0.3,\n max_tokens=1200,\n ),\n )\n return response.choices[0].message.content or \"(no response)\"\n except Exception as e:\n return f\"Error calling Deepseek API: {e}\"\n\n\nasync def event_stream(posts_per_sub: int, euro: bool):\n yield f\"data: {json.dumps({'type': 'status', 'message': 'Scraping Reddit...'})}\\n\\n\"\n\n loop = asyncio.get_event_loop()\n reddit_data = await loop.run_in_executor(None, lambda: scrape_all(limit_per_sub=posts_per_sub))\n\n ticker_count = len(reddit_data[\"ticker_counts\"])\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Found {ticker_count} unique tickers. Fetching stock data...'})}\\n\\n\"\n\n top_tickers = list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]\n stock_data = await loop.run_in_executor(None, fetch_stock_data, top_tickers)\n\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Stock data ready for {len(stock_data)} tickers. Sending to AI...'})}\\n\\n\"\n\n stock_rows = []\n for ticker in list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n stock_rows.append({\n \"ticker\": ticker,\n \"price\": sd[\"price\"],\n \"currency\": sd[\"currency\"],\n \"market_cap\": sd[\"market_cap\"],\n \"sector\": sd[\"sector\"],\n \"short_name\": sd[\"short_name\"],\n \"week_change_pct\": sd[\"week_change_pct\"],\n \"pe_ratio\": sd.get(\"pe_ratio\"),\n \"forward_pe\": sd.get(\"forward_pe\"),\n \"beta\": sd.get(\"beta\"),\n \"volume_ratio\": sd[\"volume_ratio\"],\n \"short_pct\": sd.get(\"short_pct\"),\n \"recommendation\": sd[\"recommendation\"],\n \"target_mean\": sd.get(\"target_mean\"),\n \"mentions\": reddit_data[\"ticker_counts\"].get(ticker, 0),\n })\n\n context = build_context(reddit_data, stock_data, euro=euro)\n analysis = await run_analysis(context)\n\n euro_data = []\n if euro:\n picks = extract_top_picks(analysis)\n for us_ticker in picks:\n eq = await loop.run_in_executor(None, find_european_equivalents, us_ticker)\n euro_data.append({\"us_ticker\": us_ticker, \"equivalents\": eq})\n\n yield f\"data: {json.dumps({'type': 'result', 'stocks': stock_rows, 'analysis': analysis, 'euro': euro_data})}\\n\\n\"\n yield f\"data: {json.dumps({'type': 'done'})}\\n\\n\"\n\n\n@app.get(\"/api/analyze\")\nasync def analyze(\n posts: int = Query(25, ge=5, le=100),\n euro: bool = Query(False),\n):\n return StreamingResponse(\n event_stream(posts, euro),\n media_type=\"text/event-stream\",\n headers={\n \"Cache-Control\": \"no-cache\",\n \"X-Accel-Buffering\": \"no\",\n },\n )\n\n\n@app.get(\"/\")\nasync def index():\n return HTMLResponse(open(\"static/index.html\").read())\n\n\n@app.get(\"/app\")\nasync def app_page():\n return HTMLResponse(open(\"static/app.html\").read())\n\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n"}, "7e2f2d661a88153984dcd4d2014ec5275d4cbe4e": {"t": 1785752912.2557886, "n": 7420, "h": "136b3173637a2357", "c": "#!/usr/bin/env python3\nimport asyncio\nimport json\nimport os\nimport re\nimport sys\nfrom datetime import datetime\n\nfrom dotenv import load_dotenv\nfrom openai import OpenAI\nfrom fastapi import FastAPI, Query\nfrom fastapi.responses import HTMLResponse, StreamingResponse\nfrom fastapi.staticfiles import StaticFiles\n\nfrom reddit_scraper import scrape_all\nfrom stock_data import fetch_stock_data, find_european_equivalents\n\nload_dotenv()\n\nDEEPSEEK_API_KEY = os.getenv(\"DEEPSEEK_API_KEY\")\nDEEPSEEK_BASE_URL = \"https://api.deepseek.com/v1\"\n\nclient = OpenAI(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)\napp = FastAPI(title=\"Reddit Stonks\")\nTOP_N_TICKERS = 20\n\n\ndef extract_top_picks(analysis: str) -> list[str]:\n picks: list[str] = []\n for match in re.finditer(\n r\"\\*\\*TOP PICK:\\s*\\$?(\\w+)\\*\\*|\\*\\*RUNNER-UP:\\s*\\$?(\\w+)\\*\\*|\\*\\*WILDCARD[^*]*:\\s*\\$?(\\w+)\\*\\*\",\n analysis,\n ):\n ticker = match.group(1) or match.group(2) or match.group(3)\n if ticker:\n picks.append(ticker)\n return picks\n\n\ndef build_context(reddit_data: dict, stock_data: dict, euro: bool = False) -> str:\n ticker_counts = reddit_data[\"ticker_counts\"]\n top_tickers = list(ticker_counts.keys())[:TOP_N_TICKERS]\n\n lines = [\n f\"Analysis Date: {datetime.now().strftime('%Y-%m-%d %H:%M UTC')}\",\n f\"Total Reddit Posts Analyzed: {len(reddit_data['posts'])}\",\n \"\",\n \"=== STOCK DATA ===\",\n ]\n\n for ticker in top_tickers:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n mentions = ticker_counts.get(ticker, 0)\n cap_str = f\"${sd['market_cap']/1e9:.1f}B\" if sd[\"market_cap\"] else \"N/A\"\n target_str = f\"${sd['target_mean']:.2f}\" if sd.get(\"target_mean\") else \"N/A\"\n short_str = f\"{sd['short_pct']*100:.1f}%\" if sd.get(\"short_pct\") else \"N/A\"\n\n lines.append(\n f\"${ticker} ({sd['short_name']}): \"\n f\"Price=${sd['price']:.2f}, \"\n f\"MktCap={cap_str}, \"\n f\"Sector={sd['sector']}, \"\n f\"1WkChange={sd['week_change_pct']:+.2f}%, \"\n f\"P/E={sd.get('pe_ratio', 'N/A')}, \"\n f\"FwdP/E={sd.get('forward_pe', 'N/A')}, \"\n f\"Beta={sd.get('beta', 'N/A')}, \"\n f\"50dMA={sd.get('fifty_day_avg', 'N/A')}, \"\n f\"200dMA={sd.get('two_hundred_day_avg', 'N/A')}, \"\n f\"Recommendation={sd['recommendation']}, \"\n f\"AnalystTarget={target_str}, \"\n f\"ShortFloat={short_str}, \"\n f\"VolRatio={sd['volume_ratio']}, \"\n f\"RedditMentions={mentions}\"\n )\n\n lines.append(\"\")\n lines.append(\"=== REDDIT MENTION RANKING ===\")\n for ticker, count in list(ticker_counts.items())[:TOP_N_TICKERS]:\n lines.append(f\" ${ticker}: {count} mentions\")\n\n if euro:\n lines.append(\"\")\n lines.append(\"=== NOTE ===\")\n lines.append(\"Include European exchange equivalents section in your response.\")\n\n return \"\\n\".join(lines)\n\n\nasync def run_analysis(context: str) -> str:\n system_prompt = (\n \"You are a senior quantitative analyst at a top hedge fund. \"\n \"Your specialty is combining social media sentiment analysis with \"\n \"fundamental and technical data to identify short-term trading opportunities. \"\n \"Output your analysis in clear sections with specific reasoning. \"\n \"Be concise and data-driven.\"\n )\n\n user_prompt = f\"\"\"Analyze the following data and determine which single stock has the highest probability of delivering the best return over the NEXT 7 DAYS (1 week).\n\nConsider:\n1. Reddit hype/momentum\n2. Recent price action and technical setup\n3. Valuation (P/E, forward P/E)\n4. Short squeeze potential\n5. Volume anomalies\n6. Analyst sentiment and price targets\n7. Sector momentum\n\nOutput format:\n\n**TOP PICK: $TICKER**\n- Rationale: (2-3 sentences)\n\n**RUNNER-UP: $TICKER**\n- Rationale: (1-2 sentences)\n\n**WILDCARD (High Risk/Reward): $TICKER**\n- Rationale: (1-2 sentences)\n\n**Risk Factors to Watch:**\n- (2-3 bullet points)\n\n**Confidence Score: X/10**\n- (1 sentence)\n\nDATA:\n{context}\"\"\"\n\n loop = asyncio.get_event_loop()\n try:\n response = await loop.run_in_executor(\n None,\n lambda: client.chat.completions.create(\n model=\"deepseek-chat\",\n messages=[\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt},\n ],\n temperature=0.3,\n max_tokens=1200,\n ),\n )\n return response.choices[0].message.content or \"(no response)\"\n except Exception as e:\n return f\"Error calling Deepseek API: {e}\"\n\n\nasync def event_stream(posts_per_sub: int, euro: bool):\n yield f\"data: {json.dumps({'type': 'status', 'message': 'Scraping Reddit...'})}\\n\\n\"\n\n loop = asyncio.get_event_loop()\n reddit_data = await loop.run_in_executor(None, lambda: scrape_all(limit_per_sub=posts_per_sub))\n\n ticker_count = len(reddit_data[\"ticker_counts\"])\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Found {ticker_count} unique tickers. Fetching stock data...'})}\\n\\n\"\n\n top_tickers = list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]\n stock_data = await loop.run_in_executor(None, fetch_stock_data, top_tickers)\n\n yield f\"data: {json.dumps({'type': 'status', 'message': f'Stock data ready for {len(stock_data)} tickers. Sending to AI...'})}\\n\\n\"\n\n stock_rows = []\n for ticker in list(reddit_data[\"ticker_counts\"].keys())[:TOP_N_TICKERS]:\n sd = stock_data.get(ticker)\n if not sd:\n continue\n stock_rows.append({\n \"ticker\": ticker,\n \"price\": sd[\"price\"],\n \"currency\": sd[\"currency\"],\n \"market_cap\": sd[\"market_cap\"],\n \"sector\": sd[\"sector\"],\n \"short_name\": sd[\"short_name\"],\n \"week_change_pct\": sd[\"week_change_pct\"],\n \"pe_ratio\": sd.get(\"pe_ratio\"),\n \"forward_pe\": sd.get(\"forward_pe\"),\n \"beta\": sd.get(\"beta\"),\n \"volume_ratio\": sd[\"volume_ratio\"],\n \"short_pct\": sd.get(\"short_pct\"),\n \"recommendation\": sd[\"recommendation\"],\n \"target_mean\": sd.get(\"target_mean\"),\n \"mentions\": reddit_data[\"ticker_counts\"].get(ticker, 0),\n })\n\n context = build_context(reddit_data, stock_data, euro=euro)\n analysis = await run_analysis(context)\n\n euro_data = []\n if euro:\n picks = extract_top_picks(analysis)\n for us_ticker in picks:\n eq = await loop.run_in_executor(None, find_european_equivalents, us_ticker)\n euro_data.append({\"us_ticker\": us_ticker, \"equivalents\": eq})\n\n yield f\"data: {json.dumps({'type': 'result', 'stocks': stock_rows, 'analysis': analysis, 'euro': euro_data})}\\n\\n\"\n yield f\"data: {json.dumps({'type': 'done'})}\\n\\n\"\n\n\n@app.get(\"/api/analyze\")\nasync def analyze(\n posts: int = Query(25, ge=5, le=100),\n euro: bool = Query(False),\n):\n return StreamingResponse(\n event_stream(posts, euro),\n media_type=\"text/event-stream\",\n headers={\n \"Cache-Control\": \"no-cache\",\n \"X-Accel-Buffering\": \"no\",\n },\n )\n\n\n@app.get(\"/\")\nasync def index():\n return HTMLResponse(open(\"static/index.html\").read())\n\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n"}}}}