Browse Source

Fix investment calculation for sell activities

pull/826/head
Thomas 3 years ago
parent
commit
d1dd69b299
  1. 4
      apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts
  2. 25
      apps/api/src/app/portfolio/portfolio-calculator.ts
  3. 30
      libs/ui/src/lib/activities-table/activities-table.component.html
  4. 20
      libs/ui/src/lib/activities-table/activities-table.component.ts

4
apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts

@ -80,7 +80,7 @@ describe('PortfolioCalculator', () => {
firstBuyDate: '2022-03-07', firstBuyDate: '2022-03-07',
grossPerformance: new Big('21.93'), grossPerformance: new Big('21.93'),
grossPerformancePercentage: new Big('0.14465699208443271768'), grossPerformancePercentage: new Big('0.14465699208443271768'),
investment: new Big('65.87'), investment: new Big('75.80'),
netPerformance: new Big('17.68'), netPerformance: new Big('17.68'),
netPerformancePercentage: new Big('0.11662269129287598945'), netPerformancePercentage: new Big('0.11662269129287598945'),
marketPrice: 87.8, marketPrice: 87.8,
@ -89,7 +89,7 @@ describe('PortfolioCalculator', () => {
transactionCount: 2 transactionCount: 2
} }
], ],
totalInvestment: new Big('65.87') totalInvestment: new Big('75.80')
}); });
}); });
}); });

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

@ -77,17 +77,30 @@ export class PortfolioCalculator {
const newQuantity = order.quantity const newQuantity = order.quantity
.mul(factor) .mul(factor)
.plus(oldAccumulatedSymbol.quantity); .plus(oldAccumulatedSymbol.quantity);
let investment = new Big(0);
if (newQuantity.gt(0)) {
if (order.type === 'BUY') {
investment = oldAccumulatedSymbol.investment.plus(
order.quantity.mul(unitPrice)
);
} else if (order.type === 'SELL') {
const averagePrice = oldAccumulatedSymbol.investment.div(
oldAccumulatedSymbol.quantity
);
investment = oldAccumulatedSymbol.investment.minus(
order.quantity.mul(averagePrice)
);
}
}
currentTransactionPointItem = { currentTransactionPointItem = {
investment,
currency: order.currency, currency: order.currency,
dataSource: order.dataSource, dataSource: order.dataSource,
fee: order.fee.plus(oldAccumulatedSymbol.fee), fee: order.fee.plus(oldAccumulatedSymbol.fee),
firstBuyDate: oldAccumulatedSymbol.firstBuyDate, firstBuyDate: oldAccumulatedSymbol.firstBuyDate,
investment: newQuantity.eq(0)
? new Big(0)
: unitPrice
.mul(order.quantity)
.mul(factor)
.plus(oldAccumulatedSymbol.investment),
quantity: newQuantity, quantity: newQuantity,
symbol: order.symbol, symbol: order.symbol,
transactionCount: oldAccumulatedSymbol.transactionCount + 1 transactionCount: oldAccumulatedSymbol.transactionCount + 1

30
libs/ui/src/lib/activities-table/activities-table.component.html

@ -268,16 +268,11 @@
></gf-value> ></gf-value>
</div> </div>
</td> </td>
<td *matFooterCellDef class="d-none d-lg-table-cell px-1" mat-footer-cell> <td
<div class="d-flex justify-content-end"> *matFooterCellDef
<gf-value class="d-none d-lg-table-cell px-1"
[isAbsolute]="true" mat-footer-cell
[isCurrency]="true" ></td>
[locale]="locale"
[value]="isLoading ? undefined : totalValue"
></gf-value>
</div>
</td>
</ng-container> </ng-container>
<ng-container matColumnDef="valueInBaseCurrency"> <ng-container matColumnDef="valueInBaseCurrency">
@ -299,16 +294,11 @@
></gf-value> ></gf-value>
</div> </div>
</td> </td>
<td *matFooterCellDef class="d-lg-none d-xl-none px-1" mat-footer-cell> <td
<div class="d-flex justify-content-end"> *matFooterCellDef
<gf-value class="d-lg-none d-xl-none px-1"
[isAbsolute]="true" mat-footer-cell
[isCurrency]="true" ></td>
[locale]="locale"
[value]="isLoading ? undefined : totalValue"
></gf-value>
</div>
</td>
</ng-container> </ng-container>
<ng-container matColumnDef="account"> <ng-container matColumnDef="account">

20
libs/ui/src/lib/activities-table/activities-table.component.ts

@ -79,7 +79,6 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
public searchKeywords: string[] = []; public searchKeywords: string[] = [];
public separatorKeysCodes: number[] = [ENTER, COMMA]; public separatorKeysCodes: number[] = [ENTER, COMMA];
public totalFees: number; public totalFees: number;
public totalValue: number;
private allFilters: string[]; private allFilters: string[];
private unsubscribeSubject = new Subject<void>(); private unsubscribeSubject = new Subject<void>();
@ -252,7 +251,6 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
return activity.isDraft === true; return activity.isDraft === true;
}); });
this.totalFees = this.getTotalFees(); this.totalFees = this.getTotalFees();
this.totalValue = this.getTotalValue();
} }
private getSearchableFieldValues(activities: OrderWithAccount[]): string[] { private getSearchableFieldValues(activities: OrderWithAccount[]): string[] {
@ -316,22 +314,4 @@ export class ActivitiesTableComponent implements OnChanges, OnDestroy {
return totalFees.toNumber(); return totalFees.toNumber();
} }
private getTotalValue() {
let totalValue = new Big(0);
for (const activity of this.dataSource.filteredData) {
if (isNumber(activity.valueInBaseCurrency)) {
if (activity.type === 'BUY' || activity.type === 'ITEM') {
totalValue = totalValue.plus(activity.valueInBaseCurrency);
} else if (activity.type === 'SELL') {
totalValue = totalValue.minus(activity.valueInBaseCurrency);
}
} else {
return null;
}
}
return totalValue.toNumber();
}
} }

Loading…
Cancel
Save