|
|
@ -249,6 +249,10 @@ export class PortfolioService { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const quantityOfHolding = filterBySymbol |
|
|
|
|
|
? (details.accounts[account.id]?.quantity ?? 0) |
|
|
|
|
|
: undefined; |
|
|
|
|
|
|
|
|
const valueInBaseCurrency = |
|
|
const valueInBaseCurrency = |
|
|
details.accounts[account.id]?.valueInBaseCurrency ?? 0; |
|
|
details.accounts[account.id]?.valueInBaseCurrency ?? 0; |
|
|
|
|
|
|
|
|
@ -264,6 +268,7 @@ export class PortfolioService { |
|
|
account.currency, |
|
|
account.currency, |
|
|
userCurrency |
|
|
userCurrency |
|
|
), |
|
|
), |
|
|
|
|
|
quantity: quantityOfHolding, |
|
|
value: this.exchangeRateDataService.toCurrency( |
|
|
value: this.exchangeRateDataService.toCurrency( |
|
|
valueInBaseCurrency, |
|
|
valueInBaseCurrency, |
|
|
userCurrency, |
|
|
userCurrency, |
|
|
@ -2194,6 +2199,10 @@ export class PortfolioService { |
|
|
const accounts: PortfolioDetails['accounts'] = {}; |
|
|
const accounts: PortfolioDetails['accounts'] = {}; |
|
|
const platforms: PortfolioDetails['platforms'] = {}; |
|
|
const platforms: PortfolioDetails['platforms'] = {}; |
|
|
|
|
|
|
|
|
|
|
|
const { SYMBOL: [filterBySymbol] = [] } = groupBy(filters, ({ type }) => { |
|
|
|
|
|
return type; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
let currentAccounts: (AccountWithBalance & { |
|
|
let currentAccounts: (AccountWithBalance & { |
|
|
Order?: Order[]; |
|
|
Order?: Order[]; |
|
|
platform?: Platform; |
|
|
platform?: Platform; |
|
|
@ -2205,7 +2214,7 @@ export class PortfolioService { |
|
|
} else if (filters.length === 1 && filters[0].type === 'ACCOUNT') { |
|
|
} else if (filters.length === 1 && filters[0].type === 'ACCOUNT') { |
|
|
currentAccounts = await this.accountService.accounts({ |
|
|
currentAccounts = await this.accountService.accounts({ |
|
|
include: { platform: true, tags: true }, |
|
|
include: { platform: true, tags: true }, |
|
|
where: { id: filters[0].id } |
|
|
where: { userId, id: filters[0].id } |
|
|
}); |
|
|
}); |
|
|
} else { |
|
|
} else { |
|
|
const accountIds = Array.from( |
|
|
const accountIds = Array.from( |
|
|
@ -2233,39 +2242,43 @@ export class PortfolioService { |
|
|
// Iterate over the accounts plus a null entry to group activities without
|
|
|
// Iterate over the accounts plus a null entry to group activities without
|
|
|
// an account into the unknown bucket
|
|
|
// an account into the unknown bucket
|
|
|
for (const account of [...currentAccounts, null]) { |
|
|
for (const account of [...currentAccounts, null]) { |
|
|
|
|
|
const currentAccountId = account?.id || UNKNOWN_KEY; |
|
|
|
|
|
const currentPlatformId = account?.platformId || UNKNOWN_KEY; |
|
|
|
|
|
|
|
|
const ordersByAccount = activities.filter(({ accountId }) => { |
|
|
const ordersByAccount = activities.filter(({ accountId }) => { |
|
|
return account ? accountId === account.id : !accountId; |
|
|
return account ? accountId === account.id : !accountId; |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
if (account) { |
|
|
if (account) { |
|
|
accounts[account.id] = { |
|
|
// The cash balance is not part of a holding and would distort the value
|
|
|
|
|
|
// and thus the allocation per account and platform
|
|
|
|
|
|
const balanceInBaseCurrency = filterBySymbol |
|
|
|
|
|
? 0 |
|
|
|
|
|
: this.exchangeRateDataService.toCurrency( |
|
|
|
|
|
account.balance, |
|
|
|
|
|
account.currency, |
|
|
|
|
|
userCurrency |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
accounts[currentAccountId] = { |
|
|
balance: account.balance, |
|
|
balance: account.balance, |
|
|
currency: account.currency, |
|
|
currency: account.currency, |
|
|
name: account.name, |
|
|
name: account.name, |
|
|
valueInBaseCurrency: this.exchangeRateDataService.toCurrency( |
|
|
valueInBaseCurrency: balanceInBaseCurrency |
|
|
account.balance, |
|
|
|
|
|
account.currency, |
|
|
|
|
|
userCurrency |
|
|
|
|
|
) |
|
|
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
if (platforms[account.platformId || UNKNOWN_KEY]?.valueInBaseCurrency) { |
|
|
if (platforms[currentPlatformId]) { |
|
|
platforms[account.platformId || UNKNOWN_KEY].valueInBaseCurrency += |
|
|
platforms[currentPlatformId].valueInBaseCurrency = new Big( |
|
|
this.exchangeRateDataService.toCurrency( |
|
|
platforms[currentPlatformId].valueInBaseCurrency |
|
|
account.balance, |
|
|
) |
|
|
account.currency, |
|
|
.plus(balanceInBaseCurrency) |
|
|
userCurrency |
|
|
.toNumber(); |
|
|
); |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
platforms[account.platformId || UNKNOWN_KEY] = { |
|
|
platforms[currentPlatformId] = { |
|
|
balance: account.balance, |
|
|
balance: account.balance, |
|
|
currency: account.currency, |
|
|
currency: account.currency, |
|
|
name: account.platform?.name, |
|
|
name: account.platform?.name, |
|
|
valueInBaseCurrency: this.exchangeRateDataService.toCurrency( |
|
|
valueInBaseCurrency: balanceInBaseCurrency |
|
|
account.balance, |
|
|
|
|
|
account.currency, |
|
|
|
|
|
userCurrency |
|
|
|
|
|
) |
|
|
|
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -2274,23 +2287,30 @@ export class PortfolioService { |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let quantityOfAccount = new Big(0); |
|
|
let valueOfAccountInBaseCurrency = new Big(0); |
|
|
let valueOfAccountInBaseCurrency = new Big(0); |
|
|
|
|
|
|
|
|
for (const { assetProfile, quantity, type } of ordersByAccount) { |
|
|
for (const { assetProfile, quantity, type } of ordersByAccount) { |
|
|
|
|
|
const currentQuantityOfSymbol = new Big(quantity).mul(getFactor(type)); |
|
|
|
|
|
|
|
|
|
|
|
quantityOfAccount = quantityOfAccount.plus(currentQuantityOfSymbol); |
|
|
|
|
|
|
|
|
valueOfAccountInBaseCurrency = valueOfAccountInBaseCurrency.plus( |
|
|
valueOfAccountInBaseCurrency = valueOfAccountInBaseCurrency.plus( |
|
|
new Big(quantity) |
|
|
currentQuantityOfSymbol.mul( |
|
|
.mul(getFactor(type)) |
|
|
portfolioItemsNow[assetProfile.symbol]?.marketPriceInBaseCurrency ?? |
|
|
.mul( |
|
|
0 |
|
|
portfolioItemsNow[assetProfile.symbol] |
|
|
) |
|
|
?.marketPriceInBaseCurrency ?? 0 |
|
|
|
|
|
) |
|
|
|
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const currentAccountId = account?.id || UNKNOWN_KEY; |
|
|
// The quantity is only meaningful if the activities are filtered by a
|
|
|
const currentPlatformId = account?.platformId || UNKNOWN_KEY; |
|
|
// single holding
|
|
|
|
|
|
const quantityOfHolding = filterBySymbol |
|
|
|
|
|
? quantityOfAccount.toNumber() |
|
|
|
|
|
: undefined; |
|
|
|
|
|
|
|
|
if (accounts[currentAccountId]) { |
|
|
if (accounts[currentAccountId]) { |
|
|
|
|
|
accounts[currentAccountId].quantity = quantityOfHolding; |
|
|
accounts[currentAccountId].valueInBaseCurrency = new Big( |
|
|
accounts[currentAccountId].valueInBaseCurrency = new Big( |
|
|
accounts[currentAccountId].valueInBaseCurrency |
|
|
accounts[currentAccountId].valueInBaseCurrency |
|
|
) |
|
|
) |
|
|
@ -2301,6 +2321,7 @@ export class PortfolioService { |
|
|
balance: 0, |
|
|
balance: 0, |
|
|
currency: account?.currency, |
|
|
currency: account?.currency, |
|
|
name: account?.name, |
|
|
name: account?.name, |
|
|
|
|
|
quantity: quantityOfHolding, |
|
|
valueInBaseCurrency: valueOfAccountInBaseCurrency.toNumber() |
|
|
valueInBaseCurrency: valueOfAccountInBaseCurrency.toNumber() |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|