Primera build enviada
This commit is contained in:
@@ -43,9 +43,15 @@ class CalculationService {
|
||||
let monthChange = calculatePeriodChange(sources: sources, from: monthAgo)
|
||||
let yearChange = calculatePeriodChange(sources: sources, from: yearAgo)
|
||||
|
||||
let allTimeReturn = totalValue - totalContributions
|
||||
let allTimeReturnPercentage = totalContributions > 0
|
||||
? NSDecimalNumber(decimal: allTimeReturn / totalContributions).doubleValue * 100
|
||||
let baselineTotal = sources.reduce(Decimal.zero) { partial, source in
|
||||
if let firstSnapshot = source.sortedSnapshotsByDateAscending.first {
|
||||
return partial + firstSnapshot.decimalValue
|
||||
}
|
||||
return partial + source.latestValue
|
||||
}
|
||||
let allTimeReturn = totalValue - baselineTotal
|
||||
let allTimeReturnPercentage = baselineTotal > 0
|
||||
? NSDecimalNumber(decimal: allTimeReturn / baselineTotal).doubleValue * 100
|
||||
: 0
|
||||
|
||||
let lastUpdated = snapshots.map { $0.date }.max()
|
||||
@@ -458,57 +464,36 @@ class CalculationService {
|
||||
|
||||
private func buildCategorySeries(from snapshots: [Snapshot]) -> [SeriesPoint] {
|
||||
let sortedSnapshots = snapshots.sorted { $0.date < $1.date }
|
||||
let uniqueDates = Array(Set(sortedSnapshots.map { Calendar.current.startOfDay(for: $0.date) }))
|
||||
.sorted()
|
||||
guard !uniqueDates.isEmpty else { return [] }
|
||||
|
||||
var snapshotsBySource: [UUID: [(date: Date, value: Decimal)]] = [:]
|
||||
var contributionsByDate: [Date: Decimal] = [:]
|
||||
|
||||
for snapshot in sortedSnapshots {
|
||||
guard let sourceId = snapshot.source?.id else { continue }
|
||||
snapshotsBySource[sourceId, default: []].append(
|
||||
(date: snapshot.date, value: snapshot.decimalValue)
|
||||
)
|
||||
let day = Calendar.current.startOfDay(for: snapshot.date)
|
||||
contributionsByDate[day, default: 0] += snapshot.decimalContribution
|
||||
let groupedByMonth = Dictionary(grouping: sortedSnapshots) { snapshot -> DateComponents in
|
||||
let components = Calendar.current.dateComponents([.year, .month], from: snapshot.date)
|
||||
return DateComponents(year: components.year, month: components.month)
|
||||
}
|
||||
|
||||
var indices: [UUID: Int] = [:]
|
||||
var series: [SeriesPoint] = []
|
||||
series.reserveCapacity(groupedByMonth.count)
|
||||
|
||||
for (index, date) in uniqueDates.enumerated() {
|
||||
let nextDate = index + 1 < uniqueDates.count
|
||||
? uniqueDates[index + 1]
|
||||
: Date.distantFuture
|
||||
var total: Decimal = 0
|
||||
for (key, monthSnapshots) in groupedByMonth {
|
||||
var latestBySource: [UUID: Snapshot] = [:]
|
||||
var contributions: Decimal = 0
|
||||
|
||||
for (sourceId, sourceSnapshots) in snapshotsBySource {
|
||||
var currentIndex = indices[sourceId] ?? 0
|
||||
var latest: (date: Date, value: Decimal)?
|
||||
|
||||
while currentIndex < sourceSnapshots.count && sourceSnapshots[currentIndex].date < nextDate {
|
||||
latest = sourceSnapshots[currentIndex]
|
||||
currentIndex += 1
|
||||
}
|
||||
|
||||
indices[sourceId] = currentIndex
|
||||
|
||||
if let latest {
|
||||
total += latest.value
|
||||
for snapshot in monthSnapshots {
|
||||
contributions += snapshot.decimalContribution
|
||||
guard let sourceId = snapshot.source?.id else { continue }
|
||||
if let existing = latestBySource[sourceId] {
|
||||
if snapshot.date > existing.date {
|
||||
latestBySource[sourceId] = snapshot
|
||||
}
|
||||
} else {
|
||||
latestBySource[sourceId] = snapshot
|
||||
}
|
||||
}
|
||||
|
||||
series.append(
|
||||
SeriesPoint(
|
||||
date: date,
|
||||
value: total,
|
||||
contribution: contributionsByDate[date] ?? 0
|
||||
)
|
||||
)
|
||||
let total = latestBySource.values.reduce(Decimal.zero) { $0 + $1.decimalValue }
|
||||
let date = Calendar.current.date(from: key) ?? Date()
|
||||
series.append(SeriesPoint(date: date, value: total, contribution: contributions))
|
||||
}
|
||||
|
||||
return series
|
||||
return series.sorted { $0.date < $1.date }
|
||||
}
|
||||
|
||||
private func calculateMonthlyReturns(from series: [SeriesPoint]) -> [InvestmentMetrics.MonthlyReturn] {
|
||||
|
||||
Reference in New Issue
Block a user