mango-v4-ui/components/stats/PerpMarketDetails.tsx

172 lines
6.1 KiB
TypeScript
Raw Normal View History

2022-12-30 03:40:52 -08:00
import { IconButton } from '@components/shared/Button'
import { ChevronLeftIcon } from '@heroicons/react/20/solid'
import mangoStore from '@store/mangoStore'
2023-02-10 04:55:06 -08:00
import dayjs from 'dayjs'
2022-12-30 03:40:52 -08:00
import { useTranslation } from 'next-i18next'
import dynamic from 'next/dynamic'
2023-02-10 04:55:06 -08:00
import { useMemo, useState } from 'react'
2023-01-24 16:54:24 -08:00
import { formatYAxis } from 'utils/formatting'
import { formatNumericValue } from 'utils/numbers'
2023-02-10 04:55:06 -08:00
import { usePerpFundingRate } from '@components/trade/PerpFundingRate'
2023-03-07 09:48:25 -08:00
import { PerpStatsItem } from 'types'
2023-03-07 15:12:40 -08:00
import { PerpMarket } from '@blockworks-foundation/mango-v4'
2022-12-30 03:40:52 -08:00
const DetailedAreaChart = dynamic(
() => import('@components/shared/DetailedAreaChart'),
{ ssr: false }
)
const PerpMarketDetails = ({
2023-03-07 15:12:40 -08:00
perpMarket,
2022-12-30 03:40:52 -08:00
setShowPerpDetails,
}: {
2023-03-07 15:12:40 -08:00
perpMarket: PerpMarket
setShowPerpDetails: (x: PerpMarket | null) => void
2022-12-30 03:40:52 -08:00
}) => {
const { t } = useTranslation(['common', 'trade'])
const perpStats = mangoStore((s) => s.perpStats.data)
const loadingPerpStats = mangoStore((s) => s.perpStats.loading)
2023-02-10 04:55:06 -08:00
const [priceDaysToShow, setPriceDaysToShow] = useState('30')
const [oiDaysToShow, setOiDaysToShow] = useState('30')
const [hourlyFundingeDaysToShow, setHourlyFundingDaysToShow] = useState('30')
2023-03-29 09:28:52 -07:00
const [instantFundingDaysToShow, setInstantFundingDaysToShow] = useState('30')
2023-02-10 04:55:06 -08:00
const rate = usePerpFundingRate()
2022-12-30 03:40:52 -08:00
2023-02-10 04:55:06 -08:00
const [marketStats, lastStat] = useMemo(() => {
2023-03-07 09:48:25 -08:00
if (!perpStats) return [undefined, undefined]
2023-02-10 04:55:06 -08:00
const stats = perpStats
2023-03-07 15:12:40 -08:00
.filter((stat) => stat.perp_market === perpMarket.name)
2023-02-10 04:55:06 -08:00
.reverse()
return [stats, stats[stats.length - 1]]
2023-03-07 15:12:40 -08:00
}, [perpStats, perpMarket])
2022-12-30 03:40:52 -08:00
2023-02-10 04:55:06 -08:00
const fundingRate = useMemo(() => {
if (!lastStat) return 0
if (rate?.isSuccess) {
const marketRate = rate?.data?.find(
(r) => r.market_index === perpMarket?.perpMarketIndex
)
return marketRate?.funding_rate_hourly
}
return lastStat.instantaneous_funding_rate
}, [rate, lastStat])
2023-03-07 09:48:25 -08:00
const perpHourlyStats = useMemo(() => {
const latestStat = { ...lastStat } as PerpStatsItem
latestStat.instantaneous_funding_rate = fundingRate ? fundingRate : 0
latestStat.date_hour = dayjs().toISOString()
if (marketStats) {
const perpHourly = marketStats.concat([latestStat])
return perpHourly.map((stat) => ({
...stat,
funding_rate_hourly: stat.funding_rate_hourly * 100,
}))
}
}, [marketStats, fundingRate])
2023-03-29 09:28:52 -07:00
const instantFundingRateStats = useMemo(() => {
if (marketStats) {
return marketStats.map((stat) => ({
...stat,
instantaneous_funding_rate: stat.instantaneous_funding_rate * 100,
}))
}
return []
}, [marketStats])
2022-12-30 03:40:52 -08:00
return (
<div className="grid grid-cols-2">
<div className="col-span-2 flex items-center border-b border-th-bkg-3 px-6 py-3">
<IconButton
className="mr-4"
2023-03-07 15:12:40 -08:00
onClick={() => setShowPerpDetails(null)}
size="small"
>
2022-12-30 03:40:52 -08:00
<ChevronLeftIcon className="h-5 w-5" />
</IconButton>
2023-03-07 15:12:40 -08:00
<h2 className="text-lg">{`${perpMarket.name} ${t('stats')}`}</h2>
2022-12-30 03:40:52 -08:00
</div>
2023-03-07 09:48:25 -08:00
{marketStats?.length && lastStat ? (
2022-12-30 03:40:52 -08:00
<>
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1">
<DetailedAreaChart
2023-02-10 04:55:06 -08:00
data={marketStats.concat([
{
...lastStat,
date_hour: dayjs().toISOString(),
price: perpMarket?._uiPrice || lastStat.price,
},
])}
daysToShow={priceDaysToShow}
setDaysToShow={setPriceDaysToShow}
2022-12-30 03:40:52 -08:00
heightClass="h-64"
2023-02-10 04:55:06 -08:00
loading={loadingPerpStats}
loaderHeightClass="h-[350px]"
2022-12-30 03:40:52 -08:00
prefix="$"
2023-01-24 16:54:24 -08:00
tickFormat={(x) => formatYAxis(x)}
2022-12-30 03:40:52 -08:00
title={t('price')}
xKey="date_hour"
yKey={'price'}
/>
</div>
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-l md:pl-6">
<DetailedAreaChart
2023-02-10 04:55:06 -08:00
data={marketStats.concat([
{
...lastStat,
date_hour: dayjs().toISOString(),
open_interest:
perpMarket?.baseLotsToUi(perpMarket.openInterest) ||
lastStat.open_interest,
},
])}
daysToShow={oiDaysToShow}
setDaysToShow={setOiDaysToShow}
2022-12-30 03:40:52 -08:00
heightClass="h-64"
2023-02-10 04:55:06 -08:00
loading={loadingPerpStats}
loaderHeightClass="h-[350px]"
tickFormat={(x) => formatYAxis(x)}
2022-12-30 03:40:52 -08:00
title={t('trade:open-interest')}
xKey="date_hour"
yKey={'open_interest'}
/>
</div>
2023-03-29 09:28:52 -07:00
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1">
2022-12-30 03:40:52 -08:00
<DetailedAreaChart
2023-03-07 09:48:25 -08:00
data={perpHourlyStats ? perpHourlyStats : []}
2023-02-10 04:55:06 -08:00
daysToShow={hourlyFundingeDaysToShow}
setDaysToShow={setHourlyFundingDaysToShow}
2022-12-30 03:40:52 -08:00
heightClass="h-64"
2023-02-10 04:55:06 -08:00
loading={loadingPerpStats}
loaderHeightClass="h-[350px]"
2022-12-30 03:40:52 -08:00
suffix="%"
2023-02-01 19:41:32 -08:00
tickFormat={(x) => formatNumericValue(x, 4)}
title={t('trade:hourly-funding')}
2022-12-30 03:40:52 -08:00
xKey="date_hour"
yKey={'funding_rate_hourly'}
2023-02-10 04:55:06 -08:00
yDecimals={5}
2022-12-30 03:40:52 -08:00
/>
</div>
2023-03-29 09:28:52 -07:00
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-l md:pl-6">
<DetailedAreaChart
data={instantFundingRateStats}
daysToShow={instantFundingDaysToShow}
setDaysToShow={setInstantFundingDaysToShow}
heightClass="h-64"
loading={loadingPerpStats}
loaderHeightClass="h-[350px]"
suffix="%"
tickFormat={(x) => formatNumericValue(x, 4)}
title={t('trade:instantaneous-funding')}
xKey="date_hour"
yKey={'instantaneous_funding_rate'}
yDecimals={5}
/>
</div>
2022-12-30 03:40:52 -08:00
</>
) : null}
</div>
)
2022-12-20 00:16:05 -08:00
}
export default PerpMarketDetails