Feature/add state to market data database schema (#1893)

* Add state (CLOSE / INTRADAY) to MarketData

* Update changelog
pull/1895/head^2
Thomas Kaul 2 years ago committed by GitHub
parent 67e758365f
commit 7b77dc044a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Introduced a new button to delete all activities from the portfolio activities page - Introduced a new button to delete all activities from the portfolio activities page
- Added `state` to the `MarketData` database schema to distinguish `CLOSE` and `INTRADAY` in the data gathering
## 1.260.0 - 2023-04-23 ## 1.260.0 - 2023-04-23

@ -317,7 +317,7 @@ export class AdminController {
const date = new Date(dateString); const date = new Date(dateString);
return this.marketDataService.updateMarketData({ return this.marketDataService.updateMarketData({
data: { ...data, dataSource }, data: { marketPrice: data.marketPrice, state: 'CLOSE' },
where: { where: {
dataSource_date_symbol: { dataSource_date_symbol: {
dataSource, dataSource,

@ -18,7 +18,8 @@ jest.mock('@ghostfolio/api/services/market-data/market-data.service', () => {
createdAt: date, createdAt: date,
dataSource: DataSource.YAHOO, dataSource: DataSource.YAHOO,
id: 'aefcbe3a-ee10-4c4f-9f2d-8ffad7b05584', id: 'aefcbe3a-ee10-4c4f-9f2d-8ffad7b05584',
marketPrice: 1847.839966 marketPrice: 1847.839966,
state: 'CLOSE'
}); });
}, },
getRange: ({ getRange: ({
@ -37,6 +38,7 @@ jest.mock('@ghostfolio/api/services/market-data/market-data.service', () => {
date: dateRangeStart, date: dateRangeStart,
id: '8fa48fde-f397-4b0d-adbc-fb940e830e6d', id: '8fa48fde-f397-4b0d-adbc-fb940e830e6d',
marketPrice: 1841.823902, marketPrice: 1841.823902,
state: 'CLOSE',
symbol: symbols[0] symbol: symbols[0]
}, },
{ {
@ -45,6 +47,7 @@ jest.mock('@ghostfolio/api/services/market-data/market-data.service', () => {
date: dateRangeEnd, date: dateRangeEnd,
id: '082d6893-df27-4c91-8a5d-092e84315b56', id: '082d6893-df27-4c91-8a5d-092e84315b56',
marketPrice: 1847.839966, marketPrice: 1847.839966,
state: 'CLOSE',
symbol: symbols[0] symbol: symbols[0]
} }
]); ]);

@ -6,8 +6,9 @@ import {
GATHER_ASSET_PROFILE_PROCESS, GATHER_ASSET_PROFILE_PROCESS,
GATHER_HISTORICAL_MARKET_DATA_PROCESS GATHER_HISTORICAL_MARKET_DATA_PROCESS
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { DATE_FORMAT, getStartOfUtcDate } from '@ghostfolio/common/helper';
import { UniqueAsset } from '@ghostfolio/common/interfaces'; import { UniqueAsset } from '@ghostfolio/common/interfaces';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { Process, Processor } from '@nestjs/bull'; import { Process, Processor } from '@nestjs/bull';
import { Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { Job } from 'bull'; import { Job } from 'bull';
@ -28,7 +29,7 @@ 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 prismaService: PrismaService private readonly marketDataService: MarketDataService
) {} ) {}
@Process(GATHER_ASSET_PROFILE_PROCESS) @Process(GATHER_ASSET_PROFILE_PROCESS)
@ -83,19 +84,17 @@ export class DataGatheringProcessor {
if (lastMarketPrice) { if (lastMarketPrice) {
try { try {
await this.prismaService.marketData.create({ await this.marketDataService.updateMarketData({
data: { data: {
marketPrice: lastMarketPrice,
state: 'CLOSE'
},
where: {
dataSource_date_symbol: {
dataSource, dataSource,
symbol, symbol,
date: new Date( date: getStartOfUtcDate(currentDate)
Date.UTC( }
getYear(currentDate),
getMonth(currentDate),
getDate(currentDate),
0
)
),
marketPrice: lastMarketPrice
} }
}); });
} catch {} } catch {}

@ -271,7 +271,8 @@ export class DataGatheringService {
by: ['symbol'], by: ['symbol'],
orderBy: [{ symbol: 'asc' }], orderBy: [{ symbol: 'asc' }],
where: { where: {
date: { gt: startDate } date: { gt: startDate },
state: 'CLOSE'
} }
}) })
) )

@ -291,7 +291,8 @@ export class DataProviderService {
symbol, symbol,
dataSource: response[symbol].dataSource, dataSource: response[symbol].dataSource,
date: getStartOfUtcDate(new Date()), date: getStartOfUtcDate(new Date()),
marketPrice: response[symbol].marketPrice marketPrice: response[symbol].marketPrice,
state: 'INTRADAY'
}; };
}) })
}); });

