Feature/improve import of historical market data (#2559)
* Improve historical market data import * Update changelog
This commit is contained in:
parent
16f1b16e41
commit
a7baad10d1
@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
- Improved the usability and validation in the cash balance transfer from one to another account
|
- Improved the usability and validation in the cash balance transfer from one to another account
|
||||||
- Changed the checkboxes to slide toggles in the overview of the admin control panel
|
- Changed the checkboxes to slide toggles in the overview of the admin control panel
|
||||||
|
- Switched from the deprecated (`PUT`) to the new endpoint (`POST`) to manage historical market data in the asset profile details dialog of the admin control panel
|
||||||
|
- Improved the date parsing in the import historical market data of the admin control panel
|
||||||
- Improved the localized meta data (keywords) in `html` files
|
- Improved the localized meta data (keywords) in `html` files
|
||||||
- Improved the language localization for German (`de`)
|
- Improved the language localization for German (`de`)
|
||||||
|
|
||||||
|
@ -7,7 +7,10 @@ import {
|
|||||||
GATHER_ASSET_PROFILE_PROCESS,
|
GATHER_ASSET_PROFILE_PROCESS,
|
||||||
GATHER_ASSET_PROFILE_PROCESS_OPTIONS
|
GATHER_ASSET_PROFILE_PROCESS_OPTIONS
|
||||||
} from '@ghostfolio/common/config';
|
} from '@ghostfolio/common/config';
|
||||||
import { getAssetProfileIdentifier } from '@ghostfolio/common/helper';
|
import {
|
||||||
|
getAssetProfileIdentifier,
|
||||||
|
resetHours
|
||||||
|
} from '@ghostfolio/common/helper';
|
||||||
import {
|
import {
|
||||||
AdminData,
|
AdminData,
|
||||||
AdminMarketData,
|
AdminMarketData,
|
||||||
@ -331,9 +334,9 @@ export class AdminController {
|
|||||||
const dataBulkUpdate: Prisma.MarketDataUpdateInput[] = data.marketData.map(
|
const dataBulkUpdate: Prisma.MarketDataUpdateInput[] = data.marketData.map(
|
||||||
({ date, marketPrice }) => ({
|
({ date, marketPrice }) => ({
|
||||||
dataSource,
|
dataSource,
|
||||||
date,
|
|
||||||
marketPrice,
|
marketPrice,
|
||||||
symbol,
|
symbol,
|
||||||
|
date: resetHours(parseISO(date)),
|
||||||
state: 'CLOSE'
|
state: 'CLOSE'
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { IsDate, IsNumber, IsOptional } from 'class-validator';
|
import { IsISO8601, IsNumber, IsOptional } from 'class-validator';
|
||||||
|
|
||||||
export class UpdateMarketDataDto {
|
export class UpdateMarketDataDto {
|
||||||
@IsDate()
|
@IsISO8601()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
date?: Date;
|
date?: string;
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
marketPrice: number;
|
marketPrice: number;
|
||||||
|
@ -57,10 +57,16 @@ export class MarketDataDetailDialog implements OnDestroy {
|
|||||||
|
|
||||||
public onUpdate() {
|
public onUpdate() {
|
||||||
this.adminService
|
this.adminService
|
||||||
.putMarketData({
|
.postMarketData({
|
||||||
dataSource: this.data.dataSource,
|
dataSource: this.data.dataSource,
|
||||||
date: this.data.date,
|
marketData: {
|
||||||
marketData: { marketPrice: this.data.marketPrice },
|
marketData: [
|
||||||
|
{
|
||||||
|
date: this.data.date.toISOString(),
|
||||||
|
marketPrice: this.data.marketPrice
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
symbol: this.data.symbol
|
symbol: this.data.symbol
|
||||||
})
|
})
|
||||||
.pipe(takeUntil(this.unsubscribeSubject))
|
.pipe(takeUntil(this.unsubscribeSubject))
|
||||||
|
@ -11,7 +11,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
|||||||
import { UpdateAssetProfileDto } from '@ghostfolio/api/app/admin/update-asset-profile.dto';
|
import { UpdateAssetProfileDto } from '@ghostfolio/api/app/admin/update-asset-profile.dto';
|
||||||
import { AdminService } from '@ghostfolio/client/services/admin.service';
|
import { AdminService } from '@ghostfolio/client/services/admin.service';
|
||||||
import { DataService } from '@ghostfolio/client/services/data.service';
|
import { DataService } from '@ghostfolio/client/services/data.service';
|
||||||
import { DATE_FORMAT } from '@ghostfolio/common/helper';
|
import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper';
|
||||||
import {
|
import {
|
||||||
AdminMarketDataDetails,
|
AdminMarketDataDetails,
|
||||||
UniqueAsset
|
UniqueAsset
|
||||||
@ -23,7 +23,7 @@ import {
|
|||||||
MarketData,
|
MarketData,
|
||||||
SymbolProfile
|
SymbolProfile
|
||||||
} from '@prisma/client';
|
} from '@prisma/client';
|
||||||
import { format, parseISO } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { parse as csvToJson } from 'papaparse';
|
import { parse as csvToJson } from 'papaparse';
|
||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
@ -174,7 +174,7 @@ export class AssetProfileDialog implements OnDestroy, OnInit {
|
|||||||
dataSource: this.data.dataSource,
|
dataSource: this.data.dataSource,
|
||||||
marketData: {
|
marketData: {
|
||||||
marketData: marketData.map(({ date, marketPrice }) => {
|
marketData: marketData.map(({ date, marketPrice }) => {
|
||||||
return { marketPrice, date: parseISO(date) };
|
return { marketPrice, date: parseDate(date).toISOString() };
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
symbol: this.data.symbol
|
symbol: this.data.symbol
|
||||||
|
@ -2,7 +2,6 @@ import { HttpClient, HttpParams } from '@angular/common/http';
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { UpdateAssetProfileDto } from '@ghostfolio/api/app/admin/update-asset-profile.dto';
|
import { UpdateAssetProfileDto } from '@ghostfolio/api/app/admin/update-asset-profile.dto';
|
||||||
import { UpdateBulkMarketDataDto } from '@ghostfolio/api/app/admin/update-bulk-market-data.dto';
|
import { UpdateBulkMarketDataDto } from '@ghostfolio/api/app/admin/update-bulk-market-data.dto';
|
||||||
import { UpdateMarketDataDto } from '@ghostfolio/api/app/admin/update-market-data.dto';
|
|
||||||
import { CreatePlatformDto } from '@ghostfolio/api/app/platform/create-platform.dto';
|
import { CreatePlatformDto } from '@ghostfolio/api/app/platform/create-platform.dto';
|
||||||
import { UpdatePlatformDto } from '@ghostfolio/api/app/platform/update-platform.dto';
|
import { UpdatePlatformDto } from '@ghostfolio/api/app/platform/update-platform.dto';
|
||||||
import { CreateTagDto } from '@ghostfolio/api/app/tag/create-tag.dto';
|
import { CreateTagDto } from '@ghostfolio/api/app/tag/create-tag.dto';
|
||||||
@ -247,25 +246,6 @@ export class AdminService {
|
|||||||
return this.http.post<Tag>(`/api/v1/tag`, aTag);
|
return this.http.post<Tag>(`/api/v1/tag`, aTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public putMarketData({
|
|
||||||
dataSource,
|
|
||||||
date,
|
|
||||||
marketData,
|
|
||||||
symbol
|
|
||||||
}: {
|
|
||||||
dataSource: DataSource;
|
|
||||||
date: Date;
|
|
||||||
marketData: UpdateMarketDataDto;
|
|
||||||
symbol: string;
|
|
||||||
}) {
|
|
||||||
const url = `/api/v1/admin/market-data/${dataSource}/${symbol}/${format(
|
|
||||||
date,
|
|
||||||
DATE_FORMAT
|
|
||||||
)}`;
|
|
||||||
|
|
||||||
return this.http.put<MarketData>(url, marketData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public putPlatform(aPlatform: UpdatePlatformDto) {
|
public putPlatform(aPlatform: UpdatePlatformDto) {
|
||||||
return this.http.put<Platform>(
|
return this.http.put<Platform>(
|
||||||
`/api/v1/platform/${aPlatform.id}`,
|
`/api/v1/platform/${aPlatform.id}`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user