Social Trading Network Analyzer

Social Trading Network Analyzer

Compare and analyze trader performance metrics.

Win Rate (%) Comparison

Risk vs. Profit Factor

Bubble size represents number of followers.

Trader Comparison Table

Trader Win Rate (%) Followers Risk (1-10) Profit Factor

${t.name}

Followers: ${t.followers.toLocaleString('en-US')} | Risk: ${t.riskScore}

`; item.querySelector('.btn-edit').addEventListener('click', () => startEdit(t.id)); item.querySelector('.btn-delete').addEventListener('click', () => deleteTrader(t.id)); traderList.appendChild(item); }); } function renderCharts() { const labels = traders.map(t => t.name); const winRates = traders.map(t => t.winRate); const riskScores = traders.map(t => t.riskScore); const profitFactors = traders.map(t => t.profitFactor); const followers = traders.map(t => t.followers); const backgroundColors = ['#4F46E5', '#10B981', '#F59E0B', '#EF4444', '#6366F1', '#22C55E', '#FBBF24', '#F87171']; // Win Rate Bar Chart const winRateCtx = document.getElementById('winRateChart').getContext('2d'); if (winRateChart) winRateChart.destroy(); winRateChart = new Chart(winRateCtx, { type: 'bar', data: { labels: labels, datasets: [{ label: 'Win Rate (%)', data: winRates, backgroundColor: backgroundColors.slice(0, traders.length), borderColor: '#fff', borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true, max: 100 } }, plugins: { legend: { display: false } } } }); // Risk vs Profit Bubble Chart const riskProfitCtx = document.getElementById('riskProfitChart').getContext('2d'); const bubbleData = traders.map((t, i) => ({ x: t.riskScore, y: t.profitFactor, r: Math.max(5, Math.sqrt(t.followers) / 25), // Scale bubble size label: t.name })); if (riskProfitChart) riskProfitChart.destroy(); riskProfitChart = new Chart(riskProfitCtx, { type: 'bubble', data: { datasets: [{ label: 'Traders', data: bubbleData, backgroundColor: backgroundColors.map(c => c + 'B3').slice(0, traders.length) // Add alpha }] }, options: { scales: { x: { title: { display: true, text: 'Risk Score (1-10)' } }, y: { title: { display: true, text: 'Profit Factor' } } }, plugins: { legend: { display: false } } } }); } // --- FORM & DATA LOGIC --- function handleFormSubmit(e) { e.preventDefault(); const id = parseInt(traderIdInput.value); const traderData = { name: document.getElementById('traderName').value, winRate: parseInt(document.getElementById('winRate').value), followers: parseInt(document.getElementById('followers').value), riskScore: parseInt(document.getElementById('riskScore').value), profitFactor: parseFloat(document.getElementById('profitFactor').value), }; if (id === -1) { // Add new traderData.id = traders.length > 0 ? Math.max(...traders.map(t => t.id)) + 1 : 1; traders.push(traderData); } else { // Update existing const index = traders.findIndex(t => t.id === id); if (index !== -1) { traders[index] = { ...traders[index], ...traderData }; } } renderAll(); resetForm(); } function startEdit(id) { const trader = traders.find(t => t.id === id); if (!trader) return; traderIdInput.value = trader.id; document.getElementById('traderName').value = trader.name; document.getElementById('winRate').value = trader.winRate; document.getElementById('followers').value = trader.followers; document.getElementById('riskScore').value = trader.riskScore; document.getElementById('profitFactor').value = trader.profitFactor; formTitle.textContent = 'Edit Trader'; submitBtn.textContent = 'Update Trader'; cancelBtn.classList.remove('hidden'); } function cancelEdit() { resetForm(); } function resetForm() { traderForm.reset(); traderIdInput.value = -1; formTitle.textContent = 'Add New Trader'; submitBtn.textContent = 'Add Trader'; cancelBtn.classList.add('hidden'); } function deleteTrader(id) { traders = traders.filter(t => t.id !== id); renderAll(); resetForm(); // In case we were editing the one we deleted } // --- UI FUNCTIONS --- function switchTab(tabName) { if (tabName === 'dashboard') { dashboardContent.classList.remove('hidden'); configContent.classList.add('hidden'); tabBtnDashboard.classList.add('active'); tabBtnDashboard.classList.remove('inactive'); tabBtnConfig.classList.add('inactive'); tabBtnConfig.classList.remove('active'); } else { dashboardContent.classList.add('hidden'); configContent.classList.remove('hidden'); tabBtnDashboard.classList.add('inactive'); tabBtnDashboard.classList.remove('active'); tabBtnConfig.classList.add('active'); tabBtnConfig.classList.remove('inactive'); } } // --- PDF GENERATION --- function downloadPDF() { const { jsPDF } = window.jspdf; const doc = new jsPDF(); const pageWidth = doc.internal.pageSize.getWidth(); doc.setFont("helvetica", "bold"); doc.setFontSize(20); doc.setTextColor(17, 24, 39); doc.text("Social Trading Network Analysis", pageWidth / 2, 20, { align: "center" }); doc.setFontSize(10); doc.setFont("helvetica", "normal"); doc.setTextColor(107, 114, 128); doc.text(`Report Generated: ${new Date().toLocaleDateString('en-US')}`, pageWidth / 2, 28, { align: "center" }); doc.autoTable({ startY: 40, head: [['Trader Name', 'Win Rate (%)', 'Followers', 'Risk Score', 'Profit Factor']], body: traders.map(t => [t.name, t.winRate, t.followers.toLocaleString('en-US'), t.riskScore, t.profitFactor.toFixed(2)]), theme: 'grid', headStyles: { fillColor: [31, 41, 55] }, styles: { cellPadding: 2.5, fontSize: 9 }, }); doc.save("Social_Trading_Analysis_Report.pdf"); } // --- START THE APP --- initialize(); });
Scroll to Top