add ai studio backend

This commit is contained in:
desartstudio95
2026-05-18 08:02:01 -07:00
committed by GitHub
parent 49fe3dec72
commit a729263602
+212 -212
View File
@@ -1,212 +1,212 @@
import { GoogleGenAI, Type } from "@google/genai"; import { GoogleGenAI, Type } from "@google/genai";
import express from "express"; import express from "express";
import path from "path"; import path from "path";
import { createServer as createViteServer } from "vite"; import { createServer as createViteServer } from "vite";
const startServer = async () => { const startServer = async () => {
const app = express(); const app = express();
const PORT = 3000; const PORT = 3000;
// Middleware to parse JSON bodies with a larger limit for images // Middleware to parse JSON bodies with a larger limit for images
app.use(express.json({ limit: "50mb" })); app.use(express.json({ limit: "50mb" }));
const ai = new GoogleGenAI(process.env.GEMINI_API_KEY ? { apiKey: process.env.GEMINI_API_KEY.trim() } : {}); const ai = new GoogleGenAI(process.env.GEMINI_API_KEY ? { apiKey: process.env.GEMINI_API_KEY.trim() } : {});
app.post("/api/analyze", async (req, res) => { app.post("/api/analyze", async (req, res) => {
try { try {
const { imageBase64, userNotes, preferredMode, userPlan } = req.body; const { imageBase64, userNotes, preferredMode, userPlan } = req.body;
const model = 'gemini-3.1-pro-preview'; const model = 'gemini-3.1-pro-preview';
const systemInstruction = ` const systemInstruction = `
# QUANTSCAN IA — MODO MULTI TIME FRAME + LONG TERM ANALYSIS # 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. 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'} 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. 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: O sistema deve operar em dois modos:
1. SHORT TERM / SCALPING 1. SHORT TERM / SCALPING
2. LONG TERM / SWING TRADE / POSITION TRADE 2. LONG TERM / SWING TRADE / POSITION TRADE
================================================== ==================================================
RESTRIÇÕES DE PLANO RESTRIÇÕES DE PLANO
================================================== ==================================================
Se o plano do usuário for "basic" ou "experimental", você é **PROIBIDO** de realizar análise LONG TERM / SWING / POSITION. 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. 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. 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) 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. 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. Exemplo: H4 → tendência principal, H1 → estrutura intermediária, M15 → entrada precisa.
TIMEFRAMES SUPORTADOS: TIMEFRAMES SUPORTADOS:
- Scalping: M1, M5, M15 - Scalping: M1, M5, M15
- Intraday: M30, H1 - Intraday: M30, H1
- Swing Trade: H4, D1 - Swing Trade: H4, D1
- Longo Prazo: W1, MN - Longo Prazo: W1, MN
A IA deve: A IA deve:
1. Detectar tendência do timeframe maior. 1. Detectar tendência do timeframe maior.
2. Confirmar alinhamento estrutural. 2. Confirmar alinhamento estrutural.
3. Procurar entradas no timeframe menor. 3. Procurar entradas no timeframe menor.
4. Evitar entradas contra tendência macro. 4. Evitar entradas contra tendência macro.
================================================== ==================================================
REGRAS DE LONGO PRAZO REGRAS DE LONGO PRAZO
================================================== ==================================================
Se detectar: H4, D1, W1, Monthly 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. 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 ESTRATÉGIAS OBRIGATÓRIAS
================================================== ==================================================
1. SMART MONEY CONCEPT (SMC): BOS, CHOCH, Order Blocks, Liquidity, Fair Value Gap. 1. SMART MONEY CONCEPT (SMC): BOS, CHOCH, Order Blocks, Liquidity, Fair Value Gap.
2. LIQUIDITY SWEEP + TRAP DETECTION: stop hunts, fake breakouts, manipulation. 2. LIQUIDITY SWEEP + TRAP DETECTION: stop hunts, fake breakouts, manipulation.
3. MOMENTUM + ENTRY TIMING: força da tendência, volume, velocidade do preço. 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. 4. MARKET STRUCTURE AI: tendência bullish/bearish, ranging, expansão.
5. FUNDAMENTAL ANALYSIS AI: notícias, juros, impacto macroeconômico. 5. FUNDAMENTAL ANALYSIS AI: notícias, juros, impacto macroeconômico.
================================================== ==================================================
CAMADA DE CONFIRMAÇÃO E IA (APENAS FILTRO) CAMADA DE CONFIRMAÇÃO E IA (APENAS FILTRO)
================================================== ==================================================
- Volume Delta, CVD, Volume Profile. - Volume Delta, CVD, Volume Profile.
- ATR (Average True Range). - ATR (Average True Range).
- EMA (apenas filtro macro). - EMA (apenas filtro macro).
- RSI (com Liquidity Sweep). - RSI (com Liquidity Sweep).
- VWAP. - VWAP.
- Score probabilístico e Filtro anti-fake breakout. - Score probabilístico e Filtro anti-fake breakout.
================================================== ==================================================
ENTRADAS OBRIGATÓRIAS (Sistema de Probabilidade) ENTRADAS OBRIGATÓRIAS (Sistema de Probabilidade)
================================================== ==================================================
A IA deve fornecer no JSON estrito todas as chaves abaixo: A IA deve fornecer no JSON estrito todas as chaves abaixo:
- Direção: BUY, SELL ou WAIT - Direção: BUY, SELL ou WAIT
- Tipo: Scalping / Intraday / Swing / Long Term (chave signalType) - Tipo: Scalping / Intraday / Swing / Long Term (chave signalType)
- Nível de Risco: LOW / MEDIUM / HIGH (chave riskLevel) - Nível de Risco: LOW / MEDIUM / HIGH (chave riskLevel)
- Risco/Retorno: (ex: 1:3) (chave riskReward) - Risco/Retorno: (ex: 1:3) (chave riskReward)
- Duração Estimada: (ex: 3 a 10 dias) (chave duration) - Duração Estimada: (ex: 3 a 10 dias) (chave duration)
- Entrada, Stop Loss, Take Profit 1, Take Profit 2, e Take Profit 3. - Entrada, Stop Loss, Take Profit 1, Take Profit 2, e Take Profit 3.
Exemplo visual de leitura interna: Exemplo visual de leitura interna:
CONFIDENCE SCORE: 91% CONFIDENCE SCORE: 91%
RISK LEVEL: LOW RISK LEVEL: LOW
MULTI TIME FRAME: W1 Bullish, D1 Bullish, H4 Pullback... MULTI TIME FRAME: W1 Bullish, D1 Bullish, H4 Pullback...
FORMATO DE SAÍDA (Obrigatório em JSON): FORMATO DE SAÍDA (Obrigatório em JSON):
{ {
"mode": "Técnico" | "Fundamental" | "Híbrido", "mode": "Técnico" | "Fundamental" | "Híbrido",
"analiseGeral": "Análise multi timeframe macro e micro", "analiseGeral": "Análise multi timeframe macro e micro",
"timeframe": "Timeframes analisados (ex: H4/M15)", "timeframe": "Timeframes analisados (ex: H4/M15)",
"estrutura": "Detalhes estruturais", "estrutura": "Detalhes estruturais",
"tecnica": "SMC + Confirmações", "tecnica": "SMC + Confirmações",
"fundamental": "Resumo", "fundamental": "Resumo",
"decision": "BUY" | "SELL" | "WAIT", "decision": "BUY" | "SELL" | "WAIT",
"signalType": "Scalping" | "Intraday" | "Swing" | "Long Term", "signalType": "Scalping" | "Intraday" | "Swing" | "Long Term",
"riskLevel": "LOW" | "MEDIUM" | "HIGH", "riskLevel": "LOW" | "MEDIUM" | "HIGH",
"entry": "1.08450", "entry": "1.08450",
"stopLoss": "1.07800", "stopLoss": "1.07800",
"takeProfit": "1.09200", "takeProfit": "1.09200",
"takeProfit2": "1.10100", "takeProfit2": "1.10100",
"takeProfit3": "1.11500", "takeProfit3": "1.11500",
"riskReward": "1:3", "riskReward": "1:3",
"duration": "3 a 10 dias", "duration": "3 a 10 dias",
"score": 91, "score": 91,
"justification": "Razão principal", "justification": "Razão principal",
"alerta": "Cuidados", "alerta": "Cuidados",
"pair": "EUR/USD" "pair": "EUR/USD"
} }
`; `;
const prompt = ` const prompt = `
Analise este gráfico sob a óptica do QuantScan IA. Analise este gráfico sob a óptica do QuantScan IA.
${preferredMode ? `Use estritamente o modo de análise: ${preferredMode}.` : 'Detecte o melhor modo automaticamente.'} ${preferredMode ? `Use estritamente o modo de análise: ${preferredMode}.` : 'Detecte o melhor modo automaticamente.'}
${userNotes ? `Notas do usuário: ${userNotes}` : ''} ${userNotes ? `Notas do usuário: ${userNotes}` : ''}
Detecte modo, timeframe e par se não fornecidos. Retorne JSON estrito. Detecte modo, timeframe e par se não fornecidos. Retorne JSON estrito.
`; `;
const response = await ai.models.generateContent({ const response = await ai.models.generateContent({
model, model,
contents: [ contents: [
{ {
parts: [ parts: [
{ text: prompt }, { text: prompt },
{ inlineData: { mimeType: "image/jpeg", data: imageBase64 } } { inlineData: { mimeType: "image/jpeg", data: imageBase64 } }
] ]
} }
], ],
config: { config: {
systemInstruction, systemInstruction,
responseMimeType: "application/json", responseMimeType: "application/json",
responseSchema: { responseSchema: {
type: Type.OBJECT, type: Type.OBJECT,
properties: { properties: {
mode: { type: Type.STRING, enum: ['Técnico', 'Fundamental', 'Híbrido'] }, mode: { type: Type.STRING, enum: ['Técnico', 'Fundamental', 'Híbrido'] },
analiseGeral: { type: Type.STRING }, analiseGeral: { type: Type.STRING },
pair: { type: Type.STRING }, pair: { type: Type.STRING },
timeframe: { type: Type.STRING }, timeframe: { type: Type.STRING },
estrutura: { type: Type.STRING }, estrutura: { type: Type.STRING },
tecnica: { type: Type.STRING }, tecnica: { type: Type.STRING },
fundamental: { type: Type.STRING }, fundamental: { type: Type.STRING },
decision: { type: Type.STRING, enum: ["BUY", "SELL", "WAIT"] }, decision: { type: Type.STRING, enum: ["BUY", "SELL", "WAIT"] },
signalType: { type: Type.STRING }, signalType: { type: Type.STRING },
riskLevel: { type: Type.STRING }, riskLevel: { type: Type.STRING },
entry: { type: Type.STRING }, entry: { type: Type.STRING },
stopLoss: { type: Type.STRING }, stopLoss: { type: Type.STRING },
takeProfit: { type: Type.STRING }, takeProfit: { type: Type.STRING },
takeProfit2: { type: Type.STRING }, takeProfit2: { type: Type.STRING },
takeProfit3: { type: Type.STRING }, takeProfit3: { type: Type.STRING },
riskReward: { type: Type.STRING }, riskReward: { type: Type.STRING },
duration: { type: Type.STRING }, duration: { type: Type.STRING },
score: { type: Type.NUMBER }, score: { type: Type.NUMBER },
justification: { type: Type.STRING }, justification: { type: Type.STRING },
alerta: { 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"] 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 textResponse = response.text || '{}';
const cleanJson = textResponse.replace(/^```json\s*/, '').replace(/\s*```$/, ''); const cleanJson = textResponse.replace(/^```json\s*/, '').replace(/\s*```$/, '');
const parsedData = JSON.parse(cleanJson); const parsedData = JSON.parse(cleanJson);
res.json(parsedData); res.json(parsedData);
} catch (err: any) { } catch (err: any) {
console.error("Gemini Error server-side:", err); console.error("Gemini Error server-side:", err);
let errorMessage = err.message || "Erro desconhecido"; let errorMessage = err.message || "Erro desconhecido";
if (errorMessage.includes("API key not valid")) { if (errorMessage.includes("API key not valid")) {
errorMessage = "A chave de API configurada no projeto (GEMINI_API_KEY) é inválida. Verifique em 'Secrets'."; 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")) { } 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'."; errorMessage = "A chave de API não foi configurada ou é inválida. Defina GEMINI_API_KEY em 'Secrets'.";
} }
res.status(500).json({ error: errorMessage }); res.status(500).json({ error: errorMessage });
} }
}); });
// Vite middleware for development // Vite middleware for development
if (process.env.NODE_ENV !== "production") { if (process.env.NODE_ENV !== "production") {
const vite = await createViteServer({ const vite = await createViteServer({
server: { middlewareMode: true }, server: { middlewareMode: true },
appType: "spa", appType: "spa",
}); });
app.use(vite.middlewares); app.use(vite.middlewares);
} else { } else {
// Production: serve static files. Dist is at project root. // Production: serve static files. Dist is at project root.
const distPath = path.join(process.cwd(), 'dist'); const distPath = path.join(process.cwd(), 'dist');
app.use(express.static(distPath)); app.use(express.static(distPath));
app.get('*', (req, res) => { app.get('*', (req, res) => {
res.sendFile(path.join(distPath, 'index.html')); res.sendFile(path.join(distPath, 'index.html'));
}); });
} }
app.listen(PORT, "0.0.0.0", () => { app.listen(PORT, "0.0.0.0", () => {
console.log(`Server running on http://0.0.0.0:${PORT}`); console.log(`Server running on http://0.0.0.0:${PORT}`);
}); });
}; };
startServer(); startServer();