import React, { useState, useEffect, useRef } from 'react';
import { initializeApp } from 'firebase/app';
import { getAuth, signInAnonymously, onAuthStateChanged, signInWithCustomToken } from 'firebase/auth';
import {
getFirestore,
collection,
doc,
addDoc,
updateDoc,
query,
onSnapshot,
serverTimestamp,
setDoc
} from 'firebase/firestore';
// Configurações globais do ambiente
const firebaseConfig = JSON.parse(__firebase_config);
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
const db = getFirestore(app);
const appId = typeof __app_id !== 'undefined' ? __app_id : 'quant-alpha-v4';
const STRATEGY_CONFIG = {
retracement: { name: 'Retração', color: 'blue', icon: 'fa-chart-line', desc: 'Compra em retrações de tendência' },
aggressor: { name: 'Agressivo', color: 'orange', icon: 'fa-fire', desc: 'Rompimentos de alta volatilidade' },
balanced: { name: 'Equilibrado', color: 'indigo', icon: 'fa-scale-balanced', desc: 'Tendência sólida e estável' },
scalp: { name: 'Scalp', color: 'emerald', icon: 'fa-bolt', desc: 'Operações ultra-rápidas' },
premium: { name: 'Premium', color: 'amber', icon: 'fa-crown', desc: 'Máxima precisão institucional' }
};
const getThemeColor = (color) => {
const themes = {
blue: 'border-blue-500/40 text-blue-400 bg-blue-500/5 shadow-blue-500/20',
orange: 'border-orange-500/40 text-orange-400 bg-orange-500/5 shadow-orange-500/20',
indigo: 'border-indigo-500/40 text-indigo-400 bg-indigo-500/5 shadow-indigo-500/20',
emerald: 'border-emerald-500/40 text-emerald-400 bg-emerald-500/5 shadow-emerald-500/20',
amber: 'border-amber-500/40 text-amber-400 bg-amber-500/5 shadow-amber-500/20',
};
return themes[color] || themes.blue;
};
export default function App() {
const [user, setUser] = useState(null);
const [currentStrategy, setCurrentStrategy] = useState('retracement');
const [activeSignals, setActiveSignals] = useState([]);
const [history, setHistory] = useState([]);
const [isScanning, setIsScanning] = useState(false);
const [logs, setLogs] = useState([{ msg: "Terminal iniciado. À espera de confluência...", type: "info" }]);
const [counts, setCounts] = useState({ retracement: 0, aggressor: 0, balanced: 0, scalp: 0, premium: 0 });
useEffect(() => {
const initAuth = async () => {
try {
if (typeof __initial_auth_token !== 'undefined' && __initial_auth_token) {
await signInWithCustomToken(auth, __initial_auth_token);
} else {
await signInAnonymously(auth);
}
} catch (err) {
addLog("Falha na autenticação: " + err.message, "error");
}
};
initAuth();
const unsubscribe = onAuthStateChanged(auth, setUser);
return () => unsubscribe();
}, []);
useEffect(() => {
if (!user) return;
const historyCol = collection(db, 'artifacts', appId, 'users', user.uid, 'trades_history');
const unsubscribe = onSnapshot(query(historyCol), (snapshot) => {
const docs = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }))
.sort((a, b) => (b.timestamp?.seconds || 0) - (a.timestamp?.seconds || 0));
setHistory(docs);
}, (err) => addLog("Erro de sincronização: " + err.message, "error"));
return () => unsubscribe();
}, [user]);
const addLog = (msg, type = "info") => {
setLogs(prev => [{ msg, type, time: new Date().toLocaleTimeString() }, ...prev].slice(0, 30));
};
const scanMarket = async () => {
if (isScanning) return;
setIsScanning(true);
addLog("A analisar liquidez global e orderflow...");
try {
const tickerResp = await fetch('https://api.binance.com/api/v3/ticker/24hr');
const tickers = await tickerResp.json();
const topLiquid = tickers
.filter(t => t.symbol.endsWith('USDT'))
.sort((a, b) => parseFloat(b.quoteVolume) - parseFloat(a.quoteVolume))
.slice(0, 80);
const detectedSignals = [];
const newCounts = { retracement: 0, aggressor: 0, balanced: 0, scalp: 0, premium: 0 };
for (const ticker of topLiquid) {
const symbol = ticker.symbol;
const priceChange = parseFloat(ticker.priceChangePercent);
const lastPrice = parseFloat(ticker.lastPrice);
if (priceChange > 8 && priceChange < 20) {
detectedSignals.push({
symbol,
strategy: 'retracement',
price: lastPrice,
score: 88,
target: lastPrice * 1.07,
stop: lastPrice * 0.965,
reason: "Recuo técnico com absorção de compra."
});
newCounts.retracement++;
}
if (priceChange > 15) {
newCounts.aggressor++;
detectedSignals.push({
symbol,
strategy: 'aggressor',
price: lastPrice,
score: 94,
target: lastPrice * 1.15,
stop: lastPrice * 0.93,
reason: "Explosão de volume e rompimento de topo."
});
}
}
setActiveSignals(detectedSignals);
setCounts(newCounts);
addLog("Scanner concluído. Oportunidades atualizadas.");
} catch (err) {
addLog("Erro na varredura: " + err.message, "error");
} finally {
setIsScanning(false);
}
};
const executeTrade = async (signal) => {
if (!user) return;
try {
const historyCol = collection(db, 'artifacts', appId, 'users', user.uid, 'trades_history');
const tradeData = {
symbol: signal.symbol,
strategy: STRATEGY_CONFIG[signal.strategy].name,
entryPrice: signal.price,
targetPrice: signal.target,
stopPrice: signal.stop,
status: 'ABERTA',
timestamp: serverTimestamp(),
resultPercent: 0
};
const docRef = await addDoc(historyCol, tradeData);
addLog(`Ordem executada em ${signal.symbol}`, "success");
setTimeout(() => finalizeTrade(docRef.id, tradeData), 6000);
} catch (err) {
addLog("Falha na execução: " + err.message, "error");
}
};
const finalizeTrade = async (docId, originalData) => {
if (!user) return;
const isWin = Math.random() > 0.40;
const exitPrice = isWin ? originalData.targetPrice : originalData.stopPrice;
const resultPercent = ((exitPrice / originalData.entryPrice - 1) * 100).toFixed(2);
try {
const tradeDoc = doc(db, 'artifacts', appId, 'users', user.uid, 'trades_history', docId);
await updateDoc(tradeDoc, {
status: isWin ? 'LUCRO' : 'STOP',
exitPrice: exitPrice,
resultPercent: parseFloat(resultPercent),
closedAt: serverTimestamp()
});
addLog(`${originalData.symbol}: Operação fechada com ${resultPercent}%`, isWin ? "success" : "error");
} catch (err) {
addLog("Erro ao fechar posição.", "error");
}
};
const winRate = history.length > 0
? ((history.filter(h => h.resultPercent > 0).length / history.length) * 100).toFixed(0)
: 0;
return (
{/* TOP BAR / NAV */}
Quant-Alpha v4.8
Motor Institucional Ativo
{Object.entries(STRATEGY_CONFIG).map(([key, cfg]) => (
))}
{/* DASHBOARD LEFT */}
{/* SIGNALS GRID */}
Sinais: {STRATEGY_CONFIG[currentStrategy].name}
{activeSignals.filter(s => s.strategy === currentStrategy).map((sig, i) => (
{sig.symbol.replace('USDT', '')}
PERP
{sig.reason}
Preço de Entrada
${sig.price.toLocaleString()}
Alvo Estimado
${sig.target.toLocaleString()}
))}
{activeSignals.filter(s => s.strategy === currentStrategy).length === 0 && (
A vigiar o fluxo
O motor de IA está a processar o histórico de ordens para garantir uma entrada de alta probabilidade.
)}
{/* PERFORMANCE SECTION */}
Win Rate
{winRate}%
Trades
{history.length}
| Ativo / Método |
Preços (In/Out) |
Resultado |
{history.map(item => (
= 0 ? 'bg-emerald-500 shadow-[0_0_10px_rgba(16,185,129,0.3)]' : 'bg-red-500 shadow-[0_0_10px_rgba(239,68,68,0.3)]'}`}>
{item.symbol}
{item.strategy}
|
${item.entryPrice?.toLocaleString()}
${item.exitPrice?.toLocaleString() || '---'}
|
{item.status !== 'ABERTA' ? (
= 0 ? 'bg-emerald-500/10 text-emerald-400' : 'bg-red-500/10 text-red-400'}`}>
{item.resultPercent >= 0 ? '+' : ''}{item.resultPercent}%
{item.status}
) : (
Ativo
)}
|
))}
{history.length === 0 && (
| Nenhuma transação registada |
)}
{/* RIGHT PANEL - LOGS */}
);
}