Browse Source

Fix tests

pull/5027/head
Daniel Devaud 1 year ago
parent
commit
693d6535e8
  1. 152
      apps/api/src/app/portfolio/portfolio-calculator-novn-baln-buy-and-sell.spec.ts
  2. 2
      apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell.spec.ts
  3. 47
      apps/api/src/app/portfolio/portfolio-calculator.ts

152
apps/api/src/app/portfolio/portfolio-calculator-novn-baln-buy-and-sell.spec.ts

@ -0,0 +1,152 @@
import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { parseDate } from '@ghostfolio/common/helper';
import Big from 'big.js';
import { CurrentRateServiceMock } from './current-rate.service.mock';
import { PortfolioCalculator } from './portfolio-calculator';
jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => {
return {
// eslint-disable-next-line @typescript-eslint/naming-convention
CurrentRateService: jest.fn().mockImplementation(() => {
return CurrentRateServiceMock;
})
};
});
describe('PortfolioCalculator', () => {
let currentRateService: CurrentRateService;
let exchangeRateDataService: ExchangeRateDataService;
beforeEach(() => {
currentRateService = new CurrentRateService(null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
});
describe('get current positions', () => {
it.only('with NOVN.SW and BALN.SW buy and sell', async () => {
const portfolioCalculator = new PortfolioCalculator({
currentRateService,
exchangeRateDataService,
currency: 'CHF',
orders: [
{
currency: 'CHF',
date: '2022-03-07',
dataSource: 'YAHOO',
fee: new Big(0),
name: 'Novartis AG',
quantity: new Big(2),
symbol: 'NOVN.SW',
type: 'BUY',
unitPrice: new Big(75.8)
},
{
currency: 'CHF',
date: '2022-04-01',
dataSource: 'YAHOO',
fee: new Big(0),
name: 'Novartis AG',
quantity: new Big(0),
symbol: 'NOVN.SW',
type: 'BUY',
unitPrice: new Big(80.0)
},
{
currency: 'CHF',
date: '2022-04-08',
dataSource: 'YAHOO',
fee: new Big(0),
name: 'Novartis AG',
quantity: new Big(2),
symbol: 'NOVN.SW',
type: 'SELL',
unitPrice: new Big(85.73)
},
{
currency: 'CHF',
date: '2022-03-22',
dataSource: 'YAHOO',
fee: new Big(1.55),
name: 'Bâloise Holding AG',
quantity: new Big(2),
symbol: 'BALN.SW',
type: 'BUY',
unitPrice: new Big(142.9)
},
{
currency: 'CHF',
date: '2022-04-01',
dataSource: 'YAHOO',
fee: new Big(0),
name: 'Bâloise Holding AG',
quantity: new Big(0),
symbol: 'BALN.SW',
type: 'BUY',
unitPrice: new Big(138)
},
{
currency: 'CHF',
date: '2022-04-10',
dataSource: 'YAHOO',
fee: new Big(1.65),
name: 'Bâloise Holding AG',
quantity: new Big(2),
symbol: 'BALN.SW',
type: 'SELL',
unitPrice: new Big(136.6)
}
]
});
portfolioCalculator.computeTransactionPoints();
const spy = jest
.spyOn(Date, 'now')
.mockImplementation(() => parseDate('2022-04-11').getTime());
const chartData = await portfolioCalculator.getChartData({
start: parseDate('2022-03-07'),
calculateTimeWeightedPerformance: true
});
spy.mockRestore();
expect(chartData[0]).toEqual({
date: '2022-03-07',
investmentValueWithCurrencyEffect: 151.6,
netPerformance: 0,
netPerformanceInPercentage: 0,
netPerformanceInPercentageWithCurrencyEffect: 0,
netPerformanceWithCurrencyEffect: 0,
timeWeightedPerformance: 0,
totalInvestment: 151.6,
totalInvestmentValueWithCurrencyEffect: 151.6,
value: 151.6,
valueWithCurrencyEffect: 151.6
});
expect(chartData[chartData.length - 1]).toEqual({
date: '2022-04-11',
investmentValueWithCurrencyEffect: 0,
netPerformance: 19.86,
netPerformanceInPercentage: 13.100263852242744,
netPerformanceInPercentageWithCurrencyEffect: 13.100263852242744,
netPerformanceWithCurrencyEffect: 19.86,
timeWeightedPerformance: 13.100263852242744,
totalInvestment: 0,
totalInvestmentValueWithCurrencyEffect: 0,
value: 0,
valueWithCurrencyEffect: 0
});
});
});
});

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

@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => {
netPerformanceInPercentage: 0,
netPerformanceInPercentageWithCurrencyEffect: 0,
netPerformanceWithCurrencyEffect: 0,
timeWeightedPerformance: 0,
totalInvestment: 151.6,
totalInvestmentValueWithCurrencyEffect: 151.6,
value: 151.6,
@ -106,6 +107,7 @@ describe('PortfolioCalculator', () => {
netPerformanceInPercentage: 13.100263852242744,
netPerformanceInPercentageWithCurrencyEffect: 13.100263852242744,
netPerformanceWithCurrencyEffect: 19.86,
timeWeightedPerformance: 0,
totalInvestment: 0,
totalInvestmentValueWithCurrencyEffect: 0,
value: 0,

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

@ -270,7 +270,12 @@ export class PortfolioCalculator {
[date: string]: { [symbol: string]: Big };
} = {};
if (!marketSymbols?.length) {
return [];
}
this.populateMarketSymbolMap(marketSymbols, marketSymbolMap);
const accumulatedValuesByDate: {
[date: string]: {
investmentValueWithCurrencyEffect: Big;
@ -282,6 +287,7 @@ export class PortfolioCalculator {
totalNetPerformanceValueWithCurrencyEffect: Big;
totalTimeWeightedInvestmentValue: Big;
totalTimeWeightedInvestmentValueWithCurrencyEffect: Big;
totalTimeWeightedPerformance: Big;
};
} = {};
@ -360,6 +366,7 @@ export class PortfolioCalculator {
totalNetPerformanceValueWithCurrencyEffect: Big;
totalTimeWeightedInvestmentValue: Big;
totalTimeWeightedInvestmentValueWithCurrencyEffect: Big;
totalTimeWeightedPerformance: Big;
};
}
) {
@ -368,19 +375,13 @@ export class PortfolioCalculator {
? format(previousDate, DATE_FORMAT)
: null;
let totalCurrentValue = new Big(0);
let totalInvestmentValue = new Big(0);
let maxTotalInvestmentValue = new Big(0);
let totalNetPerformanceValue = new Big(0);
let previousTotalInvestmentValue = new Big(0);
let timeWeightedPerformance = new Big(0);
if (calculateTimeWeightedPerformance && previousDateString) {
for (const symbol of Object.keys(valuesBySymbol)) {
const symbolValues = valuesBySymbol[symbol];
previousTotalInvestmentValue = previousTotalInvestmentValue.plus(
symbolValues.currentValues?.[previousDateString] ?? new Big(0)
);
}
previousTotalInvestmentValue =
accumulatedValuesByDate[previousDateString].totalInvestmentValue;
}
for (const symbol of Object.keys(valuesBySymbol)) {
@ -390,10 +391,6 @@ export class PortfolioCalculator {
totalCurrentValue = totalCurrentValue.plus(symbolCurrentValues);
totalNetPerformanceValue = totalNetPerformanceValue.plus(
symbolValues.netPerformanceValues?.[dateString] ?? new Big(0)
);
if (
previousTotalInvestmentValue.toNumber() &&
symbolValues.netPerformanceValuesPercentage &&
@ -415,11 +412,17 @@ export class PortfolioCalculator {
);
}
let totalTimeWeightedPerformance = timeWeightedPerformance.plus(
accumulatedValuesByDate[previousDateString]
?.totalTimeWeightedPerformance ?? new Big(0)
);
accumulatedValuesByDate = this.accumulatedValuesByDate(
valuesBySymbol,
symbol,
dateString,
accumulatedValuesByDate
accumulatedValuesByDate,
totalTimeWeightedPerformance
);
}
@ -429,13 +432,16 @@ export class PortfolioCalculator {
totalInvestmentValueWithCurrencyEffect,
totalNetPerformanceValueWithCurrencyEffect,
totalTimeWeightedInvestmentValue,
totalTimeWeightedInvestmentValueWithCurrencyEffect
totalTimeWeightedInvestmentValueWithCurrencyEffect,
totalInvestmentValue,
totalTimeWeightedPerformance,
totalNetPerformanceValue
} = accumulatedValuesByDate[dateString];
const netPerformanceInPercentage = maxTotalInvestmentValue.eq(0)
const netPerformanceInPercentage = totalTimeWeightedInvestmentValue.eq(0)
? 0
: totalNetPerformanceValue
.div(maxTotalInvestmentValue)
.div(totalTimeWeightedInvestmentValue)
.mul(100)
.toNumber();
@ -455,7 +461,7 @@ export class PortfolioCalculator {
totalInvestment: totalInvestmentValue.toNumber(),
value: totalCurrentValue.toNumber(),
valueWithCurrencyEffect: totalCurrentValueWithCurrencyEffect.toNumber(),
timeWeightedPerformance: timeWeightedPerformance.toNumber(),
timeWeightedPerformance: totalTimeWeightedPerformance.toNumber(),
investmentValueWithCurrencyEffect:
investmentValueWithCurrencyEffect.toNumber(),
netPerformanceWithCurrencyEffect:
@ -493,8 +499,10 @@ export class PortfolioCalculator {
totalNetPerformanceValueWithCurrencyEffect: Big;
totalTimeWeightedInvestmentValue: Big;
totalTimeWeightedInvestmentValueWithCurrencyEffect: Big;
totalTimeWeightedPerformance: Big;
};
}
},
timeWeightedPerformance: Big
) {
const symbolValues = valuesBySymbol[symbol];
@ -564,7 +572,8 @@ export class PortfolioCalculator {
totalTimeWeightedInvestmentValueWithCurrencyEffect: (
accumulatedValuesByDate[dateString]
?.totalTimeWeightedInvestmentValueWithCurrencyEffect ?? new Big(0)
).add(timeWeightedInvestmentValueWithCurrencyEffect)
).add(timeWeightedInvestmentValueWithCurrencyEffect),
totalTimeWeightedPerformance: timeWeightedPerformance
};
return accumulatedValuesByDate;

Loading…
Cancel
Save