From a729263602c92badb622216f49d29ea145ad1788 Mon Sep 17 00:00:00 2001 From: desartstudio95 Date: Mon, 18 May 2026 08:02:01 -0700 Subject: [PATCH] add ai studio backend --- server.ts | 424 +++++++++++++++++++++++++++--------------------------- 1 file changed, 212 insertions(+), 212 deletions(-) diff --git a/server.ts b/server.ts index 84bd002..0fc69cb 100644 --- a/server.ts +++ b/server.ts @@ -1,212 +1,212 @@ -import { GoogleGenAI, Type } from "@google/genai"; -import express from "express"; -import path from "path"; -import { createServer as createViteServer } from "vite"; - -const startServer = async () => { - const app = express(); - const PORT = 3000; - - // Middleware to parse JSON bodies with a larger limit for images - app.use(express.json({ limit: "50mb" })); - - const ai = new GoogleGenAI(process.env.GEMINI_API_KEY ? { apiKey: process.env.GEMINI_API_KEY.trim() } : {}); - - app.post("/api/analyze", async (req, res) => { - try { - const { imageBase64, userNotes, preferredMode, userPlan } = req.body; - - const model = 'gemini-3.1-pro-preview'; - - const systemInstruction = ` -# QUANTSCAN IA — MODO MULTI TIME FRAME + LONG TERM ANALYSIS - -Você é o QUANTSCAN IA, um sistema profissional avançado de análise Forex, Índices, Commodities e Criptomoedas baseado em Inteligência Artificial institucional. - -Plano do Usuário Atual: ${userPlan || 'basic'} - -Sua função é analisar gráficos enviados pelo usuário através de: screenshot do gráfico, foto da tela, imagem do TradingView, imagem MT4/MT5 ou corretoras. - -O sistema deve operar em dois modos: -1. SHORT TERM / SCALPING -2. LONG TERM / SWING TRADE / POSITION TRADE - -================================================== -RESTRIÇÕES DE PLANO -================================================== -Se o plano do usuário for "basic" ou "experimental", você é **PROIBIDO** de realizar análise LONG TERM / SWING / POSITION. -Independentemente do timeframe enxergado na imagem (mesmo que seja H4, D1, W1), você deve focar nas estruturas de curto prazo e gerar sinais APENAS para Scalping ou Intraday. -Para planos "pro", "elite", e "lifetime", você pode e deve realizar análises MULTI TIME FRAME e gerar decisões LONG TERM. - -================================================== -ANÁLISE MULTI TIME FRAME (OBRIGATÓRIO PARA PRO/ELITE/LIFETIME) -================================================== -A IA deve identificar automaticamente: timeframe principal, secundário e contexto macro do mercado. -Exemplo: H4 → tendência principal, H1 → estrutura intermediária, M15 → entrada precisa. - -TIMEFRAMES SUPORTADOS: -- Scalping: M1, M5, M15 -- Intraday: M30, H1 -- Swing Trade: H4, D1 -- Longo Prazo: W1, MN - -A IA deve: -1. Detectar tendência do timeframe maior. -2. Confirmar alinhamento estrutural. -3. Procurar entradas no timeframe menor. -4. Evitar entradas contra tendência macro. - -================================================== -REGRAS DE LONGO PRAZO -================================================== -Se detectar: H4, D1, W1, Monthly -A IA deve ativar automaticamente: "MODO LONG TERM ANALYSIS" e analisar tendência macro, ciclos institucionais, acumulação/distribuição, zonas de interesse, continuação ou reversão, força de tendência e pontos de holding. - -================================================== -ESTRATÉGIAS OBRIGATÓRIAS -================================================== -1. SMART MONEY CONCEPT (SMC): BOS, CHOCH, Order Blocks, Liquidity, Fair Value Gap. -2. LIQUIDITY SWEEP + TRAP DETECTION: stop hunts, fake breakouts, manipulation. -3. MOMENTUM + ENTRY TIMING: força da tendência, volume, velocidade do preço. -4. MARKET STRUCTURE AI: tendência bullish/bearish, ranging, expansão. -5. FUNDAMENTAL ANALYSIS AI: notícias, juros, impacto macroeconômico. - -================================================== -CAMADA DE CONFIRMAÇÃO E IA (APENAS FILTRO) -================================================== -- Volume Delta, CVD, Volume Profile. -- ATR (Average True Range). -- EMA (apenas filtro macro). -- RSI (com Liquidity Sweep). -- VWAP. -- Score probabilístico e Filtro anti-fake breakout. - -================================================== -ENTRADAS OBRIGATÓRIAS (Sistema de Probabilidade) -================================================== -A IA deve fornecer no JSON estrito todas as chaves abaixo: -- Direção: BUY, SELL ou WAIT -- Tipo: Scalping / Intraday / Swing / Long Term (chave signalType) -- Nível de Risco: LOW / MEDIUM / HIGH (chave riskLevel) -- Risco/Retorno: (ex: 1:3) (chave riskReward) -- Duração Estimada: (ex: 3 a 10 dias) (chave duration) -- Entrada, Stop Loss, Take Profit 1, Take Profit 2, e Take Profit 3. - -Exemplo visual de leitura interna: -CONFIDENCE SCORE: 91% -RISK LEVEL: LOW -MULTI TIME FRAME: W1 Bullish, D1 Bullish, H4 Pullback... - -FORMATO DE SAÍDA (Obrigatório em JSON): -{ - "mode": "Técnico" | "Fundamental" | "Híbrido", - "analiseGeral": "Análise multi timeframe macro e micro", - "timeframe": "Timeframes analisados (ex: H4/M15)", - "estrutura": "Detalhes estruturais", - "tecnica": "SMC + Confirmações", - "fundamental": "Resumo", - "decision": "BUY" | "SELL" | "WAIT", - "signalType": "Scalping" | "Intraday" | "Swing" | "Long Term", - "riskLevel": "LOW" | "MEDIUM" | "HIGH", - "entry": "1.08450", - "stopLoss": "1.07800", - "takeProfit": "1.09200", - "takeProfit2": "1.10100", - "takeProfit3": "1.11500", - "riskReward": "1:3", - "duration": "3 a 10 dias", - "score": 91, - "justification": "Razão principal", - "alerta": "Cuidados", - "pair": "EUR/USD" -} -`; - - const prompt = ` - 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({ - model, - contents: [ - { - parts: [ - { text: prompt }, - { inlineData: { mimeType: "image/jpeg", data: imageBase64 } } - ] - } - ], - config: { - systemInstruction, - responseMimeType: "application/json", - responseSchema: { - type: Type.OBJECT, - properties: { - 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"] }, - signalType: { type: Type.STRING }, - riskLevel: { type: Type.STRING }, - entry: { type: Type.STRING }, - stopLoss: { type: Type.STRING }, - takeProfit: { type: Type.STRING }, - takeProfit2: { type: Type.STRING }, - takeProfit3: { type: Type.STRING }, - riskReward: { type: Type.STRING }, - duration: { type: Type.STRING }, - score: { type: Type.NUMBER }, - justification: { type: Type.STRING }, - alerta: { type: Type.STRING } - }, - required: ["mode", "analiseGeral", "pair", "timeframe", "estrutura", "tecnica", "fundamental", "decision", "signalType", "riskLevel", "entry", "stopLoss", "takeProfit", "takeProfit2", "takeProfit3", "riskReward", "duration", "score", "justification", "alerta"] - } - } - }); - - const textResponse = response.text || '{}'; - const cleanJson = textResponse.replace(/^```json\s*/, '').replace(/\s*```$/, ''); - const parsedData = JSON.parse(cleanJson); - - res.json(parsedData); - } catch (err: any) { - console.error("Gemini Error server-side:", err); - let errorMessage = err.message || "Erro desconhecido"; - if (errorMessage.includes("API key not valid")) { - errorMessage = "A chave de API configurada no projeto (GEMINI_API_KEY) é inválida. Verifique em 'Secrets'."; - } else if (errorMessage.includes("API key should be set") || errorMessage.includes("API_KEY_INVALID")) { - errorMessage = "A chave de API não foi configurada ou é inválida. Defina GEMINI_API_KEY em 'Secrets'."; - } - res.status(500).json({ error: errorMessage }); - } - }); - - // Vite middleware for development - if (process.env.NODE_ENV !== "production") { - const vite = await createViteServer({ - server: { middlewareMode: true }, - appType: "spa", - }); - app.use(vite.middlewares); - } else { - // Production: serve static files. Dist is at project root. - const distPath = path.join(process.cwd(), 'dist'); - app.use(express.static(distPath)); - app.get('*', (req, res) => { - res.sendFile(path.join(distPath, 'index.html')); - }); - } - - app.listen(PORT, "0.0.0.0", () => { - console.log(`Server running on http://0.0.0.0:${PORT}`); - }); -}; - -startServer(); +import { GoogleGenAI, Type } from "@google/genai"; +import express from "express"; +import path from "path"; +import { createServer as createViteServer } from "vite"; + +const startServer = async () => { + const app = express(); + const PORT = 3000; + + // Middleware to parse JSON bodies with a larger limit for images + app.use(express.json({ limit: "50mb" })); + + const ai = new GoogleGenAI(process.env.GEMINI_API_KEY ? { apiKey: process.env.GEMINI_API_KEY.trim() } : {}); + + app.post("/api/analyze", async (req, res) => { + try { + const { imageBase64, userNotes, preferredMode, userPlan } = req.body; + + const model = 'gemini-3.1-pro-preview'; + + const systemInstruction = ` +# QUANTSCAN IA — MODO MULTI TIME FRAME + LONG TERM ANALYSIS + +Você é o QUANTSCAN IA, um sistema profissional avançado de análise Forex, Índices, Commodities e Criptomoedas baseado em Inteligência Artificial institucional. + +Plano do Usuário Atual: ${userPlan || 'basic'} + +Sua função é analisar gráficos enviados pelo usuário através de: screenshot do gráfico, foto da tela, imagem do TradingView, imagem MT4/MT5 ou corretoras. + +O sistema deve operar em dois modos: +1. SHORT TERM / SCALPING +2. LONG TERM / SWING TRADE / POSITION TRADE + +================================================== +RESTRIÇÕES DE PLANO +================================================== +Se o plano do usuário for "basic" ou "experimental", você é **PROIBIDO** de realizar análise LONG TERM / SWING / POSITION. +Independentemente do timeframe enxergado na imagem (mesmo que seja H4, D1, W1), você deve focar nas estruturas de curto prazo e gerar sinais APENAS para Scalping ou Intraday. +Para planos "pro", "elite", e "lifetime", você pode e deve realizar análises MULTI TIME FRAME e gerar decisões LONG TERM. + +================================================== +ANÁLISE MULTI TIME FRAME (OBRIGATÓRIO PARA PRO/ELITE/LIFETIME) +================================================== +A IA deve identificar automaticamente: timeframe principal, secundário e contexto macro do mercado. +Exemplo: H4 → tendência principal, H1 → estrutura intermediária, M15 → entrada precisa. + +TIMEFRAMES SUPORTADOS: +- Scalping: M1, M5, M15 +- Intraday: M30, H1 +- Swing Trade: H4, D1 +- Longo Prazo: W1, MN + +A IA deve: +1. Detectar tendência do timeframe maior. +2. Confirmar alinhamento estrutural. +3. Procurar entradas no timeframe menor. +4. Evitar entradas contra tendência macro. + +================================================== +REGRAS DE LONGO PRAZO +================================================== +Se detectar: H4, D1, W1, Monthly +A IA deve ativar automaticamente: "MODO LONG TERM ANALYSIS" e analisar tendência macro, ciclos institucionais, acumulação/distribuição, zonas de interesse, continuação ou reversão, força de tendência e pontos de holding. + +================================================== +ESTRATÉGIAS OBRIGATÓRIAS +================================================== +1. SMART MONEY CONCEPT (SMC): BOS, CHOCH, Order Blocks, Liquidity, Fair Value Gap. +2. LIQUIDITY SWEEP + TRAP DETECTION: stop hunts, fake breakouts, manipulation. +3. MOMENTUM + ENTRY TIMING: força da tendência, volume, velocidade do preço. +4. MARKET STRUCTURE AI: tendência bullish/bearish, ranging, expansão. +5. FUNDAMENTAL ANALYSIS AI: notícias, juros, impacto macroeconômico. + +================================================== +CAMADA DE CONFIRMAÇÃO E IA (APENAS FILTRO) +================================================== +- Volume Delta, CVD, Volume Profile. +- ATR (Average True Range). +- EMA (apenas filtro macro). +- RSI (com Liquidity Sweep). +- VWAP. +- Score probabilístico e Filtro anti-fake breakout. + +================================================== +ENTRADAS OBRIGATÓRIAS (Sistema de Probabilidade) +================================================== +A IA deve fornecer no JSON estrito todas as chaves abaixo: +- Direção: BUY, SELL ou WAIT +- Tipo: Scalping / Intraday / Swing / Long Term (chave signalType) +- Nível de Risco: LOW / MEDIUM / HIGH (chave riskLevel) +- Risco/Retorno: (ex: 1:3) (chave riskReward) +- Duração Estimada: (ex: 3 a 10 dias) (chave duration) +- Entrada, Stop Loss, Take Profit 1, Take Profit 2, e Take Profit 3. + +Exemplo visual de leitura interna: +CONFIDENCE SCORE: 91% +RISK LEVEL: LOW +MULTI TIME FRAME: W1 Bullish, D1 Bullish, H4 Pullback... + +FORMATO DE SAÍDA (Obrigatório em JSON): +{ + "mode": "Técnico" | "Fundamental" | "Híbrido", + "analiseGeral": "Análise multi timeframe macro e micro", + "timeframe": "Timeframes analisados (ex: H4/M15)", + "estrutura": "Detalhes estruturais", + "tecnica": "SMC + Confirmações", + "fundamental": "Resumo", + "decision": "BUY" | "SELL" | "WAIT", + "signalType": "Scalping" | "Intraday" | "Swing" | "Long Term", + "riskLevel": "LOW" | "MEDIUM" | "HIGH", + "entry": "1.08450", + "stopLoss": "1.07800", + "takeProfit": "1.09200", + "takeProfit2": "1.10100", + "takeProfit3": "1.11500", + "riskReward": "1:3", + "duration": "3 a 10 dias", + "score": 91, + "justification": "Razão principal", + "alerta": "Cuidados", + "pair": "EUR/USD" +} +`; + + const prompt = ` + 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({ + model, + contents: [ + { + parts: [ + { text: prompt }, + { inlineData: { mimeType: "image/jpeg", data: imageBase64 } } + ] + } + ], + config: { + systemInstruction, + responseMimeType: "application/json", + responseSchema: { + type: Type.OBJECT, + properties: { + 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"] }, + signalType: { type: Type.STRING }, + riskLevel: { type: Type.STRING }, + entry: { type: Type.STRING }, + stopLoss: { type: Type.STRING }, + takeProfit: { type: Type.STRING }, + takeProfit2: { type: Type.STRING }, + takeProfit3: { type: Type.STRING }, + riskReward: { type: Type.STRING }, + duration: { type: Type.STRING }, + score: { type: Type.NUMBER }, + justification: { type: Type.STRING }, + alerta: { type: Type.STRING } + }, + required: ["mode", "analiseGeral", "pair", "timeframe", "estrutura", "tecnica", "fundamental", "decision", "signalType", "riskLevel", "entry", "stopLoss", "takeProfit", "takeProfit2", "takeProfit3", "riskReward", "duration", "score", "justification", "alerta"] + } + } + }); + + const textResponse = response.text || '{}'; + const cleanJson = textResponse.replace(/^```json\s*/, '').replace(/\s*```$/, ''); + const parsedData = JSON.parse(cleanJson); + + res.json(parsedData); + } catch (err: any) { + console.error("Gemini Error server-side:", err); + let errorMessage = err.message || "Erro desconhecido"; + if (errorMessage.includes("API key not valid")) { + errorMessage = "A chave de API configurada no projeto (GEMINI_API_KEY) é inválida. Verifique em 'Secrets'."; + } else if (errorMessage.includes("API key should be set") || errorMessage.includes("API_KEY_INVALID")) { + errorMessage = "A chave de API não foi configurada ou é inválida. Defina GEMINI_API_KEY em 'Secrets'."; + } + res.status(500).json({ error: errorMessage }); + } + }); + + // Vite middleware for development + if (process.env.NODE_ENV !== "production") { + const vite = await createViteServer({ + server: { middlewareMode: true }, + appType: "spa", + }); + app.use(vite.middlewares); + } else { + // Production: serve static files. Dist is at project root. + const distPath = path.join(process.cwd(), 'dist'); + app.use(express.static(distPath)); + app.get('*', (req, res) => { + res.sendFile(path.join(distPath, 'index.html')); + }); + } + + app.listen(PORT, "0.0.0.0", () => { + console.log(`Server running on http://0.0.0.0:${PORT}`); + }); +}; + +startServer();