🚀 Extensões da Interface Web

Este arquivo documenta funcionalidades avançadas que podem ser implementadas.

1️⃣ Gráficos com Chart.js

Descrição: Visualização de dados históricos com gráficos interativos
    <!-- Adicionar antes do </head> -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    
    <!-- Adicionar após section-title -->
    <h2 class="section-title">📈 Evolução do Portfólio (Últimos 30 dias)</h2>
    <div class="chart-container">
        <canvas id="chartEvolucao"></canvas>
    </div>
    
    <!-- Adicionar antes do </body> -->
    <script>
        const ctx = document.getElementById("chartEvolucao").getContext("2d");
        
        // Dados de exemplo - substituir com query do banco de dados
        const dados = {
            labels: ["Dia 1", "Dia 2", "Dia 3", "Dia 4", "Dia 5"],
            datasets: [{
                label: "Valor do Portfólio (USDT)",
                data: [1000, 1050, 1100, 1075, 1150],
                borderColor: "#64b5f6",
                backgroundColor: "rgba(100, 181, 246, 0.1)",
                fill: true,
                tension: 0.4,
                pointRadius: 4,
                pointBackgroundColor: "#64b5f6"
            }]
        };
        
        new Chart(ctx, {
            type: "line",
            data: dados,
            options: {
                responsive: true,
                maintainAspectRatio: true,
                plugins: {
                    legend: {
                        labels: { color: "#e0e0e0" }
                    }
                },
                scales: {
                    y: {
                        grid: { color: "#2a3f5f" },
                        ticks: { color: "#9e9e9e" }
                    },
                    x: {
                        grid: { color: "#2a3f5f" },
                        ticks: { color: "#9e9e9e" }
                    }
                }
            }
        });
    </script>
    

Arquivos necessários: Chart.js (CDN), banco de dados

Dados necessários: portfolio_snapshots.data, portfolio_snapshots.valor_total

2️⃣ Distribuição Pie Charts

Descrição: Comparação visual entre distribuição atual e alvo
    <h2 class="section-title">🎯 Distribuição de Portfólio</h2>
    <div class="grid-2">
        <div class="chart-container">
            <h3 style="text-align: center; margin-bottom: 10px; color: #64b5f6;">Distribuição Atual</h3>
            <canvas id="chartDistribuicaoAtual"></canvas>
        </div>
        <div class="chart-container">
            <h3 style="text-align: center; margin-bottom: 10px; color: #64b5f6;">Distribuição Alvo</h3>
            <canvas id="chartDistribuicaoAlvo"></canvas>
        </div>
    </div>
    
    <script>
        const cores = ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF", "#FF9F40"];
        
        // Gráfico Atual
        const ctxAtual = document.getElementById("chartDistribuicaoAtual").getContext("2d");
        const dadosAtual = {
            labels: ["BTC", "ETH", "HBAR", "ADA", "SOL"],
            datasets: [{
                data: [25.5, 24.8, 25.2, 12.3, 12.2],
                backgroundColor: cores,
                borderColor: "#1a2332",
                borderWidth: 2
            }]
        };
        
        new Chart(ctxAtual, {
            type: "doughnut",
            data: dadosAtual,
            options: {
                responsive: true,
                plugins: {
                    legend: {
                        labels: { color: "#e0e0e0" }
                    }
                }
            }
        });
        
        // Gráfico Alvo
        const ctxAlvo = document.getElementById("chartDistribuicaoAlvo").getContext("2d");
        const dadosAlvo = {
            labels: ["BTC", "ETH", "HBAR", "ADA", "SOL"],
            datasets: [{
                data: [25, 25, 25, 12.5, 12.5],
                backgroundColor: cores,
                borderColor: "#1a2332",
                borderWidth: 2
            }]
        };
        
        new Chart(ctxAlvo, {
            type: "doughnut",
            data: dadosAlvo,
            options: {
                responsive: true,
                plugins: {
                    legend: {
                        labels: { color: "#e0e0e0" }
                    }
                }
            }
        });
    </script>
    

Atualização: A cada ciclo do robô

3️⃣ Banco de Dados - Histórico Múltiplos Dias

