Accurately calculate your company's weighted average shares outstanding for EPS reporting.
Weighted Average Shares Outstanding Calculator
Number of shares outstanding at the start of the reporting period.
The date when these shares were issued or repurchased.
Positive for new shares issued, negative for shares repurchased (treasury stock).
Calculation Results
—
Weighted Average Shares = Σ (Shares × Weight)
where Weight = (Days in Period Shares Outstanding) / (Total Days in Period)
—
Weighted Basic Shares
—
Weighted Diluted Shares (Est.)
—
Total Weight
Share Issuance Over Time
Visual representation of share changes and their impact on weighted average calculation.
Share Transaction Data
Date
Shares Outstanding (Start)
Shares Added/(Repurchased)
Shares Outstanding (End)
Days in Period
Weight
Weighted Shares
What is Weighted Average Per Share?
The weighted average per share is a critical financial metric used to calculate Earnings Per Share (EPS). Instead of simply using the number of shares outstanding at the end of a period, it accounts for changes in the number of shares throughout that period. This provides a more accurate representation of the average number of shares that were available to shareholders during the reporting timeframe. It's essential for investors and analysts to understand a company's profitability on a per-share basis.
Who should use it: Publicly traded companies are required to report EPS based on the weighted average per share. Investors, financial analysts, and even management use this figure to assess profitability, compare performance across different periods, and evaluate the company's value. Understanding calculating weighted average per share helps in making informed investment decisions.
Common misconceptions: A common mistake is assuming the number of shares at the end of the period is sufficient. Another misconception is that only share issuances matter; share repurchases (treasury stock) also significantly impact the weighted average per share. Calculating weighted average per share correctly is vital for accurate financial reporting.
Weighted Average Per Share Formula and Mathematical Explanation
The fundamental concept behind calculating weighted average per share is to give more "weight" to shares that were outstanding for a longer portion of the reporting period.
The formula for Weighted Average Shares Outstanding (Basic) is:
Weighted Average Shares = Σ (Shares Outstandingᵢ × Weightᵢ)
Where:
Σ denotes summation (adding up the results for each block of shares).
Shares Outstandingᵢ is the number of shares outstanding during a specific sub-period (i).
Weightᵢ is the fraction of the reporting period that those specific shares were outstanding.
To calculate the weight (Weightᵢ):
Weightᵢ = (Number of Days Shares Outstandingᵢ) / (Total Number of Days in the Reporting Period)
For diluted EPS, potential dilutive securities (like stock options, warrants, or convertible bonds) are also considered, but the basic calculation focuses on common shares.
Variable Explanations:
Variable
Meaning
Unit
Typical Range
Shares Outstandingᵢ
The number of shares held by shareholders during a specific sub-period.
Shares
Non-negative integer
Number of Days Shares Outstandingᵢ
The duration (in days) for which Shares Outstandingᵢ were outstanding within the reporting period.
Days
0 to Total Days in Period
Total Number of Days in the Reporting Period
The total number of days in the financial reporting period (e.g., 90 for a quarter, 365 for a year).
Days
90, 91, 365, 366
Weightᵢ
The proportion of the reporting period a block of shares was outstanding.
Ratio (0 to 1)
0 to 1
Weighted Average Shares
The final calculated average number of shares outstanding during the period.
Shares
Non-negative integer
Practical Examples (Real-World Use Cases)
Example 1: Simple Share Issuance
Company A reports quarterly. At the beginning of Q1 (January 1st), they had 1,000,000 shares outstanding. On March 1st (60 days into the 91-day quarter), they issued an additional 200,000 shares.
Period: Q1 (91 days)
Transaction 1: 1,000,000 shares outstanding from Jan 1 to Mar 1 (60 days). Weight = 60/91.
Transaction 2: 1,000,000 + 200,000 = 1,200,000 shares outstanding from Mar 2 to Mar 31 (31 days). Weight = 31/91.
Interpretation: The weighted average shares (1,069,231) are higher than the initial 1,000,000 due to the new shares issued mid-quarter. This impacts EPS calculations positively if net income remains constant.
Example 2: Share Repurchase
Company B reports annually. They started the year with 5,000,000 shares. On July 1st (182 days into the 365-day year), they repurchased 500,000 shares for treasury stock.
Period: Annual (365 days)
Transaction 1: 5,000,000 shares outstanding from Jan 1 to Jun 30 (182 days). Weight = 182/365.
Transaction 2: 5,000,000 – 500,000 = 4,500,000 shares outstanding from Jul 1 to Dec 31 (183 days). Weight = 183/365.
Interpretation: The weighted average shares (4,736,987) are lower than the initial 5,000,000 because of the significant share repurchase. This would increase EPS, assuming net income is unchanged. Calculating weighted average per share accurately reflects this change.
How to Use This Weighted Average Per Share Calculator
Our calculator simplifies the process of determining the weighted average shares outstanding. Follow these steps for an accurate calculation:
Input Starting Shares: Enter the number of shares your company had outstanding at the very beginning of the reporting period (e.g., the start of the quarter or year).
Enter Transaction Details: For each significant change in share count (issuances or repurchases) during the period:
Input the Date the change occurred.
Enter the Number of Shares Added/Removed. Use a positive number for new shares issued and a negative number (or a positive number in the "Repurchased" field if available) for shares bought back (treasury stock).
The calculator will automatically determine the number of days each block of shares was outstanding.
Click Calculate: Press the "Calculate" button. The calculator will compute the weighted average shares outstanding, along with key intermediate values and a representation in a table and chart.
Review Results: The primary result shows the calculated weighted average shares. Intermediate values provide a breakdown of the weights and contributions. The table details each transaction's impact.
Use for Reporting: This figure is crucial for calculating basic Earnings Per Share (EPS). The formula used is clearly displayed.
Reset: Use the "Reset" button to clear all fields and start over.
Copy Results: Use the "Copy Results" button to copy the main output and key assumptions to your clipboard for easy pasting into reports.
Decision-Making Guidance: Understanding your weighted average shares trend helps evaluate the effectiveness of share buyback programs or the impact of capital raises. A declining weighted average, assuming stable net income, generally leads to higher EPS, potentially boosting investor confidence. Conversely, significant share issuances might dilute EPS but can provide capital for growth.
Key Factors That Affect Weighted Average Per Share Results
Timing of Share Transactions: This is the most critical factor. Shares issued on the last day of the period have minimal impact, while shares issued on the first day have maximum impact. The calculator weights each transaction by the fraction of the period it was outstanding.
Magnitude of Share Changes: Large issuances significantly increase the weighted average, while large repurchases decrease it. The absolute number of shares added or removed is paramount.
Reporting Period Length: The denominator in the weight calculation is the total days in the period. A share transaction will have a larger weight in a shorter period (e.g., a quarter) compared to a full year, assuming the same number of days outstanding.
Treasury Stock Transactions: Share repurchases reduce the number of outstanding shares. When calculating the weighted average, these repurchased shares are weighted from the date of repurchase until the period's end, thus lowering the overall average.
Stock Splits and Dividends: While not directly entered as "additions," stock splits and stock dividends require retrospective adjustment of all historical share counts within the period to ensure comparability. For simplicity, this calculator focuses on direct issuances/repurchases. Properly calculating weighted average per share necessitates these adjustments.
Dilutive Securities: For calculating *diluted* EPS (a separate but related concept), the potential issuance of shares from stock options, warrants, and convertible securities must be considered. This calculator focuses on the *basic* weighted average shares calculation.
Company Growth Strategy: Decisions to raise capital through equity issuance (increasing shares) or return capital via buybacks (decreasing shares) directly influence the weighted average per share and signal management's strategic direction.
Frequently Asked Questions (FAQ)
Q1: What is the difference between basic and diluted weighted average shares?
Basic weighted average shares consider only common shares outstanding. Diluted weighted average shares include the potential impact of all dilutive securities (options, warrants, convertibles), providing a "worse-case" scenario EPS. This calculator focuses on the basic weighted average shares.
Q2: Why is the weighted average per share important?
It ensures that EPS accurately reflects the number of shares available to investors throughout the entire reporting period, preventing distortions from significant share changes occurring late in the period. It's fundamental for fair profit allocation.
Q3: How do stock splits affect the weighted average calculation?
Stock splits (and reverse splits) are typically applied retroactively. All share counts and weighted average calculations for the period *before* the split are adjusted as if the split occurred at the beginning of the period. For example, a 2-for-1 split would double all prior share counts.
Q4: What if a company issues shares on a non-business day?
The date is typically based on when the transaction is legally effective. If it's effective on a weekend, that day is still counted in the period for weighting purposes.
Q5: Does this calculator handle convertible bonds?
This calculator is designed for basic weighted average shares and direct issuances/repurchases. Convertible bonds, options, and warrants are considered for diluted EPS calculations, which require different inputs and formulas.
Q6: How often should I calculate weighted average per share?
Companies calculate it at least quarterly for financial reporting (Form 10-Q) and annually (Form 10-K). Investors may calculate it more frequently for analysis.
Q7: Can negative shares outstanding occur?
No, shares outstanding cannot be negative. A company can repurchase all its shares, resulting in zero outstanding shares, but not less than zero. Treasury stock reduces the count but doesn't create a negative balance.
Q8: What constitutes a "significant" change requiring a new weight?
Accounting standards generally require recalculation whenever the number of shares outstanding changes by a material amount. For simplicity and accuracy, recalculating for every issuance or repurchase, as this calculator does, is best practice.
Related Tools and Internal Resources
EPS Calculator: Calculate Earnings Per Share using your weighted average shares.
var form = document.getElementById('weightedAvgSharesForm');
var sharesIssuedInput = document.getElementById('sharesIssued');
var sharesIssuedDateInput = document.getElementById('sharesIssuedDate');
var sharesIssuedAdjustmentInput = document.getElementById('sharesIssuedAdjustment');
var sharesIssuedError = document.getElementById('sharesIssuedError');
var sharesIssuedDateError = document.getElementById('sharesIssuedDateError');
var sharesIssuedAdjustmentError = document.getElementById('sharesIssuedAdjustmentError');
var resultsContainer = document.getElementById('resultsContainer');
var primaryResult = document.getElementById('primaryResult');
var weightedSharesBasic = document.getElementById('weightedSharesBasic');
var weightedSharesDiluted = document.getElementById('weightedSharesDiluted');
var totalWeight = document.getElementById('totalWeight');
var dataTableBody = document.getElementById('dataTableBody');
var chart = null;
var chartData = [];
var chartInstance = null;
var primaryKeyword = "Weighted Average Per Share";
var chartCaption = document.getElementById('chart-caption');
// — Helper Functions —
function getDaysInMonth(year, month) {
return new Date(year, month + 1, 0).getDate();
}
function calculateDaysBetween(startDate, endDate) {
var oneDay = 1000 * 60 * 60 * 24;
var diff = Math.abs(endDate.getTime() – startDate.getTime());
return Math.round(diff / oneDay) + 1; // +1 to include both start and end days
}
function formatDate(date) {
var d = new Date(date);
var month = (d.getMonth() + 1).toString().padStart(2, '0');
var day = d.getDate().toString().padStart(2, '0');
var year = d.getFullYear();
return `${year}-${month}-${day}`;
}
function updateChart() {
var canvas = document.getElementById('sharesChart');
if (!canvas) return;
var ctx = canvas.getContext('2d');
if (chartInstance) {
chartInstance.destroy(); // Destroy previous chart if it exists
}
var labels = [];
var sharesOutstandingData = [];
var weightedSharesData = [];
var currentShares = 0;
var startDate = null;
if (chartData.length > 0) {
startDate = new Date(chartData[0].date);
var endDate = new Date(chartData[chartData.length – 1].date);
var totalDaysInPeriod = calculateDaysBetween(startDate, endDate);
var cumulativeDays = 0;
var lastDate = startDate;
chartData.forEach(function(item, index) {
var transactionDate = new Date(item.date);
var daysInThisSegment = calculateDaysBetween(lastDate, transactionDate);
if (index === chartData.length – 1) {
// Last segment goes to the end of the period
// Need to determine the actual end date of the period.
// For simplicity, let's assume the period ends on the last transaction date or a fixed end date if available.
// If we assume the period ends on the last transaction date for chart purposes:
daysInThisSegment = calculateDaysBetween(lastDate, transactionDate); // For last entry, this segment's duration needs careful definition.
// Let's refine this: the chart should represent the *state* at each transaction date, and segments *between* them.
// For the last segment, it extends to the assumed end of the period (e.g., end of quarter/year).
// For simplicity, let's use the last recorded date as the end date of the chart period.
// A more robust approach would require defining the reporting period end date.
// For visualization, we'll show data up to the last transaction.
}
var weight = (index === 0) ? 0 : (cumulativeDays / totalDaysInPeriod); // Weight calculation for prior segment's shares
var currentWeight = (index === chartData.length – 1) ? 1 : ( (cumulativeDays + daysInThisSegment) / totalDaysInPeriod); // Weight for current segment
labels.push(formatDate(transactionDate));
sharesOutstandingData.push(item.sharesEnd); // Show end shares for the segment
weightedSharesData.push(item.weightedShares); // Show weighted shares for the segment
cumulativeDays += daysInThisSegment;
lastDate = transactionDate;
});
// Add the final state if the period extends beyond the last transaction
var lastTransactionDate = new Date(chartData[chartData.length – 1].date);
// Determine the period end date. If not explicitly set, use the last transaction date for chart range.
var periodEndDate = lastTransactionDate; // Default to last transaction date
// Example: if reporting period is end of year, and last transaction was Dec 1, periodEndDate should be Dec 31.
// For now, we'll use the last date in chartData for the chart's end point.
// If you have a fixed reporting period end date (e.g., '2023-12-31'):
// var reportingPeriodEndDate = new Date('2023-12-31');
// var daysRemaining = calculateDaysBetween(lastTransactionDate, reportingPeriodEndDate);
// if (daysRemaining > 0) {
// labels.push(formatDate(reportingPeriodEndDate));
// sharesOutstandingData.push(chartData[chartData.length – 1].sharesEnd); // Shares remain constant
// weightedSharesData.push(chartData[chartData.length – 1].weightedShares); // Weighted shares continue calculation
// }
} else {
labels.push("No Data");
}
chartInstance = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Shares Outstanding (End of Segment)',
data: sharesOutstandingData,
borderColor: 'rgba(0, 74, 153, 1)', // Primary color
backgroundColor: 'rgba(0, 74, 153, 0.2)',
fill: false,
tension: 0.1
}, {
label: 'Weighted Average Shares',
data: weightedSharesData,
borderColor: 'rgba(40, 167, 69, 1)', // Success color
backgroundColor: 'rgba(40, 167, 69, 0.2)',
fill: false,
tension: 0.1
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Number of Shares'
}
},
x: {
title: {
display: true,
text: 'Date'
}
}
},
plugins: {
title: {
display: true,
text: 'Share Evolution and Weighted Average'
},
tooltip: {
mode: 'index',
intersect: false,
}
},
hover: {
mode: 'nearest',
intersect: true
}
}
});
if (chartData.length > 0) {
chartCaption.style.display = 'block';
} else {
chartCaption.style.display = 'none';
}
}
function validateInput(input, errorElement, label) {
var value = parseFloat(input.value);
var error = "";
if (input.value === "" || isNaN(value)) {
error = label + " is required.";
} else if (value today) {
// This check depends on context. For historical reporting, future dates might be invalid.
// For projections, they might be valid. Assuming historical context here.
// error = label + " cannot be in the future.";
}
}
if (error) {
errorElement.textContent = error;
errorElement.style.display = 'block';
input.style.borderColor = 'red';
return false;
} else {
errorElement.textContent = "";
errorElement.style.display = 'none';
input.style.borderColor = '#ccc';
return true;
}
}
function calculateWeightedAverage() {
var isValid = true;
isValid &= validateInput(sharesIssuedInput, sharesIssuedError, "Shares Issued at Beginning of Period");
isValid &= validateDateInput(sharesIssuedDateInput, sharesIssuedDateError, "Date of Share Issuance/Repurchase");
isValid &= validateInput(sharesIssuedAdjustmentInput, sharesIssuedAdjustmentError, "Shares Added/Removed from Issuance");
if (!isValid) {
resultsContainer.style.display = 'none';
return;
}
var sharesStart = parseFloat(sharesIssuedInput.value);
var issuanceDateStr = sharesIssuedDateInput.value;
var adjustment = parseFloat(sharesIssuedAdjustmentInput.value);
// Determine the reporting period. For simplicity, we assume the reporting period starts
// on the first date entered and ends on the last date entered, or a fixed period like a quarter/year.
// A more robust solution would require explicit input for the reporting period start/end dates.
// Let's assume the context is a single transaction to calculate its impact on a base.
// To make it truly "weighted average", we need multiple entries or a defined period.
// — Revised Logic for Multiple Transactions / Defined Period —
// The current form structure implies a single transaction adjustment to a starting balance.
// To calculate a true weighted average, we need historical data points or a defined period.
// Let's simulate a period based on the entries.
// Simulating multiple entries for demonstration:
// We need to collect data dynamically. The current form only allows one transaction entry.
// Let's enhance the form to add multiple transactions.
// — Enhancing Form for Multiple Entries (Conceptual – needs full implementation) —
// A common approach: have a table where users add rows for each transaction.
// For this single-input form, we'll interpret it as:
// 1. Starting Shares at the beginning of a *hypothetical* period.
// 2. A single transaction occurring on a specific date.
// 3. The period is assumed to end, say, 90 days after the starting date, or on the transaction date if it's the only one.
// This is insufficient for a true weighted average calculation which requires multiple historical points or a defined period.
// — Let's Adapt to Calculate Weight for the period *until* the transaction —
// This is still not a full weighted average, but shows the impact of one change.
// To fulfill the requirement, we need to allow multiple inputs.
// Let's restructure the calculator to handle a list of transactions.
// — RESTRUCTURED CALCULATOR INPUT —
// We need inputs for:
// 1. Reporting Period Start Date
// 2. Reporting Period End Date
// 3. A way to add multiple transactions (Date, Shares Change)
// Since the current HTML has fixed inputs, let's use them to create *one segment* of the calculation.
// We will assume the period runs from the *earliest possible date* (or a default start) up to the *latest transaction date*.
// This is a simplification. A real calculator would have a table for transactions.
// Let's simulate a scenario with multiple hardcoded transactions for the chart and table,
// and use the user inputs for the *last* transaction.
// Example Transactions (Replace with dynamic user input handling later)
var transactions = [];
// Add initial state if provided by user
if (sharesStart > 0 && sharesIssuedDateInput.value && sharesIssuedAdjustmentInput.value) {
// This structure is problematic. The user inputs ONE start share count, ONE date, ONE adjustment.
// It's not set up for multiple historical entries needed for a true weighted average.
// Let's assume the inputs define the *first* block of shares and *one* subsequent transaction.
// This still requires defining the full reporting period.
// — Let's use a more realistic structure for the calculator: —
// Input: Reporting Period Start Date, Reporting Period End Date
// Add Transaction Button: Allows adding Date and Shares Change (+/-)
// A table displays added transactions.
// Given the fixed input structure, we can only demonstrate ONE transaction's impact.
// We cannot calculate a *true* weighted average without multiple data points or period definition.
// — TEMPORARY WORKAROUND: Assume a fixed reporting period of 1 year for calculation basis —
// And use the user input as the *only* transaction occurring after the start.
var reportingPeriodStartDate = new Date('2023-01-01'); // Example start date
var reportingPeriodEndDate = new Date('2023-12-31'); // Example end date
var reportingPeriodDays = calculateDaysBetween(reportingPeriodStartDate, reportingPeriodEndDate);
var transactionDate = new Date(sharesIssuedDateInput.value);
var sharesStartValue = parseFloat(sharesIssuedInput.value);
var sharesAdjustmentValue = parseFloat(sharesIssuedAdjustmentInput.value);
// Validate the transaction date falls within the reporting period
if (transactionDate reportingPeriodEndDate) {
// Handle error: transaction date out of reporting period
// For now, proceed with calculation but acknowledge limitation
}
var transactionsData = [];
// 1. Shares outstanding from Period Start until Transaction Date
var daysBeforeTransaction = calculateDaysBetween(reportingPeriodStartDate, transactionDate);
if (daysBeforeTransaction < 0) daysBeforeTransaction = 0; // Handle case where transaction is on start date
var sharesBeforeTransaction = sharesStartValue;
var weightBefore = daysBeforeTransaction / reportingPeriodDays;
var weightedSharesBefore = sharesBeforeTransaction * weightBefore;
transactionsData.push({
date: reportingPeriodStartDate.toISOString().split('T')[0],
sharesStart: sharesStartValue,
adjustment: 0, // No adjustment before the first transaction date specified
sharesEnd: sharesBeforeTransaction,
days: daysBeforeTransaction,
weight: weightBefore,
weightedShares: weightedSharesBefore
});
// 2. Shares outstanding from Transaction Date until Period End
var daysAfterTransaction = calculateDaysBetween(transactionDate, reportingPeriodEndDate);
if (daysAfterTransaction 0 && new Date(transactionsData[0].date) > reportingPeriodStartDate) {
var firstTxDate = new Date(transactionsData[0].date);
var daysInFirstSegment = calculateDaysBetween(reportingPeriodStartDate, firstTxDate);
var weightFirstSegment = daysInFirstSegment / reportingPeriodDays;
var weightedSharesFirstSegment = segmentShares * weightFirstSegment;
tableRows.push({
date: reportingPeriodStartDate.toISOString().split('T')[0] + ' – ' + formatDate(new Date(firstTxDate.getTime() – (24 * 60 * 60 * 1000))), // End day before tx
sharesStart: segmentShares,
adjustment: 0, // No adjustment in this segment
sharesEnd: segmentShares,
days: daysInFirstSegment,
weight: weightFirstSegment.toFixed(4),
weightedShares: weightedSharesFirstSegment.toFixed(2)
});
calculatedChartData.push({ date: reportingPeriodStartDate.toISOString().split('T')[0], sharesEnd: segmentShares, weightedShares: weightedSharesFirstSegment });
totalWeightedShares += weightedSharesFirstSegment;
totalWeightValue += weightFirstSegment;
segmentStartDate = firstTxDate;
}
// Process each transaction and the segment following it
for (var i = 0; i < transactionsData.length; i++) {
var tx = transactionsData[i];
var txDate = new Date(tx.date);
var nextSegmentStartDate = (i + 1 reportingPeriodStartDate) { // If first tx is not on start date, use initial shares
currentTxShares = sharesStartValue;
} else if (i > 0) {
currentTxShares = transactionsData[i-1].sharesEnd + tx.adjustment;
} else { // Tx is on start date or before
currentTxShares = sharesStartValue + tx.adjustment;
}
// Recalculate shares based on previous segment's end state + current adjustment
var sharesForThisSegment = segmentShares + tx.adjustment;
if (i === 0 && txDate > reportingPeriodStartDate) { // If the first transaction isn't on the start date
// The segment before this transaction has 'sharesStartValue' shares.
// This segment starts ON the transaction date with 'sharesStartValue + tx.adjustment' shares.
sharesForThisSegment = sharesStartValue + tx.adjustment;
} else if (i > 0) {
// Use the end shares of the previous transaction + current adjustment
sharesForThisSegment = transactionsData[i-1].sharesEnd + tx.adjustment;
} else { // Transaction is on the start date
sharesForThisSegment = sharesStartValue + tx.adjustment;
}
// Ensure shares don't go negative
sharesForThisSegment = Math.max(0, sharesForThisSegment);
var weight = daysInSegment / reportingPeriodDays;
var weightedShares = sharesForThisSegment * weight;
// Handle the case where the transaction date IS the start date
if (txDate.getTime() === reportingPeriodStartDate.getTime() && i === 0) {
tableRows.push({
date: txDate.toISOString().split('T')[0],
sharesStart: sharesStartValue, // Initial shares before adjustment
adjustment: tx.adjustment,
sharesEnd: sharesForThisSegment,
days: daysInSegment, // This segment runs to end of period
weight: weight.toFixed(4),
weightedShares: weightedShares.toFixed(2)
});
calculatedChartData.push({ date: txDate.toISOString().split('T')[0], sharesEnd: sharesForThisSegment, weightedShares: weightedShares });
totalWeightedShares += weightedShares;
totalWeightValue += weight;
}
// Handle segments between transactions or after the last transaction
else if (daysInSegment > 0) {
tableRows.push({
date: formatDate(segmentStartDate) + ' – ' + formatDate(new Date(segmentStartDate.getTime() + (daysInSegment-1)*24*60*60*1000)), // Segment start date to segment end date
sharesStart: segmentShares, // Shares at the start of this segment
adjustment: tx.adjustment, // The adjustment that defines the *next* segment's start state
sharesEnd: sharesForThisSegment, // Shares for the duration of *this* segment
days: daysInSegment,
weight: weight.toFixed(4),
weightedShares: weightedShares.toFixed(2)
});
calculatedChartData.push({ date: formatDate(segmentStartDate), sharesEnd: sharesForThisSegment, weightedShares: weightedShares });
totalWeightedShares += weightedShares;
totalWeightValue += weight;
}
segmentShares = sharesForThisSegment; // Update shares for the next segment
segmentStartDate = nextSegmentStartDate; // Move segment start date forward
}
// Final check for total weight
if (totalWeightValue > 1.0001 || totalWeightValue < 0.9999) {
// console.warn("Total weight is not exactly 1. Total weight:", totalWeightValue);
// Adjustments might be needed for floating point precision or period definition.
}
// — Populate Table —
dataTableBody.innerHTML = ''; // Clear previous rows
tableRows.forEach(function(row) {
var tr = document.createElement('tr');
tr.innerHTML = `