Merge branch 'main' of gitea.suda.codes:giteauser/ghostfolio-mirror
This commit is contained in:
commit
dc3f25583a
@ -34,6 +34,7 @@
|
||||
{
|
||||
"files": ["*.ts"],
|
||||
"plugins": ["eslint-plugin-import", "@typescript-eslint"],
|
||||
"extends": ["plugin:@typescript-eslint/recommended-type-checked"],
|
||||
"rules": {
|
||||
"@typescript-eslint/consistent-type-definitions": "warn",
|
||||
"@typescript-eslint/dot-notation": "off",
|
||||
@ -53,7 +54,6 @@
|
||||
"ignoreParameters": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-misused-new": "error",
|
||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||
"@typescript-eslint/no-shadow": [
|
||||
"warn",
|
||||
@ -61,12 +61,10 @@
|
||||
"hoist": "all"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-unused-expressions": "warn",
|
||||
"@typescript-eslint/prefer-function-type": "warn",
|
||||
"@typescript-eslint/unified-signatures": "error",
|
||||
"@typescript-eslint/no-loss-of-precision": "warn",
|
||||
"@typescript-eslint/no-var-requires": "warn",
|
||||
"@typescript-eslint/ban-ts-comment": "warn",
|
||||
"@typescript-eslint/ban-types": "warn",
|
||||
"arrow-body-style": "off",
|
||||
"constructor-super": "error",
|
||||
@ -83,11 +81,9 @@
|
||||
"no-fallthrough": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-restricted-imports": ["error", "rxjs/Rx"],
|
||||
"no-throw-literal": "warn",
|
||||
"no-undef-init": "error",
|
||||
"no-underscore-dangle": "off",
|
||||
"no-var": "error",
|
||||
"prefer-const": "warn",
|
||||
"radix": "error",
|
||||
"no-unsafe-optional-chaining": "warn",
|
||||
"no-extra-boolean-cast": "warn",
|
||||
@ -96,7 +92,29 @@
|
||||
"no-unsafe-finally": "warn",
|
||||
"no-prototype-builtins": "warn",
|
||||
"no-async-promise-executor": "warn",
|
||||
"no-constant-condition": "warn"
|
||||
"no-constant-condition": "warn",
|
||||
|
||||
// The following rules are part of @typescript-eslint/recommended-type-checked
|
||||
// and can be remove once solved
|
||||
"@typescript-eslint/await-thenable": "warn",
|
||||
"@typescript-eslint/ban-ts-comment": "warn",
|
||||
"@typescript-eslint/no-base-to-string": "warn",
|
||||
"@typescript-eslint/no-explicit-any": "warn",
|
||||
"@typescript-eslint/no-floating-promises": "warn",
|
||||
"@typescript-eslint/no-misused-promises": "warn",
|
||||
"@typescript-eslint/no-redundant-type-constituents": "warn",
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": "warn",
|
||||
"@typescript-eslint/no-unsafe-argument": "warn",
|
||||
"@typescript-eslint/no-unsafe-assignment": "warn",
|
||||
"@typescript-eslint/no-unsafe-enum-comparison": "warn",
|
||||
"@typescript-eslint/no-unsafe-member-access": "warn",
|
||||
"@typescript-eslint/no-unsafe-return": "warn",
|
||||
"@typescript-eslint/no-unused-vars": "warn",
|
||||
"@typescript-eslint/no-unsafe-call": "warn",
|
||||
"@typescript-eslint/require-await": "warn",
|
||||
"@typescript-eslint/restrict-template-expressions": "warn",
|
||||
"@typescript-eslint/unbound-method": "warn",
|
||||
"prefer-const": "warn"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -10,6 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Added
|
||||
|
||||
- Set up a git-hook via `husky` to lint and format the changes before a commit
|
||||
- Added the `typescript-eslint/recommended-type-checked` rule to the `eslint` configuration
|
||||
|
||||
### Changed
|
||||
|
||||
- Optimized the portfolio calculations by reusing date intervals
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
import { cloneDeep, first, last, sortBy } from 'lodash';
|
||||
|
||||
export class TWRPortfolioCalculator extends PortfolioCalculator {
|
||||
private chartDatesDescending: string[];
|
||||
private chartDates: string[];
|
||||
|
||||
protected calculateOverallPerformance(
|
||||
positions: TimelinePosition[]
|
||||
@ -228,11 +228,11 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
|
||||
|
||||
const dateOfFirstTransaction = new Date(first(orders).date);
|
||||
|
||||
const unitPriceAtStartDate =
|
||||
marketSymbolMap[format(start, DATE_FORMAT)]?.[symbol];
|
||||
const endDateString = format(end, DATE_FORMAT);
|
||||
const startDateString = format(start, DATE_FORMAT);
|
||||
|
||||
const unitPriceAtEndDate =
|
||||
marketSymbolMap[format(end, DATE_FORMAT)]?.[symbol];
|
||||
const unitPriceAtStartDate = marketSymbolMap[startDateString]?.[symbol];
|
||||
const unitPriceAtEndDate = marketSymbolMap[endDateString]?.[symbol];
|
||||
|
||||
if (
|
||||
!unitPriceAtEndDate ||
|
||||
@ -278,7 +278,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
|
||||
|
||||
// Add a synthetic order at the start and the end date
|
||||
orders.push({
|
||||
date: format(start, DATE_FORMAT),
|
||||
date: startDateString,
|
||||
fee: new Big(0),
|
||||
feeInBaseCurrency: new Big(0),
|
||||
itemType: 'start',
|
||||
@ -292,7 +292,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
|
||||
});
|
||||
|
||||
orders.push({
|
||||
date: format(end, DATE_FORMAT),
|
||||
date: endDateString,
|
||||
fee: new Big(0),
|
||||
feeInBaseCurrency: new Big(0),
|
||||
itemType: 'end',
|
||||
@ -305,7 +305,6 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
|
||||
unitPrice: unitPriceAtEndDate
|
||||
});
|
||||
|
||||
let day = start;
|
||||
let lastUnitPrice: Big;
|
||||
|
||||
const ordersByDate: { [date: string]: PortfolioOrderItem[] } = {};
|
||||
@ -315,15 +314,23 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
|
||||
ordersByDate[order.date].push(order);
|
||||
}
|
||||
|
||||
while (isBefore(day, end)) {
|
||||
const dateString = format(day, DATE_FORMAT);
|
||||
if (!this.chartDates) {
|
||||
this.chartDates = Object.keys(chartDateMap).sort();
|
||||
}
|
||||
|
||||
for (const dateString of this.chartDates) {
|
||||
if (dateString < startDateString) {
|
||||
continue;
|
||||
} else if (dateString > endDateString) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ordersByDate[dateString]?.length > 0) {
|
||||
for (let order of ordersByDate[dateString]) {
|
||||
order.unitPriceFromMarketData =
|
||||
marketSymbolMap[dateString]?.[symbol] ?? lastUnitPrice;
|
||||
}
|
||||
} else if (chartDateMap[dateString]) {
|
||||
} else {
|
||||
orders.push({
|
||||
date: dateString,
|
||||
fee: new Big(0),
|
||||
@ -343,8 +350,6 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
|
||||
const lastOrder = last(orders);
|
||||
|
||||
lastUnitPrice = lastOrder.unitPriceFromMarketData ?? lastOrder.unitPrice;
|
||||
|
||||
day = addDays(day, 1);
|
||||
}
|
||||
|
||||
// Sort orders so that the start and end placeholder order are at the correct
|
||||
@ -821,14 +826,14 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
|
||||
startDate = start;
|
||||
}
|
||||
|
||||
const endDateString = format(endDate, DATE_FORMAT);
|
||||
const startDateString = format(startDate, DATE_FORMAT);
|
||||
const rangeEndDateString = format(endDate, DATE_FORMAT);
|
||||
const rangeStartDateString = format(startDate, DATE_FORMAT);
|
||||
|
||||
const currentValuesAtDateRangeStartWithCurrencyEffect =
|
||||
currentValuesWithCurrencyEffect[startDateString] ?? new Big(0);
|
||||
currentValuesWithCurrencyEffect[rangeStartDateString] ?? new Big(0);
|
||||
|
||||
const investmentValuesAccumulatedAtStartDateWithCurrencyEffect =
|
||||
investmentValuesAccumulatedWithCurrencyEffect[startDateString] ??
|
||||
investmentValuesAccumulatedWithCurrencyEffect[rangeStartDateString] ??
|
||||
new Big(0);
|
||||
|
||||
const grossPerformanceAtDateRangeStartWithCurrencyEffect =
|
||||
@ -839,14 +844,12 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
|
||||
let average = new Big(0);
|
||||
let dayCount = 0;
|
||||
|
||||
if (!this.chartDatesDescending) {
|
||||
this.chartDatesDescending = Object.keys(chartDateMap).sort().reverse();
|
||||
}
|
||||
for (let i = this.chartDates.length - 1; i >= 0; i -= 1) {
|
||||
const date = this.chartDates[i];
|
||||
|
||||
for (const date of this.chartDatesDescending) {
|
||||
if (date > endDateString) {
|
||||
if (date > rangeEndDateString) {
|
||||
continue;
|
||||
} else if (date < startDateString) {
|
||||
} else if (date < rangeStartDateString) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -869,13 +872,13 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
|
||||
}
|
||||
|
||||
netPerformanceWithCurrencyEffectMap[dateRange] =
|
||||
netPerformanceValuesWithCurrencyEffect[endDateString]?.minus(
|
||||
netPerformanceValuesWithCurrencyEffect[rangeEndDateString]?.minus(
|
||||
// If the date range is 'max', take 0 as a start value. Otherwise,
|
||||
// the value of the end of the day of the start date is taken which
|
||||
// differs from the buying price.
|
||||
dateRange === 'max'
|
||||
? new Big(0)
|
||||
: (netPerformanceValuesWithCurrencyEffect[startDateString] ??
|
||||
: (netPerformanceValuesWithCurrencyEffect[rangeStartDateString] ??
|
||||
new Big(0))
|
||||
) ?? new Big(0);
|
||||
|
||||
|
20
apps/client-e2e/.eslintrc.json
Normal file
20
apps/client-e2e/.eslintrc.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"parserOptions": {
|
||||
"project": ["apps/client-e2e/tsconfig.*?.json"]
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["src/plugins/index.js"],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"no-undef": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -4,6 +4,9 @@
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"parserOptions": {
|
||||
"project": ["apps/ui-e2e/tsconfig.json"]
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
|
@ -1,9 +1,12 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"ignorePatterns": ["!**/*", "**/*.stories.ts"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts"],
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"parserOptions": {
|
||||
"project": ["libs/ui/tsconfig.*?.json"]
|
||||
},
|
||||
"extends": [
|
||||
"plugin:@nx/angular",
|
||||
"plugin:@angular-eslint/template/process-inline-templates"
|
||||
|
@ -269,9 +269,13 @@ export class GfActivitiesTableComponent
|
||||
}
|
||||
|
||||
public toggleAllRows() {
|
||||
this.areAllRowsSelected()
|
||||
? this.selectedRows.clear()
|
||||
: this.dataSource.data.forEach((row) => this.selectedRows.select(row));
|
||||
if (this.areAllRowsSelected()) {
|
||||
this.selectedRows.clear();
|
||||
} else {
|
||||
this.dataSource.data.forEach((row) => {
|
||||
this.selectedRows.select(row);
|
||||
});
|
||||
}
|
||||
|
||||
this.selectedActivities.emit(this.selectedRows.selected);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user