This commit is contained in:
Face 2025-06-15 10:01:36 +03:00
parent ec6426781d
commit 8c23c68565

View file

@ -44,40 +44,49 @@ export async function GET({ request }) {
const value = quantity * price; const value = quantity * price;
totalCoinValue += value; totalCoinValue += value;
// Calculate total cost basis from buy transactions const allTransactions = await db.select({
const costBasisResult = await db.select({ type: transaction.type,
totalCostBasis: sql<number>`COALESCE(SUM(${transaction.totalBaseCurrencyAmount}), 0)` quantity: transaction.quantity,
totalBaseCurrencyAmount: transaction.totalBaseCurrencyAmount,
timestamp: transaction.timestamp
}) })
.from(transaction) .from(transaction)
.where( .where(
and( and(
eq(transaction.userId, userId), eq(transaction.userId, userId),
eq(transaction.coinId, holding.coinId), eq(transaction.coinId, holding.coinId)
eq(transaction.type, 'BUY')
) )
); )
.orderBy(transaction.timestamp);
// Calculate average purchase price for reference // calculate cost basis
const avgPriceResult = await db.select({ let remainingQuantity = quantity;
avgPrice: sql<number>` let totalCostBasis = 0;
CASE let runningQuantity = 0;
WHEN SUM(${transaction.quantity}) > 0
THEN SUM(${transaction.totalBaseCurrencyAmount}) / SUM(${transaction.quantity})
ELSE 0
END
`
})
.from(transaction)
.where(
and(
eq(transaction.userId, userId),
eq(transaction.coinId, holding.coinId),
eq(transaction.type, 'BUY')
)
);
const totalCostBasis = Number(costBasisResult[0]?.totalCostBasis || 0); for (const tx of allTransactions) {
const avgPurchasePrice = Number(avgPriceResult[0]?.avgPrice || 0); const txQuantity = Number(tx.quantity);
const txAmount = Number(tx.totalBaseCurrencyAmount);
if (tx.type === 'BUY') {
runningQuantity += txQuantity;
// if we still need to account for held coins
if (remainingQuantity > 0) {
const quantityToAttribute = Math.min(txQuantity, remainingQuantity);
const avgPrice = txAmount / txQuantity;
totalCostBasis += quantityToAttribute * avgPrice;
remainingQuantity -= quantityToAttribute;
}
} else if (tx.type === 'SELL') {
runningQuantity -= txQuantity;
}
// if we accounted for all held coins, break
if (remainingQuantity <= 0) break;
}
const avgPurchasePrice = quantity > 0 ? totalCostBasis / quantity : 0;
const percentageChange = totalCostBasis > 0 const percentageChange = totalCostBasis > 0
? ((value - totalCostBasis) / totalCostBasis) * 100 ? ((value - totalCostBasis) / totalCostBasis) * 100