Merge branch 'main' of github.com:ghostfolio/ghostfolio
All checks were successful
Docker image CD / build_and_push (push) Successful in 40m57s
All checks were successful
Docker image CD / build_and_push (push) Successful in 40m57s
This commit is contained in:
commit
b4656322c7
15
CHANGELOG.md
15
CHANGELOG.md
@ -7,12 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Improved the symbol lookup in the _Trackinsight_ data enhancer for asset profile data
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Handled an exception in the benchmark service related to unnamed asset profiles
|
||||||
|
|
||||||
|
## 2.142.0 - 2025-02-28
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Extended the export functionality by the platforms
|
- Extended the export functionality by the platforms
|
||||||
|
- Extended the portfolio snapshot in the portfolio calculator by the `createdAt` timestamp
|
||||||
- Extended the _Trackinsight_ data enhancer for asset profile data by `cusip`
|
- Extended the _Trackinsight_ data enhancer for asset profile data by `cusip`
|
||||||
- Added _Storybook_ to the build process
|
- Added _Storybook_ to the build process
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Upgraded `eslint` dependencies
|
||||||
|
|
||||||
## 2.141.0 - 2025-02-25
|
## 2.141.0 - 2025-02-25
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -57,7 +57,7 @@ export class PublicController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [
|
const [
|
||||||
{ holdings, markets },
|
{ createdAt, holdings, markets },
|
||||||
{ performance: performance1d },
|
{ performance: performance1d },
|
||||||
{ performance: performanceMax },
|
{ performance: performanceMax },
|
||||||
{ performance: performanceYtd }
|
{ performance: performanceYtd }
|
||||||
@ -81,6 +81,7 @@ export class PublicController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const publicPortfolioResponse: PublicPortfolioResponse = {
|
const publicPortfolioResponse: PublicPortfolioResponse = {
|
||||||
|
createdAt,
|
||||||
hasDetails,
|
hasDetails,
|
||||||
markets,
|
markets,
|
||||||
alias: access.alias,
|
alias: access.alias,
|
||||||
|
@ -176,6 +176,7 @@ export abstract class PortfolioCalculator {
|
|||||||
if (!transactionPoints.length) {
|
if (!transactionPoints.length) {
|
||||||
return {
|
return {
|
||||||
activitiesCount: 0,
|
activitiesCount: 0,
|
||||||
|
createdAt: new Date(),
|
||||||
currentValueInBaseCurrency: new Big(0),
|
currentValueInBaseCurrency: new Big(0),
|
||||||
errors: [],
|
errors: [],
|
||||||
hasErrors: false,
|
hasErrors: false,
|
||||||
|
@ -104,6 +104,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
|
|||||||
activitiesCount: this.activities.filter(({ type }) => {
|
activitiesCount: this.activities.filter(({ type }) => {
|
||||||
return ['BUY', 'SELL'].includes(type);
|
return ['BUY', 'SELL'].includes(type);
|
||||||
}).length,
|
}).length,
|
||||||
|
createdAt: new Date(),
|
||||||
errors: [],
|
errors: [],
|
||||||
historicalData: [],
|
historicalData: [],
|
||||||
totalLiabilitiesWithCurrencyEffect: new Big(0),
|
totalLiabilitiesWithCurrencyEffect: new Big(0),
|
||||||
|
@ -105,6 +105,7 @@ export class PortfolioController {
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
accounts,
|
accounts,
|
||||||
|
createdAt,
|
||||||
hasErrors,
|
hasErrors,
|
||||||
holdings,
|
holdings,
|
||||||
markets,
|
markets,
|
||||||
@ -233,6 +234,7 @@ export class PortfolioController {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
accounts,
|
accounts,
|
||||||
|
createdAt,
|
||||||
hasError,
|
hasError,
|
||||||
holdings,
|
holdings,
|
||||||
platforms,
|
platforms,
|
||||||
|
@ -376,7 +376,7 @@ export class PortfolioService {
|
|||||||
currency: userCurrency
|
currency: userCurrency
|
||||||
});
|
});
|
||||||
|
|
||||||
const { currentValueInBaseCurrency, hasErrors, positions } =
|
const { createdAt, currentValueInBaseCurrency, hasErrors, positions } =
|
||||||
await portfolioCalculator.getSnapshot();
|
await portfolioCalculator.getSnapshot();
|
||||||
|
|
||||||
const cashDetails = await this.accountService.getCashDetails({
|
const cashDetails = await this.accountService.getCashDetails({
|
||||||
@ -617,6 +617,7 @@ export class PortfolioService {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
accounts,
|
accounts,
|
||||||
|
createdAt,
|
||||||
hasErrors,
|
hasErrors,
|
||||||
holdings,
|
holdings,
|
||||||
markets,
|
markets,
|
||||||
|
@ -133,7 +133,9 @@ export class BenchmarkService {
|
|||||||
symbol
|
symbol
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.sort((a, b) => a.name.localeCompare(b.name));
|
.sort((a, b) => {
|
||||||
|
return a.name?.localeCompare(b?.name) ?? 0;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async addBenchmark({
|
public async addBenchmark({
|
||||||
|
@ -192,7 +192,10 @@ export class TrackinsightDataEnhancerService implements DataEnhancerInterface {
|
|||||||
.then((jsonRes) => {
|
.then((jsonRes) => {
|
||||||
if (
|
if (
|
||||||
jsonRes['results']?.['count'] === 1 ||
|
jsonRes['results']?.['count'] === 1 ||
|
||||||
jsonRes['results']?.['docs']?.[0]?.['ticker'] === symbol
|
// Allow exact match
|
||||||
|
jsonRes['results']?.['docs']?.[0]?.['ticker'] === symbol ||
|
||||||
|
// Allow EXCHANGE:SYMBOL
|
||||||
|
jsonRes['results']?.['docs']?.[0]?.['ticker']?.endsWith(`:${symbol}`)
|
||||||
) {
|
) {
|
||||||
return jsonRes['results']['docs'][0]['ticker'];
|
return jsonRes['results']['docs'][0]['ticker'];
|
||||||
}
|
}
|
||||||
|
@ -260,6 +260,7 @@ export class AllocationsPageComponent implements OnDestroy, OnInit {
|
|||||||
this.platforms = {};
|
this.platforms = {};
|
||||||
this.portfolioDetails = {
|
this.portfolioDetails = {
|
||||||
accounts: {},
|
accounts: {},
|
||||||
|
createdAt: undefined,
|
||||||
holdings: {},
|
holdings: {},
|
||||||
platforms: {},
|
platforms: {},
|
||||||
summary: undefined
|
summary: undefined
|
||||||
|
@ -14,6 +14,7 @@ export interface PortfolioDetails {
|
|||||||
valueInPercentage?: number;
|
valueInPercentage?: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
createdAt: Date;
|
||||||
holdings: { [symbol: string]: PortfolioPosition };
|
holdings: { [symbol: string]: PortfolioPosition };
|
||||||
markets?: {
|
markets?: {
|
||||||
[key in Market]: {
|
[key in Market]: {
|
||||||
|
@ -32,6 +32,7 @@ export interface PublicPortfolioResponse extends PublicPortfolioResponseV1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface PublicPortfolioResponseV1 {
|
interface PublicPortfolioResponseV1 {
|
||||||
|
createdAt: Date;
|
||||||
performance: {
|
performance: {
|
||||||
'1d': {
|
'1d': {
|
||||||
relativeChange: number;
|
relativeChange: number;
|
||||||
|
@ -11,6 +11,8 @@ import { Transform, Type } from 'class-transformer';
|
|||||||
export class PortfolioSnapshot {
|
export class PortfolioSnapshot {
|
||||||
activitiesCount: number;
|
activitiesCount: number;
|
||||||
|
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
@Transform(transformToBig, { toClassOnly: true })
|
@Transform(transformToBig, { toClassOnly: true })
|
||||||
@Type(() => Big)
|
@Type(() => Big)
|
||||||
currentValueInBaseCurrency: Big;
|
currentValueInBaseCurrency: Big;
|
||||||
|
50
package-lock.json
generated
50
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ghostfolio",
|
"name": "ghostfolio",
|
||||||
"version": "2.141.0",
|
"version": "2.142.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ghostfolio",
|
"name": "ghostfolio",
|
||||||
"version": "2.141.0",
|
"version": "2.142.0",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -141,9 +141,9 @@
|
|||||||
"cypress": "6.2.1",
|
"cypress": "6.2.1",
|
||||||
"eslint": "9.18.0",
|
"eslint": "9.18.0",
|
||||||
"eslint-config-prettier": "9.1.0",
|
"eslint-config-prettier": "9.1.0",
|
||||||
"eslint-plugin-cypress": "3.2.0",
|
"eslint-plugin-cypress": "4.1.0",
|
||||||
"eslint-plugin-import": "2.31.0",
|
"eslint-plugin-import": "2.31.0",
|
||||||
"eslint-plugin-storybook": "0.10.2",
|
"eslint-plugin-storybook": "0.11.2",
|
||||||
"husky": "9.1.7",
|
"husky": "9.1.7",
|
||||||
"jest": "29.7.0",
|
"jest": "29.7.0",
|
||||||
"jest-environment-jsdom": "29.7.0",
|
"jest-environment-jsdom": "29.7.0",
|
||||||
@ -17087,42 +17087,26 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-cypress": {
|
"node_modules/eslint-plugin-cypress": {
|
||||||
"version": "3.2.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-4.1.0.tgz",
|
||||||
"integrity": "sha512-HaxMz6BoU4ay+K4WrG9ZJC1NdX06FqSlAwtRDStjM0ORFT7zCNPNuRJ+kUPc17Rt2AMUBSqeD9L0zTR3uZhPpw==",
|
"integrity": "sha512-JhqkMY02mw74USwK9OFhectx3YSj6Co1NgWBxlGdKvlqiAp9vdEuQqt33DKGQFvvGS/NWtduuhWXWNnU29xDSg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"globals": "^13.20.0"
|
"globals": "^15.11.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": ">=7"
|
"eslint": ">=9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-cypress/node_modules/globals": {
|
"node_modules/eslint-plugin-cypress/node_modules/globals": {
|
||||||
"version": "13.24.0",
|
"version": "15.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz",
|
||||||
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
|
"integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
|
||||||
"type-fest": "^0.20.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=18"
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-plugin-cypress/node_modules/type-fest": {
|
|
||||||
"version": "0.20.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
|
||||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "(MIT OR CC0-1.0)",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
@ -17216,9 +17200,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-storybook": {
|
"node_modules/eslint-plugin-storybook": {
|
||||||
"version": "0.10.2",
|
"version": "0.11.2",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.10.2.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.11.2.tgz",
|
||||||
"integrity": "sha512-iOrFJfyLgRLIbWDLbbs3J4yrknvIB+uiZ8KGqGOEXTL7/BGuBMZLiIU9Q4Pm/VYJrHN4JqmMtwCSrAemHL2nFg==",
|
"integrity": "sha512-0Z4DUklJrC+GHjCRXa7PYfPzWC15DaVnwaOYenpgXiCEijXPZkLKCms+rHhtoRcWccP7Z8DpOOaP1gc3P9oOwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -17230,7 +17214,7 @@
|
|||||||
"node": ">= 18"
|
"node": ">= 18"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": ">=6"
|
"eslint": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-scope": {
|
"node_modules/eslint-scope": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ghostfolio",
|
"name": "ghostfolio",
|
||||||
"version": "2.141.0",
|
"version": "2.142.0",
|
||||||
"homepage": "https://ghostfol.io",
|
"homepage": "https://ghostfol.io",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"repository": "https://github.com/ghostfolio/ghostfolio",
|
"repository": "https://github.com/ghostfolio/ghostfolio",
|
||||||
@ -187,9 +187,9 @@
|
|||||||
"cypress": "6.2.1",
|
"cypress": "6.2.1",
|
||||||
"eslint": "9.18.0",
|
"eslint": "9.18.0",
|
||||||
"eslint-config-prettier": "9.1.0",
|
"eslint-config-prettier": "9.1.0",
|
||||||
"eslint-plugin-cypress": "3.2.0",
|
"eslint-plugin-cypress": "4.1.0",
|
||||||
"eslint-plugin-import": "2.31.0",
|
"eslint-plugin-import": "2.31.0",
|
||||||
"eslint-plugin-storybook": "0.10.2",
|
"eslint-plugin-storybook": "0.11.2",
|
||||||
"husky": "9.1.7",
|
"husky": "9.1.7",
|
||||||
"jest": "29.7.0",
|
"jest": "29.7.0",
|
||||||
"jest-environment-jsdom": "29.7.0",
|
"jest-environment-jsdom": "29.7.0",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user