From c0c174261800eab2dd383c234ae6a0252e3a9827 Mon Sep 17 00:00:00 2001 From: Valentin Zickner Date: Sun, 5 Sep 2021 15:24:42 +0200 Subject: [PATCH] add net performance to calculate timeline #324 --- .../transaction-point-symbol.interface.ts | 1 + .../portfolio/portfolio-calculator.spec.ts | 280 +++++++++++++++++- .../src/app/portfolio/portfolio-calculator.ts | 9 +- 3 files changed, 280 insertions(+), 10 deletions(-) diff --git a/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts b/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts index 91dcdd63b..929c8c26b 100644 --- a/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts @@ -4,6 +4,7 @@ import Big from 'big.js'; export interface TransactionPointSymbol { currency: Currency; fee: Big; + feeAccumulated: Big; firstBuyDate: string; investment: Big; quantity: Big; diff --git a/apps/api/src/app/portfolio/portfolio-calculator.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator.spec.ts index b8dc713e9..61c099791 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.spec.ts @@ -194,7 +194,8 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', transactionCount: 1, - fee: new Big('5') + fee: new Big('5'), + feeAccumulated: new Big('5') } ] }, @@ -208,7 +209,8 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', transactionCount: 2, - fee: new Big('10') + fee: new Big('10'), + feeAccumulated: new Big('15') } ] }, @@ -222,7 +224,8 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', transactionCount: 3, - fee: new Big('5') + fee: new Big('5'), + feeAccumulated: new Big('20') } ] } @@ -281,7 +284,8 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', transactionCount: 1, - fee: new Big('5') + fee: new Big('5'), + feeAccumulated: new Big('5') } ] }, @@ -295,7 +299,8 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', transactionCount: 1, - fee: new Big('0') + fee: new Big('0'), + feeAccumulated: new Big('5') }, { quantity: new Big('10'), @@ -304,7 +309,8 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-08-03', transactionCount: 1, - fee: new Big('10') + fee: new Big('10'), + feeAccumulated: new Big('10') } ] }, @@ -318,7 +324,8 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', transactionCount: 2, - fee: new Big('5') + fee: new Big('5'), + feeAccumulated: new Big('10') }, { quantity: new Big('10'), @@ -327,7 +334,8 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-08-03', transactionCount: 1, - fee: new Big('0') + fee: new Big('0'), + feeAccumulated: new Big('10') } ] } @@ -367,6 +375,7 @@ describe('PortfolioCalculator', () => { quantity: new Big('10'), symbol: 'VTI', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -381,6 +390,7 @@ describe('PortfolioCalculator', () => { quantity: new Big('20'), symbol: 'VTI', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 } ] @@ -395,6 +405,7 @@ describe('PortfolioCalculator', () => { quantity: new Big('5'), symbol: 'VTI', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 3 } ] @@ -409,6 +420,7 @@ describe('PortfolioCalculator', () => { quantity: new Big('35'), symbol: 'VTI', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 5 } ] @@ -423,6 +435,7 @@ describe('PortfolioCalculator', () => { quantity: new Big('45'), symbol: 'VTI', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 6 } ] @@ -463,6 +476,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -477,6 +491,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 } ] @@ -491,6 +506,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -500,6 +516,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 } ] @@ -514,6 +531,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -523,6 +541,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 3 } ] @@ -537,6 +556,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -546,6 +566,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 4 } ] @@ -560,6 +581,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -569,6 +591,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 5 } ] @@ -633,6 +656,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2017-01-03', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -647,6 +671,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2017-07-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -656,6 +681,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2017-01-03', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -670,6 +696,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2018-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -679,6 +706,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2017-07-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -688,6 +716,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2017-01-03', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -930,6 +959,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -944,6 +974,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 } ] @@ -958,6 +989,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 3 } ] @@ -1016,6 +1048,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -1031,6 +1064,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 } ] @@ -1099,6 +1133,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(50), + feeAccumulated: new Big(50), transactionCount: 1 } ] @@ -1114,6 +1149,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(50), + feeAccumulated: new Big(100), transactionCount: 2 } ] @@ -1190,6 +1226,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(50), + feeAccumulated: new Big(50), transactionCount: 1 } ] @@ -1205,6 +1242,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(50), + feeAccumulated: new Big(100), transactionCount: 2 } ] @@ -1277,6 +1315,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2010-12-31', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -1291,6 +1330,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2010-12-31', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 } ] @@ -1352,6 +1392,7 @@ describe('PortfolioCalculator', () => { currency: Currency.CHF, firstBuyDate: '2012-12-31', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -1361,6 +1402,7 @@ describe('PortfolioCalculator', () => { currency: Currency.CHF, firstBuyDate: '2012-12-31', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -1375,6 +1417,7 @@ describe('PortfolioCalculator', () => { currency: Currency.CHF, firstBuyDate: '2012-12-31', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -1384,6 +1427,7 @@ describe('PortfolioCalculator', () => { currency: Currency.CHF, firstBuyDate: '2012-12-31', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -1460,18 +1504,141 @@ describe('PortfolioCalculator', () => { { date: '2019-01-01', grossPerformance: new Big('0'), + netPerformance: new Big('0'), investment: new Big('0'), value: new Big('0') }, { date: '2020-01-01', grossPerformance: new Big('498.3'), + netPerformance: new Big('498.3'), investment: new Big('2923.7'), value: new Big('3422') // 20 * (144.38 + days=335 * 0.08) }, { date: '2021-01-01', grossPerformance: new Big('349.35'), + netPerformance: new Big('349.35'), + investment: new Big('652.55'), + value: new Big('1001.9') // 5 * (144.38 + days=700 * 0.08) + } + ]); + }); + + it('with yearly and fees', async () => { + const portfolioCalculator = new PortfolioCalculator( + currentRateService, + Currency.USD + ); + const transactionPoints = [ + { + date: '2019-02-01', + items: [ + { + quantity: new Big('10'), + symbol: 'VTI', + investment: new Big('1443.8'), + currency: Currency.USD, + firstBuyDate: '2019-02-01', + fee: new Big(50), + feeAccumulated: new Big(50), + transactionCount: 1 + } + ] + }, + { + date: '2019-08-03', + items: [ + { + quantity: new Big('20'), + symbol: 'VTI', + investment: new Big('2923.7'), + currency: Currency.USD, + firstBuyDate: '2019-02-01', + fee: new Big(50), + feeAccumulated: new Big(100), + transactionCount: 2 + } + ] + }, + { + date: '2020-02-02', + items: [ + { + quantity: new Big('5'), + symbol: 'VTI', + investment: new Big('652.55'), + currency: Currency.USD, + firstBuyDate: '2019-02-01', + fee: new Big(50), + feeAccumulated: new Big(150), + transactionCount: 3 + } + ] + }, + { + date: '2021-02-01', + items: [ + { + quantity: new Big('15'), + symbol: 'VTI', + investment: new Big('2684.05'), + currency: Currency.USD, + firstBuyDate: '2019-02-01', + fee: new Big(50), + feeAccumulated: new Big(200), + transactionCount: 4 + } + ] + }, + { + date: '2021-08-01', + items: [ + { + quantity: new Big('25'), + symbol: 'VTI', + investment: new Big('4460.95'), + currency: Currency.USD, + firstBuyDate: '2019-02-01', + fee: new Big(50), + feeAccumulated: new Big(250), + transactionCount: 5 + } + ] + } + ]; + portfolioCalculator.setTransactionPoints(transactionPoints); + const timelineSpecification: TimelineSpecification[] = [ + { + start: '2019-01-01', + accuracy: 'year' + } + ]; + const timeline: TimelinePeriod[] = + await portfolioCalculator.calculateTimeline( + timelineSpecification, + '2021-06-30' + ); + + expect(timeline).toEqual([ + { + date: '2019-01-01', + grossPerformance: new Big('0'), + netPerformance: new Big('0'), + investment: new Big('0'), + value: new Big('0') + }, + { + date: '2020-01-01', + grossPerformance: new Big('498.3'), + netPerformance: new Big('398.3'), // 100 fees + investment: new Big('2923.7'), + value: new Big('3422') // 20 * (144.38 + days=335 * 0.08) + }, + { + date: '2021-01-01', + grossPerformance: new Big('349.35'), + netPerformance: new Big('199.35'), // 150 fees investment: new Big('652.55'), value: new Big('1001.9') // 5 * (144.38 + days=700 * 0.08) } @@ -1500,180 +1667,210 @@ describe('PortfolioCalculator', () => { { date: '2019-01-01', grossPerformance: new Big('0'), + netPerformance: new Big('0'), investment: new Big('0'), value: new Big('0') }, { date: '2019-02-01', grossPerformance: new Big('0'), + netPerformance: new Big('0'), investment: new Big('1443.8'), value: new Big('1443.8') // 10 * (144.38 + days=0 * 0.08) }, { date: '2019-03-01', grossPerformance: new Big('22.4'), + netPerformance: new Big('22.4'), investment: new Big('1443.8'), value: new Big('1466.2') // 10 * (144.38 + days=28 * 0.08) }, { date: '2019-04-01', grossPerformance: new Big('47.2'), + netPerformance: new Big('47.2'), investment: new Big('1443.8'), value: new Big('1491') // 10 * (144.38 + days=59 * 0.08) }, { date: '2019-05-01', grossPerformance: new Big('71.2'), + netPerformance: new Big('71.2'), investment: new Big('1443.8'), value: new Big('1515') // 10 * (144.38 + days=89 * 0.08) }, { date: '2019-06-01', grossPerformance: new Big('96'), + netPerformance: new Big('96'), investment: new Big('1443.8'), value: new Big('1539.8') // 10 * (144.38 + days=120 * 0.08) }, { date: '2019-07-01', grossPerformance: new Big('120'), + netPerformance: new Big('120'), investment: new Big('1443.8'), value: new Big('1563.8') // 10 * (144.38 + days=150 * 0.08) }, { date: '2019-08-01', grossPerformance: new Big('144.8'), + netPerformance: new Big('144.8'), investment: new Big('1443.8'), value: new Big('1588.6') // 10 * (144.38 + days=181 * 0.08) }, { date: '2019-09-01', grossPerformance: new Big('303.1'), + netPerformance: new Big('303.1'), investment: new Big('2923.7'), value: new Big('3226.8') // 20 * (144.38 + days=212 * 0.08) }, { date: '2019-10-01', grossPerformance: new Big('351.1'), + netPerformance: new Big('351.1'), investment: new Big('2923.7'), value: new Big('3274.8') // 20 * (144.38 + days=242 * 0.08) }, { date: '2019-11-01', grossPerformance: new Big('400.7'), + netPerformance: new Big('400.7'), investment: new Big('2923.7'), value: new Big('3324.4') // 20 * (144.38 + days=273 * 0.08) }, { date: '2019-12-01', grossPerformance: new Big('448.7'), + netPerformance: new Big('448.7'), investment: new Big('2923.7'), value: new Big('3372.4') // 20 * (144.38 + days=303 * 0.08) }, { date: '2020-01-01', grossPerformance: new Big('498.3'), + netPerformance: new Big('498.3'), investment: new Big('2923.7'), value: new Big('3422') // 20 * (144.38 + days=335 * 0.08) }, { date: '2020-02-01', grossPerformance: new Big('547.9'), + netPerformance: new Big('547.9'), investment: new Big('2923.7'), value: new Big('3471.6') // 20 * (144.38 + days=365 * 0.08) }, { date: '2020-03-01', grossPerformance: new Big('226.95'), + netPerformance: new Big('226.95'), investment: new Big('652.55'), value: new Big('879.5') // 5 * (144.38 + days=394 * 0.08) }, { date: '2020-04-01', grossPerformance: new Big('239.35'), + netPerformance: new Big('239.35'), investment: new Big('652.55'), value: new Big('891.9') // 5 * (144.38 + days=425 * 0.08) }, { date: '2020-05-01', grossPerformance: new Big('251.35'), + netPerformance: new Big('251.35'), investment: new Big('652.55'), value: new Big('903.9') // 5 * (144.38 + days=455 * 0.08) }, { date: '2020-06-01', grossPerformance: new Big('263.75'), + netPerformance: new Big('263.75'), investment: new Big('652.55'), value: new Big('916.3') // 5 * (144.38 + days=486 * 0.08) }, { date: '2020-07-01', grossPerformance: new Big('275.75'), + netPerformance: new Big('275.75'), investment: new Big('652.55'), value: new Big('928.3') // 5 * (144.38 + days=516 * 0.08) }, { date: '2020-08-01', grossPerformance: new Big('288.15'), + netPerformance: new Big('288.15'), investment: new Big('652.55'), value: new Big('940.7') // 5 * (144.38 + days=547 * 0.08) }, { date: '2020-09-01', grossPerformance: new Big('300.55'), + netPerformance: new Big('300.55'), investment: new Big('652.55'), value: new Big('953.1') // 5 * (144.38 + days=578 * 0.08) }, { date: '2020-10-01', grossPerformance: new Big('312.55'), + netPerformance: new Big('312.55'), investment: new Big('652.55'), value: new Big('965.1') // 5 * (144.38 + days=608 * 0.08) }, { date: '2020-11-01', grossPerformance: new Big('324.95'), + netPerformance: new Big('324.95'), investment: new Big('652.55'), value: new Big('977.5') // 5 * (144.38 + days=639 * 0.08) }, { date: '2020-12-01', grossPerformance: new Big('336.95'), + netPerformance: new Big('336.95'), investment: new Big('652.55'), value: new Big('989.5') // 5 * (144.38 + days=669 * 0.08) }, { date: '2021-01-01', grossPerformance: new Big('349.35'), + netPerformance: new Big('349.35'), investment: new Big('652.55'), value: new Big('1001.9') // 5 * (144.38 + days=700 * 0.08) }, { date: '2021-02-01', grossPerformance: new Big('358.85'), + netPerformance: new Big('358.85'), investment: new Big('2684.05'), value: new Big('3042.9') // 15 * (144.38 + days=731 * 0.08) }, { date: '2021-03-01', grossPerformance: new Big('392.45'), + netPerformance: new Big('392.45'), investment: new Big('2684.05'), value: new Big('3076.5') // 15 * (144.38 + days=759 * 0.08) }, { date: '2021-04-01', grossPerformance: new Big('429.65'), + netPerformance: new Big('429.65'), investment: new Big('2684.05'), value: new Big('3113.7') // 15 * (144.38 + days=790 * 0.08) }, { date: '2021-05-01', grossPerformance: new Big('465.65'), + netPerformance: new Big('465.65'), investment: new Big('2684.05'), value: new Big('3149.7') // 15 * (144.38 + days=820 * 0.08) }, { date: '2021-06-01', grossPerformance: new Big('502.85'), + netPerformance: new Big('502.85'), investment: new Big('2684.05'), value: new Big('3186.9') // 15 * (144.38 + days=851 * 0.08) } @@ -1706,48 +1903,56 @@ describe('PortfolioCalculator', () => { { date: '2019-01-01', grossPerformance: new Big('0'), + netPerformance: new Big('0'), investment: new Big('0'), value: new Big('0') }, { date: '2020-01-01', grossPerformance: new Big('498.3'), + netPerformance: new Big('498.3'), investment: new Big('2923.7'), value: new Big('3422') // 20 * (144.38 + days=335 * 0.08) }, { date: '2021-01-01', grossPerformance: new Big('349.35'), + netPerformance: new Big('349.35'), investment: new Big('652.55'), value: new Big('1001.9') // 5 * (144.38 + days=700 * 0.08) }, { date: '2021-02-01', grossPerformance: new Big('358.85'), + netPerformance: new Big('358.85'), investment: new Big('2684.05'), value: new Big('3042.9') // 15 * (144.38 + days=731 * 0.08) }, { date: '2021-03-01', grossPerformance: new Big('392.45'), + netPerformance: new Big('392.45'), investment: new Big('2684.05'), value: new Big('3076.5') // 15 * (144.38 + days=759 * 0.08) }, { date: '2021-04-01', grossPerformance: new Big('429.65'), + netPerformance: new Big('429.65'), investment: new Big('2684.05'), value: new Big('3113.7') // 15 * (144.38 + days=790 * 0.08) }, { date: '2021-05-01', grossPerformance: new Big('465.65'), + netPerformance: new Big('465.65'), investment: new Big('2684.05'), value: new Big('3149.7') // 15 * (144.38 + days=820 * 0.08) }, { date: '2021-06-01', grossPerformance: new Big('502.85'), + netPerformance: new Big('502.85'), investment: new Big('2684.05'), value: new Big('3186.9') // 15 * (144.38 + days=851 * 0.08) } @@ -1785,222 +1990,259 @@ describe('PortfolioCalculator', () => { { date: '2019-01-01', grossPerformance: new Big('0'), + netPerformance: new Big('0'), investment: new Big('0'), value: new Big('0') }, { date: '2020-01-01', grossPerformance: new Big('498.3'), + netPerformance: new Big('498.3'), investment: new Big('2923.7'), value: new Big('3422') // 20 * (144.38 + days=335 * 0.08) }, { date: '2021-01-01', grossPerformance: new Big('349.35'), + netPerformance: new Big('349.35'), investment: new Big('652.55'), value: new Big('1001.9') // 5 * (144.38 + days=700 * 0.08) }, { date: '2021-02-01', grossPerformance: new Big('358.85'), + netPerformance: new Big('358.85'), investment: new Big('2684.05'), value: new Big('3042.9') // 15 * (144.38 + days=731 * 0.08) }, { date: '2021-03-01', grossPerformance: new Big('392.45'), + netPerformance: new Big('392.45'), investment: new Big('2684.05'), value: new Big('3076.5') // 15 * (144.38 + days=759 * 0.08) }, { date: '2021-04-01', grossPerformance: new Big('429.65'), + netPerformance: new Big('429.65'), investment: new Big('2684.05'), value: new Big('3113.7') // 15 * (144.38 + days=790 * 0.08) }, { date: '2021-05-01', grossPerformance: new Big('465.65'), + netPerformance: new Big('465.65'), investment: new Big('2684.05'), value: new Big('3149.7') // 15 * (144.38 + days=820 * 0.08) }, { date: '2021-06-01', grossPerformance: new Big('502.85'), + netPerformance: new Big('502.85'), investment: new Big('2684.05'), value: new Big('3186.9') // 15 * (144.38 + days=851 * 0.08) }, { date: '2021-06-02', grossPerformance: new Big('504.05'), + netPerformance: new Big('504.05'), investment: new Big('2684.05'), value: new Big('3188.1') // 15 * (144.38 + days=852 * 0.08) / +1.2 }, { date: '2021-06-03', grossPerformance: new Big('505.25'), + netPerformance: new Big('505.25'), investment: new Big('2684.05'), value: new Big('3189.3') // +1.2 }, { date: '2021-06-04', grossPerformance: new Big('506.45'), + netPerformance: new Big('506.45'), investment: new Big('2684.05'), value: new Big('3190.5') // +1.2 }, { date: '2021-06-05', grossPerformance: new Big('507.65'), + netPerformance: new Big('507.65'), investment: new Big('2684.05'), value: new Big('3191.7') // +1.2 }, { date: '2021-06-06', grossPerformance: new Big('508.85'), + netPerformance: new Big('508.85'), investment: new Big('2684.05'), value: new Big('3192.9') // +1.2 }, { date: '2021-06-07', grossPerformance: new Big('510.05'), + netPerformance: new Big('510.05'), investment: new Big('2684.05'), value: new Big('3194.1') // +1.2 }, { date: '2021-06-08', grossPerformance: new Big('511.25'), + netPerformance: new Big('511.25'), investment: new Big('2684.05'), value: new Big('3195.3') // +1.2 }, { date: '2021-06-09', grossPerformance: new Big('512.45'), + netPerformance: new Big('512.45'), investment: new Big('2684.05'), value: new Big('3196.5') // +1.2 }, { date: '2021-06-10', grossPerformance: new Big('513.65'), + netPerformance: new Big('513.65'), investment: new Big('2684.05'), value: new Big('3197.7') // +1.2 }, { date: '2021-06-11', grossPerformance: new Big('514.85'), + netPerformance: new Big('514.85'), investment: new Big('2684.05'), value: new Big('3198.9') // +1.2 }, { date: '2021-06-12', grossPerformance: new Big('516.05'), + netPerformance: new Big('516.05'), investment: new Big('2684.05'), value: new Big('3200.1') // +1.2 }, { date: '2021-06-13', grossPerformance: new Big('517.25'), + netPerformance: new Big('517.25'), investment: new Big('2684.05'), value: new Big('3201.3') // +1.2 }, { date: '2021-06-14', grossPerformance: new Big('518.45'), + netPerformance: new Big('518.45'), investment: new Big('2684.05'), value: new Big('3202.5') // +1.2 }, { date: '2021-06-15', grossPerformance: new Big('519.65'), + netPerformance: new Big('519.65'), investment: new Big('2684.05'), value: new Big('3203.7') // +1.2 }, { date: '2021-06-16', grossPerformance: new Big('520.85'), + netPerformance: new Big('520.85'), investment: new Big('2684.05'), value: new Big('3204.9') // +1.2 }, { date: '2021-06-17', grossPerformance: new Big('522.05'), + netPerformance: new Big('522.05'), investment: new Big('2684.05'), value: new Big('3206.1') // +1.2 }, { date: '2021-06-18', grossPerformance: new Big('523.25'), + netPerformance: new Big('523.25'), investment: new Big('2684.05'), value: new Big('3207.3') // +1.2 }, { date: '2021-06-19', grossPerformance: new Big('524.45'), + netPerformance: new Big('524.45'), investment: new Big('2684.05'), value: new Big('3208.5') // +1.2 }, { date: '2021-06-20', grossPerformance: new Big('525.65'), + netPerformance: new Big('525.65'), investment: new Big('2684.05'), value: new Big('3209.7') // +1.2 }, { date: '2021-06-21', grossPerformance: new Big('526.85'), + netPerformance: new Big('526.85'), investment: new Big('2684.05'), value: new Big('3210.9') // +1.2 }, { date: '2021-06-22', grossPerformance: new Big('528.05'), + netPerformance: new Big('528.05'), investment: new Big('2684.05'), value: new Big('3212.1') // +1.2 }, { date: '2021-06-23', grossPerformance: new Big('529.25'), + netPerformance: new Big('529.25'), investment: new Big('2684.05'), value: new Big('3213.3') // +1.2 }, { date: '2021-06-24', grossPerformance: new Big('530.45'), + netPerformance: new Big('530.45'), investment: new Big('2684.05'), value: new Big('3214.5') // +1.2 }, { date: '2021-06-25', grossPerformance: new Big('531.65'), + netPerformance: new Big('531.65'), investment: new Big('2684.05'), value: new Big('3215.7') // +1.2 }, { date: '2021-06-26', grossPerformance: new Big('532.85'), + netPerformance: new Big('532.85'), investment: new Big('2684.05'), value: new Big('3216.9') // +1.2 }, { date: '2021-06-27', grossPerformance: new Big('534.05'), + netPerformance: new Big('534.05'), investment: new Big('2684.05'), value: new Big('3218.1') // +1.2 }, { date: '2021-06-28', grossPerformance: new Big('535.25'), + netPerformance: new Big('535.25'), investment: new Big('2684.05'), value: new Big('3219.3') // +1.2 }, { date: '2021-06-29', grossPerformance: new Big('536.45'), + netPerformance: new Big('536.45'), investment: new Big('2684.05'), value: new Big('3220.5') // +1.2 }, { date: '2021-06-30', grossPerformance: new Big('537.65'), + netPerformance: new Big('537.65'), investment: new Big('2684.05'), value: new Big('3221.7') // +1.2 } @@ -2024,6 +2266,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -2033,6 +2276,7 @@ describe('PortfolioCalculator', () => { currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -2054,12 +2298,14 @@ describe('PortfolioCalculator', () => { { date: '2019-01-01', grossPerformance: new Big('0'), + netPerformance: new Big('0'), investment: new Big('0'), value: new Big('0') }, { date: '2020-01-01', grossPerformance: new Big('267.2'), + netPerformance: new Big('267.2'), investment: new Big('11553.75'), value: new Big('11820.95') // 10 * (144.38 + days=334 * 0.08) + 5 * 2021.99 } @@ -2165,6 +2411,7 @@ const orderTslaTransactionPoint: TransactionPoint[] = [ currency: Currency.USD, firstBuyDate: '2021-01-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -2182,6 +2429,7 @@ const ordersVTITransactionPoints: TransactionPoint[] = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -2196,6 +2444,7 @@ const ordersVTITransactionPoints: TransactionPoint[] = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 } ] @@ -2210,6 +2459,7 @@ const ordersVTITransactionPoints: TransactionPoint[] = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 3 } ] @@ -2224,6 +2474,7 @@ const ordersVTITransactionPoints: TransactionPoint[] = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 4 } ] @@ -2238,6 +2489,7 @@ const ordersVTITransactionPoints: TransactionPoint[] = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 5 } ] @@ -2255,6 +2507,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 } ] @@ -2269,6 +2522,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 } ] @@ -2283,6 +2537,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -2292,6 +2547,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 } ] @@ -2306,6 +2562,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 1 }, { @@ -2315,6 +2572,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 3 } ] @@ -2329,6 +2587,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 }, { @@ -2338,6 +2597,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 3 } ] @@ -2352,6 +2612,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 }, { @@ -2361,6 +2622,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 4 } ] @@ -2375,6 +2637,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-09-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 2 }, { @@ -2384,6 +2647,7 @@ const transactionPointsBuyAndSell = [ currency: Currency.USD, firstBuyDate: '2019-02-01', fee: new Big(0), + feeAccumulated: new Big(0), transactionCount: 5 } ] diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index 52cd4e8e7..bbefe7612 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -59,6 +59,7 @@ export class PortfolioCalculator { currentTransactionPointItem = { currency: order.currency, fee: order.fee, + feeAccumulated: order.fee.plus(oldAccumulatedSymbol.feeAccumulated), firstBuyDate: oldAccumulatedSymbol.firstBuyDate, investment: newQuantity.eq(0) ? new Big(0) @@ -74,6 +75,7 @@ export class PortfolioCalculator { currentTransactionPointItem = { currency: order.currency, fee: order.fee, + feeAccumulated: order.fee, firstBuyDate: order.date, investment: unitPrice.mul(order.quantity).mul(factor), quantity: order.quantity.mul(factor), @@ -474,6 +476,7 @@ export class PortfolioCalculator { endDate: Date ): Promise { let investment: Big = new Big(0); + let fees: Big = new Big(0); const marketSymbolMap: { [date: string]: { [symbol: string]: Big }; @@ -486,6 +489,7 @@ export class PortfolioCalculator { currencies[item.symbol] = item.currency; symbols.push(item.symbol); investment = investment.add(item.investment); + fees = fees.add(item.feeAccumulated); } let marketSymbols: GetValueObject[] = []; @@ -545,12 +549,13 @@ export class PortfolioCalculator { } } if (!invalid) { + const grossPerformance = value.minus(investment); const result = { + grossPerformance, investment, value, date: currentDateAsString, - grossPerformance: value.minus(investment), - netPerformance: new Big(0) // TODO + netPerformance: grossPerformance.minus(fees) }; results.push(result); }