Feature/increase robustness of exchange rates by always getting quotes (#2875)

* Always get quotes (with fallback to historical data)

* Update changelog
pull/2877/head
Thomas Kaul 9 months ago committed by GitHub
parent 217bb6aa5a
commit ba3cf82c6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Changed
- Inreased the robustness of the exchange rates by always getting quotes in the exchange rate data service
## 2.39.0 - 2024-01-14
### Changed

@ -243,7 +243,7 @@ export class BenchmarkService {
});
const exchangeRateAtStartDate =
exchangeRates[currentSymbolItem.currency]?.[
exchangeRates[`${currentSymbolItem.currency}${userCurrency}`]?.[
format(startDate, DATE_FORMAT)
];
@ -275,7 +275,9 @@ export class BenchmarkService {
}
const exchangeRate =
exchangeRates[format(marketDataItem.date, DATE_FORMAT)];
exchangeRates[`${currentSymbolItem.currency}${userCurrency}`]?.[
format(marketDataItem.date, DATE_FORMAT)
];
const exchangeRateFactor =
isNumber(exchangeRateAtStartDate) && isNumber(exchangeRate)
@ -300,7 +302,10 @@ export class BenchmarkService {
);
if (currentSymbolItem?.marketPrice && !includesToday) {
const exchangeRate = exchangeRates[format(new Date(), DATE_FORMAT)];
const exchangeRate =
exchangeRates[`${currentSymbolItem.currency}${userCurrency}`]?.[
format(new Date(), DATE_FORMAT)
];
const exchangeRateFactor =
isNumber(exchangeRateAtStartDate) && isNumber(exchangeRate)

@ -298,7 +298,8 @@ export class PortfolioCalculator {
start,
step,
symbol,
exchangeRates: exchangeRatesByCurrency[currencies[symbol]],
exchangeRates:
exchangeRatesByCurrency[`${currencies[symbol]}${this.currency}`],
isChartMode: true
});
@ -565,7 +566,11 @@ export class PortfolioCalculator {
for (const item of lastTransactionPoint.items) {
const marketPriceInBaseCurrency = marketSymbolMap[endDateString]?.[
item.symbol
]?.mul(exchangeRatesByCurrency[item.currency]?.[endDateString]);
]?.mul(
exchangeRatesByCurrency[`${item.currency}${this.currency}`]?.[
endDateString
]
);
const {
grossPerformance,
@ -585,7 +590,8 @@ export class PortfolioCalculator {
end,
marketSymbolMap,
start,
exchangeRates: exchangeRatesByCurrency[item.currency],
exchangeRates:
exchangeRatesByCurrency[`${item.currency}${this.currency}`],
symbol: item.symbol
});

@ -33,6 +33,10 @@ export class YahooFinanceDataEnhancerService implements DataEnhancerInterface {
symbol = `${DEFAULT_CURRENCY}${symbol}`;
}
if (symbol.includes(`${DEFAULT_CURRENCY}ZAC`)) {
symbol = `${DEFAULT_CURRENCY}ZAc`;
}
return symbol.replace('=X', '');
}

@ -7,14 +7,14 @@ export const ExchangeRateDataServiceMock = {
}): Promise<any> => {
if (targetCurrency === 'CHF') {
return Promise.resolve({
CHF: {
CHFCHF: {
'2015-01-01': 1,
'2017-12-31': 1,
'2018-01-01': 1,
'2023-01-03': 1,
'2023-07-10': 1
},
USD: {
USDCHF: {
'2015-01-01': 0.9941099999999999,
'2017-12-31': 0.9787,
'2018-01-01': 0.97373,

@ -64,7 +64,8 @@ export class ExchangeRateDataService {
} = {};
for (let currency of currencies) {
exchangeRatesByCurrency[currency] = await this.getExchangeRates({
exchangeRatesByCurrency[`${currency}${targetCurrency}`] =
await this.getExchangeRates({
startDate,
currencyFrom: currency,
currencyTo: targetCurrency
@ -82,17 +83,25 @@ export class ExchangeRateDataService {
let dateString = format(date, DATE_FORMAT);
// Check if the exchange rate for the current date is missing
if (isNaN(exchangeRatesByCurrency[currency][dateString])) {
if (
isNaN(
exchangeRatesByCurrency[`${currency}${targetCurrency}`][dateString]
)
) {
// If missing, fill with the previous exchange rate
exchangeRatesByCurrency[currency][dateString] = previousExchangeRate;
exchangeRatesByCurrency[`${currency}${targetCurrency}`][dateString] =
previousExchangeRate;
if (currency === DEFAULT_CURRENCY) {
Logger.error(
`No exchange rate has been found for ${DEFAULT_CURRENCY}${currency} at ${dateString}`,
`No exchange rate has been found for ${currency}${targetCurrency} at ${dateString}`,
'ExchangeRateDataService'
);
}
} else {
// If available, update the previous exchange rate
previousExchangeRate = exchangeRatesByCurrency[currency][dateString];
previousExchangeRate =
exchangeRatesByCurrency[`${currency}${targetCurrency}`][dateString];
}
}
}
@ -136,9 +145,6 @@ export class ExchangeRateDataService {
getYesterday()
);
if (Object.keys(result).length !== this.currencyPairs.length) {
// Load currencies directly from data provider as a fallback
// if historical data is not fully available
const quotes = await this.dataProviderService.getQuotes({
items: this.currencyPairs.map(({ dataSource, symbol }) => {
return { dataSource, symbol };
@ -155,7 +161,6 @@ export class ExchangeRateDataService {
};
}
}
}
const resultExtended = result;
@ -253,6 +258,7 @@ export class ExchangeRateDataService {
`No exchange rate has been found for ${aFromCurrency}${aToCurrency}`,
'ExchangeRateDataService'
);
return aValue;
}

Loading…
Cancel
Save