add volume to perp stats table

This commit is contained in:
saml33 2023-06-01 11:50:00 +10:00
parent aaa4c04adc
commit a8e590514b
2 changed files with 176 additions and 97 deletions

View File

@ -13,14 +13,16 @@ import {
formatFunding,
usePerpFundingRate,
} from '@components/trade/PerpFundingRate'
import { ChevronRightIcon } from '@heroicons/react/20/solid'
import { ChevronDownIcon, ChevronRightIcon } from '@heroicons/react/20/solid'
import FormatNumericValue from '@components/shared/FormatNumericValue'
import { getDecimalCount } from 'utils/numbers'
import { getDecimalCount, numberCompacter } from 'utils/numbers'
import Tooltip from '@components/shared/Tooltip'
import { PerpStatsItem } from 'types'
import useMangoGroup from 'hooks/useMangoGroup'
import { NextRouter, useRouter } from 'next/router'
import SimpleAreaChart from '@components/shared/SimpleAreaChart'
import { Disclosure, Transition } from '@headlessui/react'
import { LinkButton } from '@components/shared/Button'
export const getOneDayPerpStats = (
stats: PerpStatsItem[] | null,
@ -76,9 +78,10 @@ const PerpMarketsOverviewTable = () => {
</span>
</Tooltip>
</Th>
<Th className="text-right">{t('rolling-change')}</Th>
<Th className="text-right">{t('trade:24h-volume')}</Th>
<Th className="text-right">{t('trade:funding-rate')}</Th>
<Th className="text-right">{t('trade:open-interest')}</Th>
<Th className="text-right">{t('rolling-change')}</Th>
<Th />
</TrHead>
</thead>
@ -93,6 +96,10 @@ const PerpMarketsOverviewTable = () => {
100
: 0
const volume = marketStats.length
? marketStats.reduce((a, c) => a + c.quote_volume, 0)
: 0
let fundingRate
let fundingRateApr
if (rate.isSuccess) {
@ -186,6 +193,18 @@ const PerpMarketsOverviewTable = () => {
</p>
</div>
</Td>
<Td>
<div className="flex flex-col items-end">
<Change change={change} suffix="%" />
</div>
</Td>
<Td>
<div className="flex flex-col text-right">
<p>
{volume ? `$${numberCompacter.format(volume)}` : '-'}
</p>
</div>
</Td>
<Td>
<div className="flex items-center justify-end">
<Tooltip
@ -224,18 +243,10 @@ const PerpMarketsOverviewTable = () => {
/>
</p>
<p className="text-th-fgd-4">
<FormatNumericValue
value={openInterest * market.uiPrice}
isUsd
/>
${numberCompacter.format(openInterest * market.uiPrice)}
</p>
</div>
</Td>
<Td>
<div className="flex flex-col items-end">
<Change change={change} suffix="%" />
</div>
</Td>
<Td>
<div className="flex justify-end">
<ChevronRightIcon className="h-5 w-5 text-th-fgd-3" />
@ -247,7 +258,7 @@ const PerpMarketsOverviewTable = () => {
</tbody>
</Table>
) : (
<div>
<div className="border-b border-th-bkg-3">
{perpMarkets.map((market) => {
return (
<MobilePerpMarketItem
@ -270,7 +281,7 @@ const MobilePerpMarketItem = ({ market }: { market: PerpMarket }) => {
const perpStats = mangoStore((s) => s.perpStats.data)
const { theme } = useTheme()
const router = useRouter()
// const rate = usePerpFundingRate()
const rate = usePerpFundingRate()
const symbol = market.name.split('-')[0]
@ -280,59 +291,160 @@ const MobilePerpMarketItem = ({ market }: { market: PerpMarket }) => {
? ((market.uiPrice - marketStats[0].price) / marketStats[0].price) * 100
: 0
// let fundingRate
// if (
// rate.isSuccess
// // && bids instanceof BookSide &&
// // asks instanceof BookSide
// ) {
// const marketRate = rate.data.find(
// (r) => r.market_index === market.perpMarketIndex
// )
// fundingRate = `${marketRate?.funding_apr.toFixed(2)}%`
// } else {
// fundingRate = ''
// }
const volume = marketStats.length
? marketStats.reduce((a, c) => a + c.quote_volume, 0)
: 0
const openInterest = market.baseLotsToUi(market.openInterest)
let fundingRate: string
let fundingRateApr: string
if (rate.isSuccess) {
const marketRate = rate?.data?.find(
(r) => r.market_index === market.perpMarketIndex
)
if (marketRate) {
fundingRate = formatFunding.format(marketRate.funding_rate_hourly)
fundingRateApr = formatFunding.format(
marketRate.funding_rate_hourly * 8760
)
} else {
fundingRate = ''
fundingRateApr = ''
}
} else {
fundingRate = ''
fundingRateApr = ''
}
return (
<button
className="w-full border-b border-th-bkg-3 p-4 focus:outline-none"
onClick={() => goToPerpMarketDetails(market, router)}
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<MarketLogos market={market} />
<div>
<p className="text-left text-th-fgd-1">{market.name}</p>
<div className="flex items-center space-x-3">
<p className="font-mono">
<FormatNumericValue value={market.uiPrice} isUsd />
</p>
<Change change={change} suffix="%" />
</div>
</div>
</div>
<div className="flex items-center space-x-3">
{!loadingPerpStats ? (
marketStats.length ? (
<div className="ml-4 h-10 w-24">
<SimpleAreaChart
color={change >= 0 ? COLORS.UP[theme] : COLORS.DOWN[theme]}
data={marketStats}
name={market.name}
xKey="date_hour"
yKey="price"
<Disclosure>
{({ open }) => (
<>
<Disclosure.Button
className={`w-full border-t border-th-bkg-3 p-4 text-left first:border-t-0 focus:outline-none`}
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<div className="flex flex-shrink-0 items-center">
<MarketLogos market={market} />
</div>
<p className="leading-none text-th-fgd-1">{market.name}</p>
</div>
<div className="flex items-center space-x-3">
{!loadingPerpStats ? (
marketStats.length ? (
<div className="ml-4 h-10 w-20">
<SimpleAreaChart
color={
change >= 0 ? COLORS.UP[theme] : COLORS.DOWN[theme]
}
data={marketStats}
name={market.name}
xKey="date_hour"
yKey="price"
/>
</div>
) : symbol === 'USDC' || symbol === 'USDT' ? null : (
<p className="mb-0 text-th-fgd-4">{t('unavailable')}</p>
)
) : (
<div className="h-10 w-[104px] animate-pulse rounded bg-th-bkg-3" />
)}
<Change change={change} suffix="%" />
<ChevronDownIcon
className={`${
open ? 'rotate-180' : 'rotate-360'
} h-6 w-6 flex-shrink-0 text-th-fgd-3`}
/>
</div>
) : symbol === 'USDC' || symbol === 'USDT' ? null : (
<p className="mb-0 text-th-fgd-4">{t('unavailable')}</p>
)
) : (
<div className="h-10 w-[104px] animate-pulse rounded bg-th-bkg-3" />
)}
<ChevronRightIcon className="h-5 w-5" />
</div>
</div>
</button>
</div>
</Disclosure.Button>
<Transition
enter="transition ease-in duration-200"
enterFrom="opacity-0"
enterTo="opacity-100"
>
<Disclosure.Panel>
<div className="mx-4 grid grid-cols-2 gap-4 border-t border-th-bkg-3 pt-4 pb-4">
<div className="col-span-1">
<p className="text-xs text-th-fgd-3">{t('price')}</p>
<p className="font-mono text-th-fgd-2">
<FormatNumericValue value={market.uiPrice} isUsd />
</p>
</div>
<div className="col-span-1">
<p className="text-xs text-th-fgd-3">
{t('trade:24h-volume')}
</p>
<p className="font-mono text-th-fgd-2">
{volume ? (
<span>{numberCompacter.format(volume)}</span>
) : (
''
)}
</p>
</div>
<div className="col-span-1">
<p className="text-xs text-th-fgd-3">
{t('trade:funding-rate')}
</p>
<p className="font-mono">
<Tooltip
content={
<>
{fundingRateApr ? (
<div className="">
The 1hr rate as an APR is{' '}
<span className="font-mono text-th-fgd-2">
{fundingRateApr}
</span>
</div>
) : null}
<div className="mt-2">
Funding is paid continuously. The 1hr rate displayed
is a rolling average of the past 60 mins.
</div>
<div className="mt-2">
When positive, longs will pay shorts and when
negative shorts pay longs.
</div>
</>
}
>
<span className="tooltip-underline text-th-fgd-2">
{fundingRate}
</span>
</Tooltip>
</p>
</div>
<div className="col-span-1">
<p className="text-xs text-th-fgd-3">
{t('trade:open-interest')}
</p>
<p className="font-mono text-th-fgd-2">
<FormatNumericValue
value={openInterest}
decimals={getDecimalCount(market.minOrderSize)}
/>
<span className="mx-1 text-th-fgd-4">|</span>$
{numberCompacter.format(openInterest * market.uiPrice)}
</p>
</div>
<div className="col-span-1">
<LinkButton
className="flex items-center"
onClick={() => goToPerpMarketDetails(market, router)}
>
{t('token:token-stats', { token: market.name })}
<ChevronRightIcon className="ml-2 h-5 w-5" />
</LinkButton>
</div>
</div>
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
)
}

View File

@ -328,38 +328,5 @@ const MobileSpotMarketItem = ({
</>
)}
</Disclosure>
// <div className="border-b border-th-bkg-3 px-6 py-4">
// <div className="flex items-center justify-between">
// <div className="flex items-center">
// <MarketLogos market={market} />
// <div>
// <p className="text-th-fgd-1">{market.name}</p>
// <div className="flex items-center space-x-3">
// <p className="font-mono">
// {price ? <FormatNumericValue value={price} isUsd /> : '-'}
// </p>
// {change ? <Change change={change} suffix="%" /> : ''}
// </div>
// </div>
// </div>
// {!loadingPrices ? (
// chartData !== undefined ? (
// <div className="h-10 w-24">
// <SimpleAreaChart
// color={change >= 0 ? COLORS.UP[theme] : COLORS.DOWN[theme]}
// data={chartData}
// name={baseBank!.name}
// xKey="unixTime"
// yKey="value"
// />
// </div>
// ) : (
// <p className="mb-0 text-th-fgd-4">{t('unavailable')}</p>
// )
// ) : (
// <div className="h-10 w-[104px] animate-pulse rounded bg-th-bkg-3" />
// )}
// </div>
// </div>
)
}