Skip to content

Kiko #46

@f409820-ai

Description

@f409820-ai
<title>📊 RALF ULTRA · TRAILING STOP · PREÇO JUSTO · OPERAÇÕES · STATUS</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
        background: radial-gradient(circle at 20% 30%, #0a0c12, #020408);
        color: #eef2ff;
        font-family: 'Segoe UI', 'Inter', system-ui, sans-serif;
        padding: 16px;
        min-height: 100vh;
    }

    .container {
        max-width: 1600px;
        margin: 0 auto;
    }

    .painel-ralf {
        background: linear-gradient(145deg, #0f172a, #080c16);
        border-radius: 24px;
        border: 1px solid #f59e0b;
        overflow: hidden;
    }

    /* CABEÇALHO */
    .header {
        background: linear-gradient(135deg, #1a2333, #0f172a);
        padding: 16px 24px;
        border-bottom: 2px solid #f59e0b;
        display: flex;
        justify-content: space-between;
        align-items: center;
        flex-wrap: wrap;
        gap: 15px;
    }

    .header h2 { font-size: 1rem; background: linear-gradient(135deg, #f59e0b, #22c55e); -webkit-background-clip: text; background-clip: text; color: transparent; }

    .modo-container { display: flex; gap: 10px; background: #1e293b; padding: 6px; border-radius: 60px; }
    .modo-btn { padding: 8px 20px; border-radius: 40px; border: none; font-weight: bold; font-size: 0.8rem; cursor: pointer; background: #334155; color: #94a3b8; }
    .modo-btn.real.ativo { background: #22c55e; color: black; }
    .modo-btn.simulador.ativo { background: #f59e0b; color: black; }

    .capital-panel { background: #1e293b; padding: 6px 16px; border-radius: 40px; font-size: 0.8rem; }
    .toggle-ralf { display: flex; align-items: center; gap: 12px; background: #1e293b; padding: 6px 16px; border-radius: 40px; }
    .switch-ralf { width: 50px; height: 24px; background: #334155; border-radius: 30px; cursor: pointer; position: relative; transition: 0.2s; }
    .switch-ralf.active { background: #22c55e; }
    .switch-ralf::after { content: ""; width: 20px; height: 20px; background: white; border-radius: 50%; position: absolute; top: 2px; left: 3px; transition: 0.2s; }
    .switch-ralf.active::after { left: 27px; }

    /* BLOCOS DE INFORMAÇÕES CENTRALIZADAS */
    .info-central {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 16px;
        padding: 20px 24px;
        background: #0f172a;
        border-bottom: 1px solid #1e293b;
    }
    .info-card {
        background: #1e293b;
        border-radius: 16px;
        padding: 12px;
        text-align: center;
    }
    .info-titulo { font-size: 0.65rem; color: #94a3b8; margin-bottom: 5px; }
    .info-valor { font-size: 1.3rem; font-weight: bold; }
    .info-status { font-size: 0.7rem; margin-top: 5px; }

    .operacoes-grid {
        display: grid;
        grid-template-columns: repeat(6, 1fr);
        gap: 12px;
        padding: 16px 24px;
        background: #0f172a;
        border-bottom: 1px solid #1e293b;
    }
    .operacao-card {
        background: #1e293b;
        border-radius: 12px;
        padding: 10px;
        text-align: center;
    }
    .operacao-numero { font-size: 1.5rem; font-weight: bold; }
    .operacao-verde { color: #22c55e; }
    .operacao-vermelho { color: #ef4444; }

    /* TRAILING STOP */
    .trailing-stop {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 12px 24px;
        background: #0f172a;
        border-bottom: 1px solid #1e293b;
        flex-wrap: wrap;
        gap: 15px;
    }
    .stop-control {
        display: flex;
        align-items: center;
        gap: 10px;
    }
    .stop-switch {
        width: 50px;
        height: 24px;
        background: #334155;
        border-radius: 30px;
        cursor: pointer;
        position: relative;
        transition: 0.2s;
    }
    .stop-switch.active { background: #22c55e; }
    .stop-switch::after { content: ""; width: 20px; height: 20px; background: white; border-radius: 50%; position: absolute; top: 2px; left: 3px; transition: 0.2s; }
    .stop-switch.active::after { left: 27px; }
    .stop-input { background: #1e293b; border: 1px solid #334155; border-radius: 20px; padding: 6px 12px; color: white; width: 80px; text-align: center; }

    /* PREÇO JUSTO */
    .preco-justo-card {
        background: linear-gradient(135deg, #1a2333, #0f172a);
        border-radius: 16px;
        padding: 12px 24px;
        margin: 0 24px 16px 24px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        flex-wrap: wrap;
        gap: 15px;
        border: 1px solid #3b82f6;
    }

    /* GRÁFICO COM CONTROLE DE MINIMIZAR */
    .grafico-container {
        padding: 20px 24px;
    }
    .grafico-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 10px;
    }
    .grafico-controls button {
        background: #1e293b;
        border: none;
        border-radius: 8px;
        padding: 6px 12px;
        color: white;
        cursor: pointer;
        margin-left: 8px;
    }
    .candle-wrapper {
        background: #0a0c18;
        border-radius: 16px;
        padding: 16px;
        transition: all 0.3s ease;
        overflow: hidden;
    }
    .candle-wrapper.minimizado {
        height: 80px;
        padding: 8px;
    }
    .candle-wrapper.minimizado canvas {
        height: 60px !important;
    }
    canvas { width: 100%; height: 450px; background: #0a0c18; border-radius: 12px; transition: height 0.3s; }

    /* LEGENDAS */
    .legendas { display: flex; justify-content: center; gap: 30px; margin-top: 12px; font-size: 0.65rem; flex-wrap: wrap; }

    /* MERCADO */
    .mercado-grid {
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        gap: 12px;
        padding: 16px 24px;
        background: #0f172a;
        border-top: 1px solid #1e293b;
    }
    .mercado-card { background: #1e293b; border-radius: 12px; padding: 10px; }
    .mercado-titulo { font-size: 0.65rem; color: #94a3b8; margin-bottom: 8px; border-bottom: 1px solid #334155; padding-bottom: 4px; }
    .mercado-item { display: flex; justify-content: space-between; padding: 4px 0; font-size: 0.65rem; }
    .cruzamento { font-weight: bold; font-size: 0.8rem; margin-top: 5px; }

    .historico-area {
        padding: 12px 24px;
        background: #0f172a;
        border-top: 1px solid #1e293b;
        max-height: 100px;
        overflow-y: auto;
        font-size: 0.65rem;
    }

    .rodape { padding: 12px; text-align: center; font-size: 0.65rem; color: #475569; border-top: 1px solid #1e293b; }

    @media (max-width: 768px) {
        .info-central, .operacoes-grid, .mercado-grid { grid-template-columns: repeat(2, 1fr); }
    }
</style>

📊 RALF ULTRA · TRAILING STOP · PREÇO JUSTO · OPERAÇÕES · STATUS

💰 CONTA REAL 🎮 SIMULADOR
💰 SALDO: R$ 10.000
🔊 PIP SONORO
    <!-- BLOCO 1: INFORMAÇÕES CENTRAIS (Ativo, Preço, Status) -->
    <div class="info-central">
        <div class="info-card">
            <div class="info-titulo">🎯 ATIVO OPERADO</div>
            <div class="info-valor" id="ativoOperado">📈 WIN (ÍNDICE)</div>
            <div class="info-status" id="statusAtivo">🟢 ATIVO</div>
        </div>
        <div class="info-card">
            <div class="info-titulo">📊 PREÇO ATUAL</div>
            <div class="info-valor" id="precoAtualDisplay">118.340</div>
            <div class="info-status" id="variacaoDisplay">▲ +0.23%</div>
        </div>
        <div class="info-card">
            <div class="info-titulo">📈 ÍNDICE (WIN)</div>
            <div class="info-valor" id="statusIndice">🟢 SOBREVENDIDO</div>
            <div class="info-status">RSI: <span id="rsiIndice">32.5</span></div>
        </div>
        <div class="info-card">
            <div class="info-titulo">💵 DÓLAR (WDO)</div>
            <div class="info-valor" id="statusDolar">🔴 SOBRECOMPRADO</div>
            <div class="info-status">RSI: <span id="rsiDolar">72.3</span></div>
        </div>
    </div>

    <!-- BLOCO 2: OPERAÇÕES (Vencedoras, Perdedoras, Ganho/Perda Diária, Abertas) -->
    <div class="operacoes-grid">
        <div class="operacao-card">
            <div class="info-titulo">✅ OPERAÇÕES VENCEDORAS</div>
            <div class="operacao-numero operacao-verde" id="opsVencedoras">0</div>
        </div>
        <div class="operacao-card">
            <div class="info-titulo">❌ OPERAÇÕES PERDEDORAS</div>
            <div class="operacao-numero operacao-vermelho" id="opsPerdedoras">0</div>
        </div>
        <div class="operacao-card">
            <div class="info-titulo">📈 GANHO DIÁRIO</div>
            <div class="operacao-numero operacao-verde" id="ganhoDiario">R$ 0,00</div>
        </div>
        <div class="operacao-card">
            <div class="info-titulo">📉 PERDA DIÁRIA</div>
            <div class="operacao-numero operacao-vermelho" id="perdaDiaria">R$ 0,00</div>
        </div>
        <div class="operacao-card">
            <div class="info-titulo">🔄 OPERAÇÕES ABERTAS</div>
            <div class="operacao-numero" id="opsAbertas">0</div>
        </div>
        <div class="operacao-card">
            <div class="info-titulo">🎯 TAXA ACERTO</div>
            <div class="operacao-numero operacao-verde" id="taxaAcerto">0%</div>
        </div>
    </div>

    <!-- BLOCO 3: TRAILING STOP TÉCNICO -->
    <div class="trailing-stop">
        <div class="stop-control">
            <span>🛡️ TRAILING STOP TÉCNICO</span>
            <div id="trailingStopSwitch" class="stop-switch"></div>
            <span id="trailingStopStatus">DESLIGADO</span>
        </div>
        <div class="stop-control">
            <span>📏 DISTÂNCIA (pontos):</span>
            <input type="number" id="trailingDistancia" class="stop-input" value="50" step="10">
            <span>📊 STOP ATUAL:</span>
            <span id="stopAtual" style="background:#1e293b; padding:4px 12px; border-radius:20px;">---</span>
        </div>
    </div>

    <!-- BLOCO 4: PREÇO JUSTO + MÉTRICAS -->
    <div class="preco-justo-card">
        <div><span>💰 PREÇO JUSTO: </span><strong id="precoJusto">118.200</strong></div>
        <div><span>📊 MÉDIA MÓVEL 20: </span><strong id="media20">118.150</strong></div>
        <div><span>📈 RESISTÊNCIA: </span><strong id="resistencia">118.600</strong></div>
        <div><span>📉 SUPORTE: </span><strong id="suporte">118.080</strong></div>
        <div><span>⚡ DISTORÇÃO: </span><strong id="distorcao">-0.12%</strong></div>
    </div>

    <!-- GRÁFICO COM CONTROLE DE MINIMIZAR -->
    <div class="grafico-container">
        <div class="grafico-header">
            <span>📊 GRÁFICO DE VELAS + BANDAS + HISTOGRAMA RSI</span>
            <div class="grafico-controls">
                <button id="minimizarGrafico">─ MINIMIZAR</button>
                <button id="maximizarGrafico">🗖 MAXIMIZAR</button>
                <button id="toggleBandasBtn">📉 ESCONDER BANDAS</button>
            </div>
        </div>
        <div id="candleWrapper" class="candle-wrapper">
            <canvas id="candleCanvas" width="1200" height="450"></canvas>
        </div>
        <div class="legendas">
            <span>🟡 SUPERIOR (Máx)</span>
            <span>⚪ CENTRAL (Exaustão)</span>
            <span>🟣 INFERIOR (Mín)</span>
            <span>🟢 Candle COMPRA</span>
            <span>🔴 Candle VENDA</span>
            <span>📊 Histograma RSI</span>
        </div>
    </div>

    <!-- ANÁLISE DE MERCADO -->
    <div class="mercado-grid">
        <div class="mercado-card">
            <div class="mercado-titulo">🇧🇷 AÇÕES BR</div>
            <div class="mercado-item"><span>PETR4</span><span id="petr4">▲ +2.34%</span></div>
            <div class="mercado-item"><span>VALE3</span><span id="vale3">▲ +1.87%</span></div>
            <div class="mercado-item"><span>ITUB4</span><span id="itub4">▲ +1.23%</span></div>
        </div>
        <div class="mercado-card">
            <div class="mercado-titulo">🇺🇸 AÇÕES EUA</div>
            <div class="mercado-item"><span>NASDAQ</span><span id="nasdaq">▲ +0.87%</span></div>
            <div class="mercado-item"><span>S&P500</span><span id="sp500">▲ +0.54%</span></div>
            <div class="mercado-item"><span>DOW</span><span id="dow">● -0.12%</span></div>
        </div>
        <div class="mercado-card">
            <div class="mercado-titulo">🇪🇺 AÇÕES EUROPA</div>
            <div class="mercado-item"><span>DAX</span><span id="dax">▲ +0.45%</span></div>
            <div class="mercado-item"><span>FTSE</span><span id="ftse">▲ +0.32%</span></div>
            <div class="mercado-item"><span>EUROSTOXX</span><span id="euro">▲ +0.28%</span></div>
        </div>
        <div class="mercado-card">
            <div class="mercado-titulo">📉 5 CURVAS JUROS</div>
            <div class="mercado-item"><span>DI1F26</span><span id="di26">12.24%</span></div>
            <div class="mercado-item"><span>DI1F27</span><span id="di27">12.34%</span></div>
            <div class="mercado-item"><span>DI1F28</span><span id="di28">12.41%</span></div>
            <div class="mercado-item"><span>DI1F29</span><span id="di29">12.48%</span></div>
            <div class="mercado-item"><span>DI1F30</span><span id="di30">12.52%</span></div>
        </div>
        <div class="mercado-card">
            <div class="mercado-titulo">💰 COMMODITIES</div>
            <div class="mercado-item"><span>PETRÓLEO</span><span id="wti">▲ $78.63</span></div>
            <div class="mercado-item"><span>OURO</span><span id="ouro">▲ $2,344</span></div>
            <div class="mercado-item"><span>SOJA</span><span id="soja">▲ $12.45</span></div>
        </div>
    </div>

    <!-- HISTÓRICO -->
    <div class="historico-area" id="historicoTrades">
        <div>🟢 Sistema inicializado. Aguardando sinais do mercado...</div>
    </div>

    <div class="rodape">
        🧠 RALF ULTRA · TRAILING STOP · PREÇO JUSTO · STATUS SOBREVENDIDO/SOBRECOMPRADO · PIP SONORO
    </div>
</div>
<script> // ========== CONFIGURAÇÕES ========== let modoReal = true; let pipAtivo = true; let trailingStopAtivo = false; let bandasVisiveis = true; let audioCtx = null; let capital = 10000; let operacoesVencedoras = 0; let operacoesPerdedoras = 0; let ganhoDiario = 0; let perdaDiaria = 0; let opsAbertas = 0; let ativoAtual = "WIN (ÍNDICE)"; let precoEntradaAtual = 0; let stopAtual = 0; // Preços let precoIndice = 118340; let precoDolar = 5.2345; let precoUSD_MXN = 20.45; let historicoPrecos = []; let historicoRSI = []; // Bandas VIVAS let bandaSuperior = 118600; let bandaCentral = 118340; let bandaInferior = 118080; // RSI let rsiIndice = 50; let rsiDolar = 50; // Tendência de juros let tendenciaJuros = "ALTA"; // Velas let velas = []; let ultimoSinal = ""; // ========== SOM PIP ========== function tocarPip(texto) { if (!pipAtivo) return; try { if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)(); if (audioCtx.state === 'suspended') audioCtx.resume(); const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); osc.connect(gain); gain.connect(audioCtx.destination); osc.frequency.value = 880; gain.gain.value = 0.25; osc.start(); gain.gain.exponentialRampToValueAtTime(0.00001, audioCtx.currentTime + 0.4); osc.stop(audioCtx.currentTime + 0.4); console.log(`🔊 PIP: ${texto}`); // Adicionar ao histórico let trades = JSON.parse(localStorage.getItem('tradesList') || '[]'); trades.unshift({ hora: new Date().toLocaleTimeString('pt-BR'), tipo: texto, preco: precoIndice.toFixed(0) }); if (trades.length > 20) trades.pop(); localStorage.setItem('tradesList', JSON.stringify(trades)); atualizarHistorico(); } catch(e) {} } function atualizarHistorico() { const trades = JSON.parse(localStorage.getItem('tradesList') || '[]'); const div = document.getElementById('historicoTrades'); if (trades.length === 0) { div.innerHTML = '
🟢 Aguardando sinais do mercado...
'; return; } div.innerHTML = trades.map(t => `
[${t.hora}] ${t.tipo} @ ${t.preco}
` ).join(''); } // ========== CALCULAR RSI ========== function calcularRSI(precos, periodo = 14) { if (precos.length < periodo + 1) return 50; let ganhos = 0, perdas = 0; for (let i = precos.length - periodo; i < precos.length; i++) { let diff = precos[i] - precos[i-1]; if (diff > 0) ganhos += diff; else perdas += Math.abs(diff); } let forcaRelativa = ganhos / (perdas === 0 ? 1 : perdas); return 100 - (100 / (1 + forcaRelativa)); } // ========== ATUALIZAR BLOCO DE OPERAÇÕES ========== function atualizarBlocoOperacoes() { document.getElementById('opsVencedoras').innerHTML = operacoesVencedoras; document.getElementById('opsPerdedoras').innerHTML = operacoesPerdedoras; document.getElementById('ganhoDiario').innerHTML = `R$ ${ganhoDiario.toFixed(2)}`; document.getElementById('perdaDiaria').innerHTML = `R$ ${perdaDiaria.toFixed(2)}`; document.getElementById('opsAbertas').innerHTML = opsAbertas; let totalOps = operacoesVencedoras + operacoesPerdedoras; let taxa = totalOps > 0 ? (operacoesVencedoras / totalOps * 100).toFixed(1) : 0; document.getElementById('taxaAcerto').innerHTML = `${taxa}%`; document.getElementById('ativoOperado').innerHTML = ativoAtual; } // ========== TRAILING STOP ========== function verificarTrailingStop() { if (!trailingStopAtivo || precoEntradaAtual === 0) return false; let distancia = parseFloat(document.getElementById('trailingDistancia').value) || 50; let novoStop = precoIndice - distancia; if (novoStop > stopAtual) { stopAtual = novoStop; document.getElementById('stopAtual').innerHTML = stopAtual.toFixed(0); tocarPip(`🛡️ TRAILING STOP ajustado para ${stopAtual.toFixed(0)}`); } if (precoIndice <= stopAtual && opsAbertas > 0) { opsAbertas--; let resultado = precoIndice - precoEntradaAtual; if (resultado > 0) { operacoesVencedoras++; ganhoDiario += resultado; } else { operacoesPerdedoras++; perdaDiaria += Math.abs(resultado); } capital += resultado; precoEntradaAtual = 0; stopAtual = 0; atualizarBlocoOperacoes(); document.getElementById('capitalDisplay').innerHTML = `R$ ${capital.toFixed(2)}`; tocarPip(`🔴 STOP atingido! Operação encerrada.`); return true; } return false; } // ========== EXECUTAR OPERAÇÃO ========== function executarOperacao(tipo, preco) { if (opsAbertas > 0) { tocarPip("⚠️ Já existe operação aberta!"); return; } opsAbertas = 1; precoEntradaAtual = preco; stopAtual = preco - (parseFloat(document.getElementById('trailingDistancia').value) || 50); document.getElementById('stopAtual').innerHTML = stopAtual.toFixed(0); tocarPip(`${tipo} ${ativoAtual} @ ${preco.toFixed(0)}`); } // ========== ATUALIZAR MERCADO ========== function atualizarMercado() { // Simular tendência de juros tendenciaJuros = Math.random() > 0.45 ? "ALTA" : "BAIXA"; // Atualizar preços let variacaoIndice = (Math.random() - 0.5) * 80; if (tendenciaJuros === "ALTA") variacaoIndice -= 25; else variacaoIndice += 25; precoIndice += variacaoIndice; precoIndice = Math.min(119800, Math.max(117000, precoIndice)); precoDolar += (Math.random() - 0.5) * 0.015; precoDolar = Math.min(5.50, Math.max(5.10, precoDolar)); historicoPrecos.push(precoIndice); if (historicoPrecos.length > 50) historicoPrecos.shift(); // Calcular RSI rsiIndice = calcularRSI(historicoPrecos, 14); rsiDolar = 50 + (Math.random() - 0.5) * 40; // Atualizar status document.getElementById('precoAtualDisplay').innerHTML = precoIndice.toFixed(0); document.getElementById('statusIndice').innerHTML = rsiIndice < 30 ? "🟢 SOBREVENDIDO" : (rsiIndice > 70 ? "🔴 SOBRECOMPRADO" : "⚪ NEUTRO"); document.getElementById('statusIndice').style.color = rsiIndice < 30 ? "#22c55e" : (rsiIndice > 70 ? "#ef4444" : "#fbbf24"); document.getElementById('rsiIndice').innerHTML = rsiIndice.toFixed(1); document.getElementById('statusDolar').innerHTML = rsiDolar < 30 ? "🟢 SOBREVENDIDO" : (rsiDolar > 70 ? "🔴 SOBRECOMPRADO" : "⚪ NEUTRO"); document.getElementById('rsiDolar').innerHTML = rsiDolar.toFixed(1); // Sinal automático baseado no RSI if (rsiIndice < 30 && ultimoSinal !== "COMPRA") { ultimoSinal = "COMPRA"; if (opsAbertas === 0) { executarOperacao("🟢 COMPRA", precoIndice); } } else if (rsiIndice > 70 && ultimoSinal !== "VENDA") { ultimoSinal = "VENDA"; if (opsAbertas === 0) { executarOperacao("🔴 VENDA", precoIndice); } } // Verificar trailing stop verificarTrailingStop(); // Atualizar bandas let ultimosPrecos = historicoPrecos.slice(-20); let maxima = Math.max(...ultimosPrecos); let minima = Math.min(...ultimosPrecos); let media = ultimosPrecos.reduce((a,b)=>a+b,0)/ultimosPrecos.length; bandaSuperior = maxima; bandaCentral = media; bandaInferior = minima; // Preço justo let precoJusto = media * 0.998; let resistencia = maxima; let suporte = minima; let distorcao = ((precoIndice - precoJusto) / precoJusto * 100).toFixed(2); document.getElementById('precoJusto').innerHTML = precoJusto.toFixed(0); document.getElementById('media20').innerHTML = media.toFixed(0); document.getElementById('resistencia').innerHTML = resistencia.toFixed(0); document.getElementById('suporte').innerHTML = suporte.toFixed(0); document.getElementById('distorcao').innerHTML = `${distorcao}%`; // Gerar vela let variacao = (Math.random() - 0.5) * 60; let open = precoIndice; let close = precoIndice + variacao; let high = Math.max(open, close) + Math.random() * 30; let low = Math.min(open, close) - Math.random() * 30; let cor = "NEUTRO"; if (rsiIndice < 30) cor = "COMPRA"; else if (rsiIndice > 70) cor = "VENDA"; velas.push({ open, high, low, close, cor }); if (velas.length > 50) velas.shift(); historicoRSI.push(rsiIndice); if (historicoRSI.length > 50) historicoRSI.shift(); // Atualizar ações document.getElementById('petr4').innerHTML = tendenciaJuros === "ALTA" ? "▲ +1.23%" : "▼ -0.87%"; document.getElementById('nasdaq').innerHTML = tendenciaJuros === "ALTA" ? "▼ -0.34%" : "▲ +0.76%"; desenharGrafico(); atualizarBlocoOperacoes(); document.getElementById('capitalDisplay').innerHTML = `R$ ${capital.toFixed(2)}`; // Atualizar stop display if (precoEntradaAtual > 0) { document.getElementById('stopAtual').innerHTML = stopAtual.toFixed(0); } } // ========== DESENHAR GRÁFICO ========== function desenharGrafico() { const canvas = document.getElementById('candleCanvas'); if (!canvas) return; const ctx = canvas.getContext('2d'); const width = canvas.clientWidth; const height = canvas.clientHeight; canvas.width = width; canvas.height = height; ctx.clearRect(0, 0, width, height); if (velas.length === 0) return; let todosPrecos = velas.flatMap(v => [v.high, v.low]); let maxVal = Math.max(...todosPrecos, bandaSuperior); let minVal = Math.min(...todosPrecos, bandaInferior); let range = maxVal - minVal; if (range === 0) range = 1; let candleWidth = width / velas.length * 0.7; let spacing = width / velas.length * 0.3; let histHeight = 60; let histY = height - 45; let graficoHeight = height - histHeight - 50; function yPos(valor) { return graficoHeight - ((valor - minVal) / range) * (graficoHeight - 20); } // Velas for (let i = 0; i < velas.length; i++) { const v = velas[i]; let x = i * (candleWidth + spacing) + spacing / 2; let yHigh = yPos(v.high); let yLow = yPos(v.low); let yOpen = yPos(v.open); let yClose = yPos(v.close); ctx.beginPath(); ctx.moveTo(x + candleWidth/2, yHigh); ctx.lineTo(x + candleWidth/2, yLow); ctx.strokeStyle = '#888'; ctx.stroke(); let isGreen = v.close >= v.open; let cor = v.cor === "COMPRA" ? '#22c55e' : (v.cor === "VENDA" ? '#ef4444' : (isGreen ? '#4ade80' : '#f87171')); ctx.fillStyle = cor; ctx.fillRect(x, Math.min(yOpen, yClose), candleWidth, Math.abs(yClose - yOpen)); } // Bandas (se visíveis) if (bandasVisiveis) { ctx.setLineDash([6, 6]); ctx.beginPath(); ctx.strokeStyle = '#f59e0b'; ctx.lineWidth = 2.5; let ySup = yPos(bandaSuperior); ctx.moveTo(0, ySup); ctx.lineTo(width, ySup); ctx.stroke(); ctx.fillStyle = '#f59e0b'; ctx.fillText(`🟡 MÁX: ${bandaSuperior.toFixed(0)}`, 10, ySup - 5); ctx.beginPath(); ctx.strokeStyle = '#ffffff'; ctx.lineWidth = 2; let yCen = yPos(bandaCentral); ctx.moveTo(0, yCen); ctx.lineTo(width, yCen); ctx.stroke(); ctx.fillStyle = '#ffffff'; ctx.fillText(`⚪ CENTRAL: ${bandaCentral.toFixed(0)}`, 10, yCen - 5); ctx.beginPath(); ctx.strokeStyle = '#a855f7'; ctx.lineWidth = 2.5; let yInf = yPos(bandaInferior); ctx.moveTo(0, yInf); ctx.lineTo(width, yInf); ctx.stroke(); ctx.fillStyle = '#a855f7'; ctx.fillText(`🟣 MÍN: ${bandaInferior.toFixed(0)}`, 10, yInf - 5); ctx.setLineDash([]); } // Histograma RSI if (historicoRSI.length > 0) { let histWidth = (width / Math.min(historicoRSI.length, 50)) * 0.7; let histSpacing = width / Math.min(historicoRSI.length, 50) * 0.3; for (let i = 0; i < Math.min(historicoRSI.length, 50); i++) { let rsiVal = historicoRSI[i]; let barHeight = (rsiVal / 100) * histHeight; let x = i * (histWidth + histSpacing) + histSpacing / 2; let y = histY - barHeight; if (rsiVal < 30) ctx.fillStyle = '#22c55e'; else if (rsiVal > 70) ctx.fillStyle = '#ef4444'; else ctx.fillStyle = '#fbbf24'; ctx.fillRect(x, y, histWidth, barHeight); } } ctx.fillStyle = '#94a3b8'; ctx.font = '8px monospace'; ctx.fillText(`📊 RSI: ${rsiIndice.toFixed(1)} | <30 COMPRA | >70 VENDA`, 10, height - 8); // Preço atual let yPreco = yPos(precoIndice); ctx.beginPath(); ctx.strokeStyle = '#22c55e'; ctx.lineWidth = 1.5; ctx.setLineDash([4, 6]); ctx.moveTo(0, yPreco); ctx.lineTo(width, yPreco); ctx.stroke(); ctx.fillStyle = '#22c55e'; ctx.fillText(`💰 ${precoIndice.toFixed(0)}`, width - 80, yPreco - 5); ctx.setLineDash([]); } // ========== EVENTOS ========== document.getElementById('modoRealBtn').addEventListener('click', () => { modoReal = true; document.getElementById('modoRealBtn').classList.add('ativo'); document.getElementById('modoSimuladorBtn').classList.remove('ativo'); }); document.getElementById('modoSimuladorBtn').addEventListener('click', () => { modoReal = false; capital = 10000; document.getElementById('capitalDisplay').innerHTML = `R$ ${capital.toFixed(2)}`; document.getElementById('modoRealBtn').classList.remove('ativo'); document.getElementById('modoSimuladorBtn').classList.add('ativo'); }); document.getElementById('pipSwitch').addEventListener('click', function() { pipAtivo = !pipAtivo; this.classList.toggle('active', pipAtivo); }); document.getElementById('trailingStopSwitch').addEventListener('click', function() { trailingStopAtivo = !trailingStopAtivo; this.classList.toggle('active', trailingStopAtivo); document.getElementById('trailingStopStatus').innerHTML = trailingStopAtivo ? "LIGADO" : "DESLIGADO"; document.getElementById('trailingStopStatus').style.color = trailingStopAtivo ? "#22c55e" : "#ef4444"; }); document.getElementById('toggleBandasBtn').addEventListener('click', function() { bandasVisiveis = !bandasVisiveis; this.innerHTML = bandasVisiveis ? "📉 ESCONDER BANDAS" : "📈 MOSTRAR BANDAS"; desenharGrafico(); }); document.getElementById('minimizarGrafico').addEventListener('click', () => { document.getElementById('candleWrapper').classList.add('minimizado'); desenharGrafico(); }); document.getElementById('maximizarGrafico').addEventListener('click', () => { document.getElementById('candleWrapper').classList.remove('minimizado'); desenharGrafico(); }); // ========== INICIALIZAR ========== for (let i = 0; i < 30; i++) { historicoPrecos.push(118000 + (Math.random() - 0.5) * 800); historicoRSI.push(40 + Math.random() * 40); velas.push({ open: 118000 + (Math.random() - 0.5) * 800, high: 118500 + Math.random() * 300, low: 117500 - Math.random() * 300, close: 118000 + (Math.random() - 0.5) * 800, cor: "NEUTRO" }); } precoIndice = historicoPrecos[historicoPrecos.length - 1]; setInterval(atualizarMercado, 3000); atualizarMercado(); atualizarHistorico(); window.addEventListener('resize', () => desenharGrafico()); </script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions