Behavioral Bias Backtesting Tool

Behavioral Bias Backtesting Tool

Simulate the impact of behavioral biases on investment performance.

Understanding Behavioral Biases in Investing

Behavioral finance explores how psychology influences investor decisions and market outcomes. While traditional finance assumes rational actors, real-world investors are often swayed by cognitive biases and emotions, leading to suboptimal financial choices.

What are Behavioral Biases?

These are systematic errors in thinking that affect the decisions and judgments that people make. In investing, they can lead to deviations from a disciplined strategy and significant impacts on portfolio performance. This tool simulates how some common biases might play out over time.

  • Fear Of Missing Out (FOMO) / Herd Mentality: Impulsive buying into rising assets due to social pressure or anxiety of being left behind.
  • Loss Aversion / Disposition Effect: The tendency to hold losing investments too long (to avoid realizing a loss) and sell winning investments too early (to lock in gains).
  • Overconfidence: An exaggerated belief in one's own trading skill or ability to predict market movements, leading to excessive risk-taking or frequent trading.
  • Anchoring: Relying too heavily on a past price or initial piece of information when making current decisions.

By backtesting these biases in a simulated environment, you can gain a clearer understanding of their potential impact on your portfolio.

Set Up Your Simulation Scenario

Configure the market environment and select which behavioral biases to simulate, along with their intensity.

Market Parameters:

Number of months for the simulation (e.g., 120 = 10 years).

e.g., 0.7 for 0.7% growth per month.

Standard deviation of monthly returns.

Select Biases to Simulate:

Reacting to market rallies by chasing returns.

Holding losers too long, selling winners too early.

Excessive trading, larger positions due to inflated self-belief.

Backtest Simulation Progress

Set up your scenario and biases on the previous tab to begin.

0% Complete

Live Simulation Data (Last 5 Months):

Month Market Value ($) Rational Investor ($) Biased Investor ($) Biased Action
No data yet. Run backtest.

Backtest Results & Key Insights

Initial Investment:

$0.00

Final Market Value (Buy & Hold):

$0.00

Rational Investor Final Capital:

$0.00

Biased Investor Final Capital:

$0.00

Insights from Backtest:

Run the backtest to see insights here.

Over a simulated period of ${simulationParameters.simulationDuration} months:

`; insightsHtml += `
    `; const marketReturn = (finalSimulationSummary.finalMarketValue / simulationParameters.initialCapital - 1) * 100; const rationalReturn = (finalSimulationSummary.finalRationalCapital / simulationParameters.initialCapital - 1) * 100; const biasedReturn = (finalSimulationSummary.finalBiasedCapital / simulationParameters.initialCapital - 1) * 100; insightsHtml += `
  • A pure buy-and-hold market strategy would have yielded a return of ${marketReturn.toFixed(2)}%.
  • `; insightsHtml += `
  • The Rational Investor, tracking the market, achieved a return of ${rationalReturn.toFixed(2)}%.
  • `; insightsHtml += `
  • The Biased Investor, affected by selected biases, achieved a return of ${biasedReturn.toFixed(2)}%.
  • `; insightsHtml += `
`; if (biasedReturn < rationalReturn) { insightsHtml += `

The Biased Investor significantly underperformed the Rational Investor. This illustrates the potential negative impact of emotional and cognitive biases on long-term investment returns.

`; if (simulationParameters.enableFomo) { insightsHtml += `

• FOMO/Herd Mentality: Chasing rising markets often leads to buying at highs and suffering larger drawdowns. The simulation suggests this contributed to underperformance.

`; } if (simulationParameters.enableLossAversion) { insightsHtml += `

• Loss Aversion: Panic selling during market dips and missing subsequent recoveries likely impacted the biased portfolio negatively.

`; } if (simulationParameters.enableOverconfidence) { insightsHtml += `

• Overconfidence: The subtle penalties for frequent or suboptimal trading compounded over time, eroding returns.

`; } } else if (biasedReturn > rationalReturn && (simulationParameters.enableFomo || simulationParameters.enableLossAversion || simulationParameters.enableOverconfidence)) { insightsHtml += `

In this specific simulated scenario, even with biases enabled, the Biased Investor slightly outperformed or matched the Rational Investor. This highlights that randomness can sometimes mask the long-term detrimental effects of biases, but such outcomes are typically not sustainable or repeatable.

`; } else { insightsHtml += `

With no biases enabled, the Biased Investor's performance closely matched the Rational Investor, demonstrating that disciplined adherence to a strategy aligns with market returns.

`; } insightsHtml += `

Key Takeaways for Investors:

