|
|
@ -602,14 +602,7 @@ export class PortfolioService { |
|
|
|
userId |
|
|
|
}); |
|
|
|
|
|
|
|
const orders = activities.filter(({ SymbolProfile }) => { |
|
|
|
return ( |
|
|
|
SymbolProfile.dataSource === aDataSource && |
|
|
|
SymbolProfile.symbol === aSymbol |
|
|
|
); |
|
|
|
}); |
|
|
|
|
|
|
|
if (orders.length <= 0) { |
|
|
|
if (activities.length === 0) { |
|
|
|
return { |
|
|
|
accounts: [], |
|
|
|
averagePrice: undefined, |
|
|
@ -646,10 +639,8 @@ export class PortfolioService { |
|
|
|
]); |
|
|
|
|
|
|
|
const portfolioCalculator = this.calculatorFactory.createCalculator({ |
|
|
|
activities, |
|
|
|
userId, |
|
|
|
activities: orders.filter((order) => { |
|
|
|
return ['BUY', 'DIVIDEND', 'ITEM', 'SELL'].includes(order.type); |
|
|
|
}), |
|
|
|
calculationType: PerformanceCalculationType.TWR, |
|
|
|
currency: userCurrency |
|
|
|
}); |
|
|
@ -659,8 +650,8 @@ export class PortfolioService { |
|
|
|
|
|
|
|
const { positions } = await portfolioCalculator.getSnapshot(); |
|
|
|
|
|
|
|
const position = positions.find(({ symbol }) => { |
|
|
|
return symbol === aSymbol; |
|
|
|
const position = positions.find(({ dataSource, symbol }) => { |
|
|
|
return dataSource === aDataSource && symbol === aSymbol; |
|
|
|
}); |
|
|
|
|
|
|
|
if (position) { |
|
|
@ -673,14 +664,22 @@ export class PortfolioService { |
|
|
|
firstBuyDate, |
|
|
|
marketPrice, |
|
|
|
quantity, |
|
|
|
symbol, |
|
|
|
tags, |
|
|
|
timeWeightedInvestment, |
|
|
|
timeWeightedInvestmentWithCurrencyEffect, |
|
|
|
transactionCount |
|
|
|
} = position; |
|
|
|
|
|
|
|
const activitiesOfPosition = activities.filter(({ SymbolProfile }) => { |
|
|
|
return ( |
|
|
|
SymbolProfile.dataSource === dataSource && |
|
|
|
SymbolProfile.symbol === symbol |
|
|
|
); |
|
|
|
}); |
|
|
|
|
|
|
|
const accounts: PortfolioHoldingDetail['accounts'] = uniqBy( |
|
|
|
orders.filter(({ Account }) => { |
|
|
|
activitiesOfPosition.filter(({ Account }) => { |
|
|
|
return Account; |
|
|
|
}), |
|
|
|
'Account.id' |
|
|
@ -715,8 +714,8 @@ export class PortfolioService { |
|
|
|
); |
|
|
|
|
|
|
|
const historicalDataArray: HistoricalDataItem[] = []; |
|
|
|
let maxPrice = Math.max(orders[0].unitPrice, marketPrice); |
|
|
|
let minPrice = Math.min(orders[0].unitPrice, marketPrice); |
|
|
|
let maxPrice = Math.max(activitiesOfPosition[0].unitPrice, marketPrice); |
|
|
|
let minPrice = Math.min(activitiesOfPosition[0].unitPrice, marketPrice); |
|
|
|
|
|
|
|
if (historicalData[aSymbol]) { |
|
|
|
let j = -1; |
|
|
@ -760,10 +759,10 @@ export class PortfolioService { |
|
|
|
} else { |
|
|
|
// Add historical entry for buy date, if no historical data available
|
|
|
|
historicalDataArray.push({ |
|
|
|
averagePrice: orders[0].unitPrice, |
|
|
|
averagePrice: activitiesOfPosition[0].unitPrice, |
|
|
|
date: firstBuyDate, |
|
|
|
marketPrice: orders[0].unitPrice, |
|
|
|
quantity: orders[0].quantity |
|
|
|
marketPrice: activitiesOfPosition[0].unitPrice, |
|
|
|
quantity: activitiesOfPosition[0].quantity |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
@ -773,7 +772,6 @@ export class PortfolioService { |
|
|
|
marketPrice, |
|
|
|
maxPrice, |
|
|
|
minPrice, |
|
|
|
orders, |
|
|
|
SymbolProfile, |
|
|
|
tags, |
|
|
|
transactionCount, |
|
|
@ -805,6 +803,7 @@ export class PortfolioService { |
|
|
|
]?.toNumber(), |
|
|
|
netPerformanceWithCurrencyEffect: |
|
|
|
position.netPerformanceWithCurrencyEffectMap?.['max']?.toNumber(), |
|
|
|
orders: activitiesOfPosition, |
|
|
|
quantity: quantity.toNumber(), |
|
|
|
value: this.exchangeRateDataService.toCurrency( |
|
|
|
quantity.mul(marketPrice ?? 0).toNumber(), |
|
|
@ -862,7 +861,6 @@ export class PortfolioService { |
|
|
|
marketPrice, |
|
|
|
maxPrice, |
|
|
|
minPrice, |
|
|
|
orders, |
|
|
|
SymbolProfile, |
|
|
|
accounts: [], |
|
|
|
averagePrice: 0, |
|
|
@ -882,6 +880,7 @@ export class PortfolioService { |
|
|
|
netPerformancePercent: undefined, |
|
|
|
netPerformancePercentWithCurrencyEffect: undefined, |
|
|
|
netPerformanceWithCurrencyEffect: undefined, |
|
|
|
orders: [], |
|
|
|
quantity: 0, |
|
|
|
tags: [], |
|
|
|
transactionCount: undefined, |
|
|
@ -912,7 +911,7 @@ export class PortfolioService { |
|
|
|
userCurrency: this.getUserCurrency() |
|
|
|
}); |
|
|
|
|
|
|
|
if (activities?.length <= 0) { |
|
|
|
if (activities.length === 0) { |
|
|
|
return { |
|
|
|
hasErrors: false, |
|
|
|
positions: [] |
|
|
@ -1037,14 +1036,12 @@ export class PortfolioService { |
|
|
|
dateRange = 'max', |
|
|
|
filters, |
|
|
|
impersonationId, |
|
|
|
portfolioCalculator, |
|
|
|
userId, |
|
|
|
withExcludedAccounts = false |
|
|
|
}: { |
|
|
|
dateRange?: DateRange; |
|
|
|
filters?: Filter[]; |
|
|
|
impersonationId: string; |
|
|
|
portfolioCalculator?: PortfolioCalculator; |
|
|
|
userId: string; |
|
|
|
withExcludedAccounts?: boolean; |
|
|
|
}): Promise<PortfolioPerformanceResponse> { |
|
|
@ -1089,7 +1086,7 @@ export class PortfolioService { |
|
|
|
userId |
|
|
|
}); |
|
|
|
|
|
|
|
if (accountBalanceItems?.length <= 0 && activities?.length <= 0) { |
|
|
|
if (accountBalanceItems.length === 0 && activities.length === 0) { |
|
|
|
return { |
|
|
|
chart: [], |
|
|
|
firstOrderDate: undefined, |
|
|
@ -1106,16 +1103,14 @@ export class PortfolioService { |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
portfolioCalculator = |
|
|
|
portfolioCalculator ?? |
|
|
|
this.calculatorFactory.createCalculator({ |
|
|
|
accountBalanceItems, |
|
|
|
activities, |
|
|
|
filters, |
|
|
|
userId, |
|
|
|
calculationType: PerformanceCalculationType.TWR, |
|
|
|
currency: userCurrency |
|
|
|
}); |
|
|
|
const portfolioCalculator = this.calculatorFactory.createCalculator({ |
|
|
|
accountBalanceItems, |
|
|
|
activities, |
|
|
|
filters, |
|
|
|
userId, |
|
|
|
calculationType: PerformanceCalculationType.TWR, |
|
|
|
currency: userCurrency |
|
|
|
}); |
|
|
|
|
|
|
|
const { errors, hasErrors, historicalData } = |
|
|
|
await portfolioCalculator.getSnapshot(); |
|
|
|