@ -5,7 +5,12 @@ import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { resetHours } from '@ghostfolio/common/helper'; import { resetHours } from '@ghostfolio/common/helper';
import { UniqueAsset } from '@ghostfolio/common/interfaces'; import { UniqueAsset } from '@ghostfolio/common/interfaces';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { DataSource, MarketData, Prisma } from '@prisma/client'; import {
DataSource,
MarketData,
MarketDataState,
Prisma
} from '@prisma/client';
@Injectable() @Injectable()
export class MarketDataService { export class MarketDataService {
@ -92,7 +97,9 @@ export class MarketDataService {
} }
public async updateMarketData(params: { public async updateMarketData(params: {
data: { dataSource: DataSource } & UpdateMarketDataDto; data: {
state: MarketDataState;
} & UpdateMarketDataDto;
where: Prisma.MarketDataWhereUniqueInput; where: Prisma.MarketDataWhereUniqueInput;
}): Promise<MarketData> { }): Promise<MarketData> {
const { data, where } = params; const { data, where } = params;
@ -100,12 +107,13 @@ export class MarketDataService {
return this.prismaService.marketData.upsert({ return this.prismaService.marketData.upsert({
where, where,
create: { create: {
dataSource: data.dataSource, dataSource: where.dataSource_date_symbol.dataSource,
date: where.dataSource_date_symbol.date, date: where.dataSource_date_symbol.date,
marketPrice: data.marketPrice, marketPrice: data.marketPrice,
state: data.state,
symbol: where.dataSource_date_symbol.symbol symbol: where.dataSource_date_symbol.symbol
}, },
update: { marketPrice: data.marketPrice } update: { marketPrice: data.marketPrice, state: data.state }
}); });
} }
@ -119,16 +127,18 @@ export class MarketDataService {
data: Prisma.MarketDataUpdateInput[]; data: Prisma.MarketDataUpdateInput[];
}): Promise<MarketData[]> { }): Promise<MarketData[]> {
const upsertPromises = data.map( const upsertPromises = data.map(
({ dataSource, date, marketPrice, symbol }) => { ({ dataSource, date, marketPrice, symbol, state }) => {
return this.prismaService.marketData.upsert({ return this.prismaService.marketData.upsert({
create: { create: {
dataSource: <DataSource>dataSource, dataSource: <DataSource>dataSource,
date: <Date>date, date: <Date>date,
marketPrice: <number>marketPrice, marketPrice: <number>marketPrice,
state: <MarketDataState>state,
symbol: <string>symbol symbol: <string>symbol
}, },
update: { update: {
marketPrice: <number>marketPrice marketPrice: <number>marketPrice,
state: <MarketDataState>state
}, },
where: { where: {
dataSource_date_symbol: { dataSource_date_symbol: {

@ -0,0 +1,5 @@
-- CreateEnum
CREATE TYPE "MarketDataState" AS ENUM ('CLOSE', 'INTRADAY');
-- AlterTable
ALTER TABLE "MarketData" ADD COLUMN "state" "MarketDataState" NOT NULL DEFAULT 'CLOSE';

@ -63,8 +63,9 @@ model MarketData {
dataSource DataSource dataSource DataSource
date DateTime date DateTime
id String @id @default(uuid()) id String @id @default(uuid())
symbol String
marketPrice Float marketPrice Float
state MarketDataState @default(CLOSE)
symbol String
@@unique([dataSource, date, symbol]) @@unique([dataSource, date, symbol])
@@index([symbol]) @@index([symbol])
@ -214,9 +215,9 @@ enum DataSource {
YAHOO YAHOO
} }
enum ViewMode { enum MarketDataState {
DEFAULT CLOSE
ZEN INTRADAY
} }
enum Provider { enum Provider {
@ -237,3 +238,8 @@ enum Type {
ITEM ITEM
SELL SELL
} }
enum ViewMode {
DEFAULT
ZEN
}

Loading…
Cancel
Save