|
|
@ -16,6 +16,7 @@ import { |
|
|
|
isBefore, |
|
|
|
isSameMonth, |
|
|
|
isSameYear, |
|
|
|
isWithinInterval, |
|
|
|
max, |
|
|
|
min, |
|
|
|
set |
|
|
@ -167,8 +168,19 @@ export class PortfolioCalculator { |
|
|
|
this.transactionPoints = transactionPoints; |
|
|
|
} |
|
|
|
|
|
|
|
public async getCurrentPositions(start: Date): Promise<CurrentPositions> { |
|
|
|
if (!this.transactionPoints?.length) { |
|
|
|
public async getCurrentPositions( |
|
|
|
start: Date, |
|
|
|
end = new Date(Date.now()) |
|
|
|
): Promise<CurrentPositions> { |
|
|
|
const transactionPointsInRange = |
|
|
|
this.transactionPoints?.filter((transactionPoint) => { |
|
|
|
return isWithinInterval(parseDate(transactionPoint.date), { |
|
|
|
start, |
|
|
|
end |
|
|
|
}); |
|
|
|
}) ?? []; |
|
|
|
|
|
|
|
if (!transactionPointsInRange.length) { |
|
|
|
return { |
|
|
|
currentValue: new Big(0), |
|
|
|
hasErrors: false, |
|
|
@ -182,39 +194,36 @@ export class PortfolioCalculator { |
|
|
|
} |
|
|
|
|
|
|
|
const lastTransactionPoint = |
|
|
|
this.transactionPoints[this.transactionPoints.length - 1]; |
|
|
|
|
|
|
|
// use Date.now() to use the mock for today
|
|
|
|
const today = new Date(Date.now()); |
|
|
|
transactionPointsInRange[transactionPointsInRange.length - 1]; |
|
|
|
|
|
|
|
let firstTransactionPoint: TransactionPoint = null; |
|
|
|
let firstIndex = this.transactionPoints.length; |
|
|
|
let firstIndex = transactionPointsInRange.length; |
|
|
|
const dates = []; |
|
|
|
const dataGatheringItems: IDataGatheringItem[] = []; |
|
|
|
const currencies: { [symbol: string]: string } = {}; |
|
|
|
|
|
|
|
dates.push(resetHours(start)); |
|
|
|
for (const item of this.transactionPoints[firstIndex - 1].items) { |
|
|
|
for (const item of transactionPointsInRange[firstIndex - 1].items) { |
|
|
|
dataGatheringItems.push({ |
|
|
|
dataSource: item.dataSource, |
|
|
|
symbol: item.symbol |
|
|
|
}); |
|
|
|
currencies[item.symbol] = item.currency; |
|
|
|
} |
|
|
|
for (let i = 0; i < this.transactionPoints.length; i++) { |
|
|
|
for (let i = 0; i < transactionPointsInRange.length; i++) { |
|
|
|
if ( |
|
|
|
!isBefore(parseDate(this.transactionPoints[i].date), start) && |
|
|
|
!isBefore(parseDate(transactionPointsInRange[i].date), start) && |
|
|
|
firstTransactionPoint === null |
|
|
|
) { |
|
|
|
firstTransactionPoint = this.transactionPoints[i]; |
|
|
|
firstTransactionPoint = transactionPointsInRange[i]; |
|
|
|
firstIndex = i; |
|
|
|
} |
|
|
|
if (firstTransactionPoint !== null) { |
|
|
|
dates.push(resetHours(parseDate(this.transactionPoints[i].date))); |
|
|
|
dates.push(resetHours(parseDate(transactionPointsInRange[i].date))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
dates.push(resetHours(today)); |
|
|
|
dates.push(resetHours(end)); |
|
|
|
|
|
|
|
const marketSymbols = await this.currentRateService.getValues({ |
|
|
|
currencies, |
|
|
@ -241,7 +250,7 @@ export class PortfolioCalculator { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const todayString = format(today, DATE_FORMAT); |
|
|
|
const endDateString = format(end, DATE_FORMAT); |
|
|
|
|
|
|
|
if (firstIndex > 0) { |
|
|
|
firstIndex--; |
|
|
@ -254,7 +263,7 @@ export class PortfolioCalculator { |
|
|
|
const errors: ResponseError['errors'] = []; |
|
|
|
|
|
|
|
for (const item of lastTransactionPoint.items) { |
|
|
|
const marketValue = marketSymbolMap[todayString]?.[item.symbol]; |
|
|
|
const marketValue = marketSymbolMap[endDateString]?.[item.symbol]; |
|
|
|
|
|
|
|
const { |
|
|
|
grossPerformance, |
|
|
|