import mangoStore from '@store/mangoStore' import useMangoAccount from 'hooks/useMangoAccount' import useMangoGroup from 'hooks/useMangoGroup' import { useTranslation } from 'next-i18next' import { useEffect, useMemo } from 'react' import { ViewToShow } from './AccountPage' import { useQuery } from '@tanstack/react-query' import { fetchFundingTotals, fetchVolumeTotals } from 'utils/account' import Tooltip from '@components/shared/Tooltip' import { HealthType, toUiDecimalsForQuote, } from '@blockworks-foundation/mango-v4' import HealthBar from './HealthBar' import FormatNumericValue from '@components/shared/FormatNumericValue' import { IconButton } from '@components/shared/Button' import { CalendarIcon, ChartBarIcon } from '@heroicons/react/20/solid' import Change from '@components/shared/Change' import SheenLoader from '@components/shared/SheenLoader' import { PerformanceDataItem } from 'types' import useAccountHourlyVolumeStats from 'hooks/useAccountHourlyVolumeStats' const AccountHeroStats = ({ accountPnl, accountValue, rollingDailyData, setShowPnlHistory, handleViewChange, }: { accountPnl: number accountValue: number rollingDailyData: PerformanceDataItem[] setShowPnlHistory: (show: boolean) => void handleViewChange: (view: ViewToShow) => void }) => { const { t } = useTranslation(['common', 'account']) const { group } = useMangoGroup() const { mangoAccount, mangoAccountAddress } = useMangoAccount() const { hourlyVolumeData, loadingHourlyVolume } = useAccountHourlyVolumeStats() const totalInterestData = mangoStore( (s) => s.mangoAccount.interestTotals.data, ) useEffect(() => { if (mangoAccountAddress) { const actions = mangoStore.getState().actions actions.fetchAccountInterestTotals(mangoAccountAddress) } }, [mangoAccountAddress]) const { data: fundingData, isLoading: loadingFunding, isFetching: fetchingFunding, } = useQuery( ['funding', mangoAccountAddress], () => fetchFundingTotals(mangoAccountAddress), { cacheTime: 1000 * 60 * 10, staleTime: 1000 * 60, retry: 3, refetchOnWindowFocus: false, enabled: !!mangoAccountAddress, }, ) const { data: volumeTotalData, isLoading: loadingVolumeTotalData, isFetching: fetchingVolumeTotalData, } = useQuery( ['total-volume', mangoAccountAddress], () => fetchVolumeTotals(mangoAccountAddress), { cacheTime: 1000 * 60 * 10, staleTime: 1000 * 60, retry: 3, refetchOnWindowFocus: false, enabled: !!mangoAccountAddress, }, ) const maintHealth = useMemo(() => { return group && mangoAccount ? mangoAccount.getHealthRatioUi(group, HealthType.maint) : 0 }, [mangoAccount, group]) const leverage = useMemo(() => { if (!group || !mangoAccount) return 0 const assetsValue = toUiDecimalsForQuote( mangoAccount.getAssetsValue(group).toNumber(), ) if (isNaN(assetsValue / accountValue)) { return 0 } else { return Math.abs(1 - assetsValue / accountValue) } }, [mangoAccount, group, accountValue]) const rollingDailyPnlChange = useMemo(() => { if (!accountPnl || !rollingDailyData.length) return 0 return accountPnl - rollingDailyData[0].pnl }, [accountPnl, rollingDailyData]) const interestTotalValue = useMemo(() => { if (totalInterestData.length) { return totalInterestData.reduce( (a, c) => a + (c.borrow_interest_usd * -1 + c.deposit_interest_usd), 0, ) } return 0.0 }, [totalInterestData]) const fundingTotalValue = useMemo(() => { if (fundingData?.length && mangoAccountAddress) { return fundingData.reduce( (a, c) => a + c.long_funding + c.short_funding, 0, ) } return 0.0 }, [fundingData, mangoAccountAddress]) const oneDayInterestChange = useMemo(() => { if (rollingDailyData.length) { const first = rollingDailyData[0] const latest = rollingDailyData[rollingDailyData.length - 1] const startDayInterest = first.borrow_interest_cumulative_usd + first.deposit_interest_cumulative_usd const endDayInterest = latest.borrow_interest_cumulative_usd + latest.deposit_interest_cumulative_usd return endDayInterest - startDayInterest } return 0.0 }, [rollingDailyData]) const dailyVolume = useMemo(() => { if (!hourlyVolumeData || !hourlyVolumeData.length) return 0 // Calculate the current time in milliseconds const currentTime = new Date().getTime() // Calculate the start time for the last 24 hours in milliseconds const last24HoursStartTime = currentTime - 24 * 60 * 60 * 1000 // Filter the formatted data based on the timestamp const last24HoursData = hourlyVolumeData.filter((entry) => { const timestampMs = new Date(entry.time).getTime() return timestampMs >= last24HoursStartTime && timestampMs <= currentTime }) const volume = last24HoursData.reduce((a, c) => a + c.total_volume_usd, 0) return volume }, [hourlyVolumeData]) const loadingTotalVolume = fetchingVolumeTotalData || loadingVolumeTotalData return ( <>

Health describes how close your account is to liquidation. The lower your account health is the more likely you are to get liquidated when prices fluctuate.

{maintHealth < 100 && mangoAccountAddress ? ( <>

Your account health is {maintHealth}%

Scenario: {' '} If the prices of all your liabilities increase by{' '} {maintHealth}%, even for just a moment, some of your liabilities will be liquidated.

Scenario: {' '} If the value of your total collateral decreases by{' '} {( (1 - 1 / ((maintHealth || 0) / 100 + 1)) * 100 ).toFixed(2)} % , some of your liabilities will be liquidated.

These are examples. A combination of events can also lead to liquidation.

) : null}
} >

{t('health')}

{mangoAccountAddress ? ( handleViewChange('health-contributions')} > ) : null}

{maintHealth}%

{t('leverage')}: x

{t('free-collateral')}

{t('total')}:

{t('pnl')}

{mangoAccountAddress ? (
handleViewChange('pnl')} > setShowPnlHistory(true)} >
) : null}

{t('rolling-change')}

{t('account:lifetime-volume')}

{mangoAccountAddress ? ( handleViewChange('hourly-volume')} > ) : null}
{loadingTotalVolume && mangoAccountAddress ? (
) : (

)} {t('account:daily-volume')}: {loadingHourlyVolume && mangoAccountAddress ? (
) : ( )}

{t('total-interest-earned')}

{mangoAccountAddress ? ( handleViewChange('cumulative-interest-value') } > ) : null}

{t('rolling-change')}

{t('account:total-funding-earned')}

{mangoAccountAddress ? ( handleViewChange('hourly-funding')} > ) : null}
{(loadingFunding || fetchingFunding) && mangoAccountAddress ? (
) : (

)}
) } export default AccountHeroStats