Introduce market states (#38)

* closed
* delayed (no live data)
* open
This commit is contained in:
Thomas
2021-04-22 22:00:46 +02:00
committed by GitHub
parent cf582b2e98
commit 5cb69291f5
10 changed files with 48 additions and 13 deletions

View File

@@ -1,3 +1,4 @@
import { MarketState } from '@ghostfolio/api/services/interfaces/interfaces';
import { Currency } from '@prisma/client';
export interface PortfolioPosition {
@@ -7,10 +8,10 @@ export interface PortfolioPosition {
grossPerformancePercent: number;
industry?: string;
investment: number;
isMarketOpen: boolean;
marketChange?: number;
marketChangePercent?: number;
marketPrice: number;
marketState: MarketState;
name: string;
platforms: {
[name: string]: { current: number; original: number };

View File

@@ -5,9 +5,11 @@ import { Currency, Role, Type } from '@prisma/client';
import { ConfigurationService } from '../services/configuration.service';
import { DataProviderService } from '../services/data-provider.service';
import { AlphaVantageService } from '../services/data-provider/alpha-vantage/alpha-vantage.service';
import { GhostfolioScraperApiService } from '../services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service';
import { RakutenRapidApiService } from '../services/data-provider/rakuten-rapid-api/rakuten-rapid-api.service';
import { YahooFinanceService } from '../services/data-provider/yahoo-finance/yahoo-finance.service';
import { ExchangeRateDataService } from '../services/exchange-rate-data.service';
import { MarketState } from '../services/interfaces/interfaces';
import { PrismaService } from '../services/prisma.service';
import { RulesService } from '../services/rules.service';
import { Portfolio } from './portfolio';
@@ -17,6 +19,7 @@ describe('Portfolio', () => {
let configurationService: ConfigurationService;
let dataProviderService: DataProviderService;
let exchangeRateDataService: ExchangeRateDataService;
let ghostfolioScraperApiService: GhostfolioScraperApiService;
let portfolio: Portfolio;
let prismaService: PrismaService;
let rakutenRapidApiService: RakutenRapidApiService;
@@ -31,6 +34,7 @@ describe('Portfolio', () => {
ConfigurationService,
DataProviderService,
ExchangeRateDataService,
GhostfolioScraperApiService,
PrismaService,
RakutenRapidApiService,
RulesService,
@@ -44,6 +48,9 @@ describe('Portfolio', () => {
exchangeRateDataService = app.get<ExchangeRateDataService>(
ExchangeRateDataService
);
ghostfolioScraperApiService = app.get<GhostfolioScraperApiService>(
GhostfolioScraperApiService
);
prismaService = app.get<PrismaService>(PrismaService);
rakutenRapidApiService = app.get<RakutenRapidApiService>(
RakutenRapidApiService
@@ -154,8 +161,8 @@ describe('Portfolio', () => {
Currency.USD,
baseCurrency
),
isMarketOpen: true,
// marketPrice: 57973.008,
marketState: MarketState.open,
name: 'Bitcoin USD',
platforms: {
Other: {

View File

@@ -8,7 +8,8 @@ import { DataProviderInterface } from '../../interfaces/data-provider.interface'
import { Granularity } from '../../interfaces/granularity.type';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
IDataProviderResponse,
MarketState
} from '../../interfaces/interfaces';
import { PrismaService } from '../../prisma.service';
@@ -41,7 +42,7 @@ export class GhostfolioScraperApiService implements DataProviderInterface {
[symbol]: {
marketPrice,
currency: scraperConfig?.currency,
isMarketOpen: false,
marketState: MarketState.delayed,
name: scraperConfig?.name
}
};

View File

@@ -8,7 +8,8 @@ import { DataProviderInterface } from '../../interfaces/data-provider.interface'
import { Granularity } from '../../interfaces/granularity.type';
import {
IDataProviderHistoricalResponse,
IDataProviderResponse
IDataProviderResponse,
MarketState
} from '../../interfaces/interfaces';
import { PrismaService } from '../../prisma.service';
@@ -38,8 +39,8 @@ export class RakutenRapidApiService implements DataProviderInterface {
return {
'GF.FEAR_AND_GREED_INDEX': {
currency: undefined,
isMarketOpen: true,
marketPrice: fgi.now.value,
marketState: MarketState.open,
name: RakutenRapidApiService.FEAR_AND_GREED_INDEX_NAME
}
};

View File

@@ -9,6 +9,7 @@ import {
IDataProviderHistoricalResponse,
IDataProviderResponse,
Industry,
MarketState,
Sector,
Type
} from '../../interfaces/interfaces';
@@ -49,8 +50,10 @@ export class YahooFinanceService implements DataProviderInterface {
response[symbol] = {
currency: parseCurrency(value.price?.currency),
exchange: this.parseExchange(value.price?.exchangeName),
isMarketOpen:
value.price?.marketState === 'REGULAR' || isCrypto(symbol),
marketState:
value.price?.marketState === 'REGULAR' || isCrypto(symbol)
? MarketState.open
: MarketState.closed,
marketPrice: value.price?.regularMarketPrice || 0,
name: value.price?.longName || value.price?.shortName || symbol,
type: this.parseType(this.getType(symbol, value))

View File

@@ -12,6 +12,12 @@ export const Industry = {
Software: 'Software'
};
export const MarketState = {
closed: 'closed',
delayed: 'delayed',
open: 'open'
};
export const Sector = {
Consumer: 'Consumer',
Healthcare: 'Healthcare',
@@ -47,10 +53,10 @@ export interface IDataProviderResponse {
currency: Currency;
exchange?: string;
industry?: Industry;
isMarketOpen: boolean;
marketChange?: number;
marketChangePercent?: number;
marketPrice: number;
marketState: MarketState;
name: string;
sector?: Sector;
type?: Type;
@@ -59,6 +65,8 @@ export interface IDataProviderResponse {
export type Industry = typeof Industry[keyof typeof Industry];
export type MarketState = typeof MarketState[keyof typeof MarketState];
export type Sector = typeof Sector[keyof typeof Sector];
export type Type = typeof Type[keyof typeof Type];