|
@ -1,3 +1,5 @@ |
|
|
|
|
|
// TODO ///////////
|
|
|
|
|
|
|
|
|
import { AccountService } from '@ghostfolio/api/app/account/account.service'; |
|
|
import { AccountService } from '@ghostfolio/api/app/account/account.service'; |
|
|
import { CashDetails } from '@ghostfolio/api/app/account/interfaces/cash-details.interface'; |
|
|
import { CashDetails } from '@ghostfolio/api/app/account/interfaces/cash-details.interface'; |
|
|
import { OrderService } from '@ghostfolio/api/app/order/order.service'; |
|
|
import { OrderService } from '@ghostfolio/api/app/order/order.service'; |
|
@ -21,7 +23,11 @@ import { ImpersonationService } from '@ghostfolio/api/services/impersonation.ser |
|
|
import { MarketState } from '@ghostfolio/api/services/interfaces/interfaces'; |
|
|
import { MarketState } from '@ghostfolio/api/services/interfaces/interfaces'; |
|
|
import { EnhancedSymbolProfile } from '@ghostfolio/api/services/interfaces/symbol-profile.interface'; |
|
|
import { EnhancedSymbolProfile } from '@ghostfolio/api/services/interfaces/symbol-profile.interface'; |
|
|
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service'; |
|
|
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service'; |
|
|
import { UNKNOWN_KEY, ghostfolioCashSymbol } from '@ghostfolio/common/config'; |
|
|
import { |
|
|
|
|
|
UNKNOWN_KEY, |
|
|
|
|
|
baseCurrency, |
|
|
|
|
|
ghostfolioCashSymbol |
|
|
|
|
|
} from '@ghostfolio/common/config'; |
|
|
import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper'; |
|
|
import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper'; |
|
|
import { |
|
|
import { |
|
|
PortfolioDetails, |
|
|
PortfolioDetails, |
|
@ -78,7 +84,7 @@ export class PortfolioService { |
|
|
public async getInvestments( |
|
|
public async getInvestments( |
|
|
aImpersonationId: string |
|
|
aImpersonationId: string |
|
|
): Promise<InvestmentItem[]> { |
|
|
): Promise<InvestmentItem[]> { |
|
|
const userId = await this.getUserId(aImpersonationId); |
|
|
const userId = await this.getUserId(aImpersonationId, this.request.user.id); |
|
|
|
|
|
|
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
this.currentRateService, |
|
|
this.currentRateService, |
|
@ -106,7 +112,7 @@ export class PortfolioService { |
|
|
aImpersonationId: string, |
|
|
aImpersonationId: string, |
|
|
aDateRange: DateRange = 'max' |
|
|
aDateRange: DateRange = 'max' |
|
|
): Promise<HistoricalDataItem[]> { |
|
|
): Promise<HistoricalDataItem[]> { |
|
|
const userId = await this.getUserId(aImpersonationId); |
|
|
const userId = await this.getUserId(aImpersonationId, this.request.user.id); |
|
|
|
|
|
|
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
this.currentRateService, |
|
|
this.currentRateService, |
|
@ -148,11 +154,12 @@ export class PortfolioService { |
|
|
|
|
|
|
|
|
public async getDetails( |
|
|
public async getDetails( |
|
|
aImpersonationId: string, |
|
|
aImpersonationId: string, |
|
|
|
|
|
aUserId: string, |
|
|
aDateRange: DateRange = 'max' |
|
|
aDateRange: DateRange = 'max' |
|
|
): Promise<PortfolioDetails & { hasErrors: boolean }> { |
|
|
): Promise<PortfolioDetails & { hasErrors: boolean }> { |
|
|
const userId = await this.getUserId(aImpersonationId); |
|
|
const userId = await this.getUserId(aImpersonationId, aUserId); |
|
|
|
|
|
|
|
|
const userCurrency = this.request.user.Settings.currency; |
|
|
const userCurrency = this.request.user?.Settings?.currency ?? baseCurrency; |
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
this.currentRateService, |
|
|
this.currentRateService, |
|
|
userCurrency |
|
|
userCurrency |
|
@ -265,7 +272,7 @@ export class PortfolioService { |
|
|
aImpersonationId: string, |
|
|
aImpersonationId: string, |
|
|
aSymbol: string |
|
|
aSymbol: string |
|
|
): Promise<PortfolioPositionDetail> { |
|
|
): Promise<PortfolioPositionDetail> { |
|
|
const userId = await this.getUserId(aImpersonationId); |
|
|
const userId = await this.getUserId(aImpersonationId, this.request.user.id); |
|
|
|
|
|
|
|
|
const orders = (await this.orderService.getOrders({ userId })).filter( |
|
|
const orders = (await this.orderService.getOrders({ userId })).filter( |
|
|
(order) => order.symbol === aSymbol |
|
|
(order) => order.symbol === aSymbol |
|
@ -484,7 +491,7 @@ export class PortfolioService { |
|
|
aImpersonationId: string, |
|
|
aImpersonationId: string, |
|
|
aDateRange: DateRange = 'max' |
|
|
aDateRange: DateRange = 'max' |
|
|
): Promise<{ hasErrors: boolean; positions: Position[] }> { |
|
|
): Promise<{ hasErrors: boolean; positions: Position[] }> { |
|
|
const userId = await this.getUserId(aImpersonationId); |
|
|
const userId = await this.getUserId(aImpersonationId, this.request.user.id); |
|
|
|
|
|
|
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
this.currentRateService, |
|
|
this.currentRateService, |
|
@ -555,7 +562,7 @@ export class PortfolioService { |
|
|
aImpersonationId: string, |
|
|
aImpersonationId: string, |
|
|
aDateRange: DateRange = 'max' |
|
|
aDateRange: DateRange = 'max' |
|
|
): Promise<{ hasErrors: boolean; performance: PortfolioPerformance }> { |
|
|
): Promise<{ hasErrors: boolean; performance: PortfolioPerformance }> { |
|
|
const userId = await this.getUserId(aImpersonationId); |
|
|
const userId = await this.getUserId(aImpersonationId, this.request.user.id); |
|
|
|
|
|
|
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
this.currentRateService, |
|
|
this.currentRateService, |
|
@ -628,8 +635,8 @@ export class PortfolioService { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public async getReport(impersonationId: string): Promise<PortfolioReport> { |
|
|
public async getReport(impersonationId: string): Promise<PortfolioReport> { |
|
|
const userId = await this.getUserId(impersonationId); |
|
|
const currency = this.request.user.Settings.currency; |
|
|
const baseCurrency = this.request.user.Settings.currency; |
|
|
const userId = await this.getUserId(impersonationId, this.request.user.id); |
|
|
|
|
|
|
|
|
const { orders, transactionPoints } = await this.getTransactionPoints({ |
|
|
const { orders, transactionPoints } = await this.getTransactionPoints({ |
|
|
userId |
|
|
userId |
|
@ -643,7 +650,7 @@ export class PortfolioService { |
|
|
|
|
|
|
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
const portfolioCalculator = new PortfolioCalculator( |
|
|
this.currentRateService, |
|
|
this.currentRateService, |
|
|
this.request.user.Settings.currency |
|
|
currency |
|
|
); |
|
|
); |
|
|
portfolioCalculator.setTransactionPoints(transactionPoints); |
|
|
portfolioCalculator.setTransactionPoints(transactionPoints); |
|
|
|
|
|
|
|
@ -659,7 +666,7 @@ export class PortfolioService { |
|
|
const accounts = await this.getAccounts( |
|
|
const accounts = await this.getAccounts( |
|
|
orders, |
|
|
orders, |
|
|
portfolioItemsNow, |
|
|
portfolioItemsNow, |
|
|
baseCurrency, |
|
|
currency, |
|
|
userId |
|
|
userId |
|
|
); |
|
|
); |
|
|
return { |
|
|
return { |
|
@ -679,7 +686,7 @@ export class PortfolioService { |
|
|
accounts |
|
|
accounts |
|
|
) |
|
|
) |
|
|
], |
|
|
], |
|
|
{ baseCurrency } |
|
|
{ baseCurrency: currency } |
|
|
), |
|
|
), |
|
|
currencyClusterRisk: await this.rulesService.evaluate( |
|
|
currencyClusterRisk: await this.rulesService.evaluate( |
|
|
[ |
|
|
[ |
|
@ -700,7 +707,7 @@ export class PortfolioService { |
|
|
currentPositions |
|
|
currentPositions |
|
|
) |
|
|
) |
|
|
], |
|
|
], |
|
|
{ baseCurrency } |
|
|
{ baseCurrency: currency } |
|
|
), |
|
|
), |
|
|
fees: await this.rulesService.evaluate( |
|
|
fees: await this.rulesService.evaluate( |
|
|
[ |
|
|
[ |
|
@ -710,7 +717,7 @@ export class PortfolioService { |
|
|
this.getFees(orders) |
|
|
this.getFees(orders) |
|
|
) |
|
|
) |
|
|
], |
|
|
], |
|
|
{ baseCurrency } |
|
|
{ baseCurrency: currency } |
|
|
) |
|
|
) |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
@ -718,7 +725,7 @@ export class PortfolioService { |
|
|
|
|
|
|
|
|
public async getSummary(aImpersonationId: string): Promise<PortfolioSummary> { |
|
|
public async getSummary(aImpersonationId: string): Promise<PortfolioSummary> { |
|
|
const currency = this.request.user.Settings.currency; |
|
|
const currency = this.request.user.Settings.currency; |
|
|
const userId = await this.getUserId(aImpersonationId); |
|
|
const userId = await this.getUserId(aImpersonationId, this.request.user.id); |
|
|
|
|
|
|
|
|
const performanceInformation = await this.getPerformance(aImpersonationId); |
|
|
const performanceInformation = await this.getPerformance(aImpersonationId); |
|
|
|
|
|
|
|
@ -820,7 +827,7 @@ export class PortfolioService { |
|
|
return { transactionPoints: [], orders: [] }; |
|
|
return { transactionPoints: [], orders: [] }; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const userCurrency = this.request.user.Settings.currency; |
|
|
const userCurrency = this.request.user?.Settings?.currency ?? baseCurrency; |
|
|
const portfolioOrders: PortfolioOrder[] = orders.map((order) => ({ |
|
|
const portfolioOrders: PortfolioOrder[] = orders.map((order) => ({ |
|
|
currency: order.currency, |
|
|
currency: order.currency, |
|
|
dataSource: order.dataSource, |
|
|
dataSource: order.dataSource, |
|
@ -920,14 +927,14 @@ export class PortfolioService { |
|
|
return accounts; |
|
|
return accounts; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private async getUserId(aImpersonationId: string) { |
|
|
private async getUserId(aImpersonationId: string, aUserId: string) { |
|
|
const impersonationUserId = |
|
|
const impersonationUserId = |
|
|
await this.impersonationService.validateImpersonationId( |
|
|
await this.impersonationService.validateImpersonationId( |
|
|
aImpersonationId, |
|
|
aImpersonationId, |
|
|
this.request.user.id |
|
|
aUserId |
|
|
); |
|
|
); |
|
|
|
|
|
|
|
|
return impersonationUserId || this.request.user.id; |
|
|
return impersonationUserId || aUserId; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private getTotalByType( |
|
|
private getTotalByType( |
|
|