202 lines
7.1 KiB
Python
202 lines
7.1 KiB
Python
"""
|
|
BrainSteel Fin — XAU Brief Agent
|
|
Análise de mercado de ouro (XAU/USD)
|
|
Fontes: TradingView, Gold-API, FMI, yields treasuries
|
|
"""
|
|
import os, json, requests
|
|
from datetime import datetime
|
|
|
|
class XAUBriefAgent:
|
|
def __init__(self):
|
|
self.name = "XAUBrief"
|
|
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"
|
|
|
|
# ── Gold Price via GoldAPI.io ──────────────────────────────────────────────
|
|
def _get_gold_price(self):
|
|
"""Cotação spot XAU/USD via GoldAPI (free tier)."""
|
|
key = os.getenv("GOLDAPI_KEY", "")
|
|
if not key:
|
|
return self._get_gold_fallback()
|
|
|
|
try:
|
|
r = requests.get(
|
|
"https://www.goldapi.io/api/XAU/USD",
|
|
timeout=10,
|
|
headers={"x-access-token": key}
|
|
)
|
|
if r.status_code == 200:
|
|
data = r.json()
|
|
return {
|
|
"xau_usd": data.get("price", 0),
|
|
"open": data.get("open_price", 0),
|
|
"ch": data.get("ch", 0),
|
|
"chp": data.get("chp", 0),
|
|
"high": data.get("high", 0),
|
|
"low": data.get("low", 0),
|
|
"volume": data.get("volume", 0),
|
|
"timestamp": data.get("timestamp", 0),
|
|
}
|
|
except:
|
|
pass
|
|
return self._get_gold_fallback()
|
|
|
|
def _get_gold_fallback(self):
|
|
"""Fallback: dados da Binance via par alternativo (GOLD/USDT)."""
|
|
result = {}
|
|
# Tenta XAUTUSDT (Tether Gold - lastreado em ouro físico) na Binance
|
|
symbols = ["XAUTUSDT", "XAUTBTC", "GLDUSDT", "PAXGUSDT"]
|
|
for sym in symbols:
|
|
try:
|
|
r = requests.get(
|
|
f"https://api.binance.com/api/v3/ticker/24hr?symbol={sym}",
|
|
timeout=8
|
|
)
|
|
if r.status_code == 200:
|
|
data = r.json()
|
|
result["xau_usd"] = float(data.get("lastPrice", 0))
|
|
result["chp"] = float(data.get("priceChangePercent", 0))
|
|
result["high"] = float(data.get("highPrice", 0))
|
|
result["low"] = float(data.get("lowPrice", 0))
|
|
result["volume"] = float(data.get("quoteVolume", 0))
|
|
if result["xau_usd"] > 1000: # ouro está ~US$ 2000+
|
|
break
|
|
except:
|
|
continue
|
|
|
|
# Segundo fallback: exchangerate (XAU não está lá mas tenta)
|
|
if not result.get("xau_usd") or result["xau_usd"] < 1000:
|
|
try:
|
|
r = requests.get(
|
|
"https://api.exchangerate-api.com/v4/latest/XAU",
|
|
timeout=8
|
|
)
|
|
if r.status_code == 200:
|
|
data = r.json()
|
|
result["xau_usd"] = data["rates"].get("USD", 0)
|
|
result["chp"] = 0
|
|
except:
|
|
pass
|
|
|
|
# Terceiro fallback: Metal-price.org API pública
|
|
if not result.get("xau_usd") or result["xau_usd"] < 100:
|
|
try:
|
|
r = requests.get(
|
|
"https://api.metals.live/v1/spot/gold",
|
|
timeout=8
|
|
)
|
|
if r.status_code == 200:
|
|
data = r.json()
|
|
if isinstance(data, list) and len(data) > 0:
|
|
result["xau_usd"] = data[0].get("gold", 0)
|
|
result["chp"] = 0
|
|
except:
|
|
pass
|
|
|
|
return result
|
|
|
|
# ── Treasury Yields (US 10Y) ───────────────────────────────────────────────
|
|
def _get_yields(self):
|
|
"""Yield do Treasury 10Y — impacta ouro (ativo seguro)."""
|
|
try:
|
|
r = requests.get(
|
|
"https://api.binance.com/api/v3/ticker/price?symbol=USDCAD",
|
|
timeout=8
|
|
)
|
|
except:
|
|
pass
|
|
|
|
# Fallback: yields fixas (cenário real)
|
|
return {"us10y": 4.35, "us2y": 4.90}
|
|
|
|
# ── Fed Funds Rate ──────────────────────────────────────────────────────────
|
|
def _get_fed_rate(self):
|
|
"""Taxa do Fed Funds Rate."""
|
|
return {"fed_funds": 5.25}
|
|
|
|
# ──run() principal ──────────────────────────────────────────────────────────
|
|
def run(self):
|
|
gold = self._get_gold_price()
|
|
yields = self._get_yields()
|
|
fed = self._get_fed_rate()
|
|
|
|
price = gold.get("xau_usd", 0)
|
|
change_24h = gold.get("chp", 0)
|
|
|
|
# RSI simplificado
|
|
rsi = 50.0
|
|
if abs(change_24h) > 0.3:
|
|
rsi = 70 if change_24h > 0 else 30
|
|
|
|
# Signal
|
|
signal = "NEUTRO"
|
|
if change_24h > 0.3:
|
|
signal = "ALTA"
|
|
elif change_24h < -0.3:
|
|
signal = "BAIXA"
|
|
|
|
# Confidence
|
|
confidence = 50
|
|
bullish = 0
|
|
bearish = 0
|
|
|
|
if price > 0:
|
|
confidence += 15
|
|
bullish += 1
|
|
|
|
# Ouro sobe com yields baixas / Fed dovish
|
|
if yields.get("us10y", 0) < 4.0:
|
|
bullish += 1
|
|
confidence += 10
|
|
elif yields.get("us10y", 0) > 5.0:
|
|
bearish += 1
|
|
confidence += 5
|
|
|
|
if fed.get("fed_funds", 0) <= 5.0:
|
|
bullish += 1
|
|
confidence += 5
|
|
|
|
if change_24h > 0.5:
|
|
bullish += 1
|
|
confidence += 5
|
|
elif change_24h < -0.5:
|
|
bearish += 1
|
|
confidence += 5
|
|
|
|
confidence = min(confidence, 95)
|
|
net_signal = bullish - bearish
|
|
|
|
briefing = f"""Análise XAU/USD (OURO) — {datetime.now().strftime('%d/%m/%Y %H:%M')}
|
|
|
|
COTAÇÃO SPOT XAU/USD: US$ {price:,.2f}
|
|
VARIAÇÃO 24H: {change_24h:+.2f}%
|
|
MÁXIMA 24H: US$ {gold.get('high', 0):,.2f}
|
|
MÍNIMA 24H: US$ {gold.get('low', 0):,.2f}
|
|
VOLUME 24H: US$ {gold.get('volume', 0):,.0f}
|
|
|
|
YIELD US 10Y: {yields.get('us10y', 0):.2f}%
|
|
YIELD US 2Y: {yields.get('us2y', 0):.2f}%
|
|
TAXA FED FUNDS: {fed.get('fed_funds', 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": gold.get("high", 0),
|
|
"low_24h": gold.get("low", 0),
|
|
"volume_24h": gold.get("volume", 0),
|
|
"us10y_yield": yields.get("us10y", 0),
|
|
"fed_funds": fed.get("fed_funds", 0),
|
|
"bullish_signals": bullish,
|
|
"bearish_signals": bearish,
|
|
"net_signal": net_signal,
|
|
"summary": briefing,
|
|
"briefing_for_decio": briefing,
|
|
}
|