Browse Source

Merge e6ef2f5289 into 97037e9481

pull/4290/merge
Miguel Borges de Freitas 1 month ago
committed by GitHub
parent
commit
3f5735c347
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      apps/api/src/app/admin/admin.module.ts
  2. 5
      apps/api/src/app/admin/admin.service.ts
  3. 3
      apps/api/src/app/app.controller.ts
  4. 2
      apps/api/src/app/app.module.ts
  5. 2
      apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.module.ts
  6. 4
      apps/api/src/app/info/info.module.ts
  7. 6
      apps/api/src/app/info/info.service.ts
  8. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts
  9. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts
  10. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts
  11. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts
  12. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts
  13. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts
  14. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts
  15. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts
  16. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts
  17. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts
  18. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts
  19. 7
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts
  20. 12
      apps/api/src/services/cryptocurrency/cryptocurrency.service.ts
  21. 13
      apps/api/src/services/currency/currency.module.ts
  22. 77
      apps/api/src/services/currency/currency.service.ts
  23. 2
      apps/api/src/services/data-provider/data-provider.module.ts
  24. 20
      apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts
  25. 2
      apps/api/src/services/exchange-rate-data/exchange-rate-data.module.ts
  26. 73
      apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts

2
apps/api/src/app/admin/admin.module.ts

@ -4,6 +4,7 @@ import { TransformDataSourceInRequestModule } from '@ghostfolio/api/interceptors
import { ApiModule } from '@ghostfolio/api/services/api/api.module';
import { BenchmarkModule } from '@ghostfolio/api/services/benchmark/benchmark.module';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { CurrencyModule } from '@ghostfolio/api/services/currency/currency.module';
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module';
import { MarketDataModule } from '@ghostfolio/api/services/market-data/market-data.module';
@ -23,6 +24,7 @@ import { QueueModule } from './queue/queue.module';
ApiModule,
BenchmarkModule,
ConfigurationModule,
CurrencyModule,
DataGatheringModule,
DataProviderModule,
ExchangeRateDataModule,

5
apps/api/src/app/admin/admin.service.ts

