Skip to content

Commit c46b882

Browse files
Weighted average investment percent change
1 parent 3549e1b commit c46b882

File tree

1 file changed

+31
-11
lines changed

1 file changed

+31
-11
lines changed

packages/app/features/home/InvestmentsBalanceCard.tsx

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { useMemo } from 'react'
2424
import { IconCoin, IconError } from 'app/components/icons'
2525
import { useCoins } from 'app/provider/coins'
2626
import { investmentCoins as investmentCoinsList } from 'app/data/coins'
27+
import { formatUnits } from 'viem'
2728

2829
export const InvestmentsBalanceCard = (props: CardProps) => {
2930
const media = useMedia()
@@ -151,22 +152,41 @@ function OverlappingCoinIcons({
151152
}
152153

153154
function InvestmentsAggregate() {
154-
const tokenIds = useCoins()
155-
.investmentCoins.filter((c) => c?.balance && c.balance > 0n)
156-
.map((c) => c.coingeckoTokenId)
155+
const coins = useCoins().investmentCoins.filter((c) => c?.balance && c.balance > 0n)
157156

157+
const tokenIds = coins.map((c) => c.coingeckoTokenId)
158158
const { data: marketData, isLoading, isError } = useMultipleTokensMarketData(tokenIds)
159+
160+
const { totalValue, assetValues } = useMemo(() => {
161+
if (!marketData?.length) return { totalValue: 0, assetValues: [] }
162+
163+
// Calculate values for each asset and total
164+
const assetValues = coins.map((coin) => {
165+
const marketInfo = marketData.find((m) => m.id === coin.coingeckoTokenId)
166+
if (!marketInfo || !coin.balance) return { value: 0, percentChange: 0 }
167+
168+
const parsedBalance = formatUnits(coin.balance, coin.decimals)
169+
return {
170+
value: Number(parsedBalance) * (marketInfo.current_price ?? 0),
171+
percentChange: marketInfo.price_change_percentage_24h ?? 0,
172+
}
173+
})
174+
175+
const totalValue = assetValues.reduce((sum, asset) => sum + asset.value, 0)
176+
177+
return { totalValue, assetValues }
178+
}, [marketData, coins])
179+
159180
const aggregatePercentage = useMemo(() => {
160-
if (!marketData?.length) return 0
181+
if (totalValue <= 0) return 0
161182

162-
// Simple average of percentage changes
163-
const aggregatePercentage =
164-
marketData.reduce((total, coin) => {
165-
return total + (coin?.price_change_percentage_24h ?? 0)
166-
}, 0) / marketData.length
183+
const weightedPercentage = assetValues.reduce((sum, asset) => {
184+
const weight = asset.value / totalValue
185+
return sum + asset.percentChange * weight
186+
}, 0)
167187

168-
return Number(aggregatePercentage.toFixed(2))
169-
}, [marketData])
188+
return Math.round(weightedPercentage * 100) / 100
189+
}, [totalValue, assetValues])
170190

171191
if (tokenIds.length === 0)
172192
return (

0 commit comments

Comments
 (0)