Browse Source

Improve handling of derived currencies

pull/2891/head
Thomas Kaul 2 years ago
parent
commit
ac633051b8
  1. 100
      apps/api/src/services/data-provider/data-provider.service.ts
  2. 54
      apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts
  3. 2
      apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts
  4. 50
      apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts

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

@ -9,12 +9,16 @@ import {
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service'; import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { PROPERTY_DATA_SOURCE_MAPPING } from '@ghostfolio/common/config'; import {
DEFAULT_CURRENCY,
PROPERTY_DATA_SOURCE_MAPPING
} from '@ghostfolio/common/config';
import { DATE_FORMAT, getStartOfUtcDate } from '@ghostfolio/common/helper'; import { DATE_FORMAT, getStartOfUtcDate } from '@ghostfolio/common/helper';
import { UniqueAsset } from '@ghostfolio/common/interfaces'; import { UniqueAsset } from '@ghostfolio/common/interfaces';
import type { Granularity, UserWithSettings } from '@ghostfolio/common/types'; import type { Granularity, UserWithSettings } from '@ghostfolio/common/types';
import { Inject, Injectable, Logger } from '@nestjs/common'; import { Inject, Injectable, Logger } from '@nestjs/common';
import { DataSource, MarketData, SymbolProfile } from '@prisma/client'; import { DataSource, MarketData, SymbolProfile } from '@prisma/client';
import Big from 'big.js';
import { format, isValid } from 'date-fns'; import { format, isValid } from 'date-fns';
import { groupBy, isEmpty, isNumber } from 'lodash'; import { groupBy, isEmpty, isNumber } from 'lodash';
import ms from 'ms'; import ms from 'ms';
@ -205,6 +209,8 @@ export class DataProviderService {
): Promise<{ ): Promise<{
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
}> { }> {
// TODO
const result: { const result: {
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; [symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
} = {}; } = {};
@ -326,19 +332,99 @@ export class DataProviderService {
promises.push( promises.push(
promise.then(async (result) => { promise.then(async (result) => {
for (const [symbol, dataProviderResponse] of Object.entries( for (let [symbol, dataProviderResponse] of Object.entries(result)) {
result if (symbol === `${DEFAULT_CURRENCY}USX`) {
)) { dataProviderResponse = {
...dataProviderResponse,
marketPrice: new Big(1).mul(100).toNumber(),
marketState: 'open'
};
}
if (
[
`${DEFAULT_CURRENCY}GBp`,
`${DEFAULT_CURRENCY}ILA`,
`${DEFAULT_CURRENCY}ZAc`
].includes(symbol)
) {
continue;
}
response[symbol] = dataProviderResponse; response[symbol] = dataProviderResponse;
this.redisCacheService.set( this.redisCacheService.set(
this.redisCacheService.getQuoteKey({ this.redisCacheService.getQuoteKey({
dataSource: DataSource[dataSource], symbol,
symbol dataSource: DataSource[dataSource]
}), }),
JSON.stringify(dataProviderResponse), JSON.stringify(response[symbol]),
this.configurationService.get('CACHE_QUOTES_TTL') this.configurationService.get('CACHE_QUOTES_TTL')
); );
if (symbol === `${DEFAULT_CURRENCY}GBP`) {
response[`${DEFAULT_CURRENCY}GBp`] = {
...dataProviderResponse,
currency: 'GBp',
marketPrice: new Big(
result[`${DEFAULT_CURRENCY}GBP`].marketPrice
)
.mul(100)
.toNumber(),
marketState: 'open'
};
this.redisCacheService.set(
this.redisCacheService.getQuoteKey({
dataSource: DataSource[dataSource],
symbol: `${DEFAULT_CURRENCY}GBp`
}),
JSON.stringify(response[`${DEFAULT_CURRENCY}GBp`]),
this.configurationService.get('CACHE_QUOTES_TTL')
);
} else if (symbol === `${DEFAULT_CURRENCY}ILS`) {
response[`${DEFAULT_CURRENCY}ILA`] = {
...dataProviderResponse,
currency: 'ILA',
marketPrice: new Big(
result[`${DEFAULT_CURRENCY}ILS`].marketPrice
)
.mul(100)
.toNumber(),
marketState: 'open'
};
this.redisCacheService.set(
this.redisCacheService.getQuoteKey({
dataSource: DataSource[dataSource],
symbol: `${DEFAULT_CURRENCY}ILA`
}),
JSON.stringify(response[`${DEFAULT_CURRENCY}ILA`]),
this.configurationService.get('CACHE_QUOTES_TTL')
);
} else if (symbol === `${DEFAULT_CURRENCY}ZAR`) {
response[`${DEFAULT_CURRENCY}ZAc`] = {
...dataProviderResponse,
currency: 'ZAc',
marketPrice: new Big(
result[`${DEFAULT_CURRENCY}ZAR`].marketPrice
)
.mul(100)
.toNumber(),
marketState: 'open'
};
this.redisCacheService.set(
this.redisCacheService.getQuoteKey({
dataSource: DataSource[dataSource],
symbol: `${DEFAULT_CURRENCY}ZAc`
}),
JSON.stringify(response[`${DEFAULT_CURRENCY}ZAc`]),
this.configurationService.get('CACHE_QUOTES_TTL')
);
}
console.log({ response });
} }
Logger.debug( Logger.debug(

54
apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts

@ -196,48 +196,6 @@ export class EodHistoricalDataService implements DataProviderInterface {
{} {}
); );
if (response[`${DEFAULT_CURRENCY}GBP`]) {
response[`${DEFAULT_CURRENCY}GBp`] = {
...response[`${DEFAULT_CURRENCY}GBP`],
currency: 'GBp',
marketPrice: this.getConvertedValue({
symbol: `${DEFAULT_CURRENCY}GBp`,
value: response[`${DEFAULT_CURRENCY}GBP`].marketPrice
})
};
}
if (response[`${DEFAULT_CURRENCY}ILS`]) {
response[`${DEFAULT_CURRENCY}ILA`] = {
...response[`${DEFAULT_CURRENCY}ILS`],
currency: 'ILA',
marketPrice: this.getConvertedValue({
symbol: `${DEFAULT_CURRENCY}ILA`,
value: response[`${DEFAULT_CURRENCY}ILS`].marketPrice
})
};
}
if (response[`${DEFAULT_CURRENCY}USX`]) {
response[`${DEFAULT_CURRENCY}USX`] = {
currency: 'USX',
dataSource: this.getName(),
marketPrice: new Big(1).mul(100).toNumber(),
marketState: 'open'
};
}
if (response[`${DEFAULT_CURRENCY}ZAR`]) {
response[`${DEFAULT_CURRENCY}ZAc`] = {
...response[`${DEFAULT_CURRENCY}ZAR`],
currency: 'ZAc',
marketPrice: this.getConvertedValue({
symbol: `${DEFAULT_CURRENCY}ZAc`,
value: response[`${DEFAULT_CURRENCY}ZAR`].marketPrice
})
};
}
return response; return response;
} catch (error) { } catch (error) {
let message = error; let message = error;
@ -337,6 +295,7 @@ export class EodHistoricalDataService implements DataProviderInterface {
return aSymbol; return aSymbol;
} }
// TODO: Eliminate
private getConvertedValue({ private getConvertedValue({
symbol, symbol,
value value
@ -344,17 +303,6 @@ export class EodHistoricalDataService implements DataProviderInterface {
symbol: string; symbol: string;
value: number; value: number;
}) { }) {
if (symbol === `${DEFAULT_CURRENCY}GBp`) {
// Convert GPB to GBp (pence)
return new Big(value).mul(100).toNumber();
} else if (symbol === `${DEFAULT_CURRENCY}ILA`) {
// Convert ILS to ILA
return new Big(value).mul(100).toNumber();
} else if (symbol === `${DEFAULT_CURRENCY}ZAc`) {
// Convert ZAR to ZAc
return new Big(value).mul(100).toNumber();
}
return value; return value;
} }

2
apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts

@ -1,3 +1,5 @@
// TODO
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service'; import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service';
import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service'; import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service';

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

@ -168,30 +168,6 @@ export class ExchangeRateDataService {
const [currency1, currency2] = symbol.match(/.{1,3}/g); const [currency1, currency2] = symbol.match(/.{1,3}/g);
const [date] = Object.keys(result[symbol]); const [date] = Object.keys(result[symbol]);
// Add derived currencies
if (currency2 === 'GBP') {
resultExtended[`${currency1}GBp`] = {
[date]: {
marketPrice:
result[`${currency1}${currency2}`][date].marketPrice * 100
}
};
} else if (currency2 === 'ILS') {
resultExtended[`${currency1}ILA`] = {
[date]: {
marketPrice:
result[`${currency1}${currency2}`][date].marketPrice * 100
}
};
} else if (currency2 === 'ZAR') {
resultExtended[`${currency1}ZAc`] = {
[date]: {
marketPrice:
result[`${currency1}${currency2}`][date].marketPrice * 100
}
};
}
// Calculate the opposite direction // Calculate the opposite direction
resultExtended[`${currency2}${currency1}`] = { resultExtended[`${currency2}${currency1}`] = {
[date]: { [date]: {
@ -486,8 +462,8 @@ export class ExchangeRateDataService {
} }
} }
}) })
).forEach((account) => { ).forEach(({ currency }) => {
currencies.push(account.currency); currencies.push(currency);
}); });
( (
@ -496,8 +472,8 @@ export class ExchangeRateDataService {
orderBy: [{ currency: 'asc' }], orderBy: [{ currency: 'asc' }],
select: { currency: true } select: { currency: true }
}) })
).forEach((symbolProfile) => { ).forEach(({ currency }) => {
currencies.push(symbolProfile.currency); currencies.push(currency);
}); });
const customCurrencies = (await this.propertyService.getByKey( const customCurrencies = (await this.propertyService.getByKey(
@ -508,6 +484,24 @@ export class ExchangeRateDataService {
currencies = currencies.concat(customCurrencies); currencies = currencies.concat(customCurrencies);
} }
// Add derived currencies
currencies.push('USX');
if (currencies.includes('GBP') || currencies.includes('GBp')) {
currencies.push('GBP');
currencies.push('GBp');
}
if (currencies.includes('ILS') || currencies.includes('ILA')) {
currencies.push('ILS');
currencies.push('ILA');
}
if (currencies.includes('ZAR') || currencies.includes('ZAc')) {
currencies.push('ZAR');
currencies.push('ZAc');
}
return uniq(currencies).filter(Boolean).sort(); return uniq(currencies).filter(Boolean).sort();
} }

Loading…
Cancel
Save