Descrição: Queries para extrair histórico de performance
    // Conexão com banco de dados
    $db_host = "localhost";
    $db_user = "root";
    $db_pass = "";
    $db_name = "balanceamento_db";
    
    $conn = new mysqli($db_host, $db_user, $db_pass, $db_name);
    
    if ($conn->connect_error) {
        die("Erro: " . $conn->connect_error);
    }
    
    // Query 1: Últimos 30 dias de evolução
    $sql_evolucao = "
        SELECT data, valor_total, ganho_percentual 
        FROM portfolio_snapshots 
        WHERE data >= DATE_SUB(CURDATE(), INTERVAL 30 DAY) 
        ORDER BY data ASC
    ";
    
    $resultado = $conn->query($sql_evolucao);
    $dados_evolucao = [];
    
    while ($row = $resultado->fetch_assoc()) {
        $dados_evolucao[] = $row;
    }
    
    // Query 2: Performance por moeda (últimos 7 dias)
    $sql_moedas = "
        SELECT moeda, 
               AVG(percentual_portfolio) as pct_media,
               SUM(ganho_moeda) as ganho_total,
               AVG(ganho_percentual_moeda) as ganho_pct
        FROM coin_performance 
        WHERE data >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) 
        GROUP BY moeda 
        ORDER BY ganho_total DESC
    ";
    
    $resultado_moedas = $conn->query($sql_moedas);
    
    // Query 3: Resumo de rebalanceamentos (últimos 7 dias)
    $sql_rebalance = "
        SELECT DATE(data_hora) as dia,
               COUNT(*) as total_ops,
               SUM(CASE WHEN tipo = \"compra\" THEN 1 ELSE 0 END) as compras,
               SUM(CASE WHEN tipo = \"venda\" THEN 1 ELSE 0 END) as vendas,
               SUM(valor_usdt) as volume_total
        FROM rebalancing_transactions 
        WHERE data_hora >= DATE_SUB(NOW(), INTERVAL 7 DAY) 
        GROUP BY DATE(data_hora) 
        ORDER BY dia DESC
    ";
    
    $resultado_rebalance = $conn->query($sql_rebalance);
    

4️⃣ Sistema de Alertas

Descrição: Notificações para desvios críticos e eventos
    // Verificar desvios críticos
    function verificar_desvios_criticos($saldos_portfolio, $threshold = 5) {
        $alertas = [];
        
        foreach ($saldos_portfolio as $moeda => $dados) {
            $desvio = abs($dados["percentual_atual"] - $dados["percentual_alvo"]);
            
            if ($desvio > $threshold) {
                $alertas[] = [
                    "moeda" => $moeda,
                    "tipo" => "desvio_critico",
                    "desvio" => $desvio,
                    "percentual_atual" => $dados["percentual_atual"],
                    "percentual_alvo" => $dados["percentual_alvo"]
                ];
                
                // Gravar no banco de dados
                $sql = "INSERT INTO portfolio_events 
                        (data_hora, tipo_evento, moeda, descricao, severidade) 
                        VALUES (NOW(), 
                                \"rebalanceamento_grande\", 
                                ?, 
                                ?, 
                                \"critico\")";
                
                $descricao = "Desvio de " . number_format($desvio, 2) . "% detectado";
            }
        }
        
        return $alertas;
    }
    
    // Enviar notificação por email
    function enviar_email_alerta($destinatario, $alertas) {
        $assunto = "🚨 Alerta de Desvio - Robô de Balanceamento";
        
        $mensagem = "<h2>Alertas de Desvio Crítico</h2><ul>";
        foreach ($alertas as $alerta) {
            $mensagem .= "<li>" . $alerta["moeda"] . 
                        ": " . number_format($alerta["desvio"], 2) . 
                        "% de desvio</li>";
        }
        $mensagem .= "</ul>";
        
        $headers = "Content-Type: text/html; charset=UTF-8\r\n";
        mail($destinatario, $assunto, $mensagem, $headers);
    }
    
    // Enviar webhook para Discord
    function enviar_webhook_discord($webhook_url, $titulo, $mensagem, $cor = 16711680) {
        $data = json_encode([
            "embeds" => [[
                "title" => $titulo,
                "description" => $mensagem,
                "color" => $cor,
                "timestamp" => date("c")
            ]]
        ]);
        
        $ch = curl_init($webhook_url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_exec($ch);
        curl_close($ch);
    }
    

Canais: Email, Discord, Telegram, webhook customizado

5️⃣ Painel de Controle

Descrição: Botões para iniciar/parar robô e executar ações
    <div class="section-title">⚙️ Painel de Controle</div>
    
    <div class="grid-3">
        <div class="card">
            <div class="card-title">Status do Robô</div>
            <div style="margin: 15px 0;">
                <button style="background: #4caf50; color: white; padding: 10px 20px; 
                               border: none; border-radius: 4px; cursor: pointer; width: 100%;">
                    ▶️ Iniciar Robô
                </button>
                <button style="background: #ff9800; color: white; padding: 10px 20px; 
                               border: none; border-radius: 4px; cursor: pointer; width: 100%;
                               margin-top: 5px;">
                    ⏸ Pausar Robô
                </button>
            </div>
        </div>
        
        <div class="card">
            <div class="card-title">Rebalanceamento Manual</div>
            <div style="margin: 15px 0;">
                <button style="background: #2196f3; color: white; padding: 10px 20px; 
                               border: none; border-radius: 4px; cursor: pointer; width: 100%;">
                    🔄 Rebalancear Agora
                </button>
            </div>
        </div>
        
        <div class="card">
            <div class="card-title">Exportar Dados</div>
            <div style="margin: 15px 0;">
                <button style="background: #9c27b0; color: white; padding: 10px 20px; 
                               border: none; border-radius: 4px; cursor: pointer; width: 100%;">
                    📥 Baixar CSV
                </button>
            </div>
        </div>
    </div>
    
    <script>
        // Exemplo de integração API
        document.querySelector("button").addEventListener("click", function() {
            fetch("/projetos/balanceamento/api_controle.php?acao=iniciar", {
                method: "POST"
            })
            .then(response => response.json())
            .then(data => alert("Robô iniciado: " + data.status))
            .catch(error => console.error("Erro:", error));
        });
    </script>
    

6️⃣ API REST

Descrição: Endpoints JSON para integração com sistemas externos
    <?php
    // api_controle.php - Endpoints para controle do robô
    
    header("Content-Type: application/json");
    
    $acao = $_GET["acao"] ?? "";
    
    switch($acao) {
        case "status":
            // Retorna status atual do robô
            echo json_encode([
                "ativo" => verificar_robo_ativo($log_file),
                "fase" => $metricas["fase"],
                "valor_portfolio" => $metricas["valor_total"],
                "ganho_percentual" => $metricas["ganho_percentual"]
            ]);
            break;
            
        case "iniciar":
            // Inicia o robô em background
            $cmd = "python /path/to/robobalanceamento/robo_balanceamento.py > /dev/null 2>&1 &";
            shell_exec($cmd);
            echo json_encode(["status" => "iniciado"]);
            break;
            
        case "parar":
            // Para a execução do robô
            shell_exec("pkill -f robo_balanceamento.py");
            echo json_encode(["status" => "parado"]);
            break;
            
        case "historico":
            // Retorna histórico de últimos N dias
            $dias = $_GET["dias"] ?? 7;
            $sql = "SELECT data, valor_total, ganho_percentual 
                    FROM portfolio_snapshots 
                    WHERE data >= DATE_SUB(CURDATE(), INTERVAL $dias DAY)";
            // Executar query e retornar JSON
            break;
            
        default:
            http_response_code(400);
            echo json_encode(["erro" => "Ação não reconhecida"]);
    }
    ?>
    

Endpoints: /status, /iniciar, /parar, /historico, /alertas

7️⃣ Exportar para CSV

Descrição: Download de dados em formato CSV para análise externa
    <?php
    // export_csv.php
    
    header("Content-Type: text/csv; charset=utf-8");
    header("Content-Disposition: attachment; filename=portfolio_".date("Y-m-d").".csv");
    
    $output = fopen("php://output", "w");
    
    // Cabeçalho
    fputcsv($output, ["Data", "Moeda", "Saldo", "Preço", "Valor USDT", "% Portfolio", "% Alvo"]);
    
    // Dados de portfolio_snapshots e coin_performance
    $sql = "SELECT cp.data, cp.moeda, cp.saldo_quantidade, cp.preco_atual, 
                   cp.valor_total_usdt, cp.percentual_portfolio, cp.percentual_alvo
            FROM coin_performance cp
            ORDER BY cp.data DESC, cp.moeda ASC";
    
    $resultado = $conn->query($sql);
    
    while ($row = $resultado->fetch_assoc()) {
        fputcsv($output, $row);
    }
    
    fclose($output);
    ?>
    

📋 Checklist de Implementação

📚 Recursos Úteis


Espera: Volte em log_balanceamento.php para usar a interfacebase