@ -14,7 +14,7 @@ import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-r
import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service' ;
import { PortfolioSnapshotServiceMock } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service.mock' ;
import { parseDate } from '@ghostfolio/common/helper' ;
import { HistoricalDataItem } from '@ghostfolio/common/interface s' ;
import { TimelinePosition } from '@ghostfolio/common/model s' ;
import { PerformanceCalculationType } from '@ghostfolio/common/types/performance-calculation-type.type' ;
import { DataSource } from '@prisma/client' ;
@ -191,7 +191,8 @@ describe('PortfolioCalculator', () => {
const { activities } = await orderService . getOrdersForPortfolioCalculator (
{
userCurrency : 'CHF' ,
userId : userDummyData.id
userId : userDummyData.id ,
withCash : true
}
) ;
@ -201,7 +202,14 @@ describe('PortfolioCalculator', () => {
values : [ ]
} ) ;
const accountBalanceItems =
await accountBalanceService . getAccountBalanceItems ( {
userCurrency : 'CHF' ,
userId : userDummyData.id
} ) ;
const portfolioCalculator = portfolioCalculatorFactory . createCalculator ( {
accountBalanceItems ,
activities ,
calculationType : PerformanceCalculationType.ROAI ,
currency : 'CHF' ,
@ -210,94 +218,72 @@ describe('PortfolioCalculator', () => {
const portfolioSnapshot = await portfolioCalculator . computeSnapshot ( ) ;
const historicalData20231231 = portfolioSnapshot . historicalData . find (
( { date } ) = > {
return date === '2023-12-31' ;
}
) ;
const historicalData20240101 = portfolioSnapshot . historicalData . find (
( { date } ) = > {
return date === '2024-01-01' ;
}
) ;
const historicalData20241231 = portfolioSnapshot . historicalData . find (
( { date } ) = > {
return date === '2024-12-31' ;
}
) ;
/ * *
* Investment value with currency effect : 1000 USD * 0.85 = 850 CHF
* Total investment : 1000 USD * 0.91 = 910 CHF
* Value ( current ) : 1000 USD * 0.91 = 910 CHF
* Value with currency effect : 1000 USD * 0.85 = 850 CHF
* /
expect ( historicalData20231231 ) . toMatchObject ( {
date : '2023-12-31' ,
investmentValueWithCurrencyEffect : 850 ,
netPerformance : 0 ,
netPerformanceInPercentage : 0 ,
netPerformanceInPercentageWithCurrencyEffect : 0 ,
netPerformanceWithCurrencyEffect : 0 ,
netWorth : 850 ,
totalAccountBalance : 0 ,
totalInvestment : 910 ,
totalInvestmentValueWithCurrencyEffect : 850 ,
value : 910 ,
valueWithCurrencyEffect : 850
} ) ;
/ * *
* Net performance with currency effect : ( 1000 * 0.86 ) - ( 1000 * 0.85 ) = 10 CHF
* Total investment : 1000 USD * 0.91 = 910 CHF
* Total investment value with currency effect : 1000 USD * 0.85 = 850 CHF
* Value ( current ) : 1000 USD * 0.91 = 910 CHF
* Value with currency effect : 1000 USD * 0.86 = 860 CHF
* /
expect ( historicalData20240101 ) . toMatchObject ( {
date : '2024-01-01' ,
investmentValueWithCurrencyEffect : 0 ,
netPerformance : 0 ,
netPerformanceInPercentage : 0 ,
netPerformanceInPercentageWithCurrencyEffect : 0.011764705882352941 ,
netPerformanceWithCurrencyEffect : 10 ,
netWorth : 860 ,
totalAccountBalance : 0 ,
totalInvestment : 910 ,
totalInvestmentValueWithCurrencyEffect : 850 ,
value : 910 ,
valueWithCurrencyEffect : 860
const position = portfolioSnapshot . positions . find ( ( { symbol } ) = > {
return symbol === 'USD' ;
} ) ;
/ * *
* Investment value with currency effect : 1000 USD * 0.90 = 900 CHF
* Investment : 2000 USD * 0.91 = 1820 CHF
* Investment value with currency effect : ( 1000 USD * 0.85 ) + ( 1000 USD * 0.90 ) = 1750 CHF
* Net performance : ( 1000 USD * 1.0 ) - ( 1000 USD * 1.0 ) = 0 CHF
* Net performance with currency effect : ( 1000 USD * 0.9 ) - ( 1000 USD * 0.85 ) = 50 CHF
* Total investment : 2000 USD * 0.91 = 1820 CHF
* Total investment value with currency effect : ( 1000 USD * 0.85 ) + ( 1000 USD * 0.90 ) = 1750 CHF
* Value ( current ) : 2000 USD * 0.91 = 1820 CHF
* Value with currency effect : 2000 USD * 0.9 = 1800 CHF
* Total account balance : 2000 USD * 0.85 = 1700 CHF ( using the exchange rate on 2024 - 12 - 31 )
* Value in base currency : 2000 USD * 0.91 = 1820 CHF
* /
expect ( historicalData20241231 ) . toMatchObject < HistoricalDataItem > ( {
date : '2024-12-31' ,
investmentValueWithCurrencyEffect : 900 ,
netPerformance : 0 ,
netPerformanceInPercentage : 0 ,
netPerformanceInPercentageWithCurrencyEffect : 0.058823529411764705 ,
netPerformanceWithCurrencyEffect : 50 ,
netWorth : 1800 ,
totalAccountBalance : 0 ,
totalInvestment : 1820 ,
totalInvestmentValueWithCurrencyEffect : 1750 ,
value : 1820 ,
valueWithCurrencyEffect : 1800
expect ( position ) . toMatchObject < TimelinePosition > ( {
averagePrice : new Big ( 1 ) ,
currency : 'USD' ,
dataSource : DataSource.YAHOO ,
dividend : new Big ( 0 ) ,
dividendInBaseCurrency : new Big ( 0 ) ,
fee : new Big ( 0 ) ,
feeInBaseCurrency : new Big ( 0 ) ,
firstBuyDate : '2023-12-31' ,
grossPerformance : new Big ( 0 ) ,
grossPerformancePercentage : new Big ( 0 ) ,
grossPerformancePercentageWithCurrencyEffect : new Big (
'0.08211603004634809014'
) ,
grossPerformanceWithCurrencyEffect : new Big ( 70 ) ,
includeInTotalAssetValue : false ,
investment : new Big ( 1820 ) ,
investmentWithCurrencyEffect : new Big ( 1750 ) ,
marketPrice : 1 ,
marketPriceInBaseCurrency : 0.91 ,
netPerformance : new Big ( 0 ) ,
netPerformancePercentage : new Big ( 0 ) ,
netPerformancePercentageWithCurrencyEffectMap : {
'1d' : new Big ( '0.01111111111111111111' ) ,
'1y' : new Big ( '0.06937181021989792704' ) ,
'5y' : new Big ( '0.0818817546090273363' ) ,
max : new Big ( '0.0818817546090273363' ) ,
mtd : new Big ( '0.01111111111111111111' ) ,
wtd : new Big ( '-0.05517241379310344828' ) ,
ytd : new Big ( '0.01111111111111111111' )
} ,
netPerformanceWithCurrencyEffectMap : {
'1d' : new Big ( 20 ) ,
'1y' : new Big ( 60 ) ,
'5y' : new Big ( 70 ) ,
max : new Big ( 70 ) ,
mtd : new Big ( 20 ) ,
wtd : new Big ( - 80 ) ,
ytd : new Big ( 20 )
} ,
quantity : new Big ( 2000 ) ,
symbol : 'USD' ,
timeWeightedInvestment : new Big ( '912.47956403269754768392' ) ,
timeWeightedInvestmentWithCurrencyEffect : new Big (
'852.45231607629427792916'
) ,
transactionCount : 2 ,
valueInBaseCurrency : new Big ( 1820 )
} ) ;
expect ( portfolioSnapshot ) . toMatchObject ( {
hasErrors : false ,
totalFeesWithCurrencyEffect : new Big ( '0' ) ,
totalInterestWithCurrencyEffect : new Big ( '0' ) ,
totalLiabilitiesWithCurrencyEffect : new Big ( '0' )
totalFeesWithCurrencyEffect : new Big ( 0 ) ,
totalInterestWithCurrencyEffect : new Big ( 0 ) ,
totalLiabilitiesWithCurrencyEffect : new Big ( 0 )
} ) ;
} ) ;
} ) ;