/* * Quantitative Trading Platform - Interactive Mockup * Mock data generation for charts and displays */ // Chart initialization function initCharts() { // Initialize Portfolio Chart initPortfolioChart(); // Initialize Data Quality Chart initDataQualityChart(); // Initialize Backtest Chart initBacktestChart(); // Initialize Risk Chart initRiskChart(); } // Portfolio Performance Chart function initPortfolioChart() { const ctx = document.getElementById('portfolioChart'); if (!ctx) return; const data = generatePortfolioData(); AppState.charts.portfolioChart = new Chart(ctx, { type: 'line', data: { labels: data.map(d => d.date), datasets: [{ label: 'Portfolio Value', data: data.map(d => d.value), borderColor: '#4caf50', backgroundColor: 'rgba(76, 175, 80, 0.1)', fill: true, tension: 0.4, pointRadius: 2, pointHoverRadius: 5 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { mode: 'index', intersect: false, callbacks: { label: function(context) { return `$${context.parsed.y.toLocaleString()}`; } } } }, scales: { x: { grid: { color: 'rgba(255, 255, 255, 0.05)' }, ticks: { color: '#b0bec5' } }, y: { grid: { color: 'rgba(255, 255, 255, 0.05)' }, ticks: { color: '#b0bec5', callback: function(value) { return '$' + (value / 1000).toFixed(0) + 'k'; } } } } } }); } // Data Quality Chart function initDataQualityChart() { const ctx = document.getElementById('dataQualityChart'); if (!ctx) return; const data = generateDataQualityData(); AppState.charts.dataQualityChart = new Chart(ctx, { type: 'line', data: { labels: data.map(d => d.date), datasets: [ { label: 'Completeness (%)', data: data.map(d => d.completeness), borderColor: '#4caf50', backgroundColor: 'rgba(76, 175, 80, 0.1)', fill: true, tension: 0.4, yAxisID: 'y' }, { label: 'Latency (ms)', data: data.map(d => d.latency), borderColor: '#2196f3', backgroundColor: 'rgba(33, 150, 243, 0.1)', fill: true, tension: 0.4, yAxisID: 'y1' } ] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'top', labels: { color: '#b0bec5' } } }, scales: { x: { grid: { color: 'rgba(255, 255, 255, 0.05)' }, ticks: { color: '#b0bec5' } }, y: { type: 'linear', display: true, position: 'left', min: 80, max: 100, grid: { color: 'rgba(255, 255, 255, 0.05)' }, ticks: { color: '#b0bec5', callback: function(value) { return value + '%'; } } }, y1: { type: 'linear', display: true, position: 'right', min: 0, max: 30, grid: { drawOnChartArea: false }, ticks: { color: '#b0bec5', callback: function(value) { return value + 'ms'; } } } } } }); } // Backtest Results Chart function initBacktestChart() { const ctx = document.getElementById('backtestChart'); if (!ctx) return; const data = generateBacktestData(); AppState.charts.backtestChart = new Chart(ctx, { type: 'line', data: { labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], datasets: data.map((strategy, index) => { const colors = ['#4caf50', '#2196f3', '#9c27b0']; return { label: strategy.strategy, data: strategy.returns, borderColor: colors[index], backgroundColor: colors[index] + '20', fill: false, tension: 0.4 }; }) }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'top', labels: { color: '#b0bec5' } } }, scales: { x: { grid: { color: 'rgba(255, 255, 255, 0.05)' }, ticks: { color: '#b0bec5' } }, y: { grid: { color: 'rgba(255, 255, 255, 0.05)' }, ticks: { color: '#b0bec5', callback: function(value) { return '$' + value.toLocaleString(); } } } } } }); } // Risk Management Chart function initRiskChart() { const ctx = document.getElementById('riskChart'); if (!ctx) return; const data = generateRiskData(); AppState.charts.riskChart = new Chart(ctx, { type: 'radar', data: { labels: data.map(d => d.metric), datasets: [{ label: 'Risk Metrics', data: data.map(d => d.values[0]), backgroundColor: 'rgba(255, 152, 0, 0.2)', borderColor: 'rgba(255, 152, 0, 1)', pointBackgroundColor: 'rgba(255, 152, 0, 1)', pointBorderColor: '#fff', pointHoverBackgroundColor: '#fff', pointHoverBorderColor: 'rgba(255, 152, 0, 1)' }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } }, scales: { r: { angleLines: { color: 'rgba(255, 255, 255, 0.1)' }, grid: { color: 'rgba(255, 255, 255, 0.1)' }, pointLabels: { color: '#b0bec5' }, ticks: { color: '#b0bec5', backdropColor: 'transparent' }, min: 0, max: 10 } } } }); } // Update functions for live data function updatePortfolioChart() { if (!AppState.charts.portfolioChart) return; const newData = generatePortfolioData(); AppState.charts.portfolioChart.data.labels = newData.map(d => d.date); AppState.charts.portfolioChart.data.datasets[0].data = newData.map(d => d.value); AppState.charts.portfolioChart.update('none'); } function updateDataQualityChart() { if (!AppState.charts.dataQualityChart) return; const newData = generateDataQualityData(); AppState.charts.dataQualityChart.data.labels = newData.map(d => d.date); AppState.charts.dataQualityChart.data.datasets[0].data = newData.map(d => d.completeness); AppState.charts.dataQualityChart.data.datasets[1].data = newData.map(d => d.latency); AppState.charts.dataQualityChart.update('none'); } function updateBacktestChart() { if (!AppState.charts.backtestChart) return; const newData = generateBacktestData(); newData.forEach((strategy, index) => { AppState.charts.backtestChart.data.datasets[index].data = strategy.returns; }); AppState.charts.backtestChart.update('none'); } function updateRiskChart() { if (!AppState.charts.riskChart) return; const newData = generateRiskData(); AppState.charts.riskChart.data.datasets[0].data = newData.map(d => d.values[0]); AppState.charts.riskChart.update('none'); } // Data generation functions (same as in app.js but exported for use) function generatePortfolioData() { const data = []; let value = 100000; for (let i = 0; i < 30; i++) { const date = new Date(); date.setDate(date.getDate() - (30 - i)); const change = (Math.random() - 0.4) * 0.02 * value; value += change; data.push({ date: date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }), value: Math.max(90000, value) }); } return data; } function generateDataQualityData() { const data = []; for (let i = 0; i < 7; i++) { const date = new Date(); date.setDate(date.getDate() - (7 - i)); data.push({ date: date.toLocaleDateString('en-US', { weekday: 'short' }), completeness: 90 + Math.random() * 8, latency: 5 + Math.random() * 15, errors: Math.floor(Math.random() * 5) }); } return data; } function generateBacktestData() { const strategies = ['Dual Momentum', 'Mean Reversion', 'Pairs Trading']; const data = []; strategies.forEach(strategy => { let returns = 100; const returnsData = []; for (let i = 0; i < 12; i++) { const monthlyReturn = (Math.random() - 0.2) * 0.1; returns *= (1 + monthlyReturn); returnsData.push(returns); } data.push({ strategy, returns: returnsData, sharpe: 0.8 + Math.random() * 1.5, winRate: 50 + Math.random() * 30 }); }); return data; } function generateRiskData() { const metrics = ['VaR', 'CVaR', 'Max Drawdown', 'Volatility']; const data = []; metrics.forEach(metric => { const values = []; for (let i = 0; i < 10; i++) { values.push(Math.random() * 10); } data.push({ metric, values }); }); return data; } // Export for use in other scripts window.MockData = { initCharts, updatePortfolioChart, updateDataQualityChart, updateBacktestChart, updateRiskChart, generatePortfolioData, generateDataQualityData, generateBacktestData, generateRiskData };