diff --git a/src/App.tsx b/src/App.tsx index 360c7e1..7812554 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,7 +12,6 @@ import { PlansView } from './components/PlansView'; import { AdminDashboard } from './components/AdminDashboard'; import { LandingPage } from './components/LandingPage'; import { ProfileView } from './components/ProfileView'; -import { MarketTicker } from './components/MarketTicker'; import { TrendingUp, ShieldAlert, Ghost, Mail, Lock, UserPlus, LogIn, Loader2, ArrowLeft, User as UserIcon, Eye, EyeOff } from 'lucide-react'; import { motion, AnimatePresence } from 'motion/react'; import { onAuthStateChanged, signInWithEmailAndPassword, createUserWithEmailAndPassword, updateProfile, signOut, sendEmailVerification, sendPasswordResetEmail, User, setPersistence, browserLocalPersistence, browserSessionPersistence } from 'firebase/auth'; @@ -552,11 +551,6 @@ export default function App() {
- {/* Market Ticker */} -
- -
- {/* Desktop Header */}
@@ -565,7 +559,6 @@ export default function App() { {activeTab === 'scan' && 'Scanner de IA'} {activeTab === 'history' && 'Histórico de Sinais'} {activeTab === 'stats' && 'Performance & Dados'} - {activeTab === 'plans' && 'Nossos Planos'} {activeTab === 'profile' && 'Perfil do Usuário'} {activeTab === 'admin' && 'Painel Administrativo'} @@ -576,14 +569,6 @@ export default function App() {
- {activeTab !== 'plans' && !userData?.isPremium && ( - - )} @@ -620,7 +605,6 @@ export default function App() { {activeTab === 'scan' && } {activeTab === 'history' && } {activeTab === 'stats' && } - {activeTab === 'plans' && } {activeTab === 'profile' && } {activeTab === 'admin' && isAdmin && } diff --git a/src/components/AdminDashboard.tsx b/src/components/AdminDashboard.tsx index e66ebee..67eac83 100644 --- a/src/components/AdminDashboard.tsx +++ b/src/components/AdminDashboard.tsx @@ -83,8 +83,8 @@ export const AdminDashboard: React.FC = () => { ); return ( -
-
+
+

@@ -98,7 +98,7 @@ export const AdminDashboard: React.FC = () => { setSearchTerm(e.target.value)} /> @@ -111,7 +111,7 @@ export const AdminDashboard: React.FC = () => {

Carregando usuários...

) : ( -
+
diff --git a/src/components/AnalysisView.tsx b/src/components/AnalysisView.tsx index 0a9c19e..8bb44a8 100644 --- a/src/components/AnalysisView.tsx +++ b/src/components/AnalysisView.tsx @@ -15,6 +15,7 @@ export const AnalysisView: React.FC<{ userData?: any }> = ({ userData }) => { const [isAnalyzing, setIsAnalyzing] = useState(false); const [result, setResult] = useState(null); const [error, setError] = useState(null); + const [mode, setMode] = useState<'Técnico' | 'Fundamental' | 'Híbrido'>('Híbrido'); const [usageInfo, setUsageInfo] = useState<{ used: number, limit: number }>({ used: 0, limit: userData?.analysisLimit ?? 8 }); useEffect(() => { @@ -71,7 +72,7 @@ export const AnalysisView: React.FC<{ userData?: any }> = ({ userData }) => { } const base64 = preview.split(',')[1]; - const analysis = await analyzeForexChart(base64); + const analysis = await analyzeForexChart(base64, undefined, mode); setResult(analysis); if (auth.currentUser) { @@ -150,9 +151,39 @@ export const AnalysisView: React.FC<{ userData?: any }> = ({ userData }) => { {!result ? ( -
+
+ {isAnalyzing && ( +
+
+
+
+ Logo + +
+

Processando Scan Institucional...

+
+ )} {!preview ? (
+
+ {(['Técnico', 'Fundamental', 'Híbrido'] as const).map((m) => ( + + ))} +
= ({ userData }) => { {result.score >= 80 ? '🔥 ALTA PROBABILIDADE' : result.score >= 60 ? '⚖️ MÉDIA PROBABILIDADE' : '❌ EVITAR'}

{result.justification}

+

⚠️ {result.alerta}

- PAR - {result.pair} + MODO + {result.mode}
TF - {result.timeframe} + {result.timeframe}
@@ -298,7 +330,7 @@ export const AnalysisView: React.FC<{ userData?: any }> = ({ userData }) => { result.decision === SignalType.SELL ? 'VENDER' : 'AGUARDAR'} - Status do Signal + Decisão QuantScan
@@ -327,55 +359,30 @@ export const AnalysisView: React.FC<{ userData?: any }> = ({ userData }) => {
- {/* New Institutional Analysis Section */}

- LIQUIDITY SWEEP + TRAP DETECTION + ANÁLISE TÉCNICA (SMC + LIQ)

- {result.liquiditySweep || 'Nenhum sweep relevante detectado.'} + {result.tecnica}

- MOMENTUM + ENTRY TIMING + ANÁLISE FUNDAMENTAL

- {result.momentum || 'Momentum neutro para este timeframe.'} + {result.fundamental}

-
+

- ZONAS IMPORTANTES + ANALISE GERAL

-
- {result.keyZones?.map((zone, i) => ( - - {zone} - - )) || Identificando zonas...} -
-
-
-

- CONTEXTO INSTITUCIONAL -

-
- {['Accumulation', 'Manipulation', 'Distribution'].map((stage) => ( -
- {stage === 'Accumulation' ? 'Acumulação' : stage === 'Manipulation' ? 'Manipulação' : 'Distribuição'} -
- ))} -
+

+ {result.analiseGeral} +

@@ -432,30 +439,6 @@ export const AnalysisView: React.FC<{ userData?: any }> = ({ userData }) => {
- {/* Detailed IA Analysis */} -
-

- - IA Logic Check -

-
-
- Estrutura Dominante -

{result.structure}

-
-
- Confluências -
- {result.conceptsDetected.map((c, i) => ( - - {c} - - ))} -
-
-
-
-
+ {[ - { label: "Nº de Análises", free: "8 / dia", pro: "15 / dia", elite: "Ilimitado" }, - { label: "Score de Probabilidade", free: "Básico", pro: "Avançado", elite: "Avançado+" }, - { label: "IA Adaptativa", free: "Não", pro: "Sim", elite: "Sim" }, - { label: "Histórico de Sinais", free: "Limitado", pro: "Completo", elite: "Completo" }, - { label: "Suporte", free: "Comunidade", pro: "Prioritário", elite: "VIP Individual" }, - { label: "Processamento", free: "Normal", pro: "Rápido", elite: "Ultra Prioridade" }, + { label: "Nº de Análises", free: "8 / dia", pro: "15 / dia", elite: "30 / dia", lifetime: "Ilimitado" }, + { label: "Score de Probabilidade", free: "Básico", pro: "Avançado", elite: "Avançado+", lifetime: "Avançado+" }, + { label: "IA Adaptativa", free: "Não", pro: "Sim", elite: "Sim", lifetime: "Sim" }, + { label: "Histórico de Sinais", free: "Limitado", pro: "Completo", elite: "Completo", lifetime: "Completo" }, + { label: "Suporte", free: "Comunidade", pro: "Prioritário", elite: "VIP Individual", lifetime: "Premium 1-on-1" }, + { label: "Processamento", free: "Normal", pro: "Rápido", elite: "Ultra Prioridade", lifetime: "Ultra Prioridade" }, ].map((row, idx) => ( + ))} diff --git a/src/components/SignalHistory.tsx b/src/components/SignalHistory.tsx index 309e720..93938f9 100644 --- a/src/components/SignalHistory.tsx +++ b/src/components/SignalHistory.tsx @@ -17,14 +17,8 @@ export const SignalHistory: React.FC = () => { where('userId', '==', auth.currentUser.uid) ); - // Force refresh every hour - const refreshInterval = setInterval(() => { - // Small trick to trigger a re-subscribe if necessary, - // though onSnapshot should technically handle it. - // This satisfies the explicit request to refresh hourly. - console.log('Refreshing signal history...'); - }, 60 * 60 * 1000); - + // The onSnapshot listener below automatically handles updates + // when data in Firestore changes. const unsubscribe = onSnapshot(q, (snapshot) => { let newSignals: Signal[] = []; snapshot.forEach((doc) => { @@ -39,7 +33,6 @@ export const SignalHistory: React.FC = () => { }); return () => { - clearInterval(refreshInterval); unsubscribe(); }; }, []); diff --git a/src/services/geminiService.ts b/src/services/geminiService.ts index f32e1ff..6c9551f 100644 --- a/src/services/geminiService.ts +++ b/src/services/geminiService.ts @@ -3,26 +3,47 @@ import { AnalysisResponse, SignalType } from "../types"; const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY || '' }); -export const analyzeForexChart = async (imageBase64: string, userNotes?: string): Promise => { +export const analyzeForexChart = async (imageBase64: string, userNotes?: string, preferredMode?: 'Técnico' | 'Fundamental' | 'Híbrido'): Promise => { const model = "gemini-3-flash-preview"; const systemInstruction = ` - Você é um Analista Institucional de Forex com IA adaptativa, especializado em Fluxo de Ordens, Liquidez e Comportamento Institucional (PRO Logic). - Sua função é analisar o gráfico fornecido e identificar oportunidades de alta probabilidade instantaneamente. + Você é o QuantScan IA, um sistema avançado de análise de mercado financeiro com inteligência institucional. - Analise a imagem detalhadamente em busca de: - 1. LIQUIDITY SWEEP + TRAP DETECTION: Detectar Stop Hunts, Falsos rompimentos, Equal highs/lows e Rejeições. - 2. MOMENTUM + ENTRY TIMING: Avaliar força dos candles e rejeições. - 3. ZONAS IMPORTANTES: Oferta/Demanda e Níveis psicológicos. + Especializações: Smart Money Concepts (SMC), Liquidez, Momentum, Análise Fundamental macro, Aprendizado contínuo. - Detecte automaticamente o Timeframe e o Par de Moedas. - - Seja breve, preciso e ultrarrápido na resposta. + Sua função é gerar decisões de trading com alta precisão, explicação clara e score de probabilidade baseado na análise de imagem do gráfico e no input técnico/fundamental. + + MODOS DE ANÁLISE: + - Técnico: Foco em Timing, Estrutura e Execução. + - Fundamental: Foco em Macro, Notícias, Força de moedas. + - Híbrido: Combinação de Técnico e Fundamental (Recomendado). + + DETECÇÃO AUTOMÁTICA: Timeframe (M1-D1), Par de moeda, Estrutura. + + FORMATO DE SAÍDA (Obrigatório em JSON): + { + "mode": "Técnico" | "Fundamental" | "Híbrido", + "analiseGeral": "string", + "timeframe": "string", + "estrutura": "string", + "tecnica": "string", // Detalhada (SMC+Liquidez+Momentum) + "fundamental": "string", // Resumo macro + "decision": "BUY" | "SELL" | "WAIT", + "entry": "string", + "stopLoss": "string", + "takeProfit": "string", + "score": number, // 0-100 + "justification": "string", + "alerta": "string", + "pair": "string" + } `; const prompt = ` - Analise este gráfico de Forex sob a óptica institucional. ${userNotes ? `Notas do usuário: ${userNotes}` : ''} - Retorne a análise seguindo estritamente o esquema JSON fornecido. + Analise este gráfico sob a óptica do QuantScan IA. + ${preferredMode ? `Use estritamente o modo de análise: ${preferredMode}.` : 'Detecte o melhor modo automaticamente.'} + ${userNotes ? `Notas do usuário: ${userNotes}` : ''} + Detecte modo, timeframe e par se não fornecidos. Retorne JSON estrito. `; const response = await ai.models.generateContent({ @@ -41,38 +62,22 @@ export const analyzeForexChart = async (imageBase64: string, userNotes?: string) responseSchema: { type: Type.OBJECT, properties: { - pair: { type: Type.STRING, description: "Par de moedas detectado (ex: EURUSD)" }, - timeframe: { type: Type.STRING, description: "Timeframe detectado (ex: H1)" }, - structure: { type: Type.STRING, description: "Resumo da estrutura de mercado" }, - conceptsDetected: { - type: Type.ARRAY, - items: { type: Type.STRING }, - description: "Lista de conceitos identificados" - }, - decision: { - type: Type.STRING, - enum: ["BUY", "SELL", "WAIT"], - description: "Decisão final de trading" - }, - entry: { type: Type.STRING, description: "Preço ou zona de entrada" }, - stopLoss: { type: Type.STRING, description: "Preço de Stop Loss" }, - takeProfit: { type: Type.STRING, description: "Preço de Take Profit" }, - score: { type: Type.NUMBER, description: "Score de probabilidade de 0 a 100" }, - justification: { type: Type.STRING, description: "Explicação técnica para o score" }, - liquiditySweep: { type: Type.STRING, description: "Descrição do sweep de liquidez detectado ou armadilhas" }, - momentum: { type: Type.STRING, description: "Análise do momentum e timing de entrada" }, - keyZones: { - type: Type.ARRAY, - items: { type: Type.STRING }, - description: "Zonas importantes detectadas" - }, - institutionalContext: { - type: Type.STRING, - enum: ["Accumulation", "Manipulation", "Distribution", "None"], - description: "Fase do ciclo institucional" - } + mode: { type: Type.STRING, enum: ['Técnico', 'Fundamental', 'Híbrido'] }, + analiseGeral: { type: Type.STRING }, + pair: { type: Type.STRING }, + timeframe: { type: Type.STRING }, + estrutura: { type: Type.STRING }, + tecnica: { type: Type.STRING }, + fundamental: { type: Type.STRING }, + decision: { type: Type.STRING, enum: ["BUY", "SELL", "WAIT"] }, + entry: { type: Type.STRING }, + stopLoss: { type: Type.STRING }, + takeProfit: { type: Type.STRING }, + score: { type: Type.NUMBER }, + justification: { type: Type.STRING }, + alerta: { type: Type.STRING } }, - required: ["pair", "timeframe", "structure", "conceptsDetected", "decision", "entry", "stopLoss", "takeProfit", "score", "justification", "liquiditySweep", "momentum", "keyZones", "institutionalContext"] + required: ["mode", "analiseGeral", "pair", "timeframe", "estrutura", "tecnica", "fundamental", "decision", "entry", "stopLoss", "takeProfit", "score", "justification", "alerta"] } } }); diff --git a/src/types.ts b/src/types.ts index 6b7286a..2e422b7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -18,8 +18,6 @@ export enum SignalResult { export interface Signal { id: string; - pair: string; - timeframe: string; timestamp: number; type: SignalType; entry: string; @@ -27,10 +25,18 @@ export interface Signal { takeProfit: string; score: number; justification: string; - logicElements: string[]; result: SignalResult; screenshotUrl?: string; userId: string; + // QuantScan IA fields + mode: string; + pair: string; + analiseGeral: string; + timeframe: string; + estrutura: string; + tecnica: string; + fundamental: string; + alerta: string; } export interface UserStats { @@ -45,18 +51,18 @@ export interface UserStats { } export interface AnalysisResponse { + mode: 'Técnico' | 'Fundamental' | 'Híbrido'; + analiseGeral: string; pair: string; timeframe: string; - structure: string; - conceptsDetected: string[]; + estrutura: string; + tecnica: string; + fundamental: string; decision: SignalType; entry: string; stopLoss: string; takeProfit: string; score: number; justification: string; - liquiditySweep?: string; - momentum?: string; - keyZones?: string[]; - institutionalContext?: 'Accumulation' | 'Manipulation' | 'Distribution' | 'None'; + alerta: string; }
Begin Pro EliteLifetime
{row.label} {row.free} {row.pro} {row.elite}{row.lifetime}