Browse Source

Fix average price

pull/3092/head
Thomas Kaul 2 years ago
parent
commit
1cf3aae659
  1. 1
      apps/api/jest.config.ts
  2. 1
      apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts
  3. 26
      apps/api/src/app/portfolio/portfolio-calculator.ts
  4. 5
      apps/api/src/app/portfolio/portfolio.service.ts

1
apps/api/jest.config.ts

@ -13,7 +13,6 @@ export default {
}, },
moduleFileExtensions: ['ts', 'js', 'html'], moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/apps/api', coverageDirectory: '../../coverage/apps/api',
testTimeout: 10000,
testEnvironment: 'node', testEnvironment: 'node',
preset: '../../jest.preset.js' preset: '../../jest.preset.js'
}; };

1
apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts

@ -2,6 +2,7 @@ import { DataSource, Tag } from '@prisma/client';
import Big from 'big.js'; import Big from 'big.js';
export interface TransactionPointSymbol { export interface TransactionPointSymbol {
averagePrice: Big;
currency: string; currency: string;
dataSource: DataSource; dataSource: DataSource;
dividend: Big; dividend: Big;

26
apps/api/src/app/portfolio/portfolio-calculator.ts

@ -78,32 +78,29 @@ export class PortfolioCalculator {
const oldAccumulatedSymbol = symbols[order.symbol]; const oldAccumulatedSymbol = symbols[order.symbol];
const factor = getFactor(order.type); const factor = getFactor(order.type);
const unitPrice = new Big(order.unitPrice);
if (oldAccumulatedSymbol) { if (oldAccumulatedSymbol) {
let investment = oldAccumulatedSymbol.investment;
const newQuantity = order.quantity const newQuantity = order.quantity
.mul(factor) .mul(factor)
.plus(oldAccumulatedSymbol.quantity); .plus(oldAccumulatedSymbol.quantity);
let investment = oldAccumulatedSymbol.investment;
if (newQuantity.gt(0)) {
if (order.type === 'BUY') { if (order.type === 'BUY') {
investment = oldAccumulatedSymbol.investment.plus( investment = oldAccumulatedSymbol.investment.plus(
order.quantity.mul(unitPrice) order.quantity.mul(order.unitPrice)
); );
} else if (order.type === 'SELL') { } else if (order.type === 'SELL') {
const averagePrice = oldAccumulatedSymbol.investment.div(
oldAccumulatedSymbol.quantity
);
investment = oldAccumulatedSymbol.investment.minus( investment = oldAccumulatedSymbol.investment.minus(
order.quantity.mul(averagePrice) order.quantity.mul(oldAccumulatedSymbol.averagePrice)
); );
} }
}
currentTransactionPointItem = { currentTransactionPointItem = {
investment, investment,
averagePrice: newQuantity.gt(0)
? investment.div(newQuantity)
: new Big(0),
currency: order.currency, currency: order.currency,
dataSource: order.dataSource, dataSource: order.dataSource,
dividend: new Big(0), dividend: new Big(0),
@ -116,12 +113,13 @@ export class PortfolioCalculator {
}; };
} else { } else {
currentTransactionPointItem = { currentTransactionPointItem = {
averagePrice: order.unitPrice,
currency: order.currency, currency: order.currency,
dataSource: order.dataSource, dataSource: order.dataSource,
dividend: new Big(0), dividend: new Big(0),
fee: order.fee, fee: order.fee,
firstBuyDate: order.date, firstBuyDate: order.date,
investment: unitPrice.mul(order.quantity).mul(factor), investment: order.unitPrice.mul(order.quantity).mul(factor),
quantity: order.quantity.mul(factor), quantity: order.quantity.mul(factor),
symbol: order.symbol, symbol: order.symbol,
tags: order.tags, tags: order.tags,
@ -132,22 +130,28 @@ export class PortfolioCalculator {
symbols[order.symbol] = currentTransactionPointItem; symbols[order.symbol] = currentTransactionPointItem;
const items = lastTransactionPoint?.items ?? []; const items = lastTransactionPoint?.items ?? [];
const newItems = items.filter( const newItems = items.filter(
(transactionPointItem) => transactionPointItem.symbol !== order.symbol (transactionPointItem) => transactionPointItem.symbol !== order.symbol
); );
newItems.push(currentTransactionPointItem); newItems.push(currentTransactionPointItem);
newItems.sort((a, b) => { newItems.sort((a, b) => {
return a.symbol?.localeCompare(b.symbol); return a.symbol?.localeCompare(b.symbol);
}); });
if (lastDate !== currentDate || lastTransactionPoint === null) { if (lastDate !== currentDate || lastTransactionPoint === null) {
lastTransactionPoint = { lastTransactionPoint = {
date: currentDate, date: currentDate,
items: newItems items: newItems
}; };
this.transactionPoints.push(lastTransactionPoint); this.transactionPoints.push(lastTransactionPoint);
} else { } else {
lastTransactionPoint.items = newItems; lastTransactionPoint.items = newItems;
} }
lastDate = currentDate; lastDate = currentDate;
} }
} }

5
apps/api/src/app/portfolio/portfolio.service.ts

@ -753,7 +753,6 @@ export class PortfolioService {
averagePrice, averagePrice,
currency, currency,
dataSource, dataSource,
dividend,
dividendInBaseCurrency, dividendInBaseCurrency,
fee, fee,
firstBuyDate, firstBuyDate,
@ -804,9 +803,7 @@ export class PortfolioService {
); );
if (currentSymbol) { if (currentSymbol) {
currentAveragePrice = currentSymbol.quantity.eq(0) currentAveragePrice = currentSymbol.averagePrice.toNumber();
? 0
: currentSymbol.investment.div(currentSymbol.quantity).toNumber();
currentQuantity = currentSymbol.quantity.toNumber(); currentQuantity = currentSymbol.quantity.toNumber();
} }

Loading…
Cancel
Save