Bugfix/fix search for cryptocurrencies (#348)
* Fix the search for cryptocurrency symbols * Update changelog
This commit is contained in:
parent
a31d79821d
commit
bf8856ad19
@ -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/),
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed the search functionality for cryptocurrency symbols
|
||||||
|
|
||||||
## 1.46.0 - 05.09.2021
|
## 1.46.0 - 05.09.2021
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -19,7 +19,10 @@ import { format } from 'date-fns';
|
|||||||
import { AlphaVantageService } from './alpha-vantage/alpha-vantage.service';
|
import { AlphaVantageService } from './alpha-vantage/alpha-vantage.service';
|
||||||
import { GhostfolioScraperApiService } from './ghostfolio-scraper-api/ghostfolio-scraper-api.service';
|
import { GhostfolioScraperApiService } from './ghostfolio-scraper-api/ghostfolio-scraper-api.service';
|
||||||
import { RakutenRapidApiService } from './rakuten-rapid-api/rakuten-rapid-api.service';
|
import { RakutenRapidApiService } from './rakuten-rapid-api/rakuten-rapid-api.service';
|
||||||
import { YahooFinanceService } from './yahoo-finance/yahoo-finance.service';
|
import {
|
||||||
|
convertToYahooFinanceSymbol,
|
||||||
|
YahooFinanceService
|
||||||
|
} from './yahoo-finance/yahoo-finance.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DataProviderService {
|
export class DataProviderService {
|
||||||
@ -44,6 +47,9 @@ export class DataProviderService {
|
|||||||
return this.ghostfolioScraperApiService.get(aSymbols);
|
return this.ghostfolioScraperApiService.get(aSymbols);
|
||||||
} else if (isRakutenRapidApiSymbol(symbol)) {
|
} else if (isRakutenRapidApiSymbol(symbol)) {
|
||||||
return this.rakutenRapidApiService.get(aSymbols);
|
return this.rakutenRapidApiService.get(aSymbols);
|
||||||
|
} else {
|
||||||
|
const yahooFinanceSymbol = convertToYahooFinanceSymbol(symbol);
|
||||||
|
return this.yahooFinanceService.get([yahooFinanceSymbol]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,16 +43,12 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async get(
|
public async get(
|
||||||
aSymbols: string[]
|
aYahooFinanceSymbols: string[]
|
||||||
): Promise<{ [symbol: string]: IDataProviderResponse }> {
|
): Promise<{ [symbol: string]: IDataProviderResponse }> {
|
||||||
if (aSymbols.length <= 0) {
|
if (aYahooFinanceSymbols.length <= 0) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const yahooSymbols = aSymbols.map((symbol) => {
|
|
||||||
return this.convertToYahooSymbol(symbol);
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response: { [symbol: string]: IDataProviderResponse } = {};
|
const response: { [symbol: string]: IDataProviderResponse } = {};
|
||||||
|
|
||||||
@ -60,12 +56,12 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
[symbol: string]: IYahooFinanceQuoteResponse;
|
[symbol: string]: IYahooFinanceQuoteResponse;
|
||||||
} = await yahooFinance.quote({
|
} = await yahooFinance.quote({
|
||||||
modules: ['price', 'summaryProfile'],
|
modules: ['price', 'summaryProfile'],
|
||||||
symbols: yahooSymbols
|
symbols: aYahooFinanceSymbols
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const [yahooSymbol, value] of Object.entries(data)) {
|
for (const [yahooFinanceSymbol, value] of Object.entries(data)) {
|
||||||
// Convert symbols back
|
// Convert symbols back
|
||||||
const symbol = convertFromYahooSymbol(yahooSymbol);
|
const symbol = convertFromYahooFinanceSymbol(yahooFinanceSymbol);
|
||||||
|
|
||||||
const { assetClass, assetSubClass } = this.parseAssetClass(value.price);
|
const { assetClass, assetSubClass } = this.parseAssetClass(value.price);
|
||||||
|
|
||||||
@ -136,15 +132,15 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const yahooSymbols = aSymbols.map((symbol) => {
|
const yahooFinanceSymbols = aSymbols.map((symbol) => {
|
||||||
return this.convertToYahooSymbol(symbol);
|
return convertToYahooFinanceSymbol(symbol);
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const historicalData: {
|
const historicalData: {
|
||||||
[symbol: string]: IYahooFinanceHistoricalResponse[];
|
[symbol: string]: IYahooFinanceHistoricalResponse[];
|
||||||
} = await yahooFinance.historical({
|
} = await yahooFinance.historical({
|
||||||
symbols: yahooSymbols,
|
symbols: yahooFinanceSymbols,
|
||||||
from: format(from, DATE_FORMAT),
|
from: format(from, DATE_FORMAT),
|
||||||
to: format(to, DATE_FORMAT)
|
to: format(to, DATE_FORMAT)
|
||||||
});
|
});
|
||||||
@ -153,9 +149,11 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
|
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
for (const [yahooSymbol, timeSeries] of Object.entries(historicalData)) {
|
for (const [yahooFinanceSymbol, timeSeries] of Object.entries(
|
||||||
|
historicalData
|
||||||
|
)) {
|
||||||
// Convert symbols back
|
// Convert symbols back
|
||||||
const symbol = convertFromYahooSymbol(yahooSymbol);
|
const symbol = convertFromYahooFinanceSymbol(yahooFinanceSymbol);
|
||||||
response[symbol] = {};
|
response[symbol] = {};
|
||||||
|
|
||||||
timeSeries.forEach((timeSerie) => {
|
timeSeries.forEach((timeSerie) => {
|
||||||
@ -175,7 +173,7 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async search(aSymbol: string): Promise<{ items: LookupItem[] }> {
|
public async search(aSymbol: string): Promise<{ items: LookupItem[] }> {
|
||||||
let items: LookupItem[] = [];
|
const items: LookupItem[] = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const get = bent(
|
const get = bent(
|
||||||
@ -192,19 +190,6 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
// filter out undefined symbols
|
// filter out undefined symbols
|
||||||
return quote.symbol;
|
return quote.symbol;
|
||||||
})
|
})
|
||||||
.filter(({ quoteType }) => {
|
|
||||||
return quoteType === 'EQUITY' || quoteType === 'ETF';
|
|
||||||
})
|
|
||||||
.map(({ symbol }) => {
|
|
||||||
return symbol;
|
|
||||||
});
|
|
||||||
|
|
||||||
const marketData = await this.get(symbols);
|
|
||||||
|
|
||||||
items = searchResult.quotes
|
|
||||||
.filter((quote) => {
|
|
||||||
return quote.isYahooFinance;
|
|
||||||
})
|
|
||||||
.filter(({ quoteType }) => {
|
.filter(({ quoteType }) => {
|
||||||
return (
|
return (
|
||||||
quoteType === 'CRYPTOCURRENCY' ||
|
quoteType === 'CRYPTOCURRENCY' ||
|
||||||
@ -220,42 +205,25 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.map(({ longname, shortname, symbol }) => {
|
.map(({ symbol }) => {
|
||||||
return {
|
return symbol;
|
||||||
currency: marketData[symbol]?.currency,
|
|
||||||
dataSource: DataSource.YAHOO,
|
|
||||||
name: longname || shortname,
|
|
||||||
symbol: convertFromYahooSymbol(symbol)
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const marketData = await this.get(symbols);
|
||||||
|
|
||||||
|
for (const [symbol, value] of Object.entries(marketData)) {
|
||||||
|
items.push({
|
||||||
|
symbol,
|
||||||
|
currency: value.currency,
|
||||||
|
dataSource: DataSource.YAHOO,
|
||||||
|
name: value.name
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|
||||||
return { items };
|
return { items };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a symbol to a Yahoo symbol
|
|
||||||
*
|
|
||||||
* Currency: USDCHF=X
|
|
||||||
* Cryptocurrency: BTC-USD
|
|
||||||
*/
|
|
||||||
private convertToYahooSymbol(aSymbol: string) {
|
|
||||||
if (isCurrency(aSymbol)) {
|
|
||||||
if (isCrypto(aSymbol)) {
|
|
||||||
// Add a dash before the last three characters
|
|
||||||
// BTCUSD -> BTC-USD
|
|
||||||
// DOGEUSD -> DOGE-USD
|
|
||||||
return `${aSymbol.substring(0, aSymbol.length - 3)}-${aSymbol.substring(
|
|
||||||
aSymbol.length - 3
|
|
||||||
)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${aSymbol}=X`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return aSymbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
private parseAssetClass(aPrice: IYahooFinancePrice): {
|
private parseAssetClass(aPrice: IYahooFinancePrice): {
|
||||||
assetClass: AssetClass;
|
assetClass: AssetClass;
|
||||||
assetSubClass: AssetSubClass;
|
assetSubClass: AssetSubClass;
|
||||||
@ -290,7 +258,30 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const convertFromYahooSymbol = (aSymbol: string) => {
|
export const convertFromYahooFinanceSymbol = (aYahooFinanceSymbol: string) => {
|
||||||
const symbol = aSymbol.replace('-', '');
|
const symbol = aYahooFinanceSymbol.replace('-', '');
|
||||||
return symbol.replace('=X', '');
|
return symbol.replace('=X', '');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a symbol to a Yahoo Finance symbol
|
||||||
|
*
|
||||||
|
* Currency: USDCHF=X
|
||||||
|
* Cryptocurrency: BTC-USD
|
||||||
|
*/
|
||||||
|
export const convertToYahooFinanceSymbol = (aSymbol: string) => {
|
||||||
|
if (isCurrency(aSymbol)) {
|
||||||
|
if (isCrypto(aSymbol)) {
|
||||||
|
// Add a dash before the last three characters
|
||||||
|
// BTCUSD -> BTC-USD
|
||||||
|
// DOGEUSD -> DOGE-USD
|
||||||
|
return `${aSymbol.substring(0, aSymbol.length - 3)}-${aSymbol.substring(
|
||||||
|
aSymbol.length - 3
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${aSymbol}=X`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return aSymbol;
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user