@@ -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 (
-
-
+
+
) : (
-
+
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 && (
+
+
+
+
+

+
+
+
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) => (
| {row.label} |
{row.free} |
{row.pro} |
{row.elite} |
+ {row.lifetime} |
))}
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;
}