`; insightsHtml += `
    `; insightsHtml += `
  • Awareness is Key: Understanding your own behavioral biases is the first step to mitigating their negative impact.
  • `; insightsHtml += `
  • Discipline Over Emotion: Sticking to a well-defined investment plan and ignoring short-term emotional impulses is crucial for long-term success.
  • `; insightsHtml += `
  • Risk Management: Robust risk management strategies (e.g., diversification, position sizing) help protect against the amplified losses biases can cause.
  • `; insightsHtml += `
  • Long-Term Perspective: Focus on your long-term financial goals rather than reacting to daily market fluctuations.
  • `; insightsHtml += `
`; bbbtInsights.innerHTML = insightsHtml; } // --- Event Listeners --- // Toggle bias parameter divs enableFomoCheckbox.addEventListener('change', () => { fomoParamsDiv.style.display = enableFomoCheckbox.checked ? 'block' : 'none'; }); fomoStrengthInput.addEventListener('input', () => { fomoStrengthValueSpan.textContent = `${fomoStrengthInput.value}%`; }); enableLossAversionCheckbox.addEventListener('change', () => { lossAversionParamsDiv.style.display = enableLossAversionCheckbox.checked ? 'block' : 'none'; }); lossAversionStrengthInput.addEventListener('input', () => { lossAversionStrengthValueSpan.textContent = `${lossAversionStrengthInput.value}%`; }); enableOverconfidenceCheckbox.addEventListener('change', () => { overconfidenceParamsDiv.style.display = enableOverconfidenceCheckbox.checked ? 'block' : 'none'; }); overconfidenceStrengthInput.addEventListener('input', () => { overconfidenceStrengthValueSpan.textContent = `${overconfidenceStrengthInput.value}%`; }); // Tab navigation tabButtons.forEach((button, index) => { if (button) { button.addEventListener('click', function() { if (!simulationRunning) { updateActiveTab(index); } else { showMessageBox("Please wait for the backtest to complete before changing tabs."); } }); } }); if (nextButton) { nextButton.addEventListener('click', function() { if (!simulationRunning && currentTabIndex < tabButtons.length - 1) { updateActiveTab(currentTabIndex + 1); } else if (simulationRunning) { showMessageBox("Please wait for the backtest to complete before navigating."); } }); } if (prevButton) { prevButton.addEventListener('click', function() { if (!simulationRunning && currentTabIndex > 0) { updateActiveTab(currentTabIndex - 1); } else if (simulationRunning) { showMessageBox("Please wait for the backtest to complete before navigating."); } }); } // Start Backtest Button if (startBacktestButton) { startBacktestButton.addEventListener('click', function() { // Input validation const initialCapital = parseFloat(initialCapitalInput.value); const simulationDuration = parseInt(simulationDurationInput.value); const marketAvgReturn = parseFloat(marketAvgReturnInput.value); const marketVolatility = parseFloat(marketVolatilityInput.value); if (isNaN(initialCapital) || initialCapital <= 0) { showMessageBox("Initial Investment Capital must be a positive number."); return; } if (isNaN(simulationDuration) || simulationDuration < 12) { showMessageBox("Simulation Duration must be at least 12 months."); return; } if (isNaN(marketAvgReturn)) { showMessageBox("Average Monthly Market Return must be a number."); return; } if (isNaN(marketVolatility) || marketVolatility < 0) { showMessageBox("Monthly Market Volatility must be a non-negative number."); return; } // Check if at least one bias is enabled if not all parameters are numeric if (!enableFomoCheckbox.checked && !enableLossAversionCheckbox.checked && !enableOverconfidenceCheckbox.checked) { // No message box needed, it's a valid scenario (rational investor vs market) // But if user expects bias impact, might be worth informing? No, let's keep it simple. } updateActiveTab(2); // Go to Backtest Simulation tab runBacktest(); }); } // PDF Download Button if (downloadPdfButton) { downloadPdfButton.addEventListener('click', async function() { if (!simulationHistory || simulationHistory.length === 0) { showMessageBox("Please run a backtest first to generate a report."); return; } const pdfContentContainer = document.createElement('div'); pdfContentContainer.style.padding = '20px'; pdfContentContainer.style.backgroundColor = '#ffffff'; pdfContentContainer.style.fontFamily = 'Inter, sans-serif'; pdfContentContainer.style.fontSize = '12px'; // PDF Title const pdfTitle = document.createElement('h1'); pdfTitle.textContent = "Behavioral Bias Backtest Report"; pdfTitle.style.textAlign = 'center'; pdfTitle.style.fontSize = '24px'; pdfTitle.style.marginBottom = '20px'; pdfTitle.style.color = '#1f2937'; pdfContentContainer.appendChild(pdfTitle); // Simulation Summary const summarySection = document.createElement('div'); summarySection.innerHTML = `

