// Wall Street Watchdog AI - Full App (Frontend + Backend) // --- Frontend (React) --- import React, { useEffect, useState } from 'react'; import { Card, CardContent } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { ReloadIcon } from "lucide-react"; import axios from 'axios'; const API_ENDPOINT = "/api/alerts"; export default function WatchdogApp() { const [alerts, setAlerts] = useState([]); const [loading, setLoading] = useState(false); const [countdown, setCountdown] = useState(300); const fetchAlerts = async () => { setLoading(true); try { const res = await axios.get(API_ENDPOINT); setAlerts(res.data.alerts); } catch (err) { console.error("Error fetching alerts:", err); } setLoading(false); }; useEffect(() => { fetchAlerts(); const interval = setInterval(fetchAlerts, 300000); const countdownInterval = setInterval(() => setCountdown((c) => (c > 0 ? c - 1 : 300)), 1000); return () => { clearInterval(interval); clearInterval(countdownInterval); }; }, []); return (
Wall Street Watchdog AI
Auto-refresh in {countdown}s
{alerts.map((alert, idx) => (
{alert.ticker} — {alert.action}
{alert.source}
{alert.summary}
))}
); } // --- Backend API (FastAPI) --- from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from typing import List import requests from bs4 import BeautifulSoup from datetime import datetime import openai import os app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=[""], allow_credentials=True, allow_methods=[""], allow_headers=["*"], ) class Alert(BaseModel): ticker: str action: str summary: str source: str date: str class AlertResponse(BaseModel): alerts: List[Alert] openai.api_key = os.getenv("OPENAI_API_KEY") def summarize_text(text): try: response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": "Summarize the following financial update in 1-2 sentences."}, {"role": "user", "content": text} ] ) return response['choices'][0]['message']['content'] except: return text[:200] def get_yahoo_news(): url = "https://finance.yahoo.com/" r = requests.get(url) soup = BeautifulSoup(r.text, "html.parser") articles = soup.select("li.js-stream-content")[:5] alerts = [] for a in articles: headline = a.get_text() link = a.find("a")['href'] if a.find("a") else "" summary = summarize_text(headline) alerts.append(Alert( ticker="MKT", action="News", summary=summary, source="Yahoo Finance", date=str(datetime.utcnow()) )) return alerts def get_marketbeat_ratings(): url = "https://www.marketbeat.com/ratings/" r = requests.get(url) soup = BeautifulSoup(r.text, "html.parser") rows = soup.select("table.ratings-table tbody tr")[:5] alerts = [] for row in rows: cols = row.find_all("td") if len(cols) >= 5: ticker = cols[0].get_text(strip=True) action = cols[2].get_text(strip=True) summary = summarize_text(f"{ticker} received a {action} rating from {cols[1].get_text(strip=True)}") alerts.append(Alert( ticker=ticker, action=action, summary=summary, source="MarketBeat", date=str(datetime.utcnow()) )) return alerts def get_coindesk(): url = "https://www.coindesk.com/" r = requests.get(url) soup = BeautifulSoup(r.text, "html.parser") articles = soup.select("a.card-title")[:5] alerts = [] for a in articles: headline = a.get_text(strip=True) summary = summarize_text(headline) alerts.append(Alert( ticker="CRYPTO", action="News", summary=summary, source="CoinDesk", date=str(datetime.utcnow()) )) return alerts @app.get("/api/alerts", response_model=AlertResponse) async def get_all_alerts(): alerts = [] alerts += get_yahoo_news() alerts += get_marketbeat_ratings() alerts += get_coindesk() return {"alerts": alerts}