Feature/skip caching in portfolio calculator if active filters (#3348)
* Skip caching if active filters * Update changelog
This commit is contained in:
parent
261f5844dd
commit
a5833566a8
@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Added a form validation against the DTO in the platform management of the admin control panel
|
- Added a form validation against the DTO in the platform management of the admin control panel
|
||||||
- Added a form validation against the DTO in the tag management of the admin control panel
|
- Added a form validation against the DTO in the tag management of the admin control panel
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Skipped the caching in the portfolio calculator if there are active filters (experimental)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed an issue in the calculation of the portfolio summary caused by future liabilities
|
- Fixed an issue in the calculation of the portfolio summary caused by future liabilities
|
||||||
|
@ -32,6 +32,7 @@ export class PortfolioCalculatorFactory {
|
|||||||
calculationType,
|
calculationType,
|
||||||
currency,
|
currency,
|
||||||
dateRange = 'max',
|
dateRange = 'max',
|
||||||
|
hasFilters,
|
||||||
isExperimentalFeatures = false,
|
isExperimentalFeatures = false,
|
||||||
userId
|
userId
|
||||||
}: {
|
}: {
|
||||||
@ -40,9 +41,12 @@ export class PortfolioCalculatorFactory {
|
|||||||
calculationType: PerformanceCalculationType;
|
calculationType: PerformanceCalculationType;
|
||||||
currency: string;
|
currency: string;
|
||||||
dateRange?: DateRange;
|
dateRange?: DateRange;
|
||||||
|
hasFilters: boolean;
|
||||||
isExperimentalFeatures?: boolean;
|
isExperimentalFeatures?: boolean;
|
||||||
userId: string;
|
userId: string;
|
||||||
}): PortfolioCalculator {
|
}): PortfolioCalculator {
|
||||||
|
const useCache = !hasFilters && isExperimentalFeatures;
|
||||||
|
|
||||||
switch (calculationType) {
|
switch (calculationType) {
|
||||||
case PerformanceCalculationType.MWR:
|
case PerformanceCalculationType.MWR:
|
||||||
return new MWRPortfolioCalculator({
|
return new MWRPortfolioCalculator({
|
||||||
@ -50,7 +54,7 @@ export class PortfolioCalculatorFactory {
|
|||||||
activities,
|
activities,
|
||||||
currency,
|
currency,
|
||||||
dateRange,
|
dateRange,
|
||||||
isExperimentalFeatures,
|
useCache,
|
||||||
userId,
|
userId,
|
||||||
configurationService: this.configurationService,
|
configurationService: this.configurationService,
|
||||||
currentRateService: this.currentRateService,
|
currentRateService: this.currentRateService,
|
||||||
@ -64,7 +68,7 @@ export class PortfolioCalculatorFactory {
|
|||||||
currency,
|
currency,
|
||||||
currentRateService: this.currentRateService,
|
currentRateService: this.currentRateService,
|
||||||
dateRange,
|
dateRange,
|
||||||
isExperimentalFeatures,
|
useCache,
|
||||||
userId,
|
userId,
|
||||||
configurationService: this.configurationService,
|
configurationService: this.configurationService,
|
||||||
exchangeRateDataService: this.exchangeRateDataService,
|
exchangeRateDataService: this.exchangeRateDataService,
|
||||||
|
@ -56,14 +56,15 @@ export abstract class PortfolioCalculator {
|
|||||||
private currency: string;
|
private currency: string;
|
||||||
private currentRateService: CurrentRateService;
|
private currentRateService: CurrentRateService;
|
||||||
private dataProviderInfos: DataProviderInfo[];
|
private dataProviderInfos: DataProviderInfo[];
|
||||||
|
private dateRange: DateRange;
|
||||||
private endDate: Date;
|
private endDate: Date;
|
||||||
private exchangeRateDataService: ExchangeRateDataService;
|
private exchangeRateDataService: ExchangeRateDataService;
|
||||||
private isExperimentalFeatures: boolean;
|
|
||||||
private redisCacheService: RedisCacheService;
|
private redisCacheService: RedisCacheService;
|
||||||
private snapshot: PortfolioSnapshot;
|
private snapshot: PortfolioSnapshot;
|
||||||
private snapshotPromise: Promise<void>;
|
private snapshotPromise: Promise<void>;
|
||||||
private startDate: Date;
|
private startDate: Date;
|
||||||
private transactionPoints: TransactionPoint[];
|
private transactionPoints: TransactionPoint[];
|
||||||
|
private useCache: boolean;
|
||||||
private userId: string;
|
private userId: string;
|
||||||
|
|
||||||
public constructor({
|
public constructor({
|
||||||
@ -74,8 +75,8 @@ export abstract class PortfolioCalculator {
|
|||||||
currentRateService,
|
currentRateService,
|
||||||
dateRange,
|
dateRange,
|
||||||
exchangeRateDataService,
|
exchangeRateDataService,
|
||||||
isExperimentalFeatures,
|
|
||||||
redisCacheService,
|
redisCacheService,
|
||||||
|
useCache,
|
||||||
userId
|
userId
|
||||||
}: {
|
}: {
|
||||||
accountBalanceItems: HistoricalDataItem[];
|
accountBalanceItems: HistoricalDataItem[];
|
||||||
@ -85,16 +86,16 @@ export abstract class PortfolioCalculator {
|
|||||||
currentRateService: CurrentRateService;
|
currentRateService: CurrentRateService;
|
||||||
dateRange: DateRange;
|
dateRange: DateRange;
|
||||||
exchangeRateDataService: ExchangeRateDataService;
|
exchangeRateDataService: ExchangeRateDataService;
|
||||||
isExperimentalFeatures: boolean;
|
|
||||||
redisCacheService: RedisCacheService;
|
redisCacheService: RedisCacheService;
|
||||||
|
useCache: boolean;
|
||||||
userId: string;
|
userId: string;
|
||||||
}) {
|
}) {
|
||||||
this.accountBalanceItems = accountBalanceItems;
|
this.accountBalanceItems = accountBalanceItems;
|
||||||
this.configurationService = configurationService;
|
this.configurationService = configurationService;
|
||||||
this.currency = currency;
|
this.currency = currency;
|
||||||
this.currentRateService = currentRateService;
|
this.currentRateService = currentRateService;
|
||||||
|
this.dateRange = dateRange;
|
||||||
this.exchangeRateDataService = exchangeRateDataService;
|
this.exchangeRateDataService = exchangeRateDataService;
|
||||||
this.isExperimentalFeatures = isExperimentalFeatures;
|
|
||||||
|
|
||||||
this.activities = activities
|
this.activities = activities
|
||||||
.map(
|
.map(
|
||||||
@ -129,6 +130,7 @@ export abstract class PortfolioCalculator {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.redisCacheService = redisCacheService;
|
this.redisCacheService = redisCacheService;
|
||||||
|
this.useCache = useCache;
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
|
|
||||||
const { endDate, startDate } = getInterval(dateRange);
|
const { endDate, startDate } = getInterval(dateRange);
|
||||||
@ -1047,11 +1049,13 @@ export abstract class PortfolioCalculator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async initialize() {
|
private async initialize() {
|
||||||
if (this.isExperimentalFeatures) {
|
if (this.useCache) {
|
||||||
const startTimeTotal = performance.now();
|
const startTimeTotal = performance.now();
|
||||||
|
|
||||||
const cachedSnapshot = await this.redisCacheService.get(
|
const cachedSnapshot = await this.redisCacheService.get(
|
||||||
this.redisCacheService.getPortfolioSnapshotKey(this.userId)
|
this.redisCacheService.getPortfolioSnapshotKey({
|
||||||
|
userId: this.userId
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
if (cachedSnapshot) {
|
if (cachedSnapshot) {
|
||||||
@ -1074,7 +1078,9 @@ export abstract class PortfolioCalculator {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.redisCacheService.set(
|
this.redisCacheService.set(
|
||||||
this.redisCacheService.getPortfolioSnapshotKey(this.userId),
|
this.redisCacheService.getPortfolioSnapshotKey({
|
||||||
|
userId: this.userId
|
||||||
|
}),
|
||||||
JSON.stringify(this.snapshot),
|
JSON.stringify(this.snapshot),
|
||||||
this.configurationService.get('CACHE_QUOTES_TTL')
|
this.configurationService.get('CACHE_QUOTES_TTL')
|
||||||
);
|
);
|
||||||
|
@ -123,6 +123,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities,
|
activities,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'CHF',
|
currency: 'CHF',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities,
|
activities,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'CHF',
|
currency: 'CHF',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities,
|
activities,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'CHF',
|
currency: 'CHF',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -121,6 +121,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities,
|
activities,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'CHF',
|
currency: 'CHF',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities,
|
activities,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -106,6 +106,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities,
|
activities,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'CHF',
|
currency: 'CHF',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities,
|
activities,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities,
|
activities,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -121,6 +121,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities,
|
activities,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities: [],
|
activities: [],
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'CHF',
|
currency: 'CHF',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities,
|
activities,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'CHF',
|
currency: 'CHF',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => {
|
|||||||
activities,
|
activities,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: 'CHF',
|
currency: 'CHF',
|
||||||
|
hasFilters: false,
|
||||||
userId: userDummyData.id
|
userId: userDummyData.id
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -277,9 +277,11 @@ export class PortfolioService {
|
|||||||
|
|
||||||
const portfolioCalculator = this.calculatorFactory.createCalculator({
|
const portfolioCalculator = this.calculatorFactory.createCalculator({
|
||||||
activities,
|
activities,
|
||||||
|
dateRange,
|
||||||
userId,
|
userId,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: this.request.user.Settings.settings.baseCurrency,
|
currency: this.request.user.Settings.settings.baseCurrency,
|
||||||
|
hasFilters: filters?.length > 0,
|
||||||
isExperimentalFeatures:
|
isExperimentalFeatures:
|
||||||
this.request.user.Settings.settings.isExperimentalFeatures
|
this.request.user.Settings.settings.isExperimentalFeatures
|
||||||
});
|
});
|
||||||
@ -358,6 +360,7 @@ export class PortfolioService {
|
|||||||
userId,
|
userId,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: userCurrency,
|
currency: userCurrency,
|
||||||
|
hasFilters: filters?.length > 0,
|
||||||
isExperimentalFeatures:
|
isExperimentalFeatures:
|
||||||
this.request.user?.Settings.settings.isExperimentalFeatures
|
this.request.user?.Settings.settings.isExperimentalFeatures
|
||||||
});
|
});
|
||||||
@ -660,6 +663,7 @@ export class PortfolioService {
|
|||||||
}),
|
}),
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: userCurrency,
|
currency: userCurrency,
|
||||||
|
hasFilters: true,
|
||||||
isExperimentalFeatures:
|
isExperimentalFeatures:
|
||||||
this.request.user.Settings.settings.isExperimentalFeatures
|
this.request.user.Settings.settings.isExperimentalFeatures
|
||||||
});
|
});
|
||||||
@ -931,6 +935,7 @@ export class PortfolioService {
|
|||||||
userId,
|
userId,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: this.request.user.Settings.settings.baseCurrency,
|
currency: this.request.user.Settings.settings.baseCurrency,
|
||||||
|
hasFilters: filters?.length > 0,
|
||||||
isExperimentalFeatures:
|
isExperimentalFeatures:
|
||||||
this.request.user.Settings.settings.isExperimentalFeatures
|
this.request.user.Settings.settings.isExperimentalFeatures
|
||||||
});
|
});
|
||||||
@ -1085,7 +1090,7 @@ export class PortfolioService {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const { endDate, startDate } = getInterval(dateRange);
|
const { endDate } = getInterval(dateRange);
|
||||||
|
|
||||||
const { activities } = await this.orderService.getOrders({
|
const { activities } = await this.orderService.getOrders({
|
||||||
endDate,
|
endDate,
|
||||||
@ -1123,6 +1128,7 @@ export class PortfolioService {
|
|||||||
userId,
|
userId,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: userCurrency,
|
currency: userCurrency,
|
||||||
|
hasFilters: filters?.length > 0,
|
||||||
isExperimentalFeatures:
|
isExperimentalFeatures:
|
||||||
this.request.user.Settings.settings.isExperimentalFeatures
|
this.request.user.Settings.settings.isExperimentalFeatures
|
||||||
});
|
});
|
||||||
@ -1220,6 +1226,7 @@ export class PortfolioService {
|
|||||||
userId,
|
userId,
|
||||||
calculationType: PerformanceCalculationType.TWR,
|
calculationType: PerformanceCalculationType.TWR,
|
||||||
currency: this.request.user.Settings.settings.baseCurrency,
|
currency: this.request.user.Settings.settings.baseCurrency,
|
||||||
|
hasFilters: false,
|
||||||
isExperimentalFeatures:
|
isExperimentalFeatures:
|
||||||
this.request.user.Settings.settings.isExperimentalFeatures
|
this.request.user.Settings.settings.isExperimentalFeatures
|
||||||
});
|
});
|
||||||
|
@ -24,7 +24,7 @@ export class RedisCacheService {
|
|||||||
return this.cache.get(key);
|
return this.cache.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPortfolioSnapshotKey(userId: string) {
|
public getPortfolioSnapshotKey({ userId }: { userId: string }) {
|
||||||
return `portfolio-snapshot-${userId}`;
|
return `portfolio-snapshot-${userId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,9 @@ export class PortfolioChangedListener {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.redisCacheService.remove(
|
this.redisCacheService.remove(
|
||||||
this.redisCacheService.getPortfolioSnapshotKey(event.getUserId())
|
this.redisCacheService.getPortfolioSnapshotKey({
|
||||||
|
userId: event.getUserId()
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user