Backtest Summary:

Initial Investment${formatCurrency(finalSimulationSummary.initialCapital)}
Simulation Duration${simulationParameters.simulationDuration} Months
Final Market Value (Buy & Hold)${formatCurrency(finalSimulationSummary.finalMarketValue)}
Rational Investor Final Capital${formatCurrency(finalSimulationSummary.finalRationalCapital)}
Biased Investor Final Capital${formatCurrency(finalSimulationSummary.finalBiasedCapital)}
`; pdfContentContainer.appendChild(summarySection); // Simulation Parameters Used const paramsSection = document.createElement('div'); paramsSection.innerHTML = `

Parameters Used:

${simulationParameters.enableFomo ? `` : ''} ${simulationParameters.enableLossAversion ? `` : ''} ${simulationParameters.enableOverconfidence ? `` : ''}
Average Monthly Market Return${simulationParameters.marketAvgReturn}%
Monthly Market Volatility (Std. Dev.)${simulationParameters.marketVolatility}%
FOMO Enabled${simulationParameters.enableFomo ? 'Yes' : 'No'}
FOMO Strength${simulationParameters.fomoStrength}%
Loss Aversion Enabled${simulationParameters.enableLossAversion ? 'Yes' : 'No'}
Loss Aversion Strength${simulationParameters.lossAversionStrength}%
Overconfidence Enabled${simulationParameters.enableOverconfidence ? 'Yes' : 'No'}
Overconfidence Strength${simulationParameters.overconfidenceStrength}%
`; pdfContentContainer.appendChild(paramsSection); // Detailed Simulation History (Every 10th month or if total months < 20, show all) const historyHtml = `

Detailed Simulation History (Selected Months):

Showing data for every 10th month and final month for brevity. All data points if duration is less than 20 months.

${simulationHistory .filter((data, index) => simulationParameters.simulationDuration < 20 || index % 10 === 0 || index === simulationHistory.length - 1) .map(data => ` `).join('')}
Month Market Value ($) Rational Investor ($) Biased Investor ($) Biased Action
${data.month} ${formatCurrency(data.marketValue)} ${formatCurrency(data.rationalCapital)} ${formatCurrency(data.biasedCapital)} ${data.biasedAction}
`; pdfContentContainer.insertAdjacentHTML('beforeend', historyHtml); // Insights const insightsHeading = document.createElement('h2'); insightsHeading.style.fontSize = '18px'; insightsHeading.style.fontWeight = '600'; insightsHeading.style.marginTop = '20px'; insightsHeading.style.marginBottom = '10px'; insightsHeading.style.color = '#374151'; insightsHeading.textContent = 'Key Insights:'; pdfContentContainer.appendChild(insightsHeading); pdfContentContainer.appendChild(bbbtInsights.cloneNode(true)); // Clone the insights div for PDF pdfContentContainer.style.position = 'absolute'; pdfContentContainer.style.left = '-9999px'; document.body.appendChild(pdfContentContainer); try { const canvas = await html2canvas(pdfContentContainer, { scale: 1.5, useCORS: true, windowWidth: pdfContentContainer.scrollWidth, windowHeight: pdfContentContainer.scrollHeight }); const imgData = canvas.toDataURL('image/jpeg', 0.8); const { jsPDF } = window.jspdf; const pdf = new jsPDF('p', 'mm', 'a4'); const imgWidth = 210; const pageHeight = 297; const imgHeight = canvas.height * imgWidth / canvas.width; let heightLeft = imgHeight; let position = 0; pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight, null, 'MEDIUM'); heightLeft -= pageHeight; while (heightLeft >= 0) { position = heightLeft - imgHeight; pdf.addPage(); pdf.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight, null, 'MEDIUM'); heightLeft -= pageHeight; } pdf.save('Behavioral_Bias_Backtest_Report.pdf'); } catch (error) { console.error('Error generating PDF:', error); showMessageBox('Error generating PDF. Please ensure your browser supports canvas rendering and try again.'); } finally { if (pdfContentContainer.parentNode) { pdfContentContainer.parentNode.removeChild(pdfContentContainer); } } }); } // Close message box event listener if (messageBoxCloseButton) { messageBoxCloseButton.addEventListener('click', hideMessageBox); } // --- Initialization --- updateActiveTab(0); // Initialize the first tab as active on load });
Scroll to Top