ghstedpixel/BRIE
0
1import os2import time3import json4import requests5from requests.adapters import HTTPAdapter6from urllib3.util.retry import Retry7 8class DiscordNotifier:9 def __init__(self, webhook_url):10 self.webhook_url = webhook_url.strip()11 self.session = requests.Session()12 retries = Retry(13 total=3,14 connect=3,15 read=3,16 backoff_factor=1,17 status_forcelist=[429, 500, 502, 503, 504],18 allowed_methods=frozenset(["POST"]),19 raise_on_status=False,20 )21 adapter = HTTPAdapter(max_retries=retries)22 self.session.mount("https://", adapter)23 self.session.mount("http://", adapter)24 25 def send_ticker_alert(self, ticker, signal, price, change, color):26 payload = {27 "content": f"๐ **BRIE SIGNAL: {ticker}**",28 "embeds": [{29 "title": f"{ticker} is {signal}",30 "color": color,31 "fields": [32 {"name": "Price", "value": f"${price:.2f}", "inline": True},33 {"name": "Change", "value": f"{change:+.2f}%", "inline": True}34 ]35 }]36 }37 r = self.session.post(self.webhook_url, json=payload, timeout=(5, 20))38 if r.status_code not in (200, 204):39 print(f"โ ๏ธ Discord responded with status {r.status_code} for {ticker}")40 return False41 return True42 43 44def run_alpaca_briefing(tickers):45 finnhub_key = os.getenv("FINHUB_KEY")46 webhook = os.getenv("DISCORD_WEBHOOK")47 48 if not finnhub_key:49 return "โ Missing FINHUB_KEY"50 if not webhook:51 return "โ Missing DISCORD_WEBHOOK"52 53 notifier = DiscordNotifier(webhook)54 sent_count = 055 errors = []56 57 for ticker in tickers:58 ticker_clean = ticker.strip().upper()59 try:60 url = f"https://finnhub.io/api/v1/quote?symbol={ticker_clean}&token={finnhub_key}"61 resp = requests.get(url, timeout=(5, 10))62 resp.raise_for_status()63 data = resp.json()64 65 price = data.get("c", 0)66 change = data.get("dp", 0)67 if price == 0:68 errors.append(f"{ticker_clean} (No Data)")69 continue70 71 if change > 1.5:72 sig, col = "BULLISH", 306699373 elif change < -1.5:74 sig, col = "BEARISH", 1515833275 else:76 sig, col = "NEUTRAL", 980727077 78 if notifier.send_ticker_alert(ticker_clean, sig, price, change, col):79 sent_count += 180 else:81 errors.append(f"{ticker_clean} (Discord Failed)")82 83 time.sleep(2)84 except requests.exceptions.ReadTimeout:85 errors.append(f"{ticker_clean} (Timeout)")86 except Exception:87 errors.append(f"{ticker_clean} (API Error)")88 89 return f"โ
Brie: {sent_count} signals processed." + (f" โ ๏ธ Issues: {', '.join(errors)}" if errors else "")