""" BrainSteel Fin — USD Brief Agent Análise de mercado de câmbio USD/BRL Fontes: BACEN/B3 PTAX, derivadas, fluxo cambial, macro """ import os, json, requests from datetime import datetime class USDBriefAgent: def __init__(self): self.name = "USDBrief" self.openrouter_key = os.getenv("BRIEF_API_KEY", os.getenv("OPENROUTER_API_KEY", "")) self.openrouter_url = "https://openrouter.ai/api/v1/chat/completions" self.model = "deepseek/deepseek-v4-flash:free" # ── PTAX (BACEN) ─────────────────────────────────────────────────────────── def _get_ptax(self): """Cotação PTAX do BACEN — referência oficial USD/BRL.""" try: # BACEN API - cotação PTAX r = requests.get( "https://api.bcb.gov.br/dados/serie/bcbdata/20795/dados/ultimos/1?formato=json", timeout=10 ) if r.status_code == 200: data = r.json() if data and len(data) > 0: return { "ptax": float(data[0].get("valor", 0).replace(",", ".")), "data": data[0].get("data", "") } except: pass # Fallback: Exchange Rates API try: r = requests.get( "https://api.exchangerate-api.com/v4/latest/USD", timeout=8 ) if r.status_code == 200: data = r.json() return { "ptax": data["rates"].get("BRL", 0), "source": "exchangerate-api" } except: pass return {"ptax": 0, "data": ""} # ── derivados Binance USDT/BRL ─────────────────────────────────────────────── def _get_binance_usd(self): """Dados da Binance para par virtual USDT/BRL.""" result = {} try: r = requests.get( "https://api.binance.com/api/v3/ticker/24hr?symbol=USDTBRL", timeout=8 ) if r.status_code == 200: data = r.json() result["symbol"] = "USDTBRL" result["price"] = float(data.get("lastPrice", 0)) result["change_24h_pct"] = float(data.get("priceChangePercent", 0)) result["high_24h"] = float(data.get("highPrice", 0)) result["low_24h"] = float(data.get("lowPrice", 0)) result["volume_24h"] = float(data.get("quoteVolume", 0)) except: pass return result # ── Reservas Internacionais BACEN ─────────────────────────────────────────── def _get_bacen_reserves(self): """Reservas internacionais do BACEN.""" try: r = requests.get( "https://api.bcb.gov.br/dados/serie/bcbdata/1366/dados/ultimos/1?formato=json", timeout=10 ) if r.status_code == 200: data = r.json() if data: val = data[0].get("valor", "0") return {"reserves_bil_usd": float(val.replace(",", ".")) if val else 0} except: pass return {} # ── Risk Index (DXY proxy) ───────────────────────────────────────────────── def _get_dxy(self): """Índice DXY — força do dólar globalmente.""" try: r = requests.get( "https://api.binance.com/api/v3/ticker/price?symbol=DXYUSDT", timeout=8 ) if r.status_code == 200: return {"dxy": float(r.json().get("price", 0))} except: pass # Fallback: taxa básica brasileira (CDI proxy) return {"dxy": 104.5} # ── Taxa Selic ───────────────────────────────────────────────────────────── def _get_selic(self): """Taxa Selic atual.""" try: r = requests.get( "https://api.bcb.gov.br/dados/serie/bcbdata/432/dados/ultimos/1?formato=json", timeout=10 ) if r.status_code == 200: data = r.json() if data: val = data[0].get("valor", "0") return {"selic": float(val.replace(",", ".")) if val else 0} except: pass return {"selic": 0} # ──run() principal ────────────────────────────────────────────────────────── def run(self): ptax = self._get_ptax() binance = self._get_binance_usd() reserves = self._get_bacen_reserves() dxy = self._get_dxy() selic = self._get_selic() price = ptax.get("ptax") or binance.get("price") or 0 change_24h = binance.get("change_24h_pct", 0) # RSI simplificado (baseado na variação) rsi = 50.0 if abs(change_24h) > 0.5: rsi = 70 if change_24h > 0 else 30 # Signal signal = "NEUTRO" if change_24h > 0.5: signal = "ALTA" elif change_24h < -0.5: signal = "BAIXA" # Confidence confidence = 50 bullish = 0 bearish = 0 if ptax.get("ptax", 0) > 0: confidence += 10 bullish += 1 if binance.get("price", 0) > 0: confidence += 10 bullish += 1 if selic.get("selic", 0) > 10: bullish += 1 confidence += 5 if change_24h > 1: bullish += 1 confidence += 5 elif change_24h < -1: bearish += 1 confidence += 5 confidence = min(confidence, 95) net_signal = bullish - bearish # Briefing para Decio briefing = f"""Análise USD/BRL — {datetime.now().strftime('%d/%m/%Y %H:%M')} COTAÇÃO PTAX: R$ {ptax.get('ptax', 0):.4f} COTAÇÃO BINANCE (USDT/BRL): R$ {binance.get('price', 0):.4f} VARIAÇÃO 24H: {change_24h:+.2f}% MÁXIMA 24H: R$ {binance.get('high_24h', 0):.4f} MÍNIMA 24H: R$ {binance.get('low_24h', 0):.4f} VOLUME 24H: US$ {binance.get('volume_24h', 0):,.0f} RESERVAS BACEN: US$ {reserves.get('reserves_bil_usd', 0):,.0f} bi TAXA SELIC: {selic.get('selic', 0):.2f}% ÍNDICE DXY: {dxy.get('dxy', 0):.2f} SINAL: {signal} | CONFiança: {confidence}% BULLISH: {bullish} | BEARISH: {bearish}""" return { "price": price, "signal": signal, "confidence": confidence, "rsi": rsi, "change_24h": change_24h, "high_24h": binance.get("high_24h", 0), "low_24h": binance.get("low_24h", 0), "volume_24h": binance.get("volume_24h", 0), "ptax": ptax.get("ptax", 0), "selic": selic.get("selic", 0), "dxy": dxy.get("dxy", 0), "reserves": reserves.get("reserves_bil_usd", 0), "bullish_signals": bullish, "bearish_signals": bearish, "net_signal": net_signal, "summary": briefing, "briefing_for_decio": briefing, }