Browse Source

Merge 0ea845100b into b2634db99f

pull/4524/merge
csehatt741 3 days ago
committed by GitHub
parent
commit
7f95e98e4d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 6
      apps/api/src/services/data-provider/errors/asset-profile-delisted.error.ts
  3. 17
      apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts
  4. 24
      apps/api/src/services/queues/data-gathering/data-gathering.processor.ts

1
CHANGELOG.md

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Added the data gathering status column to the historical market data table of the admin control - Added the data gathering status column to the historical market data table of the admin control
- Deactivated asset profiles automatically on delisting in the _Yahoo Finance_ service
### Changed ### Changed

6
apps/api/src/services/data-provider/errors/asset-profile-delisted.error.ts

@ -0,0 +1,6 @@
export class AssetProfileDelistedError extends Error {
public constructor(message: string) {
super(message);
this.name = 'AssetProfileDelistedError';
}
}

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

@ -1,5 +1,6 @@
import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service'; import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service';
import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service'; import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service';
import { AssetProfileDelistedError } from '@ghostfolio/api/services/data-provider/errors/asset-profile-delisted.error';
import { import {
DataProviderInterface, DataProviderInterface,
GetAssetProfileParams, GetAssetProfileParams,
@ -143,12 +144,16 @@ export class YahooFinanceService implements DataProviderInterface {
return response; return response;
} catch (error) { } catch (error) {
throw new Error( if (error.message === 'No data found, symbol may be delisted') {
`Could not get historical market data for ${symbol} (${this.getName()}) from ${format( throw new AssetProfileDelistedError(error.message);
from, } else {
DATE_FORMAT throw new Error(
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` `Could not get historical market data for ${symbol} (${this.getName()}) from ${format(
); from,
DATE_FORMAT
)} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`
);
}
} }
} }

24
apps/api/src/services/queues/data-gathering/data-gathering.processor.ts

@ -1,6 +1,8 @@
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { AssetProfileDelistedError } from '@ghostfolio/api/services/data-provider/errors/asset-profile-delisted.error';
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service';
import { import {
DATA_GATHERING_QUEUE, DATA_GATHERING_QUEUE,
DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY, DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY,
@ -33,7 +35,8 @@ export class DataGatheringProcessor {
public constructor( public constructor(
private readonly dataGatheringService: DataGatheringService, private readonly dataGatheringService: DataGatheringService,
private readonly dataProviderService: DataProviderService, private readonly dataProviderService: DataProviderService,
private readonly marketDataService: MarketDataService private readonly marketDataService: MarketDataService,
private readonly symbolProfileService: SymbolProfileService
) {} ) {}
@Process({ @Process({
@ -76,8 +79,9 @@ export class DataGatheringProcessor {
name: GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME name: GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME
}) })
public async gatherHistoricalMarketData(job: Job<IDataGatheringItem>) { public async gatherHistoricalMarketData(job: Job<IDataGatheringItem>) {
const { dataSource, date, symbol } = job.data;
try { try {
const { dataSource, date, symbol } = job.data;
let currentDate = parseISO(date as unknown as string); let currentDate = parseISO(date as unknown as string);
Logger.log( Logger.log(
@ -142,12 +146,26 @@ export class DataGatheringProcessor {
`DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})` `DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})`
); );
} catch (error) { } catch (error) {
if (error instanceof AssetProfileDelistedError) {
await this.symbolProfileService.updateSymbolProfile(
{
dataSource,
symbol
},
{
isActive: false
}
);
await job.discard();
}
Logger.error( Logger.error(
error, error,
`DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})` `DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS_JOB_NAME})`
); );
throw new Error(error); throw error;
} }
} }
} }

Loading…
Cancel
Save