Feature/integrate wealth items into transaction point concept (#3084)
* Integrate (wealth) items into transaction point concept * Update changelog
This commit is contained in:
parent
66992ef915
commit
5596e5f03b
@ -10,10 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Improved the usability of the benchmarks in the markets overview
|
- Improved the usability of the benchmarks in the markets overview
|
||||||
|
- Integrated (wealth) items into the transaction point concept in the portfolio service
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed a missing value in the activities table on mobile
|
- Fixed a missing value in the activities table on mobile
|
||||||
|
- Fixed a missing value on the public page
|
||||||
- Displayed the button to fetch the current market price only if the activity is from today
|
- Displayed the button to fetch the current market price only if the activity is from today
|
||||||
|
|
||||||
## 2.59.0 - 2024-02-29
|
## 2.59.0 - 2024-02-29
|
||||||
|
@ -43,7 +43,7 @@ export class ImportController {
|
|||||||
@UseInterceptors(TransformDataSourceInResponseInterceptor)
|
@UseInterceptors(TransformDataSourceInResponseInterceptor)
|
||||||
public async import(
|
public async import(
|
||||||
@Body() importData: ImportDataDto,
|
@Body() importData: ImportDataDto,
|
||||||
@Query('dryRun') isDryRun?: boolean
|
@Query('dryRun') isDryRun = false
|
||||||
): Promise<ImportResponse> {
|
): Promise<ImportResponse> {
|
||||||
if (
|
if (
|
||||||
!hasPermission(this.request.user.permissions, permissions.createAccount)
|
!hasPermission(this.request.user.permissions, permissions.createAccount)
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
GATHER_ASSET_PROFILE_PROCESS_OPTIONS
|
GATHER_ASSET_PROFILE_PROCESS_OPTIONS
|
||||||
} from '@ghostfolio/common/config';
|
} from '@ghostfolio/common/config';
|
||||||
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
|
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
|
||||||
import { Filter } from '@ghostfolio/common/interfaces';
|
import { Filter, UniqueAsset } from '@ghostfolio/common/interfaces';
|
||||||
import { OrderWithAccount } from '@ghostfolio/common/types';
|
import { OrderWithAccount } from '@ghostfolio/common/types';
|
||||||
|
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
@ -200,6 +200,17 @@ export class OrderService {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getLatestOrder({ dataSource, symbol }: UniqueAsset) {
|
||||||
|
return this.prismaService.order.findFirst({
|
||||||
|
orderBy: {
|
||||||
|
date: 'desc'
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
SymbolProfile: { dataSource, symbol }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public async getOrders({
|
public async getOrders({
|
||||||
filters,
|
filters,
|
||||||
includeDrafts = false,
|
includeDrafts = false,
|
||||||
|
@ -108,6 +108,7 @@ describe('CurrentRateService', () => {
|
|||||||
currentRateService = new CurrentRateService(
|
currentRateService = new CurrentRateService(
|
||||||
dataProviderService,
|
dataProviderService,
|
||||||
marketDataService,
|
marketDataService,
|
||||||
|
null,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { OrderService } from '@ghostfolio/api/app/order/order.service';
|
||||||
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
|
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
|
||||||
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
|
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
|
||||||
import { resetHours } from '@ghostfolio/common/helper';
|
import { resetHours } from '@ghostfolio/common/helper';
|
||||||
@ -22,6 +23,7 @@ export class CurrentRateService {
|
|||||||
public constructor(
|
public constructor(
|
||||||
private readonly dataProviderService: DataProviderService,
|
private readonly dataProviderService: DataProviderService,
|
||||||
private readonly marketDataService: MarketDataService,
|
private readonly marketDataService: MarketDataService,
|
||||||
|
private readonly orderService: OrderService,
|
||||||
@Inject(REQUEST) private readonly request: RequestWithUser
|
@Inject(REQUEST) private readonly request: RequestWithUser
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -121,11 +123,17 @@ export class CurrentRateService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
// Fallback to unit price of latest activity
|
||||||
|
const latestActivity = await this.orderService.getLatestOrder({
|
||||||
|
dataSource,
|
||||||
|
symbol
|
||||||
|
});
|
||||||
|
|
||||||
value = {
|
value = {
|
||||||
dataSource,
|
dataSource,
|
||||||
symbol,
|
symbol,
|
||||||
date: today,
|
date: today,
|
||||||
marketPrice: 0
|
marketPrice: latestActivity?.unitPrice ?? 0
|
||||||
};
|
};
|
||||||
|
|
||||||
response.values.push(value);
|
response.values.push(value);
|
||||||
|
@ -21,7 +21,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
let exchangeRateDataService: ExchangeRateDataService;
|
let exchangeRateDataService: ExchangeRateDataService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
currentRateService = new CurrentRateService(null, null, null);
|
currentRateService = new CurrentRateService(null, null, null, null);
|
||||||
|
|
||||||
exchangeRateDataService = new ExchangeRateDataService(
|
exchangeRateDataService = new ExchangeRateDataService(
|
||||||
null,
|
null,
|
||||||
|
@ -21,7 +21,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
let exchangeRateDataService: ExchangeRateDataService;
|
let exchangeRateDataService: ExchangeRateDataService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
currentRateService = new CurrentRateService(null, null, null);
|
currentRateService = new CurrentRateService(null, null, null, null);
|
||||||
|
|
||||||
exchangeRateDataService = new ExchangeRateDataService(
|
exchangeRateDataService = new ExchangeRateDataService(
|
||||||
null,
|
null,
|
||||||
|
@ -34,7 +34,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
let exchangeRateDataService: ExchangeRateDataService;
|
let exchangeRateDataService: ExchangeRateDataService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
currentRateService = new CurrentRateService(null, null, null);
|
currentRateService = new CurrentRateService(null, null, null, null);
|
||||||
|
|
||||||
exchangeRateDataService = new ExchangeRateDataService(
|
exchangeRateDataService = new ExchangeRateDataService(
|
||||||
null,
|
null,
|
||||||
|
@ -34,7 +34,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
let exchangeRateDataService: ExchangeRateDataService;
|
let exchangeRateDataService: ExchangeRateDataService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
currentRateService = new CurrentRateService(null, null, null);
|
currentRateService = new CurrentRateService(null, null, null, null);
|
||||||
|
|
||||||
exchangeRateDataService = new ExchangeRateDataService(
|
exchangeRateDataService = new ExchangeRateDataService(
|
||||||
null,
|
null,
|
||||||
|
@ -21,7 +21,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
let exchangeRateDataService: ExchangeRateDataService;
|
let exchangeRateDataService: ExchangeRateDataService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
currentRateService = new CurrentRateService(null, null, null);
|
currentRateService = new CurrentRateService(null, null, null, null);
|
||||||
|
|
||||||
exchangeRateDataService = new ExchangeRateDataService(
|
exchangeRateDataService = new ExchangeRateDataService(
|
||||||
null,
|
null,
|
||||||
|
@ -21,7 +21,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
let exchangeRateDataService: ExchangeRateDataService;
|
let exchangeRateDataService: ExchangeRateDataService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
currentRateService = new CurrentRateService(null, null, null);
|
currentRateService = new CurrentRateService(null, null, null, null);
|
||||||
|
|
||||||
exchangeRateDataService = new ExchangeRateDataService(
|
exchangeRateDataService = new ExchangeRateDataService(
|
||||||
null,
|
null,
|
||||||
|
@ -21,7 +21,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
let exchangeRateDataService: ExchangeRateDataService;
|
let exchangeRateDataService: ExchangeRateDataService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
currentRateService = new CurrentRateService(null, null, null);
|
currentRateService = new CurrentRateService(null, null, null, null);
|
||||||
|
|
||||||
exchangeRateDataService = new ExchangeRateDataService(
|
exchangeRateDataService = new ExchangeRateDataService(
|
||||||
null,
|
null,
|
||||||
|
@ -10,7 +10,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
let exchangeRateDataService: ExchangeRateDataService;
|
let exchangeRateDataService: ExchangeRateDataService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
currentRateService = new CurrentRateService(null, null, null);
|
currentRateService = new CurrentRateService(null, null, null, null);
|
||||||
|
|
||||||
exchangeRateDataService = new ExchangeRateDataService(
|
exchangeRateDataService = new ExchangeRateDataService(
|
||||||
null,
|
null,
|
||||||
|
@ -825,6 +825,7 @@ export class PortfolioCalculator {
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'BUY':
|
case 'BUY':
|
||||||
|
case 'ITEM':
|
||||||
factor = 1;
|
factor = 1;
|
||||||
break;
|
break;
|
||||||
case 'SELL':
|
case 'SELL':
|
||||||
|
@ -342,7 +342,8 @@ export class PortfolioController {
|
|||||||
@Query('assetClasses') filterByAssetClasses?: string,
|
@Query('assetClasses') filterByAssetClasses?: string,
|
||||||
@Query('range') dateRange: DateRange = 'max',
|
@Query('range') dateRange: DateRange = 'max',
|
||||||
@Query('tags') filterByTags?: string,
|
@Query('tags') filterByTags?: string,
|
||||||
@Query('withExcludedAccounts') withExcludedAccounts = false
|
@Query('withExcludedAccounts') withExcludedAccounts = false,
|
||||||
|
@Query('withItems') withItems = false
|
||||||
): Promise<PortfolioPerformanceResponse> {
|
): Promise<PortfolioPerformanceResponse> {
|
||||||
const hasReadRestrictedAccessPermission =
|
const hasReadRestrictedAccessPermission =
|
||||||
this.userService.hasReadRestrictedAccessPermission({
|
this.userService.hasReadRestrictedAccessPermission({
|
||||||
@ -361,6 +362,7 @@ export class PortfolioController {
|
|||||||
filters,
|
filters,
|
||||||
impersonationId,
|
impersonationId,
|
||||||
withExcludedAccounts,
|
withExcludedAccounts,
|
||||||
|
withItems,
|
||||||
userId: this.request.user.id
|
userId: this.request.user.id
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -515,7 +517,8 @@ export class PortfolioController {
|
|||||||
dateOfFirstActivity: portfolioPosition.dateOfFirstActivity,
|
dateOfFirstActivity: portfolioPosition.dateOfFirstActivity,
|
||||||
markets: hasDetails ? portfolioPosition.markets : undefined,
|
markets: hasDetails ? portfolioPosition.markets : undefined,
|
||||||
name: portfolioPosition.name,
|
name: portfolioPosition.name,
|
||||||
netPerformancePercent: portfolioPosition.netPerformancePercent,
|
netPerformancePercentWithCurrencyEffect:
|
||||||
|
portfolioPosition.netPerformancePercentWithCurrencyEffect,
|
||||||
sectors: hasDetails ? portfolioPosition.sectors : [],
|
sectors: hasDetails ? portfolioPosition.sectors : [],
|
||||||
symbol: portfolioPosition.symbol,
|
symbol: portfolioPosition.symbol,
|
||||||
url: portfolioPosition.url,
|
url: portfolioPosition.url,
|
||||||
|
@ -277,7 +277,8 @@ export class PortfolioService {
|
|||||||
await this.getTransactionPoints({
|
await this.getTransactionPoints({
|
||||||
filters,
|
filters,
|
||||||
userId,
|
userId,
|
||||||
includeDrafts: true
|
includeDrafts: true,
|
||||||
|
types: ['BUY', 'SELL']
|
||||||
});
|
});
|
||||||
|
|
||||||
if (transactionPoints.length === 0) {
|
if (transactionPoints.length === 0) {
|
||||||
@ -702,7 +703,7 @@ export class PortfolioService {
|
|||||||
.filter((order) => {
|
.filter((order) => {
|
||||||
tags = tags.concat(order.tags);
|
tags = tags.concat(order.tags);
|
||||||
|
|
||||||
return order.type === 'BUY' || order.type === 'SELL';
|
return ['BUY', 'ITEM', 'SELL'].includes(order.type);
|
||||||
})
|
})
|
||||||
.map((order) => ({
|
.map((order) => ({
|
||||||
currency: order.SymbolProfile.currency,
|
currency: order.SymbolProfile.currency,
|
||||||
@ -957,7 +958,8 @@ export class PortfolioService {
|
|||||||
const { portfolioOrders, transactionPoints } =
|
const { portfolioOrders, transactionPoints } =
|
||||||
await this.getTransactionPoints({
|
await this.getTransactionPoints({
|
||||||
filters,
|
filters,
|
||||||
userId
|
userId,
|
||||||
|
types: ['BUY', 'SELL']
|
||||||
});
|
});
|
||||||
|
|
||||||
if (transactionPoints?.length <= 0) {
|
if (transactionPoints?.length <= 0) {
|
||||||
@ -1087,13 +1089,15 @@ export class PortfolioService {
|
|||||||
filters,
|
filters,
|
||||||
impersonationId,
|
impersonationId,
|
||||||
userId,
|
userId,
|
||||||
withExcludedAccounts = false
|
withExcludedAccounts = false,
|
||||||
|
withItems = false
|
||||||
}: {
|
}: {
|
||||||
dateRange?: DateRange;
|
dateRange?: DateRange;
|
||||||
filters?: Filter[];
|
filters?: Filter[];
|
||||||
impersonationId: string;
|
impersonationId: string;
|
||||||
userId: string;
|
userId: string;
|
||||||
withExcludedAccounts?: boolean;
|
withExcludedAccounts?: boolean;
|
||||||
|
withItems?: boolean;
|
||||||
}): Promise<PortfolioPerformanceResponse> {
|
}): Promise<PortfolioPerformanceResponse> {
|
||||||
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 });
|
||||||
@ -1128,7 +1132,8 @@ export class PortfolioService {
|
|||||||
await this.getTransactionPoints({
|
await this.getTransactionPoints({
|
||||||
filters,
|
filters,
|
||||||
userId,
|
userId,
|
||||||
withExcludedAccounts
|
withExcludedAccounts,
|
||||||
|
types: withItems ? ['BUY', 'ITEM', 'SELL'] : ['BUY', 'SELL']
|
||||||
});
|
});
|
||||||
|
|
||||||
const portfolioCalculator = new PortfolioCalculator({
|
const portfolioCalculator = new PortfolioCalculator({
|
||||||
@ -1280,7 +1285,8 @@ export class PortfolioService {
|
|||||||
|
|
||||||
const { orders, portfolioOrders, transactionPoints } =
|
const { orders, portfolioOrders, transactionPoints } =
|
||||||
await this.getTransactionPoints({
|
await this.getTransactionPoints({
|
||||||
userId
|
userId,
|
||||||
|
types: ['BUY', 'SELL']
|
||||||
});
|
});
|
||||||
|
|
||||||
const portfolioCalculator = new PortfolioCalculator({
|
const portfolioCalculator = new PortfolioCalculator({
|
||||||
@ -1913,11 +1919,13 @@ export class PortfolioService {
|
|||||||
private async getTransactionPoints({
|
private async getTransactionPoints({
|
||||||
filters,
|
filters,
|
||||||
includeDrafts = false,
|
includeDrafts = false,
|
||||||
|
types = ['BUY', 'ITEM', 'SELL'],
|
||||||
userId,
|
userId,
|
||||||
withExcludedAccounts = false
|
withExcludedAccounts = false
|
||||||
}: {
|
}: {
|
||||||
filters?: Filter[];
|
filters?: Filter[];
|
||||||
includeDrafts?: boolean;
|
includeDrafts?: boolean;
|
||||||
|
types?: ActivityType[];
|
||||||
userId: string;
|
userId: string;
|
||||||
withExcludedAccounts?: boolean;
|
withExcludedAccounts?: boolean;
|
||||||
}): Promise<{
|
}): Promise<{
|
||||||
@ -1931,10 +1939,10 @@ export class PortfolioService {
|
|||||||
const { activities, count } = await this.orderService.getOrders({
|
const { activities, count } = await this.orderService.getOrders({
|
||||||
filters,
|
filters,
|
||||||
includeDrafts,
|
includeDrafts,
|
||||||
|
types,
|
||||||
userCurrency,
|
userCurrency,
|
||||||
userId,
|
userId,
|
||||||
withExcludedAccounts,
|
withExcludedAccounts
|
||||||
types: ['BUY', 'SELL']
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
@ -2006,7 +2014,7 @@ export class PortfolioService {
|
|||||||
userCurrency,
|
userCurrency,
|
||||||
userId,
|
userId,
|
||||||
withExcludedAccounts,
|
withExcludedAccounts,
|
||||||
types: ['ITEM', 'LIABILITY']
|
types: ['LIABILITY']
|
||||||
});
|
});
|
||||||
|
|
||||||
const accounts: PortfolioDetails['accounts'] = {};
|
const accounts: PortfolioDetails['accounts'] = {};
|
||||||
@ -2094,18 +2102,14 @@ export class PortfolioService {
|
|||||||
Account,
|
Account,
|
||||||
quantity,
|
quantity,
|
||||||
SymbolProfile,
|
SymbolProfile,
|
||||||
type,
|
type
|
||||||
valueInBaseCurrency
|
|
||||||
} of ordersByAccount) {
|
} of ordersByAccount) {
|
||||||
const unitPriceInBaseCurrency =
|
|
||||||
portfolioItemsNow[SymbolProfile.symbol]?.marketPriceInBaseCurrency ??
|
|
||||||
valueInBaseCurrency ??
|
|
||||||
0;
|
|
||||||
|
|
||||||
let currentValueOfSymbolInBaseCurrency =
|
let currentValueOfSymbolInBaseCurrency =
|
||||||
quantity * unitPriceInBaseCurrency;
|
quantity *
|
||||||
|
portfolioItemsNow[SymbolProfile.symbol]
|
||||||
|
?.marketPriceInBaseCurrency ?? 0;
|
||||||
|
|
||||||
if (type === 'LIABILITY' || type === 'SELL') {
|
if (['LIABILITY', 'SELL'].includes(type)) {
|
||||||
currentValueOfSymbolInBaseCurrency *= -1;
|
currentValueOfSymbolInBaseCurrency *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ export class SymbolController {
|
|||||||
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
|
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
|
||||||
@UseInterceptors(TransformDataSourceInResponseInterceptor)
|
@UseInterceptors(TransformDataSourceInResponseInterceptor)
|
||||||
public async lookupSymbol(
|
public async lookupSymbol(
|
||||||
@Query('includeIndices') includeIndices: boolean = false,
|
@Query('includeIndices') includeIndices = false,
|
||||||
@Query('query') query = ''
|
@Query('query') query = ''
|
||||||
): Promise<{ items: LookupItem[] }> {
|
): Promise<{ items: LookupItem[] }> {
|
||||||
try {
|
try {
|
||||||
|
@ -166,13 +166,15 @@ export class ManualService implements DataProviderInterface {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const symbolProfile of symbolProfiles) {
|
for (const { currency, symbol } of symbolProfiles) {
|
||||||
response[symbolProfile.symbol] = {
|
let marketPrice = marketData.find((marketDataItem) => {
|
||||||
currency: symbolProfile.currency,
|
return marketDataItem.symbol === symbol;
|
||||||
|
})?.marketPrice;
|
||||||
|
|
||||||
|
response[symbol] = {
|
||||||
|
currency,
|
||||||
|
marketPrice,
|
||||||
dataSource: this.getName(),
|
dataSource: this.getName(),
|
||||||
marketPrice: marketData.find((marketDataItem) => {
|
|
||||||
return marketDataItem.symbol === symbolProfile.symbol;
|
|
||||||
})?.marketPrice,
|
|
||||||
marketState: 'delayed'
|
marketState: 'delayed'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,8 @@ export class AccountDetailDialog implements OnDestroy, OnInit {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
range: 'max',
|
range: 'max',
|
||||||
withExcludedAccounts: true
|
withExcludedAccounts: true,
|
||||||
|
withItems: true
|
||||||
})
|
})
|
||||||
.pipe(takeUntil(this.unsubscribeSubject))
|
.pipe(takeUntil(this.unsubscribeSubject))
|
||||||
.subscribe(({ chart }) => {
|
.subscribe(({ chart }) => {
|
||||||
|
@ -437,11 +437,13 @@ export class DataService {
|
|||||||
public fetchPortfolioPerformance({
|
public fetchPortfolioPerformance({
|
||||||
filters,
|
filters,
|
||||||
range,
|
range,
|
||||||
withExcludedAccounts = false
|
withExcludedAccounts = false,
|
||||||
|
withItems = false
|
||||||
}: {
|
}: {
|
||||||
filters?: Filter[];
|
filters?: Filter[];
|
||||||
range: DateRange;
|
range: DateRange;
|
||||||
withExcludedAccounts?: boolean;
|
withExcludedAccounts?: boolean;
|
||||||
|
withItems?: boolean;
|
||||||
}): Observable<PortfolioPerformanceResponse> {
|
}): Observable<PortfolioPerformanceResponse> {
|
||||||
let params = this.buildFiltersAsQueryParams({ filters });
|
let params = this.buildFiltersAsQueryParams({ filters });
|
||||||
params = params.append('range', range);
|
params = params.append('range', range);
|
||||||
@ -450,6 +452,10 @@ export class DataService {
|
|||||||
params = params.append('withExcludedAccounts', withExcludedAccounts);
|
params = params.append('withExcludedAccounts', withExcludedAccounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (withItems) {
|
||||||
|
params = params.append('withItems', withItems);
|
||||||
|
}
|
||||||
|
|
||||||
return this.http
|
return this.http
|
||||||
.get<any>(`/api/v2/portfolio/performance`, {
|
.get<any>(`/api/v2/portfolio/performance`, {
|
||||||
params
|
params
|
||||||
|
@ -13,7 +13,7 @@ export interface PortfolioPublicDetails {
|
|||||||
| 'dateOfFirstActivity'
|
| 'dateOfFirstActivity'
|
||||||
| 'markets'
|
| 'markets'
|
||||||
| 'name'
|
| 'name'
|
||||||
| 'netPerformancePercent'
|
| 'netPerformancePercentWithCurrencyEffect'
|
||||||
| 'sectors'
|
| 'sectors'
|
||||||
| 'symbol'
|
| 'symbol'
|
||||||
| 'url'
|
| 'url'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user