Browse Source

Fix missing quotes

pull/7085/head
Thomas Kaul 4 weeks ago
parent
commit
6c0acf07e1
  1. 4
      apps/api/src/app/endpoints/watchlist/watchlist.service.ts
  2. 4
      apps/api/src/app/portfolio/current-rate.service.ts
  3. 8
      apps/api/src/app/symbol/symbol.service.ts
  4. 8
      apps/api/src/services/benchmark/benchmark.service.ts
  5. 75
      apps/api/src/services/data-provider/data-provider.service.ts
  6. 9
      apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts
  7. 4
      apps/api/src/services/queues/data-gathering/data-gathering.service.ts

4
apps/api/src/app/endpoints/watchlist/watchlist.service.ts

@ -4,6 +4,7 @@ import { MarketDataService } from '@ghostfolio/api/services/market-data/market-d
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { DataGatheringService } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
import { WatchlistResponse } from '@ghostfolio/common/interfaces';
import { BadRequestException, Injectable } from '@nestjs/common';
@ -127,7 +128,8 @@ export class WatchlistService {
const performancePercent =
this.benchmarkService.calculateChangeInPercentage(
allTimeHigh?.marketPrice,
quotes[symbol]?.marketPrice
quotes[getAssetProfileIdentifier({ dataSource, symbol })]
?.marketPrice
);
return {

4
apps/api/src/app/portfolio/current-rate.service.ts

@ -51,13 +51,13 @@ export class CurrentRateService {
const values: GetValueObject[] = [];
if (includesToday) {
const quotesBySymbol = await this.dataProviderService.getQuotes({
const quotes = await this.dataProviderService.getQuotes({
items: dataGatheringItems,
user: this.request?.user
});
for (const { dataSource, symbol } of dataGatheringItems) {
const quote = quotesBySymbol[symbol];
const quote = quotes[getAssetProfileIdentifier({ dataSource, symbol })];
if (quote?.dataProviderInfo) {
dataProviderInfos.push(quote.dataProviderInfo);

8
apps/api/src/app/symbol/symbol.service.ts

@ -1,7 +1,10 @@
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { DataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
import {
DATE_FORMAT,
getAssetProfileIdentifier
} from '@ghostfolio/common/helper';
import {
DataProviderHistoricalResponse,
HistoricalDataItem,
@ -46,7 +49,8 @@ export class SymbolService {
items: [dataGatheringItem]
});
({ currency, marketPrice } = quotes[dataGatheringItem.symbol] ?? {});
({ currency, marketPrice } =
quotes[getAssetProfileIdentifier(dataGatheringItem)] ?? {});
}
if (dataGatheringItem.dataSource && marketPrice >= 0) {

8
apps/api/src/services/benchmark/benchmark.service.ts

@ -8,7 +8,10 @@ import {
CACHE_TTL_INFINITE,
PROPERTY_BENCHMARKS
} from '@ghostfolio/common/config';
import { calculateBenchmarkTrend } from '@ghostfolio/common/helper';
import {
calculateBenchmarkTrend,
getAssetProfileIdentifier
} from '@ghostfolio/common/helper';
import {
AssetProfileIdentifier,
Benchmark,
@ -266,8 +269,9 @@ export class BenchmarkService {
let storeInCache = true;
const benchmarks = allTimeHighs.map((allTimeHigh, index) => {
const { dataSource, symbol } = benchmarkAssetProfiles[index];
const { marketPrice } =
quotes[benchmarkAssetProfiles[index].symbol] ?? {};
quotes[getAssetProfileIdentifier({ dataSource, symbol })] ?? {};
let performancePercentFromAllTimeHigh = 0;

75
apps/api/src/services/data-provider/data-provider.service.ts

@ -77,7 +77,9 @@ export class DataProviderService implements OnModuleInit {
useCache: false
});
if (quotes[symbol]?.marketPrice > 0) {
if (
quotes[getAssetProfileIdentifier({ dataSource, symbol })]?.marketPrice > 0
) {
return true;
}
@ -514,7 +516,6 @@ export class DataProviderService implements OnModuleInit {
return result;
}
// TODO: Change symbol in response to assetProfileIdentifier
public async getQuotes({
items,
requestTimeout,
@ -526,10 +527,14 @@ export class DataProviderService implements OnModuleInit {
useCache?: boolean;
user?: UserWithSettings;
}): Promise<{
[symbol: string]: DataProviderResponse;
[assetProfileIdentifier: string]: DataProviderResponse;
}> {
// Keyed by asset profile identifier; each entry carries its symbol so the
// market data can be persisted without parsing the key
const response: {
[symbol: string]: DataProviderResponse;
[assetProfileIdentifier: string]: DataProviderResponse & {
symbol: string;
};
} = {};
const startTimeTotal = performance.now();
@ -538,11 +543,17 @@ export class DataProviderService implements OnModuleInit {
return symbol === `${DEFAULT_CURRENCY}USX`;
})
) {
response[`${DEFAULT_CURRENCY}USX`] = {
response[
getAssetProfileIdentifier({
dataSource: this.getDataSourceForExchangeRates(),
symbol: `${DEFAULT_CURRENCY}USX`
})
] = {
currency: 'USX',
dataSource: this.getDataSourceForExchangeRates(),
marketPrice: 100,
marketState: 'open'
marketState: 'open',
symbol: `${DEFAULT_CURRENCY}USX`
};
}
@ -557,8 +568,13 @@ export class DataProviderService implements OnModuleInit {
if (quoteString) {
try {
const cachedDataProviderResponse = JSON.parse(quoteString);
response[symbol] = cachedDataProviderResponse;
const cachedDataProviderResponse = JSON.parse(
quoteString
) as DataProviderResponse;
response[getAssetProfileIdentifier({ dataSource, symbol })] = {
...cachedDataProviderResponse,
symbol
};
continue;
} catch {}
}
@ -646,14 +662,19 @@ export class DataProviderService implements OnModuleInit {
continue;
}
response[symbol] = dataProviderResponse;
response[
getAssetProfileIdentifier({
symbol,
dataSource: DataSource[dataSource]
})
] = { ...dataProviderResponse, symbol };
this.redisCacheService.set(
this.redisCacheService.getQuoteKey({
symbol,
dataSource: DataSource[dataSource]
}),
JSON.stringify(response[symbol]),
JSON.stringify(dataProviderResponse),
this.configurationService.get('CACHE_QUOTES_TTL')
);
@ -663,7 +684,7 @@ export class DataProviderService implements OnModuleInit {
rootCurrency
} of DERIVED_CURRENCIES) {
if (symbol === `${DEFAULT_CURRENCY}${rootCurrency}`) {
response[`${DEFAULT_CURRENCY}${currency}`] = {
const derivedDataProviderResponse: DataProviderResponse = {
...dataProviderResponse,
currency,
marketPrice: new Big(
@ -674,12 +695,22 @@ export class DataProviderService implements OnModuleInit {
marketState: 'open'
};
response[
getAssetProfileIdentifier({
dataSource: DataSource[dataSource],
symbol: `${DEFAULT_CURRENCY}${currency}`
})
] = {
...derivedDataProviderResponse,
symbol: `${DEFAULT_CURRENCY}${currency}`
};
this.redisCacheService.set(
this.redisCacheService.getQuoteKey({
dataSource: DataSource[dataSource],
symbol: `${DEFAULT_CURRENCY}${currency}`
}),
JSON.stringify(response[`${DEFAULT_CURRENCY}${currency}`]),
JSON.stringify(derivedDataProviderResponse),
this.configurationService.get('CACHE_QUOTES_TTL')
);
}
@ -697,21 +728,21 @@ export class DataProviderService implements OnModuleInit {
try {
await this.marketDataService.updateMany({
data: Object.keys(response)
.filter((symbol) => {
data: Object.values(response)
.filter((dataProviderResponse) => {
return (
isNumber(response[symbol].marketPrice) &&
response[symbol].marketPrice > 0 &&
response[symbol].marketState === 'open'
isNumber(dataProviderResponse.marketPrice) &&
dataProviderResponse.marketPrice > 0 &&
dataProviderResponse.marketState === 'open'
);
})
.map((symbol) => {
.map((dataProviderResponse) => {
return {
symbol,
dataSource: response[symbol].dataSource,
dataSource: dataProviderResponse.dataSource,
date: getStartOfUtcDate(new Date()),
marketPrice: response[symbol].marketPrice,
state: 'INTRADAY'
marketPrice: dataProviderResponse.marketPrice,
state: 'INTRADAY',
symbol: dataProviderResponse.symbol
};
})
});

9
apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts

@ -11,6 +11,7 @@ import {
} from '@ghostfolio/common/config';
import {
DATE_FORMAT,
getAssetProfileIdentifier,
getYesterday,
resetHours
} from '@ghostfolio/common/helper';
@ -176,11 +177,13 @@ export class ExchangeRateDataService {
requestTimeout: ms('30 seconds')
});
for (const symbol of Object.keys(quotes)) {
if (isNumber(quotes[symbol].marketPrice)) {
for (const { dataSource, symbol } of this.currencyPairs) {
const quote = quotes[getAssetProfileIdentifier({ dataSource, symbol })];
if (isNumber(quote?.marketPrice)) {
result[symbol] = {
[format(getYesterday(), DATE_FORMAT)]: {
marketPrice: quotes[symbol].marketPrice
marketPrice: quote.marketPrice
}
};
}

4
apps/api/src/services/queues/data-gathering/data-gathering.service.ts

@ -301,9 +301,9 @@ export class DataGatheringService {
const data: Prisma.MarketDataUpdateInput[] = [];
for (const { dataSource, symbol } of assetProfileIdentifiers) {
const quote = quotes[symbol];
const quote = quotes[getAssetProfileIdentifier({ dataSource, symbol })];
if (quote?.dataSource !== dataSource || !quote.marketPrice) {
if (!quote?.marketPrice) {
continue;
}

Loading…
Cancel
Save