Historical Stock Price Seasonality Analyzer
Enter a stock ticker to analyze simulated historical monthly performance. (Examples: SIM1, SIM2)
Simulated historical data not available or insufficient for ticker: ${ticker}. Try SIM1 or SIM2.
`; resultsArea.style.display = 'block'; return; } // Calculate monthly percentage changes const monthlyChanges = Array(12).fill(null).map(() => []); // Array of 12 arrays (one for each month) // Group data by year and month for easier processing const yearlyData = {}; data.forEach(d => { if (!yearlyData[d.year]) yearlyData[d.year] = Array(12).fill(null); yearlyData[d.year][d.month - 1] = d.close; }); Object.keys(yearlyData).sort().forEach(year => { const yearPrices = yearlyData[year]; for (let i = 0; i < 12; i++) { // Iterate through months 0-11 let prevMonthClose; if (i === 0) { // January // Look for December of previous year const prevYear = parseInt(year) - 1; if (yearlyData[prevYear] && yearlyData[prevYear][11] !== null) { prevMonthClose = yearlyData[prevYear][11]; } } else { prevMonthClose = yearPrices[i-1]; } const currentMonthClose = yearPrices[i]; if (prevMonthClose !== null && currentMonthClose !== null && prevMonthClose > 0) { const change = ((currentMonthClose - prevMonthClose) / prevMonthClose) * 100; monthlyChanges[i].push(change); } } }); const averageMonthlyChanges = monthlyChanges.map(changes => { if (changes.length === 0) return 0; // Or null if prefer to skip months with no data return changes.reduce((sum, val) => sum + val, 0) / changes.length; }); // Find strongest and weakest months let maxChange = -Infinity, minChange = Infinity; let strongestMonthIdx = -1, weakestMonthIdx = -1; averageMonthlyChanges.forEach((change, idx) => { if (change > maxChange) { maxChange = change; strongestMonthIdx = idx; } if (change < minChange) { minChange = change; weakestMonthIdx = idx; } }); const summaryText = `Analysis for ${ticker}: Strongest performing month on average is ${monthNames[strongestMonthIdx]} (${maxChange.toFixed(2)}%). Weakest performing month on average is ${monthNames[weakestMonthIdx]} (${minChange.toFixed(2)}%).`; // Generate Chart HTML let maxAbsChangeForScale = 0; averageMonthlyChanges.forEach(change => { if (Math.abs(change) > maxAbsChangeForScale) { maxAbsChangeForScale = Math.abs(change); } }); // Add a small buffer to maxAbsChangeForScale to prevent bars from hitting the top/bottom exactly maxAbsChangeForScale = maxAbsChangeForScale > 0 ? maxAbsChangeForScale * 1.1 : 5; // Default to 5% if all changes are 0 const chartHtml = averageMonthlyChanges.map((change, idx) => { const isPositive = change >= 0; const barHeightPercentage = maxAbsChangeForScale > 0 ? (Math.abs(change) / maxAbsChangeForScale) * 50 : 0; // Max 50% of chart height for one direction let barStyle = `height: ${barHeightPercentage}%;`; if (isPositive) { barStyle += `bottom: 25px;`; // Starts from the zero line upwards } else { barStyle += `top: calc(50% + 12.5px); transform: scaleY(-1);`; // Starts from zero line downwards, flip } return `
${change.toFixed(1)}%
${monthNames[idx]}
Historical Stock Price Seasonality Analysis
For Ticker: ${ticker}
Generated: ${new Date().toLocaleString()}
Seasonality Analysis for ${ticker}
${summaryText}
Average Monthly Performance (%)
${chartHtml}
| Month | Average % Change |
|---|
Disclaimer: This analysis is based on simulated historical data and does not guarantee future performance. For illustrative purposes only.