diff --git a/CHANGELOG.md b/CHANGELOG.md index 27907fb58..9d49d3fd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed the distorted tooltip in the performance chart on the home page +- Fixed a calculation issue of the current month in the investment timeline grouped by month ## 1.170.0 - 19.07.2022 diff --git a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts index ea35cdd79..d826e1d0e 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -62,6 +62,10 @@ describe('PortfolioCalculator', () => { parseDate('2021-11-22') ); + const investments = portfolioCalculator.getInvestments(); + + const investmentsByMonth = portfolioCalculator.getInvestmentsByMonth(); + spy.mockRestore(); expect(currentPositions).toEqual({ @@ -91,6 +95,15 @@ describe('PortfolioCalculator', () => { ], totalInvestment: new Big('0') }); + + expect(investments).toEqual([ + { date: '2021-11-22', investment: new Big('285.8') }, + { date: '2021-11-30', investment: new Big('0') } + ]); + + expect(investmentsByMonth).toEqual([ + { date: '2021-11-01', investment: new Big('12.6') } + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts index a6fe1af40..b8cc6050a 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts @@ -51,6 +51,10 @@ describe('PortfolioCalculator', () => { parseDate('2021-11-30') ); + const investments = portfolioCalculator.getInvestments(); + + const investmentsByMonth = portfolioCalculator.getInvestmentsByMonth(); + spy.mockRestore(); expect(currentPositions).toEqual({ @@ -80,6 +84,14 @@ describe('PortfolioCalculator', () => { ], totalInvestment: new Big('273.2') }); + + expect(investments).toEqual([ + { date: '2021-11-30', investment: new Big('273.2') } + ]); + + expect(investmentsByMonth).toEqual([ + { date: '2021-11-01', investment: new Big('273.2') } + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-no-orders.spec.ts index 18d6cb34d..32935a20e 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-no-orders.spec.ts @@ -39,6 +39,10 @@ describe('PortfolioCalculator', () => { new Date() ); + const investments = portfolioCalculator.getInvestments(); + + const investmentsByMonth = portfolioCalculator.getInvestmentsByMonth(); + spy.mockRestore(); expect(currentPositions).toEqual({ @@ -51,6 +55,10 @@ describe('PortfolioCalculator', () => { positions: [], totalInvestment: new Big(0) }); + + expect(investments).toEqual([]); + + expect(investmentsByMonth).toEqual([]); }); }); }); diff --git a/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index d215f9e1e..745dc9c39 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -62,6 +62,10 @@ describe('PortfolioCalculator', () => { parseDate('2022-03-07') ); + const investments = portfolioCalculator.getInvestments(); + + const investmentsByMonth = portfolioCalculator.getInvestmentsByMonth(); + spy.mockRestore(); expect(currentPositions).toEqual({ @@ -91,6 +95,16 @@ describe('PortfolioCalculator', () => { ], totalInvestment: new Big('75.80') }); + + expect(investments).toEqual([ + { date: '2022-03-07', investment: new Big('151.6') }, + { date: '2022-04-08', investment: new Big('75.8') } + ]); + + expect(investmentsByMonth).toEqual([ + { date: '2022-03-01', investment: new Big('151.6') }, + { date: '2022-04-01', investment: new Big('-85.73') } + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index 5b21fe146..cafc65b8b 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -332,7 +332,7 @@ export class PortfolioCalculator { } const investments = []; - let currentDate = parseDate(this.orders[0].date); + let currentDate: Date; let investmentByMonth = new Big(0); for (const [index, order] of this.orders.entries()) { @@ -340,27 +340,34 @@ export class PortfolioCalculator { isSameMonth(parseDate(order.date), currentDate) && isSameYear(parseDate(order.date), currentDate) ) { + // Same month: Add up investments + investmentByMonth = investmentByMonth.plus( order.quantity.mul(order.unitPrice).mul(this.getFactor(order.type)) ); + } else { + // New month: Store previous month and reset - if (index === this.orders.length - 1) { + if (currentDate) { investments.push({ date: format(set(currentDate, { date: 1 }), DATE_FORMAT), investment: investmentByMonth }); } - } else { - investments.push({ - date: format(set(currentDate, { date: 1 }), DATE_FORMAT), - investment: investmentByMonth - }); currentDate = parseDate(order.date); investmentByMonth = order.quantity .mul(order.unitPrice) .mul(this.getFactor(order.type)); } + + if (index === this.orders.length - 1) { + // Store current month (latest order) + investments.push({ + date: format(set(currentDate, { date: 1 }), DATE_FORMAT), + investment: investmentByMonth + }); + } } return investments; diff --git a/package.json b/package.json index 091ca3662..e6a9d92cf 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "start:server": "nx serve api --watch", "start:storybook": "nx run ui:storybook", "test": "nx test", - "test:single": "nx test --test-file portfolio-calculator-new.spec.ts", + "test:single": "nx test --test-file portfolio-calculator-novn-buy-and-sell-partially.spec.ts", "ts-node": "ts-node", "update": "nx migrate latest", "watch:server": "nx build api --watch", diff --git a/test/import/ok-novn-buy-and-sell-partially.json b/test/import/ok-novn-buy-and-sell-partially.json new file mode 100644 index 000000000..c184b4ba4 --- /dev/null +++ b/test/import/ok-novn-buy-and-sell-partially.json @@ -0,0 +1,28 @@ +{ + "meta": { + "date": "2022-07-21T21:28:05.857Z", + "version": "dev" + }, + "activities": [ + { + "fee": 0, + "quantity": 1, + "type": "SELL", + "unitPrice": 85.73, + "currency": "CHF", + "dataSource": "YAHOO", + "date": "2022-04-07T22:00:00.000Z", + "symbol": "NOVN.SW" + }, + { + "fee": 0, + "quantity": 2, + "type": "BUY", + "unitPrice": 75.8, + "currency": "CHF", + "dataSource": "YAHOO", + "date": "2022-03-06T23:00:00.000Z", + "symbol": "NOVN.SW" + } + ] +}