Feature/reuse markets calculation in public portfolio endpoint (#3882)
* Reuse markets calculation in public portfolio endpoint * Update changelog
This commit is contained in:
parent
8cbefbc1f4
commit
b50a1fc63d
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Optimized the portfolio calculations by reusing date intervals
|
- Optimized the portfolio calculations by reusing date intervals
|
||||||
|
- Refactored the calculation of the allocations by market on the public page
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ export class PublicController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [
|
const [
|
||||||
{ holdings },
|
{ holdings, markets },
|
||||||
{ performance: performance1d },
|
{ performance: performance1d },
|
||||||
{ performance: performanceMax },
|
{ performance: performanceMax },
|
||||||
{ performance: performanceYtd }
|
{ performance: performanceYtd }
|
||||||
@ -76,8 +76,13 @@ export class PublicController {
|
|||||||
})
|
})
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
Object.values(markets).forEach((market) => {
|
||||||
|
delete market.valueInBaseCurrency;
|
||||||
|
});
|
||||||
|
|
||||||
const publicPortfolioResponse: PublicPortfolioResponse = {
|
const publicPortfolioResponse: PublicPortfolioResponse = {
|
||||||
hasDetails,
|
hasDetails,
|
||||||
|
markets,
|
||||||
alias: access.alias,
|
alias: access.alias,
|
||||||
holdings: {},
|
holdings: {},
|
||||||
performance: {
|
performance: {
|
||||||
|
@ -32,7 +32,7 @@ export class PublicPageComponent implements OnInit {
|
|||||||
public deviceType: string;
|
public deviceType: string;
|
||||||
public holdings: PublicPortfolioResponse['holdings'][string][];
|
public holdings: PublicPortfolioResponse['holdings'][string][];
|
||||||
public markets: {
|
public markets: {
|
||||||
[key in Market]: { name: string; value: number };
|
[key in Market]: { id: Market; valueInPercentage: number };
|
||||||
};
|
};
|
||||||
public positions: {
|
public positions: {
|
||||||
[symbol: string]: Pick<PortfolioPosition, 'currency' | 'name'> & {
|
[symbol: string]: Pick<PortfolioPosition, 'currency' | 'name'> & {
|
||||||
@ -102,24 +102,7 @@ export class PublicPageComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.holdings = [];
|
this.holdings = [];
|
||||||
this.markets = {
|
this.markets = this.publicPortfolioDetails.markets;
|
||||||
[UNKNOWN_KEY]: {
|
|
||||||
name: UNKNOWN_KEY,
|
|
||||||
value: 0
|
|
||||||
},
|
|
||||||
developedMarkets: {
|
|
||||||
name: 'developedMarkets',
|
|
||||||
value: 0
|
|
||||||
},
|
|
||||||
emergingMarkets: {
|
|
||||||
name: 'emergingMarkets',
|
|
||||||
value: 0
|
|
||||||
},
|
|
||||||
otherMarkets: {
|
|
||||||
name: 'otherMarkets',
|
|
||||||
value: 0
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.positions = {};
|
this.positions = {};
|
||||||
this.sectors = {
|
this.sectors = {
|
||||||
[UNKNOWN_KEY]: {
|
[UNKNOWN_KEY]: {
|
||||||
@ -150,13 +133,6 @@ export class PublicPageComponent implements OnInit {
|
|||||||
// Prepare analysis data by continents, countries, holdings and sectors except for liquidity
|
// Prepare analysis data by continents, countries, holdings and sectors except for liquidity
|
||||||
|
|
||||||
if (position.countries.length > 0) {
|
if (position.countries.length > 0) {
|
||||||
this.markets.developedMarkets.value +=
|
|
||||||
position.markets.developedMarkets * position.valueInBaseCurrency;
|
|
||||||
this.markets.emergingMarkets.value +=
|
|
||||||
position.markets.emergingMarkets * position.valueInBaseCurrency;
|
|
||||||
this.markets.otherMarkets.value +=
|
|
||||||
position.markets.otherMarkets * position.valueInBaseCurrency;
|
|
||||||
|
|
||||||
for (const country of position.countries) {
|
for (const country of position.countries) {
|
||||||
const { code, continent, name, weight } = country;
|
const { code, continent, name, weight } = country;
|
||||||
|
|
||||||
@ -192,9 +168,6 @@ export class PublicPageComponent implements OnInit {
|
|||||||
|
|
||||||
this.countries[UNKNOWN_KEY].value +=
|
this.countries[UNKNOWN_KEY].value +=
|
||||||
this.publicPortfolioDetails.holdings[symbol].valueInBaseCurrency;
|
this.publicPortfolioDetails.holdings[symbol].valueInBaseCurrency;
|
||||||
|
|
||||||
this.markets[UNKNOWN_KEY].value +=
|
|
||||||
this.publicPortfolioDetails.holdings[symbol].valueInBaseCurrency;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position.sectors.length > 0) {
|
if (position.sectors.length > 0) {
|
||||||
@ -227,21 +200,6 @@ export class PublicPageComponent implements OnInit {
|
|||||||
: position.valueInPercentage
|
: position.valueInPercentage
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const marketsTotal =
|
|
||||||
this.markets.developedMarkets.value +
|
|
||||||
this.markets.emergingMarkets.value +
|
|
||||||
this.markets.otherMarkets.value +
|
|
||||||
this.markets[UNKNOWN_KEY].value;
|
|
||||||
|
|
||||||
this.markets.developedMarkets.value =
|
|
||||||
this.markets.developedMarkets.value / marketsTotal;
|
|
||||||
this.markets.emergingMarkets.value =
|
|
||||||
this.markets.emergingMarkets.value / marketsTotal;
|
|
||||||
this.markets.otherMarkets.value =
|
|
||||||
this.markets.otherMarkets.value / marketsTotal;
|
|
||||||
this.markets[UNKNOWN_KEY].value =
|
|
||||||
this.markets[UNKNOWN_KEY].value / marketsTotal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnDestroy() {
|
public ngOnDestroy() {
|
||||||
|
@ -156,7 +156,7 @@
|
|||||||
i18n
|
i18n
|
||||||
size="large"
|
size="large"
|
||||||
[isPercent]="true"
|
[isPercent]="true"
|
||||||
[value]="markets?.developedMarkets?.value"
|
[value]="markets?.developedMarkets?.valueInPercentage"
|
||||||
>Developed Markets</gf-value
|
>Developed Markets</gf-value
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@ -165,7 +165,7 @@
|
|||||||
i18n
|
i18n
|
||||||
size="large"
|
size="large"
|
||||||
[isPercent]="true"
|
[isPercent]="true"
|
||||||
[value]="markets?.emergingMarkets?.value"
|
[value]="markets?.emergingMarkets?.valueInPercentage"
|
||||||
>Emerging Markets</gf-value
|
>Emerging Markets</gf-value
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@ -174,17 +174,17 @@
|
|||||||
i18n
|
i18n
|
||||||
size="large"
|
size="large"
|
||||||
[isPercent]="true"
|
[isPercent]="true"
|
||||||
[value]="markets?.otherMarkets?.value"
|
[value]="markets?.otherMarkets?.valueInPercentage"
|
||||||
>Other Markets</gf-value
|
>Other Markets</gf-value
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@if (markets?.[UNKNOWN_KEY]?.value > 0) {
|
@if (markets?.[UNKNOWN_KEY]?.valueInPercentage > 0) {
|
||||||
<div class="col-xs-12 col-md my-2">
|
<div class="col-xs-12 col-md my-2">
|
||||||
<gf-value
|
<gf-value
|
||||||
i18n
|
i18n
|
||||||
size="large"
|
size="large"
|
||||||
[isPercent]="true"
|
[isPercent]="true"
|
||||||
[value]="markets?.[UNKNOWN_KEY]?.value"
|
[value]="markets?.[UNKNOWN_KEY]?.valueInPercentage"
|
||||||
>No data available</gf-value
|
>No data available</gf-value
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { PortfolioPosition } from '../portfolio-position.interface';
|
import { PortfolioDetails, PortfolioPosition } from '..';
|
||||||
|
import { Market } from '../../types';
|
||||||
|
|
||||||
export interface PublicPortfolioResponse extends PublicPortfolioResponseV1 {
|
export interface PublicPortfolioResponse extends PublicPortfolioResponseV1 {
|
||||||
alias?: string;
|
alias?: string;
|
||||||
@ -22,6 +23,12 @@ export interface PublicPortfolioResponse extends PublicPortfolioResponseV1 {
|
|||||||
| 'valueInPercentage'
|
| 'valueInPercentage'
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
markets: {
|
||||||
|
[key in Market]: Pick<
|
||||||
|
PortfolioDetails['markets'][key],
|
||||||
|
'id' | 'valueInPercentage'
|
||||||
|
>;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PublicPortfolioResponseV1 {
|
interface PublicPortfolioResponseV1 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user