Refactor custom cryptocurrencies (#433)

pull/434/head
Thomas Kaul 3 years ago committed by GitHub
parent e24e5e1c44
commit 19e2d54791
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Added support for more cryptocurrency symbols like _Avalanche_, _Polygon_, _SHIBA INU_ etc.
### Changed
- Changed the data provider service to handle a dynamic list of services

@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { CryptocurrencyService } from './cryptocurrency.service';
@Module({
providers: [CryptocurrencyService],
exports: [CryptocurrencyService]
})
export class CryptocurrencyModule {}

@ -0,0 +1,28 @@
import { Injectable } from '@nestjs/common';
const cryptocurrencies = require('cryptocurrencies');
const customCryptocurrencies = require('./custom-cryptocurrencies.json');
@Injectable()
export class CryptocurrencyService {
private combinedCryptocurrencies: string[];
public constructor() {}
public isCrypto(aSymbol = '') {
const cryptocurrencySymbol = aSymbol.substring(0, aSymbol.length - 3);
return this.getCryptocurrencies().includes(cryptocurrencySymbol);
}
private getCryptocurrencies() {
if (!this.combinedCryptocurrencies) {
this.combinedCryptocurrencies = [
...cryptocurrencies.symbols(),
...Object.keys(customCryptocurrencies)
];
}
return this.combinedCryptocurrencies;
}
}

@ -0,0 +1,6 @@
{
"1INCH": "1inch",
"AVAX": "Avalanche",
"MATIC": "Polygon",
"SHIB": "Shiba Inu"
}

@ -1,4 +1,5 @@
import { ConfigurationModule } from '@ghostfolio/api/services/configuration.module';
import { CryptocurrencyModule } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.module';
import { TrackinsightDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/trackinsight/trackinsight.service';
import { GhostfolioScraperApiService } from '@ghostfolio/api/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service';
import { RakutenRapidApiService } from '@ghostfolio/api/services/data-provider/rakuten-rapid-api/rakuten-rapid-api.service';
@ -10,7 +11,7 @@ import { AlphaVantageService } from './alpha-vantage/alpha-vantage.service';
import { DataProviderService } from './data-provider.service';
@Module({
imports: [ConfigurationModule, PrismaModule],
imports: [ConfigurationModule, CryptocurrencyModule, PrismaModule],
providers: [
AlphaVantageService,
DataProviderService,

@ -1,6 +1,7 @@
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service';
import { DataEnhancerInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-enhancer.interface';
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
import {
IDataGatheringItem,
IDataProviderHistoricalResponse,
@ -13,7 +14,6 @@ import { Inject, Injectable } from '@nestjs/common';
import { DataSource, MarketData } from '@prisma/client';
import { format } from 'date-fns';
import { isEmpty } from 'lodash';
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
@Injectable()
export class DataProviderService {

@ -1,11 +1,11 @@
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { Granularity } from '@ghostfolio/common/types';
import { DataSource } from '@prisma/client';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
} from '../../interfaces/interfaces';
import { DataSource } from '@prisma/client';
export interface DataProviderInterface {
canHandle(symbol: string): boolean;

@ -1,6 +1,7 @@
import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface';
import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service';
import { UNKNOWN_KEY } from '@ghostfolio/common/config';
import { DATE_FORMAT, isCrypto, isCurrency } from '@ghostfolio/common/helper';
import { DATE_FORMAT, isCurrency } from '@ghostfolio/common/helper';
import { Granularity } from '@ghostfolio/common/types';
import { Injectable } from '@nestjs/common';
import { AssetClass, AssetSubClass, DataSource } from '@prisma/client';
@ -26,7 +27,9 @@ import {
export class YahooFinanceService implements DataProviderInterface {
private yahooFinanceHostname = 'https://query1.finance.yahoo.com';
public constructor() {}
public constructor(
private readonly cryptocurrencyService: CryptocurrencyService
) {}
public canHandle(symbol: string) {
return true;
@ -65,7 +68,8 @@ export class YahooFinanceService implements DataProviderInterface {
dataSource: DataSource.YAHOO,
exchange: this.parseExchange(value.price?.exchangeName),
marketState:
value.price?.marketState === 'REGULAR' || isCrypto(symbol)
value.price?.marketState === 'REGULAR' ||
this.cryptocurrencyService.isCrypto(symbol)
? MarketState.open
: MarketState.closed,
marketPrice: value.price?.regularMarketPrice || 0,
@ -249,7 +253,10 @@ export class YahooFinanceService implements DataProviderInterface {
) {
if (isCurrency(aSymbol.substring(0, aSymbol.length - 3))) {
return `${aSymbol}=X`;
} else if (isCrypto(aSymbol) || isCrypto(aSymbol.replace('1', ''))) {
} else if (
this.cryptocurrencyService.isCrypto(aSymbol) ||
this.cryptocurrencyService.isCrypto(aSymbol.replace('1', ''))
) {
// Add a dash before the last three characters
// BTCUSD -> BTC-USD
// DOGEUSD -> DOGE-USD

@ -1,11 +0,0 @@
{
"SHIB": "SHIBA INU USD",
"SOL1": "Solana",
"DOT1": "Polkadot",
"LUNA1": "Terra",
"AVAX": "Avalanche",
"MATIC": "MaticNetwork",
"ATOM1": "Cosmos",
"FTT1": "FTXToken",
"1INCH": "1inch"
}

@ -3,11 +3,6 @@ import { getDate, getMonth, getYear, parse, subDays } from 'date-fns';
import { ghostfolioScraperApiSymbolPrefix } from './config';
const cryptocurrencies = require('cryptocurrencies');
const customSymbolList = require('./customCryptocurrencies.json')
customSymbolList.symbols = () => Object.keys(customSymbolList);
export const DEMO_USER_ID = '9b112b4d-3b7d-4bad-9bdd-3b0f7b4dac2f';
export function capitalize(aString: string) {
@ -53,9 +48,9 @@ export function getUtc(aDateString: string) {
return new Date(
Date.UTC(
parseInt(yearString),
parseInt(monthString) - 1,
parseInt(dayString)
parseInt(yearString, 10),
parseInt(monthString, 10) - 1,
parseInt(dayString, 10)
)
);
}
@ -82,11 +77,6 @@ export function groupBy<T, K extends keyof T>(
return map;
}
export function isCrypto(aSymbol = '') {
const cryptocurrencySymbol = aSymbol.substring(0, aSymbol.length - 3);
return cryptocurrencies.symbols().includes(cryptocurrencySymbol) || customSymbolList.symbols().includes(cryptocurrencySymbol);
}
export function isCurrency(aSymbol = '') {
return currencies[aSymbol];
}

Loading…
Cancel
Save