From e741ce79da3b1631d6563efe356e7e7d577c949c Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 16 Nov 2023 11:22:41 +0100 Subject: [PATCH] Handle Error if only free stocks + removed lock --- .../src/app/portfolio/portfolio-calculator.ts | 9 ++- .../data-gathering/data-gathering.service.ts | 28 +++----- .../market-data/market-data.service.ts | 72 ++++++++----------- package.json | 1 - yarn.lock | 5 -- 5 files changed, 47 insertions(+), 68 deletions(-) diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index 626faf0c9..16b41136c 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -740,7 +740,7 @@ export class PortfolioCalculator { totalInvestment = totalInvestment.plus(currentPosition.investment); - if (currentPosition.grossPerformance) { + if (currentPosition.grossPerformance !== null) { grossPerformance = grossPerformance.plus( currentPosition.grossPerformance ); @@ -750,7 +750,7 @@ export class PortfolioCalculator { hasErrors = true; } - if (currentPosition.grossPerformancePercentage) { + if (currentPosition.grossPerformancePercentage !== null) { // Use the average from the initial value and the current investment as // a weight const weight = (initialValues[currentPosition.symbol] ?? new Big(0)) @@ -1191,6 +1191,11 @@ export class PortfolioCalculator { initialValue = valueOfInvestmentBeforeTransaction; } else if (transactionInvestment.gt(0)) { initialValue = transactionInvestment; + } else if (order.type === 'STAKE') { + // For Parachain Rewards or Stock SpinOffs, first transactionInvestment might be 0 if the symbol has been acquired for free + initialValue = order.quantity.mul( + marketSymbolMap[order.date]?.[order.symbol] ?? new Big(0) + ); } } diff --git a/apps/api/src/services/data-gathering/data-gathering.service.ts b/apps/api/src/services/data-gathering/data-gathering.service.ts index 213f91692..78531b745 100644 --- a/apps/api/src/services/data-gathering/data-gathering.service.ts +++ b/apps/api/src/services/data-gathering/data-gathering.service.ts @@ -24,7 +24,6 @@ import { DataSource } from '@prisma/client'; import { JobOptions, Queue } from 'bull'; import { format, min, subDays, subYears } from 'date-fns'; import { isEmpty } from 'lodash'; -import AwaitLock from 'await-lock'; @Injectable() export class DataGatheringService { @@ -41,8 +40,6 @@ export class DataGatheringService { private readonly symbolProfileService: SymbolProfileService ) {} - lock = new AwaitLock(); - public async addJobToQueue({ data, name, @@ -103,21 +100,16 @@ export class DataGatheringService { historicalData[symbol][format(date, DATE_FORMAT)].marketPrice; if (marketPrice) { - await this.lock.acquireAsync(); - try { - return await this.prismaService.marketData.upsert({ - create: { - dataSource, - date, - marketPrice, - symbol - }, - update: { marketPrice }, - where: { dataSource_date_symbol: { dataSource, date, symbol } } - }); - } finally { - this.lock.release(); - } + return await this.prismaService.marketData.upsert({ + create: { + dataSource, + date, + marketPrice, + symbol + }, + update: { marketPrice }, + where: { dataSource_date_symbol: { dataSource, date, symbol } } + }); } } catch (error) { Logger.error(error, 'DataGatheringService'); diff --git a/apps/api/src/services/market-data/market-data.service.ts b/apps/api/src/services/market-data/market-data.service.ts index 716bfd236..ae0e0ef80 100644 --- a/apps/api/src/services/market-data/market-data.service.ts +++ b/apps/api/src/services/market-data/market-data.service.ts @@ -13,14 +13,11 @@ import { Prisma } from '@prisma/client'; import { DateQueryHelper } from '@ghostfolio/api/helper/dateQueryHelper'; -import AwaitLock from 'await-lock'; @Injectable() export class MarketDataService { public constructor(private readonly prismaService: PrismaService) {} - lock = new AwaitLock(); - private dateQueryHelper = new DateQueryHelper(); public async deleteMany({ dataSource, symbol }: UniqueAsset) { @@ -132,22 +129,17 @@ export class MarketDataService { where: Prisma.MarketDataWhereUniqueInput; }): Promise { const { data, where } = params; - await this.lock.acquireAsync(); - try { - return this.prismaService.marketData.upsert({ - where, - create: { - dataSource: where.dataSource_date_symbol.dataSource, - date: where.dataSource_date_symbol.date, - marketPrice: data.marketPrice, - state: data.state, - symbol: where.dataSource_date_symbol.symbol - }, - update: { marketPrice: data.marketPrice, state: data.state } - }); - } finally { - this.lock.release(); - } + return this.prismaService.marketData.upsert({ + where, + create: { + dataSource: where.dataSource_date_symbol.dataSource, + date: where.dataSource_date_symbol.date, + marketPrice: data.marketPrice, + state: data.state, + symbol: where.dataSource_date_symbol.symbol + }, + update: { marketPrice: data.marketPrice, state: data.state } + }); } /** @@ -160,34 +152,30 @@ export class MarketDataService { data: Prisma.MarketDataUpdateInput[]; }): Promise { const upsertPromises = data.map( - async ({ dataSource, date, marketPrice, symbol, state }) => { - await this.lock.acquireAsync(); - try { - return this.prismaService.marketData.upsert({ - create: { + ({ dataSource, date, marketPrice, symbol, state }) => { + return this.prismaService.marketData.upsert({ + create: { + dataSource: dataSource, + date: date, + marketPrice: marketPrice, + state: state, + symbol: symbol + }, + update: { + marketPrice: marketPrice, + state: state + }, + where: { + dataSource_date_symbol: { dataSource: dataSource, date: date, - marketPrice: marketPrice, - state: state, symbol: symbol - }, - update: { - marketPrice: marketPrice, - state: state - }, - where: { - dataSource_date_symbol: { - dataSource: dataSource, - date: date, - symbol: symbol - } } - }); - } finally { - this.lock.release(); - } + } + }); } ); - return await Promise.all(upsertPromises); + + return this.prismaService.$transaction(upsertPromises); } } diff --git a/package.json b/package.json index ac3223a23..a7d7cd90b 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,6 @@ "@simplewebauthn/server": "8.3.2", "@stripe/stripe-js": "1.47.0", "alphavantage": "2.2.0", - "await-lock": "^2.2.2", "big.js": "6.2.1", "body-parser": "1.20.1", "bootstrap": "4.6.0", diff --git a/yarn.lock b/yarn.lock index 7048cedb8..a70ef8e84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7366,11 +7366,6 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -await-lock@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/await-lock/-/await-lock-2.2.2.tgz#a95a9b269bfd2f69d22b17a321686f551152bcef" - integrity sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw== - aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"