Institutional Ownership Change Analyzer

Institutional Ownership Change Analyzer

Overall Ownership Trends (Mock Data)

Avg. Ownership Change: Calculating...

Net Share Change: Calculating...

Companies w/ Increased Ownership: 0

No companies match your search criteria.

'; return; } filteredCompanies.forEach(company => { const card = document.createElement('div'); card.className = 'company-card'; const ownershipChangePercent = company.currentOwnershipPercent - company.previousOwnershipPercent; const shareChange = company.currentShares - company.previousShares; const changeClass = getChangeClass(ownershipChangePercent); const changeSign = ownershipChangePercent > 0 ? '+' : (ownershipChangePercent < 0 ? '' : ''); const shareChangeSign = shareChange > 0 ? '+' : (shareChange < 0 ? '' : ''); card.innerHTML = `

${company.name} (${company.ticker})

${company.sector} - ${company.country}

Prev. Ownership:
${company.previousOwnershipPercent.toFixed(1)}% (${formatNumber(company.previousShares)} shares)
Curr. Ownership:
${company.currentOwnershipPercent.toFixed(1)}% (${formatNumber(company.currentShares)} shares)
Ownership % Change:
${changeSign}${ownershipChangePercent.toFixed(1)}%
Net Share Change:
${shareChangeSign}${formatNumber(shareChange)}

Institutional Activity:

  • Increased Positions: ${formatNumber(company.institutionsIncreased)}
  • Decreased Positions: ${formatNumber(company.institutionsDecreased)}
  • Held Positions: ${formatNumber(company.institutionsHeld)}
`; companiesGrid.appendChild(card); }); } function updateSummaryMetrics(dataToSummarize) { if (!avgOwnershipChangeEl || !netShareChangeEl || !companiesIncreasedOwnEl) { console.error("One or more summary metric DOM elements not found."); return; } if (dataToSummarize.length === 0) { avgOwnershipChangeEl.textContent = 'N/A'; netShareChangeEl.textContent = 'N/A'; companiesIncreasedOwnEl.textContent = '0'; return; } let totalOwnershipChangePercent = 0; let totalNetShareChange = 0; let companiesIncreasedCount = 0; dataToSummarize.forEach(company => { const ownershipChange = company.currentOwnershipPercent - company.previousOwnershipPercent; const shareChangeVal = company.currentShares - company.previousShares; totalOwnershipChangePercent += ownershipChange; totalNetShareChange += shareChangeVal; if (ownershipChange > 0) { companiesIncreasedCount++; } }); const avgChange = totalOwnershipChangePercent / dataToSummarize.length; const avgChangeSign = avgChange > 0 ? '+' : (avgChange < 0 ? '' : ''); avgOwnershipChangeEl.textContent = `${avgChangeSign}${avgChange.toFixed(2)}%`; avgOwnershipChangeEl.className = `font-bold ${getChangeClass(avgChange)}`; const netShareSign = totalNetShareChange > 0 ? '+' : (totalNetShareChange < 0 ? '' : ''); netShareChangeEl.textContent = `${netShareSign}${formatNumber(totalNetShareChange)} shares`; netShareChangeEl.className = `font-bold ${getChangeClass(totalNetShareChange / 1e9)}`; // Normalize for color companiesIncreasedOwnEl.textContent = companiesIncreasedCount; } function filterCompanies() { if (!searchInput) { console.error("Error: searchInput element not found."); renderCompanies(companiesOwnershipData); updateSummaryMetrics(companiesOwnershipData); return; } const searchTerm = searchInput.value.toLowerCase().trim(); const filtered = companiesOwnershipData.filter(company => company.name.toLowerCase().includes(searchTerm) || company.ticker.toLowerCase().includes(searchTerm) ); renderCompanies(filtered); updateSummaryMetrics(filtered); } function generatePdf() { if (!pdfContentEl) { console.error("Error: pdfContent element not found. Cannot generate PDF."); const msgBox = document.createElement('div'); msgBox.textContent = "Error preparing PDF content. Please try again."; msgBox.style.cssText = "position:fixed; top:20px; left:50%; transform:translateX(-50%); background:red; color:white; padding:10px; border-radius:5px; z-index:1000;"; document.body.appendChild(msgBox); setTimeout(() => msgBox.remove(), 3000); return; } const opt = { margin: [0.5, 0.5, 0.5, 0.5], // inches filename: 'institutional_ownership_report.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2, logging: false, useCORS: true, letterRendering: true, scrollY: 0 }, jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }, pagebreak: { mode: ['avoid-all', 'css', 'legacy'] } }; const pdfTitleElement = pdfContentEl.querySelector('.print\\:block'); if (pdfTitleElement) { pdfTitleElement.classList.remove('hidden'); } const contentCloneForPdf = pdfContentEl.cloneNode(true); html2pdf().from(contentCloneForPdf).set(opt).save().then(() => { if (pdfTitleElement) { pdfTitleElement.classList.add('hidden'); } }).catch(err => { console.error("Error generating PDF:", err); if (pdfTitleElement) { pdfTitleElement.classList.add('hidden'); } const errorBox = document.createElement('div'); errorBox.textContent = "Failed to generate PDF. See console for details."; errorBox.style.cssText = "position:fixed; top:20px; left:50%; transform:translateX(-50%); background:red; color:white; padding:10px; border-radius:5px; z-index:1000;"; document.body.appendChild(errorBox); setTimeout(() => errorBox.remove(), 3000); }); } // --- Event Listeners --- if (searchInput) { searchInput.addEventListener('input', filterCompanies); } else { console.warn("Search input element not found. Search functionality will be disabled."); } if (downloadPdfButton) { downloadPdfButton.addEventListener('click', generatePdf); } else { console.warn("PDF download button not found. PDF functionality will be disabled."); } // --- Initial Render --- renderCompanies(companiesOwnershipData); updateSummaryMetrics(companiesOwnershipData); });
Scroll to Top