A professional tool for investors, accountants, and inventory managers.
Weighted Average Price Calculator
Enter your lots below. Add more rows if needed.
Weighted Average Price (WAP)
$0.00
Total Quantity
0
Total Cost
$0.00
Lots Counted
0
Logic Used: WAP = (Sum of all (Unit Price × Quantity)) ÷ (Sum of all Quantities)
Breakdown by Lot
Lot #
Unit Price ($)
Quantity
Lot Cost ($)
% of Total Qty
What is Calculate Weighted Average Price?
When managing inventory, trading stocks, or analyzing procurement costs, simply averaging the unit prices often leads to incorrect financial data. To calculate weighted average price (WAP), you must account for the volume (quantity) purchased at each specific price point. This method gives a more accurate reflection of the cost per unit across your entire holding.
This metric is essential for investors employing a Dollar Cost Averaging (DCA) strategy, accountants dealing with inventory valuation methods like Moving Average Cost, and procurement managers ensuring they meet budget targets across multiple supplier batches. Unlike a simple arithmetic mean, the weighted average price ensures that a large purchase at a high price impacts the average more significantly than a small purchase at a low price.
Common Misconception: Many people simply add up the prices of different lots and divide by the number of lots. This is incorrect because it ignores the quantity. If you buy 1 share at $100 and 100 shares at $10, your average cost is much closer to $10, not $55.
Calculate Weighted Average Price: Formula and Logic
The mathematical foundation to calculate weighted average price is straightforward but powerful. It involves finding the total value of all items and dividing it by the total count of items.
Interpretation: Even though the price went as high as $160, the heavy volume purchased at $130 kept the average price low.
Example 2: Retail Inventory
A clothing store restocks jeans throughout the year at different wholesale rates:
January: 100 units @ $20
June: 200 units @ $25
Calculation: ((100×20) + (200×25)) / 300 = (2000 + 5000) / 300 = $23.33.
When setting the retail price, the store owner should base their margin on the $23.33 cost basis, not simply $22.50 (the arithmetic mean).
How to Use This Weighted Average Price Calculator
Enter Unit Price: Input the cost per item for your first batch.
Enter Quantity: Input the number of items bought at that specific price.
Add Rows: Click "Add Lot" to include additional purchases or inventory batches.
Review Results: The tool instantly updates the WAP, Total Cost, and Total Quantity.
Analyze the Chart: The bar chart visualizes how each lot's price compares to the final weighted average.
Key Factors That Affect Weighted Average Price Results
Several variables can significantly influence the outcome when you calculate weighted average price:
Volume Disparities: A single large order can skew the average significantly toward that order's price, rendering smaller orders mathematically negligible.
Price Volatility: High variance in purchase prices (e.g., in crypto markets) makes WAP a crucial metric for understanding break-even points.
Transaction Fees: True "cost basis" often includes fees. While this basic calculator uses raw price, advanced financial analysis should add fees to the Unit Price inputs.
Inflation: In inventory accounting, later purchases often have higher prices due to inflation, raising the WAP over time (FIFO vs. Weighted Average methods).
Currency Fluctuations: If purchasing internationally, the exchange rate at the time of each batch purchase affects the effective unit price.
Stock Splits: In equities, stock splits change the quantity and price drastically; you must adjust inputs to post-split numbers for accuracy.
Frequently Asked Questions (FAQ)
Is Weighted Average Price the same as Break-Even Price?
Often, yes. If you are selling an asset, you generally need to sell above your weighted average price to make a profit on the total position, assuming no other fees.
Can I use this for crypto trading?
Absolutely. It is the standard way to calculate your entry price across multiple buy orders for Bitcoin, Ethereum, or other tokens.
How does this differ from FIFO (First-In, First-Out)?
FIFO assumes you sell the oldest items first. Weighted Average pools all items into a single cost "bucket". WAP is often smoother but can obscure the specific profitability of individual old lots.
What happens if I enter a negative quantity?
Negative quantities typically represent selling or removing items. While this calculator supports basic negative inputs mathematically, standard WAP calculations usually look at the "accumulation" phase (positive numbers).
Why is my Weighted Average Price closer to the lower price?
This occurs because you purchased a significantly higher quantity of units at the lower price. The calculation is "weighted" by volume.
Does this calculator save my data?
No, this is a client-side tool for privacy. Data is processed in your browser and lost upon refresh.
Can I include tax in the Unit Price?
Yes. For the most accurate "landed cost," you should include taxes, shipping, and fees in the Unit Price field before calculating.
Is this useful for school grades?
Yes, the logic is identical. "Unit Price" would be the grade, and "Quantity" would be the credit hours or weight of the assignment.
Related Tools and Resources
Explore more of our financial calculators to optimize your strategy:
// State management using var (Strict requirement)
var rowCount = 0;
var maxRows = 20;
// Initialize the calculator
window.onload = function() {
// Start with 3 rows
addRow();
addRow();
addRow();
calculateLogic();
};
function addRow() {
if (rowCount >= maxRows) {
alert("Maximum row limit reached.");
return;
}
rowCount++;
var list = document.getElementById('inputList');
var div = document.createElement('div');
div.className = 'input-row';
div.id = 'row-' + rowCount;
// HTML construction for the row
var html = ";
// Unit Price Input
html += '
';
html += '';
html += ";
html += '';
html += '
';
// Quantity Input
html += '
';
html += '';
html += ";
html += '';
html += '
';
// Remove Button (only if not the first row, or always allow but handle logic)
html += '';
div.innerHTML = html;
list.appendChild(div);
}
function removeRow(id) {
var row = document.getElementById('row-' + id);
if (row) {
row.parentNode.removeChild(row);
calculateLogic();
}
}
function resetCalculator() {
document.getElementById('inputList').innerHTML = ";
rowCount = 0;
addRow();
addRow();
addRow();
calculateLogic();
}
function calculateLogic() {
var totalCost = 0;
var totalQty = 0;
var validRows = 0;
var tableData = [];
var rows = document.getElementById('inputList').children;
// Loop through all input rows
for (var i = 0; i < rows.length; i++) {
var rowId = rows[i].id.split('-')[1]; // get number from 'row-X'
var priceInput = document.getElementById('price-' + rowId);
var qtyInput = document.getElementById('qty-' + rowId);
var price = parseFloat(priceInput.value);
var qty = parseFloat(qtyInput.value);
// Validation visuals
var errPrice = document.getElementById('err-price-' + rowId);
var errQty = document.getElementById('err-qty-' + rowId);
errPrice.innerText = "";
errQty.innerText = "";
if (priceInput.value !== "" && isNaN(price)) {
errPrice.innerText = "Invalid number";
}
if (qtyInput.value !== "" && isNaN(qty)) {
errQty.innerText = "Invalid number";
}
// Calculation Core
if (!isNaN(price) && !isNaN(qty) && qty !== 0) {
var lineCost = price * qty;
totalCost += lineCost;
totalQty += qty;
validRows++;
tableData.push({
id: rowId,
price: price,
qty: qty,
cost: lineCost
});
}
}
// Calculate WAP
var wap = 0;
if (totalQty !== 0) {
wap = totalCost / totalQty;
}
// Update DOM Results
document.getElementById('wapResult').innerText = formatCurrency(wap);
document.getElementById('totalQtyResult').innerText = formatNumber(totalQty);
document.getElementById('totalCostResult').innerText = formatCurrency(totalCost);
document.getElementById('lotsCountResult').innerText = validRows;
updateTable(tableData, totalQty);
drawChart(tableData, wap);
}
function updateTable(data, totalQty) {
var tbody = document.querySelector('#resultTable tbody');
var html = '';
for (var i = 0; i < data.length; i++) {
var row = data[i];
var percentage = (totalQty !== 0) ? (row.qty / totalQty) * 100 : 0;
html += '
';
html += '
' + (i + 1) + '
';
html += '
' + formatCurrency(row.price) + '
';
html += '
' + formatNumber(row.qty) + '
';
html += '
' + formatCurrency(row.cost) + '
';
html += '
' + percentage.toFixed(1) + '%
';
html += '
';
}
if (data.length === 0) {
html = '
Enter values to see breakdown
';
}
tbody.innerHTML = html;
}
function drawChart(data, wap) {
var canvas = document.getElementById('wapChart');
var ctx = canvas.getContext('2d');
// Reset canvas size for crispness
var container = canvas.parentElement;
canvas.width = container.offsetWidth;
canvas.height = container.offsetHeight;
var width = canvas.width;
var height = canvas.height;
var padding = 50;
ctx.clearRect(0, 0, width, height);
if (data.length === 0) {
ctx.font = "16px sans-serif";
ctx.fillStyle = "#666";
ctx.textAlign = "center";
ctx.fillText("Enter data to view chart", width/2, height/2);
return;
}
// Determine Max Price for Y-Axis Scaling (include WAP in range)
var maxPrice = wap;
for (var i = 0; i maxPrice) maxPrice = data[i].price;
}
maxPrice = maxPrice * 1.2; // Add 20% buffer
if (maxPrice === 0) maxPrice = 100;
// Draw Axes
ctx.beginPath();
ctx.strokeStyle = "#ccc";
ctx.moveTo(padding, padding);
ctx.lineTo(padding, height – padding); // Y axis
ctx.lineTo(width – padding, height – padding); // X axis
ctx.stroke();
// Draw Y Axis Labels
ctx.textAlign = "right";
ctx.fillStyle = "#666";
ctx.font = "12px sans-serif";
for (var j = 0; j <= 5; j++) {
var yVal = (maxPrice / 5) * j;
var yPos = height – padding – (yVal / maxPrice * (height – 2 * padding));
ctx.fillText(yVal.toFixed(1), padding – 10, yPos + 4);
// Grid lines
ctx.beginPath();
ctx.strokeStyle = "#eee";
ctx.moveTo(padding, yPos);
ctx.lineTo(width – padding, yPos);
ctx.stroke();
}
// Draw Bars (Individual Prices)
var barWidth = (width – 2 * padding) / data.length * 0.5;
var spacing = (width – 2 * padding) / data.length;
for (var k = 0; k < data.length; k++) {
var item = data[k];
var barHeight = (item.price / maxPrice) * (height – 2 * padding);
var xPos = padding + (spacing * k) + (spacing/2) – (barWidth/2);
var yPos = height – padding – barHeight;
// Bar
ctx.fillStyle = "#004a99";
ctx.fillRect(xPos, yPos, barWidth, barHeight);
// Label
ctx.fillStyle = "#333";
ctx.textAlign = "center";
ctx.fillText("Lot " + (k+1), xPos + barWidth/2, height – padding + 20);
}
// Draw WAP Line
var wapY = height – padding – ((wap / maxPrice) * (height – 2 * padding));
ctx.beginPath();
ctx.strokeStyle = "#28a745";
ctx.lineWidth = 3;
ctx.setLineDash([5, 5]);
ctx.moveTo(padding, wapY);
ctx.lineTo(width – padding, wapY);
ctx.stroke();
ctx.setLineDash([]);
// WAP Label
ctx.fillStyle = "#28a745";
ctx.font = "bold 12px sans-serif";
ctx.textAlign = "right";
ctx.fillText("WAP: " + formatCurrency(wap), width – padding – 10, wapY – 10);
}
function formatCurrency(num) {
return '$' + num.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
function formatNumber(num) {
return num.toLocaleString('en-US', { maximumFractionDigits: 2 });
}
function copyResults() {
var wap = document.getElementById('wapResult').innerText;
var qty = document.getElementById('totalQtyResult').innerText;
var cost = document.getElementById('totalCostResult').innerText;
var text = "Weighted Average Price Calculation:\n";
text += "——————————–\n";
text += "Weighted Avg Price: " + wap + "\n";
text += "Total Quantity: " + qty + "\n";
text += "Total Cost: " + cost + "\n";
text += "——————————–\n";
text += "Generated by FinancialCalc Tools";
// Create temporary textarea to copy
var tempInput = document.createElement("textarea");
tempInput.value = text;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand("copy");
document.body.removeChild(tempInput);
alert("Results copied to clipboard!");
}