@ -1,7 +1,7 @@
import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service' ;
import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service' ;
import { AccountService } from '@ghostfolio/api/app/account/account.service' ;
import { AccountService } from '@ghostfolio/api/app/account/account.service' ;
import { CashDetails } from '@ghostfolio/api/app/account/interfaces/cash-details.interface' ;
import { CashDetails } from '@ghostfolio/api/app/account/interfaces/cash-details.interface' ;
import { Order Service } from '@ghostfolio/api/app/order/order .service' ;
import { Activities Service } from '@ghostfolio/api/app/activities/activities .service' ;
import { UserService } from '@ghostfolio/api/app/user/user.service' ;
import { UserService } from '@ghostfolio/api/app/user/user.service' ;
import { getFactor } from '@ghostfolio/api/helper/portfolio.helper' ;
import { getFactor } from '@ghostfolio/api/helper/portfolio.helper' ;
import { AccountClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rules/account-cluster-risk/current-investment' ;
import { AccountClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rules/account-cluster-risk/current-investment' ;
@ -13,7 +13,7 @@ import { CurrencyClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rul
import { EconomicMarketClusterRiskDevelopedMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/developed-markets' ;
import { EconomicMarketClusterRiskDevelopedMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/developed-markets' ;
import { EconomicMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/emerging-markets' ;
import { EconomicMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/economic-market-cluster-risk/emerging-markets' ;
import { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup' ;
import { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup' ;
import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment ' ;
import { FeeRatioTotalInvestmentVolume } from '@ghostfolio/api/models/rules/fees/fee-ratio-total-investment-volume ' ;
import { BuyingPower } from '@ghostfolio/api/models/rules/liquidity/buying-power' ;
import { BuyingPower } from '@ghostfolio/api/models/rules/liquidity/buying-power' ;
import { RegionalMarketClusterRiskAsiaPacific } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/asia-pacific' ;
import { RegionalMarketClusterRiskAsiaPacific } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/asia-pacific' ;
import { RegionalMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/emerging-markets' ;
import { RegionalMarketClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/regional-market-cluster-risk/emerging-markets' ;
@ -105,13 +105,13 @@ export class PortfolioService {
public constructor (
public constructor (
private readonly accountBalanceService : AccountBalanceService ,
private readonly accountBalanceService : AccountBalanceService ,
private readonly accountService : AccountService ,
private readonly accountService : AccountService ,
private readonly activitiesService : ActivitiesService ,
private readonly benchmarkService : BenchmarkService ,
private readonly benchmarkService : BenchmarkService ,
private readonly calculatorFactory : PortfolioCalculatorFactory ,
private readonly calculatorFactory : PortfolioCalculatorFactory ,
private readonly dataProviderService : DataProviderService ,
private readonly dataProviderService : DataProviderService ,
private readonly exchangeRateDataService : ExchangeRateDataService ,
private readonly exchangeRateDataService : ExchangeRateDataService ,
private readonly i18nService : I18nService ,
private readonly i18nService : I18nService ,
private readonly impersonationService : ImpersonationService ,
private readonly impersonationService : ImpersonationService ,
private readonly orderService : OrderService ,
@Inject ( REQUEST ) private readonly request : RequestWithUser ,
@Inject ( REQUEST ) private readonly request : RequestWithUser ,
private readonly rulesService : RulesService ,
private readonly rulesService : RulesService ,
private readonly symbolProfileService : SymbolProfileService ,
private readonly symbolProfileService : SymbolProfileService ,
@ -403,10 +403,10 @@ export class PortfolioService {
const user = await this . userService . user ( { id : userId } ) ;
const user = await this . userService . user ( { id : userId } ) ;
const userCurrency = this . getUserCurrency ( user ) ;
const userCurrency = this . getUserCurrency ( user ) ;
const { endDate , startDate } = getIntervalFromDateRange ( dateRange ) ;
const { endDate , startDate } = getIntervalFromDateRange ( { dateRange } ) ;
const { activities } =
const { activities } =
await this . orderService . getOrder sForPortfolioCalculator( {
await this . activitiesService . getActivitie sForPortfolioCalculator( {
filters ,
filters ,
userCurrency ,
userCurrency ,
userId
userId
@ -490,7 +490,7 @@ export class PortfolioService {
) ;
) ;
const { activities } =
const { activities } =
await this . orderService . getOrder sForPortfolioCalculator( {
await this . activitiesService . getActivitie sForPortfolioCalculator( {
filters ,
filters ,
userCurrency ,
userCurrency ,
userId
userId
@ -623,6 +623,28 @@ export class PortfolioService {
? 0
? 0
: valueInBaseCurrency . div ( filteredValueInBaseCurrency ) . toNumber ( ) ,
: valueInBaseCurrency . div ( filteredValueInBaseCurrency ) . toNumber ( ) ,
assetClass : assetProfile.assetClass ,
assetClass : assetProfile.assetClass ,
assetProfile : {
assetClass : assetProfile.assetClass ,
assetSubClass : assetProfile.assetSubClass ,
countries : assetProfile.countries ,
currency : assetProfile.currency ,
dataSource : assetProfile.dataSource ,
holdings : assetProfile.holdings.map (
( { allocationInPercentage , name } ) = > {
return {
allocationInPercentage ,
name ,
valueInBaseCurrency : valueInBaseCurrency
. mul ( allocationInPercentage )
. toNumber ( )
} ;
}
) ,
name : assetProfile.name ,
sectors : assetProfile.sectors ,
symbol : assetProfile . symbol ,
url : assetProfile.url
} ,
assetSubClass : assetProfile.assetSubClass ,
assetSubClass : assetProfile.assetSubClass ,
countries : assetProfile.countries ,
countries : assetProfile.countries ,
dataSource : assetProfile.dataSource ,
dataSource : assetProfile.dataSource ,
@ -758,7 +780,7 @@ export class PortfolioService {
const userCurrency = this . getUserCurrency ( user ) ;
const userCurrency = this . getUserCurrency ( user ) ;
const { activities } =
const { activities } =
await this . orderService . getOrder sForPortfolioCalculator( {
await this . activitiesService . getActivitie sForPortfolioCalculator( {
userCurrency ,
userCurrency ,
userId
userId
} ) ;
} ) ;
@ -988,7 +1010,7 @@ export class PortfolioService {
userId ,
userId ,
userCurrency
userCurrency
} ) ,
} ) ,
this . orderService . getOrder sForPortfolioCalculator( {
this . activitiesService . getActivitie sForPortfolioCalculator( {
filters ,
filters ,
userCurrency ,
userCurrency ,
userId
userId
@ -1007,7 +1029,8 @@ export class PortfolioService {
netPerformancePercentage : 0 ,
netPerformancePercentage : 0 ,
netPerformancePercentageWithCurrencyEffect : 0 ,
netPerformancePercentageWithCurrencyEffect : 0 ,
netPerformanceWithCurrencyEffect : 0 ,
netPerformanceWithCurrencyEffect : 0 ,
totalInvestment : 0
totalInvestment : 0 ,
totalInvestmentValueWithCurrencyEffect : 0
}
}
} ;
} ;
}
}
@ -1024,7 +1047,7 @@ export class PortfolioService {
const { errors , hasErrors , historicalData } =
const { errors , hasErrors , historicalData } =
await portfolioCalculator . getSnapshot ( ) ;
await portfolioCalculator . getSnapshot ( ) ;
const { endDate , startDate } = getIntervalFromDateRange ( dateRange ) ;
const { endDate , startDate } = getIntervalFromDateRange ( { dateRange } ) ;
const { chart } = await portfolioCalculator . getPerformance ( {
const { chart } = await portfolioCalculator . getPerformance ( {
end : endDate ,
end : endDate ,
@ -1038,6 +1061,7 @@ export class PortfolioService {
netPerformanceWithCurrencyEffect ,
netPerformanceWithCurrencyEffect ,
netWorth ,
netWorth ,
totalInvestment ,
totalInvestment ,
totalInvestmentValueWithCurrencyEffect ,
valueWithCurrencyEffect
valueWithCurrencyEffect
} = chart ? . at ( - 1 ) ? ? {
} = chart ? . at ( - 1 ) ? ? {
netPerformance : 0 ,
netPerformance : 0 ,
@ -1058,6 +1082,7 @@ export class PortfolioService {
netPerformance ,
netPerformance ,
netPerformanceWithCurrencyEffect ,
netPerformanceWithCurrencyEffect ,
totalInvestment ,
totalInvestment ,
totalInvestmentValueWithCurrencyEffect ,
currentNetWorth : netWorth ,
currentNetWorth : netWorth ,
currentValueInBaseCurrency : valueWithCurrencyEffect ,
currentValueInBaseCurrency : valueWithCurrencyEffect ,
netPerformancePercentage : netPerformanceInPercentage ,
netPerformancePercentage : netPerformanceInPercentage ,
@ -1306,11 +1331,11 @@ export class PortfolioService {
} ) ,
} ) ,
rules : await this . rulesService . evaluate (
rules : await this . rulesService . evaluate (
[
[
new FeeRatioInitialInvestment (
new FeeRatioTotalInvestmentVolume (
this . exchangeRateDataService ,
this . exchangeRateDataService ,
this . i18nService ,
this . i18nService ,
userSettings . language ,
userSettings . language ,
summary . committedFunds ,
summary . totalBuy + summary . totalSell ,
summary . fees
summary . fees
)
)
] ,
] ,
@ -1346,7 +1371,12 @@ export class PortfolioService {
} ) {
} ) {
userId = await this . getUserId ( impersonationId , userId ) ;
userId = await this . getUserId ( impersonationId , userId ) ;
await this . orderService . assignTags ( { dataSource , symbol , tags , userId } ) ;
await this . activitiesService . assignTags ( {
dataSource ,
symbol ,
tags ,
userId
} ) ;
}
}
private getAggregatedMarkets ( holdings : Record < string , PortfolioPosition > ) : {
private getAggregatedMarkets ( holdings : Record < string , PortfolioPosition > ) : {
@ -1669,6 +1699,17 @@ export class PortfolioService {
allocationInPercentage : 0 ,
allocationInPercentage : 0 ,
assetClass : AssetClass.LIQUIDITY ,
assetClass : AssetClass.LIQUIDITY ,
assetSubClass : AssetSubClass.CASH ,
assetSubClass : AssetSubClass.CASH ,
assetProfile : {
currency ,
assetClass : AssetClass.LIQUIDITY ,
assetSubClass : AssetSubClass.CASH ,
countries : [ ] ,
dataSource : undefined ,
holdings : [ ] ,
name : currency ,
sectors : [ ] ,
symbol : currency
} ,
countries : [ ] ,
countries : [ ] ,
dataSource : undefined ,
dataSource : undefined ,
dateOfFirstActivity : undefined ,
dateOfFirstActivity : undefined ,
@ -1838,7 +1879,7 @@ export class PortfolioService {
userId = await this . getUserId ( impersonationId , userId ) ;
userId = await this . getUserId ( impersonationId , userId ) ;
const user = await this . userService . user ( { id : userId } ) ;
const user = await this . userService . user ( { id : userId } ) ;
const { activities } = await this . orderService . getOrder s( {
const { activities } = await this . activitiesService . getActivitie s( {
userCurrency ,
userCurrency ,
userId ,
userId ,
withExcludedAccountsAndActivities : true
withExcludedAccountsAndActivities : true
@ -1860,8 +1901,11 @@ export class PortfolioService {
}
}
}
}
const { currentValueInBaseCurrency , totalInvestment } =
const {
await portfolioCalculator . getSnapshot ( ) ;
currentValueInBaseCurrency ,
totalInvestment ,
totalInvestmentWithCurrencyEffect
} = await portfolioCalculator . getSnapshot ( ) ;
const { performance } = await this . getPerformance ( {
const { performance } = await this . getPerformance ( {
impersonationId ,
impersonationId ,
@ -1908,8 +1952,6 @@ export class PortfolioService {
. plus ( emergencyFundHoldingsValueInBaseCurrency )
. plus ( emergencyFundHoldingsValueInBaseCurrency )
. toNumber ( ) ;
. toNumber ( ) ;
const committedFunds = new Big ( totalBuy ) . minus ( totalSell ) ;
const totalOfExcludedActivities = this . getSumOfActivityType ( {
const totalOfExcludedActivities = this . getSumOfActivityType ( {
userCurrency ,
userCurrency ,
activities : excludedActivities ,
activities : excludedActivities ,
@ -1973,7 +2015,6 @@ export class PortfolioService {
activityCount : activities.filter ( ( { type } ) = > {
activityCount : activities.filter ( ( { type } ) = > {
return [ 'BUY' , 'SELL' ] . includes ( type ) ;
return [ 'BUY' , 'SELL' ] . includes ( type ) ;
} ) . length ,
} ) . length ,
committedFunds : committedFunds.toNumber ( ) ,
currentValueInBaseCurrency : currentValueInBaseCurrency.toNumber ( ) ,
currentValueInBaseCurrency : currentValueInBaseCurrency.toNumber ( ) ,
dividendInBaseCurrency : dividendInBaseCurrency.toNumber ( ) ,
dividendInBaseCurrency : dividendInBaseCurrency.toNumber ( ) ,
emergencyFund : {
emergencyFund : {
@ -2004,6 +2045,8 @@ export class PortfolioService {
interestInBaseCurrency : interest.toNumber ( ) ,
interestInBaseCurrency : interest.toNumber ( ) ,
liabilitiesInBaseCurrency : liabilities.toNumber ( ) ,
liabilitiesInBaseCurrency : liabilities.toNumber ( ) ,
totalInvestment : totalInvestment.toNumber ( ) ,
totalInvestment : totalInvestment.toNumber ( ) ,
totalInvestmentValueWithCurrencyEffect :
totalInvestmentWithCurrencyEffect . toNumber ( ) ,
totalValueInBaseCurrency : netWorth
totalValueInBaseCurrency : netWorth
} ;
} ;
}
}