diff --git a/server/src/index.js b/server/src/index.js index 3d39c6c..6a2041b 100644 --- a/server/src/index.js +++ b/server/src/index.js @@ -3874,6 +3874,132 @@ async function computeTotalPnlSeries(login, account, perAccountCombinedBalances, }); } + let baselineEquityInjection = null; + if ( + netDepositOptions.applyAccountCagrStartDate !== false && + typeof displayStartIso === 'string' && + displayStartIso && + typeof cagrStartDate === 'string' && + points.length > 0 + ) { + const baselineIndex = points.findIndex(function (point) { + return point && typeof point.date === 'string' && point.date === displayStartIso; + }); + if (baselineIndex >= 0) { + const baselinePoint = points[baselineIndex]; + const baselineEquityCandidate = baselinePoint ? Number(baselinePoint.equityCad) : null; + const baselineNetDepositsCandidate = baselinePoint + ? Number(baselinePoint.cumulativeNetDepositsCad) + : null; + let baselineTotalPnlCandidate = baselinePoint ? Number(baselinePoint.totalPnlCad) : null; + if (!Number.isFinite(baselineTotalPnlCandidate)) { + if (Number.isFinite(baselineEquityCandidate) && Number.isFinite(baselineNetDepositsCandidate)) { + baselineTotalPnlCandidate = baselineEquityCandidate - baselineNetDepositsCandidate; + } + } + const baselineEquity = Number.isFinite(baselineEquityCandidate) ? baselineEquityCandidate : null; + const baselineNetDeposits = Number.isFinite(baselineNetDepositsCandidate) + ? baselineNetDepositsCandidate + : null; + const baselineTotalPnl = Number.isFinite(baselineTotalPnlCandidate) + ? baselineTotalPnlCandidate + : baselineEquity !== null && baselineNetDeposits !== null + ? baselineEquity - baselineNetDeposits + : null; + if (baselineEquity !== null && baselineNetDeposits !== null) { + baselineEquityInjection = baselineEquity; + + for (let i = baselineIndex; i < points.length; i += 1) { + const point = points[i]; + if (!point || typeof point !== 'object') { + continue; + } + + const originalNetDeposits = Number.isFinite(point.cumulativeNetDepositsCad) + ? point.cumulativeNetDepositsCad + : null; + + if (originalNetDeposits !== null) { + const adjustedDeposits = originalNetDeposits - baselineNetDeposits + baselineEquity; + point.cumulativeNetDepositsCad = + Math.abs(adjustedDeposits) < CASH_FLOW_EPSILON ? 0 : adjustedDeposits; + if (Number.isFinite(point.equityCad)) { + const derivedPnl = point.equityCad - point.cumulativeNetDepositsCad; + point.totalPnlCad = Math.abs(derivedPnl) < CASH_FLOW_EPSILON ? 0 : derivedPnl; + } else if (baselineTotalPnl !== null && Number.isFinite(point.totalPnlCad)) { + const adjustedPnl = point.totalPnlCad - baselineTotalPnl; + point.totalPnlCad = Math.abs(adjustedPnl) < CASH_FLOW_EPSILON ? 0 : adjustedPnl; + } + } else if (baselineTotalPnl !== null && Number.isFinite(point.totalPnlCad)) { + const adjustedPnl = point.totalPnlCad - baselineTotalPnl; + point.totalPnlCad = Math.abs(adjustedPnl) < CASH_FLOW_EPSILON ? 0 : adjustedPnl; + } + + if (i === baselineIndex) { + point.cumulativeNetDepositsCad = baselineEquity; + if (Number.isFinite(point.totalPnlCad)) { + point.totalPnlCad = 0; + } + } + } + + if ( + netDepositsSummary.netDeposits && + Number.isFinite(netDepositsSummary.netDeposits.combinedCad) + ) { + const adjustedNetDeposits = netDepositsSummary.netDeposits.combinedCad + baselineEquity; + netDepositsSummary.netDeposits.combinedCad = + Math.abs(adjustedNetDeposits) < CASH_FLOW_EPSILON ? 0 : adjustedNetDeposits; + } + + if (netDepositsSummary.totalPnl) { + if ( + Number.isFinite(netDepositsSummary.totalEquityCad) && + netDepositsSummary.netDeposits && + Number.isFinite(netDepositsSummary.netDeposits.combinedCad) + ) { + const derivedTotalPnl = + netDepositsSummary.totalEquityCad - netDepositsSummary.netDeposits.combinedCad; + netDepositsSummary.totalPnl.combinedCad = + Math.abs(derivedTotalPnl) < CASH_FLOW_EPSILON ? 0 : derivedTotalPnl; + } else if ( + baselineTotalPnl !== null && + Number.isFinite(netDepositsSummary.totalPnl.combinedCad) + ) { + const adjustedTotalPnl = netDepositsSummary.totalPnl.combinedCad - baselineTotalPnl; + netDepositsSummary.totalPnl.combinedCad = + Math.abs(adjustedTotalPnl) < CASH_FLOW_EPSILON ? 0 : adjustedTotalPnl; + } + } else if ( + Number.isFinite(netDepositsSummary.totalEquityCad) && + netDepositsSummary.netDeposits && + Number.isFinite(netDepositsSummary.netDeposits.combinedCad) + ) { + const derivedTotalPnl = + netDepositsSummary.totalEquityCad - netDepositsSummary.netDeposits.combinedCad; + const preservedAllTime = + netDepositsSummary.totalPnl && Number.isFinite(netDepositsSummary.totalPnl.allTimeCad) + ? netDepositsSummary.totalPnl.allTimeCad + : undefined; + netDepositsSummary.totalPnl = { + combinedCad: Math.abs(derivedTotalPnl) < CASH_FLOW_EPSILON ? 0 : derivedTotalPnl, + }; + if (preservedAllTime !== undefined) { + netDepositsSummary.totalPnl.allTimeCad = preservedAllTime; + } + } + + if (baselineEquityInjection !== null) { + netDepositsSummary.metadata = Object.assign({}, netDepositsSummary.metadata, { + baselineEquityInjectedCad: baselineEquityInjection, + baselineNetDepositsCad: baselineNetDeposits, + baselineTotalPnlCad: baselineTotalPnl, + }); + } + } + } + } + const summaryTotalPnl = netDepositsSummary.totalPnl && Number.isFinite(netDepositsSummary.totalPnl.combinedCad) ? netDepositsSummary.totalPnl.combinedCad : null; @@ -3933,34 +4059,53 @@ async function computeTotalPnlSeries(login, account, perAccountCombinedBalances, const rebasedPoints = filteredPoints.map((point) => ({ ...point })); if (cagrStartDate && displayStartDate && rebasedPoints.length) { + const baselineEquity = Number.isFinite(rebasedPoints[0].equityCad) + ? rebasedPoints[0].equityCad + : null; const baselineNetDeposits = Number.isFinite(rebasedPoints[0].cumulativeNetDepositsCad) ? rebasedPoints[0].cumulativeNetDepositsCad : null; const baselineTotalPnl = Number.isFinite(rebasedPoints[0].totalPnlCad) ? rebasedPoints[0].totalPnlCad - : null; + : baselineEquity !== null && baselineNetDeposits !== null + ? baselineEquity - baselineNetDeposits + : null; + rebasedPoints.forEach((entry, index) => { - if (baselineNetDeposits !== null && Number.isFinite(entry.cumulativeNetDepositsCad)) { - const adjustedNetDeposits = entry.cumulativeNetDepositsCad - baselineNetDeposits; + if (!entry || typeof entry !== 'object') { + return; + } + + const originalTotalPnl = Number.isFinite(entry.totalPnlCad) ? entry.totalPnlCad : null; + const originalNetDeposits = Number.isFinite(entry.cumulativeNetDepositsCad) + ? entry.cumulativeNetDepositsCad + : null; + + if (baselineEquity !== null && baselineNetDeposits !== null && originalNetDeposits !== null) { + const adjustedNetDeposits = originalNetDeposits - baselineNetDeposits + baselineEquity; entry.cumulativeNetDepositsCad = Math.abs(adjustedNetDeposits) < CASH_FLOW_EPSILON ? 0 : adjustedNetDeposits; - if (Number.isFinite(entry.equityCad)) { - const derivedPnl = entry.equityCad - entry.cumulativeNetDepositsCad; - entry.totalPnlCad = Math.abs(derivedPnl) < CASH_FLOW_EPSILON ? 0 : derivedPnl; - } else if (baselineTotalPnl !== null && Number.isFinite(entry.totalPnlCad)) { - const adjustedPnl = entry.totalPnlCad - baselineTotalPnl; - entry.totalPnlCad = Math.abs(adjustedPnl) < CASH_FLOW_EPSILON ? 0 : adjustedPnl; - } - } else if (baselineTotalPnl !== null && Number.isFinite(entry.totalPnlCad)) { - const adjustedPnl = entry.totalPnlCad - baselineTotalPnl; + } + + if (Number.isFinite(entry.equityCad) && Number.isFinite(entry.cumulativeNetDepositsCad)) { + const derivedPnl = entry.equityCad - entry.cumulativeNetDepositsCad; + entry.totalPnlCad = Math.abs(derivedPnl) < CASH_FLOW_EPSILON ? 0 : derivedPnl; + } else if (baselineTotalPnl !== null && originalTotalPnl !== null) { + const adjustedPnl = originalTotalPnl - baselineTotalPnl; entry.totalPnlCad = Math.abs(adjustedPnl) < CASH_FLOW_EPSILON ? 0 : adjustedPnl; } + if (index === 0) { - if (Number.isFinite(entry.cumulativeNetDepositsCad)) { - entry.cumulativeNetDepositsCad = 0; + if (baselineEquity !== null) { + entry.cumulativeNetDepositsCad = baselineEquity; } if (Number.isFinite(entry.totalPnlCad)) { entry.totalPnlCad = 0; + } else if ( + Number.isFinite(entry.equityCad) && + Number.isFinite(entry.cumulativeNetDepositsCad) + ) { + entry.totalPnlCad = 0; } } });