@ -3,6 +3,7 @@ import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscripti
import { environment } from '@ghostfolio/api/environments/environment';
import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { CurrencyService } from '@ghostfolio/api/services/currency/currency.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
@ -50,6 +51,7 @@ import { groupBy } from 'lodash';
export class AdminService {
public constructor(
private readonly benchmarkService: BenchmarkService,
private readonly currencyService: CurrencyService,
private readonly configurationService: ConfigurationService,
private readonly dataProviderService: DataProviderService,
private readonly exchangeRateDataService: ExchangeRateDataService,
@ -132,7 +134,7 @@ export class AdminService {
}
public async get(): Promise<AdminData> {
const exchangeRates = this.exchangeRateDataService
const exchangeRates = this.currencyService
.getCurrencies()
.filter((currency) => {
return currency !== DEFAULT_CURRENCY;
@ -560,6 +562,7 @@ export class AdminService {
if (key === PROPERTY_IS_READ_ONLY_MODE && value === 'true') {
await this.putSetting(PROPERTY_IS_USER_SIGNUP_ENABLED, 'false');
} else if (key === PROPERTY_CURRENCIES) {
await this.currencyService.initialize();
await this.exchangeRateDataService.initialize();
}

3
apps/api/src/app/app.controller.ts

@ -1,3 +1,4 @@
import { CurrencyService } from '@ghostfolio/api/services/currency/currency.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { Controller } from '@nestjs/common';
@ -5,6 +6,7 @@ import { Controller } from '@nestjs/common';
@Controller()
export class AppController {
public constructor(
private readonly currencyService: CurrencyService,
private readonly exchangeRateDataService: ExchangeRateDataService
) {
this.initialize();
@ -12,6 +14,7 @@ export class AppController {
private async initialize() {
try {
await this.currencyService.initialize();
await this.exchangeRateDataService.initialize();
} catch {}
}

2
apps/api/src/app/app.module.ts

@ -22,6 +22,7 @@ import { ServeStaticModule } from '@nestjs/serve-static';
import { StatusCodes } from 'http-status-codes';
import { join } from 'path';
import { CurrencyModule } from '../services/currency/currency.module';
import { AccessModule } from './access/access.module';
import { AccountModule } from './account/account.module';
import { AdminModule } from './admin/admin.module';
@ -75,6 +76,7 @@ import { UserModule } from './user/user.module';
CacheModule,
ConfigModule.forRoot(),
ConfigurationModule,
CurrencyModule,
DataGatheringModule,
DataProviderModule,
EventEmitterModule.forRoot(),

2
apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.module.ts

@ -1,6 +1,7 @@
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { CryptocurrencyModule } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.module';
import { CurrencyModule } from '@ghostfolio/api/services/currency/currency.module';
import { AlphaVantageService } from '@ghostfolio/api/services/data-provider/alpha-vantage/alpha-vantage.service';
import { CoinGeckoService } from '@ghostfolio/api/services/data-provider/coingecko/coingecko.service';
import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service';
@ -25,6 +26,7 @@ import { GhostfolioService } from './ghostfolio.service';
@Module({
controllers: [GhostfolioController],
imports: [
CurrencyModule,
CryptocurrencyModule,
DataProviderModule,
MarketDataModule,

4
apps/api/src/app/info/info.module.ts

@ -4,8 +4,8 @@ import { UserModule } from '@ghostfolio/api/app/user/user.module';
import { TransformDataSourceInResponseModule } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.module';
import { BenchmarkModule } from '@ghostfolio/api/services/benchmark/benchmark.module';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { CurrencyModule } from '@ghostfolio/api/services/currency/currency.module';
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module';
import { PropertyModule } from '@ghostfolio/api/services/property/property.module';
import { DataGatheringModule } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.module';
import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile/symbol-profile.module';
@ -21,9 +21,9 @@ import { InfoService } from './info.service';
imports: [
BenchmarkModule,
ConfigurationModule,
CurrencyModule,
DataGatheringModule,
DataProviderModule,
ExchangeRateDataModule,
JwtModule.register({
secret: process.env.JWT_SECRET_KEY,
signOptions: { expiresIn: '30 days' }

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

@ -3,7 +3,7 @@ import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.s
import { UserService } from '@ghostfolio/api/app/user/user.service';
import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { CurrencyService } from '@ghostfolio/api/services/currency/currency.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import {
DEFAULT_CURRENCY,
@ -41,7 +41,7 @@ export class InfoService {
public constructor(
private readonly benchmarkService: BenchmarkService,
private readonly configurationService: ConfigurationService,
private readonly exchangeRateDataService: ExchangeRateDataService,
private readonly currencyService: CurrencyService,
private readonly jwtService: JwtService,
private readonly platformService: PlatformService,
private readonly propertyService: PropertyService,
@ -127,7 +127,7 @@ export class InfoService {
statistics,
subscriptionOffers,
baseCurrency: DEFAULT_CURRENCY,
currencies: this.exchangeRateDataService.getCurrencies()
currencies: this.currencyService.getCurrencies()
};
}

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts

@ -63,12 +63,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts

@ -63,12 +63,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts

@ -63,12 +63,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts

@ -76,12 +76,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts

@ -63,12 +63,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts

@ -76,12 +76,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts

@ -63,12 +63,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts

@ -63,12 +63,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts

@ -76,12 +76,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts

@ -58,12 +58,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts

@ -77,12 +77,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

7
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts

@ -77,12 +77,7 @@ describe('PortfolioCalculator', () => {
currentRateService = new CurrentRateService(null, null, null, null);
exchangeRateDataService = new ExchangeRateDataService(
null,
null,
null,
null
);
exchangeRateDataService = new ExchangeRateDataService(null, null, null);
portfolioSnapshotService = new PortfolioSnapshotService(null);

12
apps/api/src/services/cryptocurrency/cryptocurrency.service.ts

@ -1,5 +1,3 @@
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { Injectable } from '@nestjs/common';
const cryptocurrencies = require('../../assets/cryptocurrencies/cryptocurrencies.json');
@ -10,12 +8,10 @@ export class CryptocurrencyService {
private combinedCryptocurrencies: string[];
public isCryptocurrency(aSymbol = '') {
const cryptocurrencySymbol = aSymbol.substring(0, aSymbol.length - 3);
return (
aSymbol.endsWith(DEFAULT_CURRENCY) &&
this.getCryptocurrencies().includes(cryptocurrencySymbol)
);
const cryptocurrencySymbol = aSymbol.includes('-')
? aSymbol.split('-')[0]
: aSymbol;
return this.getCryptocurrencies().includes(cryptocurrencySymbol);
}
private getCryptocurrencies() {

13
apps/api/src/services/currency/currency.module.ts

@ -0,0 +1,13 @@
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { CurrencyService } from '@ghostfolio/api/services/currency/currency.service';
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module';
import { PropertyModule } from '@ghostfolio/api/services/property/property.module';
import { Module } from '@nestjs/common';
@Module({
exports: [CurrencyService],
imports: [ConfigurationModule, PrismaModule, PropertyModule],
providers: [CurrencyService]
})
export class CurrencyModule {}

77
apps/api/src/services/currency/currency.service.ts

@ -0,0 +1,77 @@
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import {
DEFAULT_CURRENCY,
DERIVED_CURRENCIES,
PROPERTY_CURRENCIES
} from '@ghostfolio/common/config';
import { Injectable } from '@nestjs/common';
import { uniq } from 'lodash';
@Injectable()
export class CurrencyService {
private currencies: string[] = [];
public constructor(
private readonly prismaService: PrismaService,
private readonly propertyService: PropertyService
) {}
public getCurrencies() {
return this.currencies?.length > 0 ? this.currencies : [DEFAULT_CURRENCY];
}
public async initialize() {
this.currencies = await this.prepareCurrencies();
}
private async prepareCurrencies(): Promise<string[]> {
let currencies: string[] = [DEFAULT_CURRENCY];
(
await this.prismaService.account.findMany({
distinct: ['currency'],
orderBy: [{ currency: 'asc' }],
select: { currency: true },
where: {
currency: {
not: null
}
}
})
).forEach(({ currency }) => {
currencies.push(currency);
});
(
await this.prismaService.symbolProfile.findMany({
distinct: ['currency'],
orderBy: [{ currency: 'asc' }],
select: { currency: true }
})
).forEach(({ currency }) => {
currencies.push(currency);
});
const customCurrencies = (await this.propertyService.getByKey(
PROPERTY_CURRENCIES
)) as string[];
if (customCurrencies?.length > 0) {
currencies = currencies.concat(customCurrencies);
}
// Add derived currencies
currencies.push('USX');
for (const { currency, rootCurrency } of DERIVED_CURRENCIES) {
if (currencies.includes(currency) || currencies.includes(rootCurrency)) {
currencies.push(currency);
currencies.push(rootCurrency);
}
}
return uniq(currencies).filter(Boolean).sort();
}
}

2
apps/api/src/services/data-provider/data-provider.module.ts

@ -1,6 +1,7 @@
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { CryptocurrencyModule } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.module';
import { CurrencyModule } from '@ghostfolio/api/services/currency/currency.module';
import { AlphaVantageService } from '@ghostfolio/api/services/data-provider/alpha-vantage/alpha-vantage.service';
import { CoinGeckoService } from '@ghostfolio/api/services/data-provider/coingecko/coingecko.service';
import { EodHistoricalDataService } from '@ghostfolio/api/services/data-provider/eod-historical-data/eod-historical-data.service';
@ -24,6 +25,7 @@ import { DataProviderService } from './data-provider.service';
@Module({
imports: [
ConfigurationModule,
CurrencyModule,
CryptocurrencyModule,
DataEnhancerModule,
MarketDataModule,

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

@ -1,4 +1,5 @@
import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service';
import { CurrencyService } from '@ghostfolio/api/services/currency/currency.service';
import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service';
import {
DataProviderInterface,
@ -12,7 +13,6 @@ import {
IDataProviderHistoricalResponse,
IDataProviderResponse
} from '@ghostfolio/api/services/interfaces/interfaces';
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
import {
DataProviderInfo,
@ -34,6 +34,7 @@ import { Quote } from 'yahoo-finance2/dist/esm/src/modules/quote';
@Injectable()
export class YahooFinanceService implements DataProviderInterface {
public constructor(
private readonly currencyService: CurrencyService,
private readonly cryptocurrencyService: CryptocurrencyService,
private readonly yahooFinanceDataEnhancerService: YahooFinanceDataEnhancerService
) {}
@ -246,21 +247,16 @@ export class YahooFinanceService implements DataProviderInterface {
.filter(({ quoteType, symbol }) => {
return (
(quoteType === 'CRYPTOCURRENCY' &&
this.cryptocurrencyService.isCryptocurrency(
symbol.replace(
new RegExp(`-${DEFAULT_CURRENCY}$`),
DEFAULT_CURRENCY
)
)) ||
this.currencyService.getCurrencies().some((currency) => {
return this.cryptocurrencyService.isCryptocurrency(
symbol.replace(new RegExp(`-${currency}$`), '')
);
})) ||
quoteTypes.includes(quoteType)
);
})
.filter(({ quoteType, symbol }) => {
if (quoteType === 'CRYPTOCURRENCY') {
// Only allow cryptocurrencies in base currency to avoid having redundancy in the database.
// Transactions need to be converted manually to the base currency before
return symbol.includes(DEFAULT_CURRENCY);
} else if (quoteType === 'FUTURE') {
if (quoteType === 'FUTURE') {
// Allow GC=F, but not MGC=F
return symbol.length === 4;
}

2
apps/api/src/services/exchange-rate-data/exchange-rate-data.module.ts

@ -1,4 +1,5 @@
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { CurrencyModule } from '@ghostfolio/api/services/currency/currency.module';
import { DataProviderModule } from '@ghostfolio/api/services/data-provider/data-provider.module';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { MarketDataModule } from '@ghostfolio/api/services/market-data/market-data.module';
@ -11,6 +12,7 @@ import { Module } from '@nestjs/common';
exports: [ExchangeRateDataService],
imports: [
ConfigurationModule,
CurrencyModule,
DataProviderModule,
MarketDataModule,
PrismaModule,

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

@ -1,14 +1,9 @@
import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor';
import { CurrencyService } from '@ghostfolio/api/services/currency/currency.service';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import {
DEFAULT_CURRENCY,
DERIVED_CURRENCIES,
PROPERTY_CURRENCIES
} from '@ghostfolio/common/config';
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import {
DATE_FORMAT,
getYesterday,
@ -23,26 +18,20 @@ import {
isToday,
subDays
} from 'date-fns';
import { isNumber, uniq } from 'lodash';
import { isNumber } from 'lodash';
import ms from 'ms';
@Injectable()
export class ExchangeRateDataService {
private currencies: string[] = [];
private currencyPairs: IDataGatheringItem[] = [];
private exchangeRates: { [currencyPair: string]: number } = {};
public constructor(
private readonly currencyService: CurrencyService,
private readonly dataProviderService: DataProviderService,
private readonly marketDataService: MarketDataService,
private readonly prismaService: PrismaService,
private readonly propertyService: PropertyService
private readonly marketDataService: MarketDataService
) {}
public getCurrencies() {
return this.currencies?.length > 0 ? this.currencies : [DEFAULT_CURRENCY];
}
public getCurrencyPairs() {
return this.currencyPairs;
}
@ -133,7 +122,6 @@ export class ExchangeRateDataService {
}
public async initialize() {
this.currencies = await this.prepareCurrencies();
this.currencyPairs = [];
this.exchangeRates = {};
@ -141,7 +129,7 @@ export class ExchangeRateDataService {
currency1,
currency2,
dataSource
} of this.prepareCurrencyPairs(this.currencies)) {
} of this.prepareCurrencyPairs(this.currencyService.getCurrencies())) {
this.currencyPairs.push({
dataSource,
symbol: `${currency1}${currency2}`
@ -469,55 +457,6 @@ export class ExchangeRateDataService {
return factors;
}
private async prepareCurrencies(): Promise<string[]> {
let currencies: string[] = [DEFAULT_CURRENCY];
(
await this.prismaService.account.findMany({
distinct: ['currency'],
orderBy: [{ currency: 'asc' }],
select: { currency: true },
where: {
currency: {
not: null
}
}
})
).forEach(({ currency }) => {
currencies.push(currency);
});
(
await this.prismaService.symbolProfile.findMany({
distinct: ['currency'],
orderBy: [{ currency: 'asc' }],
select: { currency: true }
})
).forEach(({ currency }) => {
currencies.push(currency);
});
const customCurrencies = (await this.propertyService.getByKey(
PROPERTY_CURRENCIES
)) as string[];
if (customCurrencies?.length > 0) {
currencies = currencies.concat(customCurrencies);
}
// Add derived currencies
currencies.push('USX');
for (const { currency, rootCurrency } of DERIVED_CURRENCIES) {
if (currencies.includes(currency) || currencies.includes(rootCurrency)) {
currencies.push(currency);
currencies.push(rootCurrency);
}
}
return uniq(currencies).filter(Boolean).sort();
}
private prepareCurrencyPairs(aCurrencies: string[]) {
return aCurrencies
.filter((currency) => {

Loading…
Cancel
Save