Trading Bot Simulator

Trading Bot Simulator

Backtest a Simple Moving Average (SMA) Crossover strategy.

Performance Dashboard

Price Action & Signals

Equity Curve

Configuration

Strategy Parameters

Historical Daily Prices

Date Price ($)

Trade Log

Entry Date Exit Date Entry Price Exit Price P/L ($)

${kpis.winRate.toFixed(2)}%

`; renderCharts(result); } function renderCharts(result) { const { historicalData } = state; const priceCtx = document.getElementById('price-chart').getContext('2d'); const equityCtx = document.getElementById('equity-chart').getContext('2d'); const chartOptions = { color: '#d1d5db' }; Chart.defaults.color = chartOptions.color; if (priceChart) priceChart.destroy(); priceChart = new Chart(priceCtx, { type: 'line', data: { labels: historicalData.map(d => d.date), datasets: [ { label: 'Price', data: historicalData.map(d => d.price), borderColor: '#9ca3af', borderWidth: 2, pointRadius: 0 }, { label: `SMA(${state.settings.shortSma})`, data: result.shortSma, borderColor: '#60a5fa', borderWidth: 1.5, pointRadius: 0 }, { label: `SMA(${state.settings.longSma})`, data: result.longSma, borderColor: '#f87171', borderWidth: 1.5, pointRadius: 0 }, { label: 'Buy', data: result.signals.buys, type: 'scatter', backgroundColor: '#22c55e', pointRadius: 5, pointStyle: 'triangle', rotation: 0 }, { label: 'Sell', data: result.signals.sells, type: 'scatter', backgroundColor: '#ef4444', pointRadius: 5, pointStyle: 'triangle', rotation: 180 } ] }, options: { scales: { x: { type: 'time', time: { unit: 'month' }, grid: { color: '#374151'} }, y: { grid: { color: '#374151'} } } } }); if (equityChart) equityChart.destroy(); equityChart = new Chart(equityCtx, { type: 'line', data: { labels: result.equityCurve.map(d => d.date), datasets: [{ label: 'Equity', data: result.equityCurve.map(d => d.value), borderColor: '#3b82f6', borderWidth: 2, pointRadius: 0, fill: true, backgroundColor: 'rgba(59, 130, 246, 0.1)' }] }, options: { scales: { x: { type: 'time', time: { unit: 'month' }, grid: { color: '#374151'} }, y: { grid: { color: '#374151'} } } } }); } function updateTradeLog() { const logBody = document.getElementById('trade-log-body'); logBody.innerHTML = ''; if (!state.backtestResult || state.backtestResult.trades.length === 0) { logBody.innerHTML = `No trades were executed.`; return; } state.backtestResult.trades.forEach(trade => { const tr = document.createElement('tr'); tr.innerHTML = ` ${trade.entryDate} ${trade.exitDate} $${trade.entryPrice.toFixed(2)} $${trade.exitPrice.toFixed(2)} $${trade.pnl.toFixed(2)} `; logBody.appendChild(tr); }); } runBacktestBtn.addEventListener('click', runBacktest); // --- PDF GENERATION --- async function generatePdfReport() { const result = state.backtestResult; if (!result) { alert("Please run a backtest first."); return; } downloadPdfBtn.disabled = true; downloadPdfBtn.textContent = 'Generating...'; const priceChartImg = priceChart.toBase64Image(); const equityChartImg = equityChart.toBase64Image(); const kpis = result.kpis; const settings = state.settings; const reportHtml = `

Trade Strategy & Performance

Ticker: ${settings.ticker.toUpperCase()}
Date: ${new Date().toLocaleDateString()}

Performance Metrics

TOTAL P/L
$${kpis.totalPnl.toFixed(2)}
TOTAL RETURN
${kpis.totalReturn.toFixed(2)}%
WIN RATE
${kpis.winRate.toFixed(2)}%
TRADES
${kpis.numTrades}

Equity Curve

Price Action & Signals

`; const pdfTemplate = document.getElementById('pdf-template'); pdfTemplate.innerHTML = reportHtml; pdfTemplate.classList.remove('invisible'); try { const { jsPDF } = window.jspdf; const canvas = await html2canvas(pdfTemplate.querySelector('.pdf-report-container'), { scale: 2 }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = (canvas.height * pdfWidth) / canvas.width; pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, pdfHeight); pdf.save(`${settings.ticker}_Performance_Report.pdf`); } catch(e) { console.error('PDF Generation Error:', e); } finally { downloadPdfBtn.disabled = false; downloadPdfBtn.textContent = 'Download Performance Report'; pdfTemplate.classList.add('invisible'); } } downloadPdfBtn.addEventListener('click', generatePdfReport); // --- INITIALIZATION --- generateSampleData(); populateSettingsUI(); renderDataTable(); runBacktest(); switchTab(0); });
Scroll to Top