Browse Source

Get quantity from position

pull/1560/head
Thomas 3 years ago
parent
commit
06295c0091
  1. 5
      apps/api/src/app/import/import.controller.ts
  2. 78
      apps/api/src/app/import/import.service.ts
  3. 9
      apps/api/src/app/portfolio/portfolio.service.ts
  4. 1
      libs/common/src/lib/interfaces/historical-data-item.interface.ts
  5. 3
      libs/common/src/lib/types/account-with-platform.type.ts
  6. 2
      libs/common/src/lib/types/index.ts
  7. 4
      libs/common/src/lib/types/order-with-account.type.ts

5
apps/api/src/app/import/import.controller.ts

@ -90,9 +90,12 @@ export class ImportController {
@Param('dataSource') dataSource: DataSource, @Param('dataSource') dataSource: DataSource,
@Param('symbol') symbol: string @Param('symbol') symbol: string
): Promise<ImportResponse> { ): Promise<ImportResponse> {
const userCurrency = this.request.user.Settings.settings.baseCurrency;
const result = await this.importService.getDividends({ const result = await this.importService.getDividends({
dataSource, dataSource,
symbol symbol,
userCurrency
}); });
if (!result || isEmpty(result)) { if (!result || isEmpty(result)) {

78
apps/api/src/app/import/import.service.ts

@ -8,7 +8,10 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service'; import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service';
import { parseDate } from '@ghostfolio/common/helper'; import { parseDate } from '@ghostfolio/common/helper';
import { ImportResponse, UniqueAsset } from '@ghostfolio/common/interfaces'; import { ImportResponse, UniqueAsset } from '@ghostfolio/common/interfaces';
import { OrderWithAccount } from '@ghostfolio/common/types'; import {
AccountWithPlatform,
OrderWithAccount
} from '@ghostfolio/common/types';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { SymbolProfile } from '@prisma/client'; import { SymbolProfile } from '@prisma/client';
import Big from 'big.js'; import Big from 'big.js';
@ -28,14 +31,18 @@ export class ImportService {
public async getDividends({ public async getDividends({
dataSource, dataSource,
symbol symbol,
}: UniqueAsset): Promise<ImportResponse> { userCurrency
}: UniqueAsset & { userCurrency: string }): Promise<ImportResponse> {
try { try {
const { firstBuyDate } = await this.portfolioService.getPosition( const { firstBuyDate, historicalData, orders } =
dataSource, await this.portfolioService.getPosition(dataSource, undefined, symbol);
undefined,
symbol const accounts = orders.map(({ Account }) => {
); return Account;
});
const mostFrequentAccount = this.getMostFrequentAccount(accounts);
const [[assetProfile], dividends] = await Promise.all([ const [[assetProfile], dividends] = await Promise.all([
this.symbolProfileService.getSymbolProfiles([ this.symbolProfileService.getSymbolProfiles([
@ -55,10 +62,20 @@ export class ImportService {
return { return {
activities: Object.entries(dividends).map( activities: Object.entries(dividends).map(
([dateString, historicalDataItem]) => { ([dateString, { marketPrice }]) => {
const quantity =
historicalData.find((historicalDataItem) => {
return historicalDataItem.date === dateString;
})?.quantity ?? 0;
const value = new Big(quantity).mul(marketPrice).toNumber();
return { return {
accountId: undefined, quantity,
accountUserId: undefined, value,
Account: mostFrequentAccount,
accountId: mostFrequentAccount.id,
accountUserId: mostFrequentAccount.userId,
comment: undefined, comment: undefined,
createdAt: undefined, createdAt: undefined,
date: parseDate(dateString), date: parseDate(dateString),
@ -66,15 +83,17 @@ export class ImportService {
feeInBaseCurrency: 0, feeInBaseCurrency: 0,
id: assetProfile.id, id: assetProfile.id,
isDraft: false, isDraft: false,
quantity: 0,
SymbolProfile: <SymbolProfile>(<unknown>assetProfile), SymbolProfile: <SymbolProfile>(<unknown>assetProfile),
symbolProfileId: undefined, symbolProfileId: assetProfile.id,
type: 'DIVIDEND', type: 'DIVIDEND',
unitPrice: historicalDataItem.marketPrice, unitPrice: marketPrice,
updatedAt: undefined, updatedAt: undefined,
userId: undefined, userId: mostFrequentAccount.userId,
value: 0, valueInBaseCurrency: this.exchangeRateDataService.toCurrency(
valueInBaseCurrency: 0 value,
assetProfile.currency,
userCurrency
)
}; };
} }
) )
@ -225,6 +244,31 @@ export class ImportService {
return activities; return activities;
} }
private getMostFrequentAccount(accounts: AccountWithPlatform[]) {
const accountFrequencyCountMap: { [accountId: string]: number } = {};
// Iterate through the array of accounts and increment the frequency for each account
for (const account of accounts) {
accountFrequencyCountMap[account.id] =
(accountFrequencyCountMap[account.id] || 0) + 1;
}
// Find the account with the highest frequency
let maxFrequencyCount = 0;
let mostFrequentAccount: AccountWithPlatform;
for (const accountId in accountFrequencyCountMap) {
if (accountFrequencyCountMap[accountId] > maxFrequencyCount) {
mostFrequentAccount = accounts.find(
(account) => account.id === accountId
);
maxFrequencyCount = accountFrequencyCountMap[accountId];
}
}
return mostFrequentAccount;
}
private async validateActivities({ private async validateActivities({
activitiesDto, activitiesDto,
maxActivitiesToImport, maxActivitiesToImport,

9
apps/api/src/app/portfolio/portfolio.service.ts

@ -660,8 +660,9 @@ export class PortfolioService {
} }
const positionCurrency = orders[0].SymbolProfile.currency; const positionCurrency = orders[0].SymbolProfile.currency;
const [SymbolProfile] = const [SymbolProfile] = await this.symbolProfileService.getSymbolProfiles([
await this.symbolProfileService.getSymbolProfilesBySymbols([aSymbol]); { dataSource: aDataSource, symbol: aSymbol }
]);
const portfolioOrders: PortfolioOrder[] = orders const portfolioOrders: PortfolioOrder[] = orders
.filter((order) => { .filter((order) => {
@ -745,6 +746,7 @@ export class PortfolioService {
historicalDataArray.push({ historicalDataArray.push({
averagePrice: orders[0].unitPrice, averagePrice: orders[0].unitPrice,
date: firstBuyDate, date: firstBuyDate,
quantity: orders[0].quantity,
value: orders[0].unitPrice value: orders[0].unitPrice
}); });
} }
@ -761,6 +763,7 @@ export class PortfolioService {
j++; j++;
} }
let currentAveragePrice = 0; let currentAveragePrice = 0;
let currentQuantity = 0;
const currentSymbol = transactionPoints[j].items.find( const currentSymbol = transactionPoints[j].items.find(
(item) => item.symbol === aSymbol (item) => item.symbol === aSymbol
); );
@ -768,11 +771,13 @@ export class PortfolioService {
currentAveragePrice = currentSymbol.quantity.eq(0) currentAveragePrice = currentSymbol.quantity.eq(0)
? 0 ? 0
: currentSymbol.investment.div(currentSymbol.quantity).toNumber(); : currentSymbol.investment.div(currentSymbol.quantity).toNumber();
currentQuantity = currentSymbol.quantity.toNumber();
} }
historicalDataArray.push({ historicalDataArray.push({
date, date,
averagePrice: currentAveragePrice, averagePrice: currentAveragePrice,
quantity: currentQuantity,
value: marketPrice value: marketPrice
}); });

1
libs/common/src/lib/interfaces/historical-data-item.interface.ts

@ -4,6 +4,7 @@ export interface HistoricalDataItem {
grossPerformancePercent?: number; grossPerformancePercent?: number;
netPerformance?: number; netPerformance?: number;
netPerformanceInPercentage?: number; netPerformanceInPercentage?: number;
quantity?: number;
totalInvestment?: number; totalInvestment?: number;
value?: number; value?: number;
} }

3
libs/common/src/lib/types/account-with-platform.type.ts

@ -0,0 +1,3 @@
import { Account, Platform } from '@prisma/client';
export type AccountWithPlatform = Account & { Platform?: Platform };

2
libs/common/src/lib/types/index.ts

@ -1,4 +1,5 @@
import type { AccessWithGranteeUser } from './access-with-grantee-user.type'; import type { AccessWithGranteeUser } from './access-with-grantee-user.type';
import { AccountWithPlatform } from './account-with-platform.type';
import { AccountWithValue } from './account-with-value.type'; import { AccountWithValue } from './account-with-value.type';
import type { ColorScheme } from './color-scheme'; import type { ColorScheme } from './color-scheme';
import type { DateRange } from './date-range.type'; import type { DateRange } from './date-range.type';
@ -13,6 +14,7 @@ import type { ViewMode } from './view-mode.type';
export type { export type {
AccessWithGranteeUser, AccessWithGranteeUser,
AccountWithPlatform,
AccountWithValue, AccountWithValue,
ColorScheme, ColorScheme,
DateRange, DateRange,

4
libs/common/src/lib/types/order-with-account.type.ts

@ -1,6 +1,6 @@
import { Account, Order, Platform, SymbolProfile, Tag } from '@prisma/client'; import { Order, SymbolProfile, Tag } from '@prisma/client';
type AccountWithPlatform = Account & { Platform?: Platform }; import { AccountWithPlatform } from './account-with-platform.type';
export type OrderWithAccount = Order & { export type OrderWithAccount = Order & {
Account?: AccountWithPlatform; Account?: AccountWithPlatform;

Loading…
Cancel
Save