@ -25,7 +25,7 @@ import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper';
import {
Accounts ,
PortfolioDetails ,
PortfolioPerformance ,
PortfolioPerformanceResponse ,
PortfolioReport ,
PortfolioSummary ,
Position ,
@ -99,15 +99,22 @@ export class PortfolioService {
}
}
const value = details . accounts [ account . id ] ? . current ? ? 0 ;
const result = {
. . . account ,
transactionCount ,
convertedBalance : this.exchangeRateDataService.toCurrency (
value ,
balanceInBaseCurrency : this.exchangeRateDataService.toCurrency (
account . balance ,
account . currency ,
userCurrency
) ,
value : details.accounts [ account . id ] ? . current ? ? 0
valueInBaseCurrency : this.exchangeRateDataService.toCurrency (
value ,
account . currency ,
userCurrency
)
} ;
delete result . Order ;
@ -118,17 +125,26 @@ export class PortfolioService {
public async getAccountsWithAggregations ( aUserId : string ) : Promise < Accounts > {
const accounts = await this . getAccounts ( aUserId ) ;
let totalBalance = 0 ;
let totalValue = 0 ;
let totalBalanceInBaseCurrency = new Big ( 0 ) ;
let totalValueInBaseCurrency = new Big ( 0 ) ;
let transactionCount = 0 ;
for ( const account of accounts ) {
totalBalance += account . convertedBalance ;
totalValue += account . value ;
totalBalanceInBaseCurrency = totalBalanceInBaseCurrency . plus (
account . balanceInBaseCurrency
) ;
totalValueInBaseCurrency = totalValueInBaseCurrency . plus (
account . valueInBaseCurrency
) ;
transactionCount += account . transactionCount ;
}
return { accounts , totalBalance , totalValue , transactionCount } ;
return {
accounts ,
transactionCount ,
totalBalanceInBaseCurrency : totalBalanceInBaseCurrency.toNumber ( ) ,
totalValueInBaseCurrency : totalValueInBaseCurrency.toNumber ( )
} ;
}
public async getInvestments (
@ -281,13 +297,11 @@ export class PortfolioService {
userId
} ) ;
if ( transactionPoints ? . length <= 0 ) {
return { accounts : { } , holdings : { } , hasErrors : false } ;
}
portfolioCalculator . setTransactionPoints ( transactionPoints ) ;
const portfolioStart = parseDate ( transactionPoints [ 0 ] . date ) ;
const portfolioStart = parseDate (
transactionPoints [ 0 ] ? . date ? ? format ( new Date ( ) , DATE_FORMAT )
) ;
const startDate = this . getStartDate ( aDateRange , portfolioStart ) ;
const currentPositions = await portfolioCalculator . getCurrentPositions (
startDate
@ -300,9 +314,11 @@ export class PortfolioService {
const holdings : PortfolioDetails [ 'holdings' ] = { } ;
const totalInvestment = currentPositions . totalInvestment . plus (
cashDetails . balance
cashDetails . balanceInBaseCurrency
) ;
const totalValue = currentPositions . currentValue . plus (
cashDetails . balanceInBaseCurrency
) ;
const totalValue = currentPositions . currentValue . plus ( cashDetails . balance ) ;
const dataGatheringItems = currentPositions . positions . map ( ( position ) = > {
return {
@ -315,7 +331,7 @@ export class PortfolioService {
) ;
const [ dataProviderResponses , symbolProfiles ] = await Promise . all ( [
this . dataProviderService . get ( dataGatheringItems ) ,
this . dataProviderService . getQuotes ( dataGatheringItems ) ,
this . symbolProfileService . getSymbolProfiles ( symbols )
] ) ;
@ -346,7 +362,6 @@ export class PortfolioService {
countries : symbolProfile.countries ,
currency : item.currency ,
dataSource : symbolProfile.dataSource ,
exchange : dataProviderResponse.exchange ,
grossPerformance : item.grossPerformance?.toNumber ( ) ? ? 0 ,
grossPerformancePercent :
item . grossPerformancePercentage ? . toNumber ( ) ? ? 0 ,
@ -423,7 +438,7 @@ export class PortfolioService {
} ;
}
const positionCurrency = orders [ 0 ] . currency ;
const positionCurrency = orders [ 0 ] . SymbolProfile . currency ;
const [ SymbolProfile ] = await this . symbolProfileService . getSymbolProfiles ( [
aSymbol
] ) ;
@ -433,13 +448,13 @@ export class PortfolioService {
return order . type === 'BUY' || order . type === 'SELL' ;
} )
. map ( ( order ) = > ( {
currency : order.currency ,
dataSource : order.SymbolProfile? .dataSource ? ? order . dataSource ,
currency : order.SymbolProfile. currency ,
dataSource : order.SymbolProfile.dataSource ,
date : format ( order . date , DATE_FORMAT ) ,
fee : new Big ( order . fee ) ,
name : order.SymbolProfile?.name ,
quantity : new Big ( order . quantity ) ,
symbol : order . symbol ,
symbol : order . SymbolProfile . symbol ,
type : order . type ,
unitPrice : new Big ( order . unitPrice )
} ) ) ;
@ -552,9 +567,10 @@ export class PortfolioService {
SymbolProfile ,
transactionCount ,
averagePrice : averagePrice.toNumber ( ) ,
grossPerformancePercent : position.grossPerformancePercentage.toNumber ( ) ,
grossPerformancePercent :
position . grossPerformancePercentage ? . toNumber ( ) ,
historicalData : historicalDataArray ,
netPerformancePercent : position.netPerformancePercentage.toNumber ( ) ,
netPerformancePercent : position.netPerformancePercentage? .toNumber ( ) ,
quantity : quantity.toNumber ( ) ,
value : this.exchangeRateDataService.toCurrency (
quantity . mul ( marketPrice ) . toNumber ( ) ,
@ -563,7 +579,7 @@ export class PortfolioService {
)
} ;
} else {
const currentData = await this . dataProviderService . get ( [
const currentData = await this . dataProviderService . getQuotes ( [
{ dataSource : DataSource.YAHOO , symbol : aSymbol }
] ) ;
const marketPrice = currentData [ aSymbol ] ? . marketPrice ;
@ -660,7 +676,7 @@ export class PortfolioService {
const symbols = positions . map ( ( position ) = > position . symbol ) ;
const [ dataProviderResponses , symbolProfiles ] = await Promise . all ( [
this . dataProviderService . get ( dataGatheringItem ) ,
this . dataProviderService . getQuotes ( dataGatheringItem ) ,
this . symbolProfileService . getSymbolProfiles ( symbols )
] ) ;
@ -696,7 +712,7 @@ export class PortfolioService {
public async getPerformance (
aImpersonationId : string ,
aDateRange : DateRange = 'max'
) : Promise < { hasErrors : boolean ; performance : PortfolioPerformance } > {
) : Promise < PortfolioPerformanceResponse > {
const userId = await this . getUserId ( aImpersonationId , this . request . user . id ) ;
const portfolioCalculator = new PortfolioCalculator (
@ -848,7 +864,7 @@ export class PortfolioService {
const performanceInformation = await this . getPerformance ( aImpersonationId ) ;
const { balance } = await this . accountService . getCashDetails (
const { balanceInBaseCurrency } = await this . accountService . getCashDetails (
userId ,
userCurrency
) ;
@ -866,7 +882,7 @@ export class PortfolioService {
const committedFunds = new Big ( totalBuy ) . minus ( totalSell ) ;
const netWorth = new Big ( balance )
const netWorth = new Big ( balanceInBaseCurrency )
. plus ( performanceInformation . performance . currentValue )
. plus ( items )
. toNumber ( ) ;
@ -882,7 +898,7 @@ export class PortfolioService {
totalSell ,
annualizedPerformancePercent :
performanceInformation . performance . annualizedPerformancePercent ,
cash : balance ,
cash : balanceInBaseCurrency ,
committedFunds : committedFunds.toNumber ( ) ,
ordersCount : orders.filter ( ( order ) = > {
return order . type === 'BUY' || order . type === 'SELL' ;
@ -971,7 +987,7 @@ export class PortfolioService {
. map ( ( order ) = > {
return this . exchangeRateDataService . toCurrency (
new Big ( order . quantity ) . mul ( order . unitPrice ) . toNumber ( ) ,
order . currency ,
order . SymbolProfile . currency ,
this . request . user . Settings . currency
) ;
} )
@ -990,7 +1006,7 @@ export class PortfolioService {
. map ( ( order ) = > {
return this . exchangeRateDataService . toCurrency (
order . fee ,
order . currency ,
order . SymbolProfile . currency ,
this . request . user . Settings . currency
) ;
} )
@ -1012,7 +1028,7 @@ export class PortfolioService {
. map ( ( order ) = > {
return this . exchangeRateDataService . toCurrency (
new Big ( order . quantity ) . mul ( order . unitPrice ) . toNumber ( ) ,
order . currency ,
order . SymbolProfile . currency ,
this . request . user . Settings . currency
) ;
} )
@ -1064,24 +1080,24 @@ export class PortfolioService {
}
const portfolioOrders : PortfolioOrder [ ] = orders . map ( ( order ) = > ( {
currency : order.currency ,
dataSource : order.SymbolProfile? .dataSource ? ? order . dataSource ,
currency : order.SymbolProfile. currency ,
dataSource : order.SymbolProfile.dataSource ,
date : format ( order . date , DATE_FORMAT ) ,
fee : new Big (
this . exchangeRateDataService . toCurrency (
order . fee ,
order . currency ,
order . SymbolProfile . currency ,
userCurrency
)
) ,
name : order.SymbolProfile?.name ,
quantity : new Big ( order . quantity ) ,
symbol : order . symbol ,
symbol : order . SymbolProfile . symbol ,
type : order . type ,
unitPrice : new Big (
this . exchangeRateDataService . toCurrency (
order . unitPrice ,
order . currency ,
order . SymbolProfile . currency ,
userCurrency
)
)
@ -1113,22 +1129,18 @@ export class PortfolioService {
return accountId === account . id ;
} ) ;
const convertedBalance = this . exchangeRateDataService . toCurrency (
account . balance ,
account . currency ,
userCurrency
) ;
accounts [ account . id ] = {
balance : convertedB alance,
balance : account.balance ,
currency : account.currency ,
current : convertedB alance,
current : account.balance ,
name : account.name ,
original : convertedB alance
original : account.b alance
} ;
for ( const order of ordersByAccount ) {
let currentValueOfSymbol =
order . quantity * portfolioItemsNow [ order . symbol ] . marketPrice ;
order . quantity *
portfolioItemsNow [ order . SymbolProfile . symbol ] . marketPrice ;
let originalValueOfSymbol = order . quantity * order . unitPrice ;
if ( order . type === 'SELL' ) {
@ -1178,7 +1190,7 @@ export class PortfolioService {
. map ( ( order ) = > {
return this . exchangeRateDataService . toCurrency (
order . quantity * order . unitPrice ,
order . currency ,
order . SymbolProfile . currency ,
currency
) ;
} )