Skip to content

Commit f771b79

Browse files
Weighted average investment percent change
1 parent 418b8ad commit f771b79

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
@@ -25,6 +25,7 @@ import { useMemo } from 'react'
2525
import { IconCoin, IconError } from 'app/components/icons'
2626
import { useCoins } from 'app/provider/coins'
2727
import { investmentCoins as investmentCoinsList } from 'app/data/coins'
28+
import { formatUnits } from 'viem'
2829
import { HomeBodyCard } from './screen'
2930

3031
export const InvestmentsBalanceCard = (props: CardProps) => {
@@ -141,22 +142,41 @@ function OverlappingCoinIcons({
141142
}
142143

143144
function InvestmentsAggregate() {
144-
const tokenIds = useCoins()
145-
.investmentCoins.filter((c) => c?.balance && c.balance > 0n)
146-
.map((c) => c.coingeckoTokenId)
145+
const coins = useCoins().investmentCoins.filter((c) => c?.balance && c.balance > 0n)
147146

147+
const tokenIds = coins.map((c) => c.coingeckoTokenId)
148148
const { data: marketData, isLoading, isError } = useMultipleTokensMarketData(tokenIds)
149+
150+
const { totalValue, assetValues } = useMemo(() => {
151+
if (!marketData?.length) return { totalValue: 0, assetValues: [] }
152+
153+
// Calculate values for each asset and total
154+
const assetValues = coins.map((coin) => {
155+
const marketInfo = marketData.find((m) => m.id === coin.coingeckoTokenId)
156+
if (!marketInfo || !coin.balance) return { value: 0, percentChange: 0 }
157+
158+
const parsedBalance = formatUnits(coin.balance, coin.decimals)
159+
return {
160+
value: Number(parsedBalance) * (marketInfo.current_price ?? 0),
161+
percentChange: marketInfo.price_change_percentage_24h ?? 0,
162+
}
163+
})
164+
165+
const totalValue = assetValues.reduce((sum, asset) => sum + asset.value, 0)
166+
167+
return { totalValue, assetValues }
168+
}, [marketData, coins])
169+
149170
const aggregatePercentage = useMemo(() => {
150-
if (!marketData?.length) return 0
171+
if (totalValue <= 0) return 0
151172

152-
// Simple average of percentage changes
153-
const aggregatePercentage =
154-
marketData.reduce((total, coin) => {
155-
return total + (coin?.price_change_percentage_24h ?? 0)
156-
}, 0) / marketData.length
173+
const weightedPercentage = assetValues.reduce((sum, asset) => {
174+
const weight = asset.value / totalValue
175+
return sum + asset.percentChange * weight
176+
}, 0)
157177

158-
return Number(aggregatePercentage.toFixed(2))
159-
}, [marketData])
178+
return Math.round(weightedPercentage * 100) / 100
179+
}, [totalValue, assetValues])
160180

161181
if (tokenIds.length === 0)
162182
return (

0 commit comments

Comments
 (0)