Browse Source

Fix big.js crash and duplicate asset imports

pull/6866/head
Andrea Bugeja 1 week ago
parent
commit
774a11aa2a
  1. 6
      apps/api/src/app/import/import.service.ts
  2. 148
      apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts
  3. 5
      apps/api/src/services/market-data/market-data.service.ts
  4. 1583
      package-lock.json

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

@ -284,7 +284,11 @@ export class ImportService {
); );
// If there is no asset profile or if the asset profile belongs to a different user, then create a new asset profile // If there is no asset profile or if the asset profile belongs to a different user, then create a new asset profile
if (!existingAssetProfile || existingAssetProfile.userId !== user.id) { if (
!existingAssetProfile ||
(existingAssetProfile.userId !== null &&
existingAssetProfile.userId !== user.id)
) {
const assetProfile: CreateAssetProfileDto = omit( const assetProfile: CreateAssetProfileDto = omit(
assetProfileWithMarketData, assetProfileWithMarketData,
'marketData' 'marketData'

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

@ -229,36 +229,63 @@ export class ExchangeRateDataService {
return 0; return 0;
} }
let normalizedValue = aValue;
let normalizedFromCurrency = aFromCurrency;
let normalizedToCurrency = aToCurrency;
const fromDerived = DERIVED_CURRENCIES.find(
(c) => c.currency === aFromCurrency
);
if (fromDerived) {
normalizedFromCurrency = fromDerived.rootCurrency;
normalizedValue = normalizedValue / fromDerived.factor;
}
const toDerived = DERIVED_CURRENCIES.find(
(c) => c.currency === aToCurrency
);
if (toDerived) {
normalizedToCurrency = toDerived.rootCurrency;
normalizedValue = normalizedValue * toDerived.factor;
}
let factor: number; let factor: number;
if (aFromCurrency === aToCurrency) { if (normalizedFromCurrency === normalizedToCurrency) {
factor = 1; factor = 1;
} else { } else {
if (this.exchangeRates[`${aFromCurrency}${aToCurrency}`]) { if (
factor = this.exchangeRates[`${aFromCurrency}${aToCurrency}`]; this.exchangeRates[`${normalizedFromCurrency}${normalizedToCurrency}`]
) {
factor =
this.exchangeRates[
`${normalizedFromCurrency}${normalizedToCurrency}`
];
} else { } else {
// Calculate indirectly via base currency // Calculate indirectly via base currency
const factor1 = const factor1 =
this.exchangeRates[`${aFromCurrency}${DEFAULT_CURRENCY}`]; this.exchangeRates[`${normalizedFromCurrency}${DEFAULT_CURRENCY}`];
const factor2 = this.exchangeRates[`${DEFAULT_CURRENCY}${aToCurrency}`]; const factor2 =
this.exchangeRates[`${DEFAULT_CURRENCY}${normalizedToCurrency}`];
factor = factor1 * factor2; factor = factor1 * factor2;
this.exchangeRates[`${aFromCurrency}${aToCurrency}`] = factor; this.exchangeRates[`${normalizedFromCurrency}${normalizedToCurrency}`] =
factor;
} }
} }
if (isNumber(factor) && !isNaN(factor)) { if (isNumber(factor) && !isNaN(factor)) {
return factor * aValue; return factor * normalizedValue;
} }
// Fallback with error, if currencies are not available // Fallback with error, if currencies are not available
Logger.error( Logger.error(
`No exchange rate has been found for ${aFromCurrency}${aToCurrency}`, `No exchange rate has been found for ${normalizedFromCurrency}${normalizedToCurrency}. Please complement market data for USD${normalizedFromCurrency} and USD${normalizedToCurrency}.`,
'ExchangeRateDataService' 'ExchangeRateDataService'
); );
return aValue; return undefined;
} }
public async toCurrencyAtDate( public async toCurrencyAtDate(
@ -271,22 +298,48 @@ export class ExchangeRateDataService {
return 0; return 0;
} }
let normalizedValue = aValue;
let normalizedFromCurrency = aFromCurrency;
let normalizedToCurrency = aToCurrency;
const fromDerived = DERIVED_CURRENCIES.find(
(c) => c.currency === aFromCurrency
);
if (fromDerived) {
normalizedFromCurrency = fromDerived.rootCurrency;
normalizedValue = normalizedValue / fromDerived.factor;
}
const toDerived = DERIVED_CURRENCIES.find(
(c) => c.currency === aToCurrency
);
if (toDerived) {
normalizedToCurrency = toDerived.rootCurrency;
normalizedValue = normalizedValue * toDerived.factor;
}
if (isToday(aDate)) { if (isToday(aDate)) {
return this.toCurrency(aValue, aFromCurrency, aToCurrency); return this.toCurrency(
normalizedValue,
normalizedFromCurrency,
normalizedToCurrency
);
} }
const derivedCurrencyFactor = const derivedCurrencyFactor =
this.derivedCurrencyFactors[`${aFromCurrency}${aToCurrency}`]; this.derivedCurrencyFactors[
`${normalizedFromCurrency}${normalizedToCurrency}`
];
let factor: number; let factor: number;
if (aFromCurrency === aToCurrency) { if (normalizedFromCurrency === normalizedToCurrency) {
factor = 1; factor = 1;
} else if (derivedCurrencyFactor) { } else if (derivedCurrencyFactor) {
factor = derivedCurrencyFactor; factor = derivedCurrencyFactor;
} else { } else {
const dataSource = const dataSource =
this.dataProviderService.getDataSourceForExchangeRates(); this.dataProviderService.getDataSourceForExchangeRates();
const symbol = `${aFromCurrency}${aToCurrency}`; const symbol = `${normalizedFromCurrency}${normalizedToCurrency}`;
const marketData = await this.marketDataService.get({ const marketData = await this.marketDataService.get({
dataSource, dataSource,
@ -303,28 +356,28 @@ export class ExchangeRateDataService {
let marketPriceBaseCurrencyToCurrency: number; let marketPriceBaseCurrencyToCurrency: number;
try { try {
if (aFromCurrency === DEFAULT_CURRENCY) { if (normalizedFromCurrency === DEFAULT_CURRENCY) {
marketPriceBaseCurrencyFromCurrency = 1; marketPriceBaseCurrencyFromCurrency = 1;
} else { } else {
marketPriceBaseCurrencyFromCurrency = ( marketPriceBaseCurrencyFromCurrency = (
await this.marketDataService.get({ await this.marketDataService.get({
dataSource, dataSource,
date: aDate, date: aDate,
symbol: `${DEFAULT_CURRENCY}${aFromCurrency}` symbol: `${DEFAULT_CURRENCY}${normalizedFromCurrency}`
}) })
)?.marketPrice; )?.marketPrice;
} }
} catch {} } catch {}
try { try {
if (aToCurrency === DEFAULT_CURRENCY) { if (normalizedToCurrency === DEFAULT_CURRENCY) {
marketPriceBaseCurrencyToCurrency = 1; marketPriceBaseCurrencyToCurrency = 1;
} else { } else {
marketPriceBaseCurrencyToCurrency = ( marketPriceBaseCurrencyToCurrency = (
await this.marketDataService.get({ await this.marketDataService.get({
dataSource, dataSource,
date: aDate, date: aDate,
symbol: `${DEFAULT_CURRENCY}${aToCurrency}` symbol: `${DEFAULT_CURRENCY}${normalizedToCurrency}`
}) })
)?.marketPrice; )?.marketPrice;
} }
@ -338,14 +391,14 @@ export class ExchangeRateDataService {
} }
if (isNumber(factor) && !isNaN(factor)) { if (isNumber(factor) && !isNaN(factor)) {
return factor * aValue; return factor * normalizedValue;
} }
Logger.error( Logger.error(
`No exchange rate has been found for ${aFromCurrency}${aToCurrency} at ${format( `No exchange rate has been found for ${normalizedFromCurrency}${normalizedToCurrency} at ${format(
aDate, aDate,
DATE_FORMAT DATE_FORMAT
)}`, )}. Please complement market data for USD${normalizedFromCurrency} and USD${normalizedToCurrency}.`,
'ExchangeRateDataService' 'ExchangeRateDataService'
); );
@ -366,27 +419,50 @@ export class ExchangeRateDataService {
const dates = eachDayOfInterval({ end: endDate, start: startDate }); const dates = eachDayOfInterval({ end: endDate, start: startDate });
const factors: { [dateString: string]: number } = {}; const factors: { [dateString: string]: number } = {};
if (currencyFrom === currencyTo) { let normalizedCurrencyFrom = currencyFrom;
let normalizedCurrencyTo = currencyTo;
let conversionFactorFrom = 1;
let conversionFactorTo = 1;
const fromDerived = DERIVED_CURRENCIES.find(
(c) => c.currency === currencyFrom
);
if (fromDerived) {
normalizedCurrencyFrom = fromDerived.rootCurrency;
conversionFactorFrom = 1 / fromDerived.factor;
}
const toDerived = DERIVED_CURRENCIES.find((c) => c.currency === currencyTo);
if (toDerived) {
normalizedCurrencyTo = toDerived.rootCurrency;
conversionFactorTo = toDerived.factor;
}
if (normalizedCurrencyFrom === normalizedCurrencyTo) {
for (const date of dates) { for (const date of dates) {
factors[format(date, DATE_FORMAT)] = 1; factors[format(date, DATE_FORMAT)] =
conversionFactorFrom * conversionFactorTo;
} }
return factors; return factors;
} }
const derivedCurrencyFactor = const derivedCurrencyFactor =
this.derivedCurrencyFactors[`${currencyFrom}${currencyTo}`]; this.derivedCurrencyFactors[
`${normalizedCurrencyFrom}${normalizedCurrencyTo}`
];
if (derivedCurrencyFactor) { if (derivedCurrencyFactor) {
for (const date of dates) { for (const date of dates) {
factors[format(date, DATE_FORMAT)] = derivedCurrencyFactor; factors[format(date, DATE_FORMAT)] =
conversionFactorFrom * derivedCurrencyFactor * conversionFactorTo;
} }
return factors; return factors;
} }
const dataSource = this.dataProviderService.getDataSourceForExchangeRates(); const dataSource = this.dataProviderService.getDataSourceForExchangeRates();
const symbol = `${currencyFrom}${currencyTo}`; const symbol = `${normalizedCurrencyFrom}${normalizedCurrencyTo}`;
const marketData = await this.marketDataService.getRange({ const marketData = await this.marketDataService.getRange({
assetProfileIdentifiers: [ assetProfileIdentifiers: [
@ -400,7 +476,8 @@ export class ExchangeRateDataService {
if (marketData?.length > 0) { if (marketData?.length > 0) {
for (const { date, marketPrice } of marketData) { for (const { date, marketPrice } of marketData) {
factors[format(date, DATE_FORMAT)] = marketPrice; factors[format(date, DATE_FORMAT)] =
conversionFactorFrom * marketPrice * conversionFactorTo;
} }
} else { } else {
// Calculate indirectly via base currency // Calculate indirectly via base currency
@ -413,7 +490,7 @@ export class ExchangeRateDataService {
} = {}; } = {};
try { try {
if (currencyFrom === DEFAULT_CURRENCY) { if (normalizedCurrencyFrom === DEFAULT_CURRENCY) {
for (const date of dates) { for (const date of dates) {
marketPriceBaseCurrencyFromCurrency[format(date, DATE_FORMAT)] = 1; marketPriceBaseCurrencyFromCurrency[format(date, DATE_FORMAT)] = 1;
} }
@ -422,7 +499,7 @@ export class ExchangeRateDataService {
assetProfileIdentifiers: [ assetProfileIdentifiers: [
{ {
dataSource, dataSource,
symbol: `${DEFAULT_CURRENCY}${currencyFrom}` symbol: `${DEFAULT_CURRENCY}${normalizedCurrencyFrom}`
} }
], ],
dateQuery: { gte: startDate, lt: endDate } dateQuery: { gte: startDate, lt: endDate }
@ -436,7 +513,7 @@ export class ExchangeRateDataService {
} catch {} } catch {}
try { try {
if (currencyTo === DEFAULT_CURRENCY) { if (normalizedCurrencyTo === DEFAULT_CURRENCY) {
for (const date of dates) { for (const date of dates) {
marketPriceBaseCurrencyToCurrency[format(date, DATE_FORMAT)] = 1; marketPriceBaseCurrencyToCurrency[format(date, DATE_FORMAT)] = 1;
} }
@ -445,7 +522,7 @@ export class ExchangeRateDataService {
assetProfileIdentifiers: [ assetProfileIdentifiers: [
{ {
dataSource, dataSource,
symbol: `${DEFAULT_CURRENCY}${currencyTo}` symbol: `${DEFAULT_CURRENCY}${normalizedCurrencyTo}`
} }
], ],
dateQuery: { dateQuery: {
@ -471,16 +548,17 @@ export class ExchangeRateDataService {
if (isNaN(factor)) { if (isNaN(factor)) {
throw new Error('Exchange rate is not a number'); throw new Error('Exchange rate is not a number');
} else { } else {
factors[format(date, DATE_FORMAT)] = factor; factors[format(date, DATE_FORMAT)] =
conversionFactorFrom * factor * conversionFactorTo;
} }
} catch { } catch {
let errorMessage = `No exchange rate has been found for ${currencyFrom}${currencyTo} at ${format( let errorMessage = `No exchange rate has been found for ${normalizedCurrencyFrom}${normalizedCurrencyTo} at ${format(
date, date,
DATE_FORMAT DATE_FORMAT
)}. Please complement market data for ${DEFAULT_CURRENCY}${currencyFrom}`; )}. Please complement market data for ${DEFAULT_CURRENCY}${normalizedCurrencyFrom}`;
if (DEFAULT_CURRENCY !== currencyTo) { if (DEFAULT_CURRENCY !== normalizedCurrencyTo) {
errorMessage = `${errorMessage} and ${DEFAULT_CURRENCY}${currencyTo}`; errorMessage = `${errorMessage} and ${DEFAULT_CURRENCY}${normalizedCurrencyTo}`;
} }
Logger.error(`${errorMessage}.`, 'ExchangeRateDataService'); Logger.error(`${errorMessage}.`, 'ExchangeRateDataService');

5
apps/api/src/services/market-data/market-data.service.ts

@ -35,8 +35,9 @@ export class MarketDataService {
where: { where: {
dataSource, dataSource,
symbol, symbol,
date: resetHours(date) date: { lte: resetHours(date) }
} },
orderBy: { date: 'desc' }
}); });
} }

1583
package-lock.json

File diff suppressed because it is too large
Loading…
Cancel
Save