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('symbol') symbol: string
): Promise<ImportResponse> {
const userCurrency = this.request.user.Settings.settings.baseCurrency;
const result = await this.importService.getDividends({
dataSource,
symbol
symbol,
userCurrency
});
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 { parseDate } from '@ghostfolio/common/helper';
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 { SymbolProfile } from '@prisma/client';
import Big from 'big.js';
@ -28,14 +31,18 @@ export class ImportService {
public async getDividends({
dataSource,
symbol
}: UniqueAsset): Promise<ImportResponse> {
symbol,
userCurrency
}: UniqueAsset & { userCurrency: string }): Promise<ImportResponse> {
try {
const { firstBuyDate } = await this.portfolioService.getPosition(
dataSource,
undefined,
symbol
);
const { firstBuyDate, historicalData, orders } =
await this.portfolioService.getPosition(dataSource, undefined, symbol);
const accounts = orders.map(({ Account }) => {
return Account;
});
const mostFrequentAccount = this.getMostFrequentAccount(accounts);
const [[assetProfile], dividends] = await Promise.all([
this.symbolProfileService.getSymbolProfiles([
@ -55,10 +62,20 @@ export class ImportService {
return {
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 {
accountId: undefined,
accountUserId: undefined,
quantity,
value,
Account: mostFrequentAccount,
accountId: mostFrequentAccount.id,
accountUserId: mostFrequentAccount.userId,
comment: undefined,
createdAt: undefined,
date: parseDate(dateString),
@ -66,15 +83,17 @@ export class ImportService {
feeInBaseCurrency: 0,
id: assetProfile.id,
isDraft: false,
quantity: 0,
SymbolProfile: <SymbolProfile>(<unknown>assetProfile),
symbolProfileId: undefined,
symbolProfileId: assetProfile.id,
type: 'DIVIDEND',
unitPrice: historicalDataItem.marketPrice,
unitPrice: marketPrice,
updatedAt: undefined,
userId: undefined,
value: 0,
valueInBaseCurrency: 0
userId: mostFrequentAccount.userId,
valueInBaseCurrency: this.exchangeRateDataService.toCurrency(
value,
assetProfile.currency,
userCurrency
)
};
}
)
@ -225,6 +244,31 @@ export class ImportService {
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({
activitiesDto,
maxActivitiesToImport,

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

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

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

@ -4,6 +4,7 @@ export interface HistoricalDataItem {
grossPerformancePercent?: number;
netPerformance?: number;
netPerformanceInPercentage?: number;
quantity?: number;
totalInvestment?: 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 { AccountWithPlatform } from './account-with-platform.type';
import { AccountWithValue } from './account-with-value.type';
import type { ColorScheme } from './color-scheme';
import type { DateRange } from './date-range.type';
@ -13,6 +14,7 @@ import type { ViewMode } from './view-mode.type';
export type {
AccessWithGranteeUser,
AccountWithPlatform,
AccountWithValue,
ColorScheme,
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 & {
Account?: AccountWithPlatform;

Loading…
Cancel
Save