|
|
@ -201,6 +201,26 @@ export class GfAllocationsPageComponent implements OnInit { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private extractCurrency({ |
|
|
|
|
|
assetClass, |
|
|
|
|
|
assetSubClass, |
|
|
|
|
|
currency |
|
|
|
|
|
}: { |
|
|
|
|
|
assetClass: PortfolioPosition['assetProfile']['assetClass']; |
|
|
|
|
|
assetSubClass: PortfolioPosition['assetProfile']['assetSubClass']; |
|
|
|
|
|
currency?: PortfolioPosition['assetProfile']['currency']; |
|
|
|
|
|
}) { |
|
|
|
|
|
if ( |
|
|
|
|
|
assetClass === AssetClass.COMMODITY || |
|
|
|
|
|
assetSubClass === AssetSubClass.CRYPTOCURRENCY |
|
|
|
|
|
) { |
|
|
|
|
|
// Commodities and cryptocurrencies have no meaningful currency exposure
|
|
|
|
|
|
return UNKNOWN_KEY; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return currency; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private extractEtfProvider({ |
|
|
private extractEtfProvider({ |
|
|
assetSubClass, |
|
|
assetSubClass, |
|
|
name |
|
|
name |
|
|
@ -339,7 +359,7 @@ export class GfAllocationsPageComponent implements OnInit { |
|
|
position.assetProfile.assetSubClass || (UNKNOWN_KEY as AssetSubClass), |
|
|
position.assetProfile.assetSubClass || (UNKNOWN_KEY as AssetSubClass), |
|
|
assetSubClassLabel: |
|
|
assetSubClassLabel: |
|
|
position.assetProfile.assetSubClassLabel || UNKNOWN_KEY, |
|
|
position.assetProfile.assetSubClassLabel || UNKNOWN_KEY, |
|
|
currency: position.assetProfile.currency, |
|
|
currency: this.extractCurrency(position.assetProfile), |
|
|
etfProvider: this.extractEtfProvider({ |
|
|
etfProvider: this.extractEtfProvider({ |
|
|
assetSubClass: position.assetProfile.assetSubClass, |
|
|
assetSubClass: position.assetProfile.assetSubClass, |
|
|
name: position.assetProfile.name |
|
|
name: position.assetProfile.name |
|
|
@ -348,119 +368,117 @@ export class GfAllocationsPageComponent implements OnInit { |
|
|
name: position.assetProfile.name |
|
|
name: position.assetProfile.name |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
if (position.assetProfile.assetClass !== AssetClass.LIQUIDITY) { |
|
|
// Prepare analysis data by continents, countries, holdings and sectors
|
|
|
// Prepare analysis data by continents, countries, holdings and sectors except for liquidity
|
|
|
|
|
|
|
|
|
if (position.assetProfile.countries.length > 0) { |
|
|
if (position.assetProfile.countries.length > 0) { |
|
|
for (const country of position.assetProfile.countries) { |
|
|
for (const country of position.assetProfile.countries) { |
|
|
const { code, continent, weight } = country; |
|
|
const { code, continent, weight } = country; |
|
|
|
|
|
|
|
|
if (this.continents[continent]?.value) { |
|
|
if (this.continents[continent]?.value) { |
|
|
this.continents[continent].value += |
|
|
this.continents[continent].value += |
|
|
weight * |
|
|
|
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
|
|
|
? position.valueInBaseCurrency |
|
|
|
|
|
: position.valueInPercentage); |
|
|
|
|
|
} else { |
|
|
|
|
|
this.continents[continent] = { |
|
|
|
|
|
name: translate(continent), |
|
|
|
|
|
value: |
|
|
weight * |
|
|
weight * |
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
? position.valueInBaseCurrency |
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
: position.valueInPercentage); |
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage) |
|
|
} else { |
|
|
}; |
|
|
this.continents[continent] = { |
|
|
} |
|
|
name: translate(continent), |
|
|
|
|
|
value: |
|
|
if (this.countries[code]?.value) { |
|
|
weight * |
|
|
this.countries[code].value += |
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
weight * |
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage) |
|
|
? position.valueInBaseCurrency |
|
|
}; |
|
|
: position.valueInPercentage); |
|
|
} |
|
|
} else { |
|
|
|
|
|
this.countries[code] = { |
|
|
if (this.countries[code]?.value) { |
|
|
name: getCountryName({ |
|
|
this.countries[code].value += |
|
|
code, |
|
|
|
|
|
locale: this.user?.settings?.locale |
|
|
|
|
|
}), |
|
|
|
|
|
value: |
|
|
weight * |
|
|
weight * |
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
? position.valueInBaseCurrency |
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
: position.valueInPercentage); |
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage) |
|
|
} else { |
|
|
}; |
|
|
this.countries[code] = { |
|
|
|
|
|
name: getCountryName({ |
|
|
|
|
|
code, |
|
|
|
|
|
locale: this.user?.settings?.locale |
|
|
|
|
|
}), |
|
|
|
|
|
value: |
|
|
|
|
|
weight * |
|
|
|
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
|
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
|
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage) |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} else { |
|
|
|
|
|
this.continents[UNKNOWN_KEY].value += isNumber( |
|
|
|
|
|
position.valueInBaseCurrency |
|
|
|
|
|
) |
|
|
|
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
|
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage; |
|
|
|
|
|
|
|
|
|
|
|
this.countries[UNKNOWN_KEY].value += isNumber( |
|
|
|
|
|
position.valueInBaseCurrency |
|
|
|
|
|
) |
|
|
|
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
|
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
this.continents[UNKNOWN_KEY].value += isNumber( |
|
|
|
|
|
position.valueInBaseCurrency |
|
|
|
|
|
) |
|
|
|
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
|
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage; |
|
|
|
|
|
|
|
|
|
|
|
this.countries[UNKNOWN_KEY].value += isNumber( |
|
|
|
|
|
position.valueInBaseCurrency |
|
|
|
|
|
) |
|
|
|
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
|
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (position.assetProfile.holdings.length > 0) { |
|
|
if (position.assetProfile.holdings.length > 0) { |
|
|
for (const { |
|
|
for (const { |
|
|
allocationInPercentage, |
|
|
allocationInPercentage, |
|
|
name, |
|
|
name, |
|
|
valueInBaseCurrency |
|
|
valueInBaseCurrency |
|
|
} of position.assetProfile.holdings) { |
|
|
} of position.assetProfile.holdings) { |
|
|
const normalizedAssetName = this.normalizeAssetName(name); |
|
|
const normalizedAssetName = this.normalizeAssetName(name); |
|
|
|
|
|
|
|
|
if (this.topHoldingsMap[normalizedAssetName]?.value) { |
|
|
if (this.topHoldingsMap[normalizedAssetName]?.value) { |
|
|
this.topHoldingsMap[normalizedAssetName].value += isNumber( |
|
|
this.topHoldingsMap[normalizedAssetName].value += isNumber( |
|
|
valueInBaseCurrency |
|
|
valueInBaseCurrency |
|
|
) |
|
|
) |
|
|
|
|
|
? valueInBaseCurrency |
|
|
|
|
|
: allocationInPercentage * |
|
|
|
|
|
this.portfolioDetails.holdings[symbol].valueInPercentage; |
|
|
|
|
|
} else { |
|
|
|
|
|
this.topHoldingsMap[normalizedAssetName] = { |
|
|
|
|
|
name, |
|
|
|
|
|
value: isNumber(valueInBaseCurrency) |
|
|
? valueInBaseCurrency |
|
|
? valueInBaseCurrency |
|
|
: allocationInPercentage * |
|
|
: allocationInPercentage * |
|
|
this.portfolioDetails.holdings[symbol].valueInPercentage; |
|
|
this.portfolioDetails.holdings[symbol].valueInPercentage |
|
|
} else { |
|
|
}; |
|
|
this.topHoldingsMap[normalizedAssetName] = { |
|
|
|
|
|
name, |
|
|
|
|
|
value: isNumber(valueInBaseCurrency) |
|
|
|
|
|
? valueInBaseCurrency |
|
|
|
|
|
: allocationInPercentage * |
|
|
|
|
|
this.portfolioDetails.holdings[symbol].valueInPercentage |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (position.assetProfile.sectors.length > 0) { |
|
|
if (position.assetProfile.sectors.length > 0) { |
|
|
for (const sector of position.assetProfile.sectors) { |
|
|
for (const sector of position.assetProfile.sectors) { |
|
|
const { name, weight } = sector; |
|
|
const { name, weight } = sector; |
|
|
|
|
|
|
|
|
if (this.sectors[name]?.value) { |
|
|
if (this.sectors[name]?.value) { |
|
|
this.sectors[name].value += |
|
|
this.sectors[name].value += |
|
|
|
|
|
weight * |
|
|
|
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
|
|
|
? position.valueInBaseCurrency |
|
|
|
|
|
: position.valueInPercentage); |
|
|
|
|
|
} else { |
|
|
|
|
|
this.sectors[name] = { |
|
|
|
|
|
name: translate(name), |
|
|
|
|
|
value: |
|
|
weight * |
|
|
weight * |
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
? position.valueInBaseCurrency |
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
: position.valueInPercentage); |
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage) |
|
|
} else { |
|
|
}; |
|
|
this.sectors[name] = { |
|
|
|
|
|
name: translate(name), |
|
|
|
|
|
value: |
|
|
|
|
|
weight * |
|
|
|
|
|
(isNumber(position.valueInBaseCurrency) |
|
|
|
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
|
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage) |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} else { |
|
|
|
|
|
this.sectors[UNKNOWN_KEY].value += isNumber( |
|
|
|
|
|
position.valueInBaseCurrency |
|
|
|
|
|
) |
|
|
|
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
|
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
this.sectors[UNKNOWN_KEY].value += isNumber( |
|
|
|
|
|
position.valueInBaseCurrency |
|
|
|
|
|
) |
|
|
|
|
|
? this.portfolioDetails.holdings[symbol].valueInBaseCurrency |
|
|
|
|
|
: this.portfolioDetails.holdings[symbol].valueInPercentage; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (this.holdings[symbol].assetSubClass === 'ETF') { |
|
|
if (this.holdings[symbol].assetSubClass === 'ETF') { |
|
|
|