diff --git a/centrifuge-app/src/components/Portfolio/CardPortfolioValue.tsx b/centrifuge-app/src/components/Portfolio/CardPortfolioValue.tsx
index 37c2e3313..9e4068d0d 100644
--- a/centrifuge-app/src/components/Portfolio/CardPortfolioValue.tsx
+++ b/centrifuge-app/src/components/Portfolio/CardPortfolioValue.tsx
@@ -73,18 +73,24 @@ export function CardPortfolioValue({
-
- Current portfolio value
-
- {formatBalance(currentPortfolioValue || 0, config.baseCurrency)}
-
-
- {/*
- Profit
-
- + {formatBalance(Dec(portfolioValue || 0), config.baseCurrency)}
-
- */}
+
+
+ Current portfolio value
+
+ {formatBalance(currentPortfolioValue || 0, config.baseCurrency)}
+
+
+
+ Total P&L
+
+ {formatBalance(currentPortfolioValue || 0, config.baseCurrency)}
+
+
+
diff --git a/centrifuge-app/src/components/Portfolio/Holdings.tsx b/centrifuge-app/src/components/Portfolio/Holdings.tsx
index 8ea2f99b7..b08fae5b2 100644
--- a/centrifuge-app/src/components/Portfolio/Holdings.tsx
+++ b/centrifuge-app/src/components/Portfolio/Holdings.tsx
@@ -1,4 +1,4 @@
-import { Token, evmToSubstrateAddress } from '@centrifuge/centrifuge-js'
+import { CurrencyBalance, Token, evmToSubstrateAddress } from '@centrifuge/centrifuge-js'
import { formatBalance, useBalances, useCentrifuge, useWallet } from '@centrifuge/centrifuge-react'
import { Box, Grid, IconDownload, IconMinus, IconPlus, IconSend, Shelf, Text, Thumbnail } from '@centrifuge/fabric'
import Decimal from 'decimal.js-light'
@@ -36,6 +36,8 @@ type Row = {
showActions?: boolean
address?: string
connectedNetwork?: string | null
+ realizedProfit?: CurrencyBalance | undefined
+ unrealizedProfit?: CurrencyBalance | undefined
}
const columns: Column[] = [
@@ -81,6 +83,30 @@ const columns: Column[] = [
sortKey: 'marketValue',
align: 'left',
},
+ {
+ header: ,
+ cell: ({ currency, unrealizedProfit }: Row) => {
+ return (
+
+ {unrealizedProfit ? formatBalanceAbbreviated(unrealizedProfit, currency?.symbol, 2) : '-'}
+
+ )
+ },
+ sortKey: 'realizedProfit',
+ align: 'left',
+ },
+ {
+ header: ,
+ cell: ({ currency, unrealizedProfit }: Row) => {
+ return (
+
+ {unrealizedProfit ? formatBalanceAbbreviated(unrealizedProfit, currency?.symbol, 2) : '-'}
+
+ )
+ },
+ sortKey: 'unrealizedProfit',
+ align: 'left',
+ },
{
align: 'left',
header: '', // invest redeem buttons
diff --git a/centrifuge-app/src/components/Portfolio/usePortfolio.ts b/centrifuge-app/src/components/Portfolio/usePortfolio.ts
index baae396c3..33dff4ca0 100644
--- a/centrifuge-app/src/components/Portfolio/usePortfolio.ts
+++ b/centrifuge-app/src/components/Portfolio/usePortfolio.ts
@@ -147,6 +147,7 @@ export function usePortfolio(substrateAddress?: string) {
sumClaimedTrancheTokens
trancheId
poolId
+ unrealizedProfit
tranche {
tokenPrice
}
@@ -176,6 +177,12 @@ export function usePortfolio(substrateAddress?: string) {
trancheId
}
}
+ investorTransactions {
+ nodes {
+ realizedProfitFifo
+ trancheId
+ }
+ }
}
}`,
{
@@ -187,7 +194,12 @@ export function usePortfolio(substrateAddress?: string) {
)
const data = useMemo(() => {
- const trancheBalances: Record = {}
+ const trancheBalances: Record<
+ string,
+ { totalTrancheTokens: TokenBalance; tokenPrice: Price; unrealizedProfit: CurrencyBalance | undefined }
+ > = {}
+
+ console.log('sub', subData)
subData?.account?.investorPositions.nodes.forEach((position: any) => {
const pool = pools?.find((p) => p.id === position.poolId)
@@ -196,12 +208,24 @@ export function usePortfolio(substrateAddress?: string) {
const tokenPrice = pool?.tranches.find((t) => trancheId === t.id)?.tokenPrice ?? Price.fromFloat(1)
const balance = new TokenBalance(position.holdingQuantity, decimals)
const existing = trancheBalances[trancheId]
+
+ const unrealizedProfit = subData?.account?.trancheBalances?.nodes.find(
+ (tb: any) => tb.trancheId === position.trancheId
+ )
+
if (existing) {
existing.totalTrancheTokens.iadd(balance)
} else {
- trancheBalances[trancheId] = { totalTrancheTokens: balance, tokenPrice }
+ trancheBalances[trancheId] = {
+ totalTrancheTokens: balance,
+ tokenPrice,
+ unrealizedProfit: unrealizedProfit
+ ? new CurrencyBalance(unrealizedProfit.unrealizedProfit, decimals)
+ : undefined,
+ }
}
})
+
// return (
// (subData?.account as undefined | {}) &&
// (Object.fromEntries(
@@ -265,6 +289,7 @@ export function usePortfolio(substrateAddress?: string) {
// }
// >)
// )
+
return trancheBalances
}, [subData, pools])
@@ -278,6 +303,7 @@ type PortfolioToken = {
trancheId: string
poolId: string
currency: Token['currency']
+ unrealizedProfit: CurrencyBalance | undefined
}
export function usePortfolioTokens(address?: string) {
@@ -310,6 +336,7 @@ export function usePortfolioTokens(address?: string) {
trancheId: trancheId,
poolId: trancheTokenPrices[trancheId].poolId,
currency: trancheTokenPrices[trancheId].currency,
+ unrealizedProfit: tranche.unrealizedProfit,
}
}, [] as PortfolioToken[])
}
diff --git a/centrifuge-app/src/components/Tooltips.tsx b/centrifuge-app/src/components/Tooltips.tsx
index e881d0cf9..eb9e48fff 100644
--- a/centrifuge-app/src/components/Tooltips.tsx
+++ b/centrifuge-app/src/components/Tooltips.tsx
@@ -330,6 +330,14 @@ export const tooltipText = {
label: 'Linear accrual',
body: 'If enabled, the price of the asset is updated continuously based on linear accrual from the latest known market price to the value at maturity.',
},
+ unrealizedPL: {
+ label: 'Unrealized P&L',
+ body: 'Unrealized profit / loss from current holdings (based on FiFo-weighted sales at the current token price)',
+ },
+ realizedPL: {
+ label: 'Realized P&L',
+ body: 'Realized profit / loss from executed redemptions',
+ },
}
export type TooltipsProps = {