Browse Source

add data enhancer for trackinsight

Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com>
pull/410/head
Valentin Zickner 4 years ago
parent
commit
50d1a60364
  1. 9
      apps/api/src/services/data-provider/data-provider.module.ts
  2. 23
      apps/api/src/services/data-provider/data-provider.service.ts
  3. 8
      apps/api/src/services/data-provider/interfaces/data-enhancer.interface.ts
  4. 44
      apps/api/src/services/data-provider/trackinsight-enhancer/trackinsight-enhancer.service.ts

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

@ -7,6 +7,7 @@ import { Module } from '@nestjs/common';
import { AlphaVantageService } from './alpha-vantage/alpha-vantage.service'; import { AlphaVantageService } from './alpha-vantage/alpha-vantage.service';
import { DataProviderService } from './data-provider.service'; import { DataProviderService } from './data-provider.service';
import { TrackinsightEnhancerService } from '@ghostfolio/api/services/data-provider/trackinsight-enhancer/trackinsight-enhancer.service';
@Module({ @Module({
imports: [ConfigurationModule, PrismaModule], imports: [ConfigurationModule, PrismaModule],
@ -15,7 +16,13 @@ import { DataProviderService } from './data-provider.service';
DataProviderService, DataProviderService,
GhostfolioScraperApiService, GhostfolioScraperApiService,
RakutenRapidApiService, RakutenRapidApiService,
YahooFinanceService TrackinsightEnhancerService,
YahooFinanceService,
{
provide: 'DataEnhancers',
useFactory: (trackinsight) => [trackinsight],
inject: [TrackinsightEnhancerService]
}
], ],
exports: [DataProviderService, GhostfolioScraperApiService] exports: [DataProviderService, GhostfolioScraperApiService]
}) })

23
apps/api/src/services/data-provider/data-provider.service.ts

@ -8,7 +8,7 @@ import {
import { PrismaService } from '@ghostfolio/api/services/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma.service';
import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { DATE_FORMAT } from '@ghostfolio/common/helper';
import { Granularity } from '@ghostfolio/common/types'; import { Granularity } from '@ghostfolio/common/types';
import { Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { DataSource, MarketData } from '@prisma/client'; import { DataSource, MarketData } from '@prisma/client';
import { format } from 'date-fns'; import { format } from 'date-fns';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
@ -17,6 +17,7 @@ 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 { YahooFinanceService } from './yahoo-finance/yahoo-finance.service';
import { DataEnhancerInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-enhancer.interface';
@Injectable() @Injectable()
export class DataProviderService { export class DataProviderService {
@ -26,7 +27,9 @@ export class DataProviderService {
private readonly ghostfolioScraperApiService: GhostfolioScraperApiService, private readonly ghostfolioScraperApiService: GhostfolioScraperApiService,
private readonly prismaService: PrismaService, private readonly prismaService: PrismaService,
private readonly rakutenRapidApiService: RakutenRapidApiService, private readonly rakutenRapidApiService: RakutenRapidApiService,
private readonly yahooFinanceService: YahooFinanceService private readonly yahooFinanceService: YahooFinanceService,
@Inject('DataEnhancers')
private readonly dataEnhancers: DataEnhancerInterface[]
) { ) {
this.rakutenRapidApiService?.setPrisma(this.prismaService); this.rakutenRapidApiService?.setPrisma(this.prismaService);
} }
@ -45,6 +48,22 @@ export class DataProviderService {
]; ];
} }
const promises = [];
for (const symbol of Object.keys(response)) {
let promise = Promise.resolve(response[symbol]);
for (const dataEnhancer of this.dataEnhancers) {
promise = promise.then((r) =>
dataEnhancer.enhance(symbol, r).catch((e) => {
console.error(`Failed to enhance data for symbol ${symbol}`, e);
return r;
})
);
}
promises.push(promise.then((r) => (response[symbol] = r)));
}
await Promise.all(promises);
return response; return response;
} }

8
apps/api/src/services/data-provider/interfaces/data-enhancer.interface.ts

@ -0,0 +1,8 @@
import { IDataProviderResponse } from '@ghostfolio/api/services/interfaces/interfaces';
export interface DataEnhancerInterface {
enhance(
symbol: string,
response: IDataProviderResponse
): Promise<IDataProviderResponse>;
}

44
apps/api/src/services/data-provider/trackinsight-enhancer/trackinsight-enhancer.service.ts

@ -0,0 +1,44 @@
import { DataEnhancerInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-enhancer.interface';
import { IDataProviderResponse } from '@ghostfolio/api/services/interfaces/interfaces';
import bent from 'bent';
const countries = require('countries-list/dist/countries.json');
const getJSON = bent('json');
export class TrackinsightEnhancerService implements DataEnhancerInterface {
public async enhance(
symbol: string,
response: IDataProviderResponse
): Promise<IDataProviderResponse> {
if (
!(response.assetClass === 'EQUITY' && response.assetSubClass === 'ETF')
) {
return response;
}
const holdings = await getJSON(
`https://data.trackinsight.com/holdings/${symbol}.json`
);
if (!response.countries || response.countries.length === 0) {
response.countries = [];
for (const [name, value] of Object.entries<any>(holdings.countries)) {
let countryCode: string;
for (const [key, country] of Object.entries<any>(countries)) {
if (country.name === name) {
countryCode = key;
break;
}
}
response.countries.push({
code: countryCode,
weight: value.weight
});
}
}
return Promise.resolve(response);
}
}
Loading…
Cancel
Save