Merge pull request #207 from blockworks-foundation/perp-volume-stats
add total perp volume to mango stats
This commit is contained in:
commit
fa83167f58
|
@ -3,6 +3,7 @@ import { useMemo, useState } from 'react'
|
||||||
import mangoStore from '@store/mangoStore'
|
import mangoStore from '@store/mangoStore'
|
||||||
import { PerpStatsItem } from 'types'
|
import { PerpStatsItem } from 'types'
|
||||||
import DetailedAreaOrBarChart from '@components/shared/DetailedAreaOrBarChart'
|
import DetailedAreaOrBarChart from '@components/shared/DetailedAreaOrBarChart'
|
||||||
|
import { formatYAxis } from 'utils/formatting'
|
||||||
|
|
||||||
interface OiValueItem {
|
interface OiValueItem {
|
||||||
date: string
|
date: string
|
||||||
|
@ -14,97 +15,143 @@ interface FeeValueItem {
|
||||||
feeValue: number
|
feeValue: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface VolumeValueItem {
|
||||||
|
date: string
|
||||||
|
volume: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PerpStatsData {
|
||||||
|
feeValues: FeeValueItem[]
|
||||||
|
openInterestValues: OiValueItem[]
|
||||||
|
volumeValues: VolumeValueItem[]
|
||||||
|
}
|
||||||
|
|
||||||
const MangoPerpStatsCharts = () => {
|
const MangoPerpStatsCharts = () => {
|
||||||
const { t } = useTranslation(['common', 'token', 'trade'])
|
const { t } = useTranslation(['common', 'token', 'trade'])
|
||||||
const loadingPerpStats = mangoStore((s) => s.perpStats.loading)
|
const loadingPerpStats = mangoStore((s) => s.perpStats.loading)
|
||||||
const perpStats = mangoStore((s) => s.perpStats.data)
|
const perpStats = mangoStore((s) => s.perpStats.data)
|
||||||
const [oiDaysToShow, setOiDaysToShow] = useState('30')
|
|
||||||
const [feesDaysToShow, setFeesDaysToShow] = useState('30')
|
const [feesDaysToShow, setFeesDaysToShow] = useState('30')
|
||||||
// const perpMarkets = mangoStore((s) => s.perpMarkets)
|
const [oiDaysToShow, setOiDaysToShow] = useState('30')
|
||||||
|
const [volumeDaysToShow, setVolumeDaysToShow] = useState('30')
|
||||||
|
|
||||||
// const currentTotalOpenInterestValue = useMemo(() => {
|
const [feeValues, openInterestValues, volumeValues] = useMemo(() => {
|
||||||
// if (!perpMarkets.length) return 0
|
if (!perpStats || !perpStats.length) return [[], [], []]
|
||||||
// return perpMarkets.reduce((a: number, c: PerpMarket) => {
|
const data = perpStats.reduce(
|
||||||
// const value = a + c.openInterest.toNumber() * c.uiPrice
|
(a: PerpStatsData, c: PerpStatsItem) => {
|
||||||
// return value
|
const hasDateFee = a.feeValues.find(
|
||||||
// }, 0)
|
(d: FeeValueItem) => d.date === c.date_hour
|
||||||
// }, [perpMarkets])
|
)
|
||||||
|
|
||||||
const totalFeeValues = useMemo(() => {
|
const hasDateOpenInterest = a.openInterestValues.find(
|
||||||
if (!perpStats || !perpStats.length) return []
|
(d: OiValueItem) => d.date === c.date_hour
|
||||||
const values = perpStats.reduce((a: FeeValueItem[], c: PerpStatsItem) => {
|
)
|
||||||
const hasDate = a.find((d: FeeValueItem) => d.date === c.date_hour)
|
|
||||||
if (!hasDate) {
|
|
||||||
a.push({
|
|
||||||
date: c.date_hour,
|
|
||||||
feeValue: c.total_fees,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
hasDate.feeValue = hasDate.feeValue + c.total_fees
|
|
||||||
}
|
|
||||||
return a.sort(
|
|
||||||
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
|
|
||||||
)
|
|
||||||
}, [])
|
|
||||||
return values
|
|
||||||
}, [perpStats])
|
|
||||||
|
|
||||||
const totalOpenInterestValues = useMemo(() => {
|
const hasDateVolume = a.volumeValues.find(
|
||||||
if (!perpStats || !perpStats.length) return []
|
(d: VolumeValueItem) => d.date === c.date_hour
|
||||||
const values = perpStats.reduce((a: OiValueItem[], c: PerpStatsItem) => {
|
)
|
||||||
const hasDate = a.find((d: OiValueItem) => d.date === c.date_hour)
|
|
||||||
if (!hasDate) {
|
if (!hasDateFee) {
|
||||||
a.push({
|
a.feeValues.push({
|
||||||
date: c.date_hour,
|
date: c.date_hour,
|
||||||
openInterest: Math.floor(c.open_interest * c.price),
|
feeValue: c.total_fees,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
hasDate.openInterest =
|
hasDateFee.feeValue += c.total_fees
|
||||||
hasDate.openInterest + Math.floor(c.open_interest * c.price)
|
}
|
||||||
}
|
|
||||||
return a.sort(
|
if (!hasDateOpenInterest) {
|
||||||
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
|
a.openInterestValues.push({
|
||||||
)
|
date: c.date_hour,
|
||||||
}, [])
|
openInterest: Math.floor(c.open_interest * c.price),
|
||||||
return values
|
})
|
||||||
|
} else {
|
||||||
|
hasDateOpenInterest.openInterest += Math.floor(
|
||||||
|
c.open_interest * c.price
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasDateVolume) {
|
||||||
|
a.volumeValues.push({
|
||||||
|
date: c.date_hour,
|
||||||
|
volume: c.cumulative_quote_volume,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
hasDateVolume.volume += c.cumulative_quote_volume
|
||||||
|
}
|
||||||
|
|
||||||
|
return a
|
||||||
|
},
|
||||||
|
{ feeValues: [], openInterestValues: [], volumeValues: [] }
|
||||||
|
)
|
||||||
|
|
||||||
|
const { feeValues, openInterestValues, volumeValues } = data
|
||||||
|
|
||||||
|
const sortedFeeValues = feeValues.sort(
|
||||||
|
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
|
||||||
|
)
|
||||||
|
const sortedOpenInterestValues = openInterestValues.sort(
|
||||||
|
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
|
||||||
|
)
|
||||||
|
const sortedVolumeValues = volumeValues.sort(
|
||||||
|
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
|
||||||
|
)
|
||||||
|
|
||||||
|
return [sortedFeeValues, sortedOpenInterestValues, sortedVolumeValues]
|
||||||
}, [perpStats])
|
}, [perpStats])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{totalFeeValues.length ? (
|
{feeValues.length ? (
|
||||||
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:pl-6">
|
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:pl-6">
|
||||||
<DetailedAreaOrBarChart
|
<DetailedAreaOrBarChart
|
||||||
data={totalFeeValues}
|
data={feeValues}
|
||||||
daysToShow={feesDaysToShow}
|
daysToShow={feesDaysToShow}
|
||||||
setDaysToShow={setFeesDaysToShow}
|
setDaysToShow={setFeesDaysToShow}
|
||||||
heightClass="h-64"
|
heightClass="h-64"
|
||||||
loading={loadingPerpStats}
|
loading={loadingPerpStats}
|
||||||
loaderHeightClass="h-[350px]"
|
loaderHeightClass="h-[350px]"
|
||||||
prefix="$"
|
prefix="$"
|
||||||
tickFormat={(x) => `$${x.toFixed(2)}`}
|
tickFormat={(x) => `$${formatYAxis(x)}`}
|
||||||
title="Perp Fees"
|
title="Perp Fees"
|
||||||
xKey="date"
|
xKey="date"
|
||||||
yKey={'feeValue'}
|
yKey={'feeValue'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
{totalOpenInterestValues.length ? (
|
{openInterestValues.length ? (
|
||||||
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-r">
|
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:border-r">
|
||||||
<DetailedAreaOrBarChart
|
<DetailedAreaOrBarChart
|
||||||
data={totalOpenInterestValues}
|
data={openInterestValues}
|
||||||
daysToShow={oiDaysToShow}
|
daysToShow={oiDaysToShow}
|
||||||
setDaysToShow={setOiDaysToShow}
|
setDaysToShow={setOiDaysToShow}
|
||||||
heightClass="h-64"
|
heightClass="h-64"
|
||||||
loading={loadingPerpStats}
|
loading={loadingPerpStats}
|
||||||
loaderHeightClass="h-[350px]"
|
loaderHeightClass="h-[350px]"
|
||||||
prefix="$"
|
prefix="$"
|
||||||
tickFormat={(x) => `$${Math.floor(x)}`}
|
tickFormat={(x) => `$${formatYAxis(x)}`}
|
||||||
title={t('trade:open-interest')}
|
title={t('trade:open-interest')}
|
||||||
xKey="date"
|
xKey="date"
|
||||||
yKey={'openInterest'}
|
yKey={'openInterest'}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
{volumeValues.length ? (
|
||||||
|
<div className="col-span-2 border-b border-th-bkg-3 py-4 px-6 md:col-span-1 md:pl-6">
|
||||||
|
<DetailedAreaOrBarChart
|
||||||
|
data={volumeValues}
|
||||||
|
daysToShow={volumeDaysToShow}
|
||||||
|
setDaysToShow={setVolumeDaysToShow}
|
||||||
|
heightClass="h-64"
|
||||||
|
loading={loadingPerpStats}
|
||||||
|
loaderHeightClass="h-[350px]"
|
||||||
|
prefix="$"
|
||||||
|
tickFormat={(x) => `$${formatYAxis(x)}`}
|
||||||
|
title={t('stats:perp-volume')}
|
||||||
|
xKey="date"
|
||||||
|
yKey={'volume'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"hourly": "Hourly",
|
"hourly": "Hourly",
|
||||||
"largest-perp-positions": "Largest Positions",
|
"largest-perp-positions": "Largest Positions",
|
||||||
"perp-details": "{{market}} Stats",
|
"perp-details": "{{market}} Stats",
|
||||||
|
"perp-volume": "Perp Volume",
|
||||||
"pnl-liquidation-fee": "Positive PnL Liquidation Fee",
|
"pnl-liquidation-fee": "Positive PnL Liquidation Fee",
|
||||||
"settle-pnl-factor": "Settle PnL Factor",
|
"settle-pnl-factor": "Settle PnL Factor",
|
||||||
"six-hourly": "6-Hourly",
|
"six-hourly": "6-Hourly",
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"hourly": "Hourly",
|
"hourly": "Hourly",
|
||||||
"largest-perp-positions": "Largest Positions",
|
"largest-perp-positions": "Largest Positions",
|
||||||
"perp-details": "{{market}} Stats",
|
"perp-details": "{{market}} Stats",
|
||||||
|
"perp-volume": "Perp Volume",
|
||||||
"pnl-liquidation-fee": "Positive PnL Liquidation Fee",
|
"pnl-liquidation-fee": "Positive PnL Liquidation Fee",
|
||||||
"settle-pnl-factor": "Settle PnL Factor",
|
"settle-pnl-factor": "Settle PnL Factor",
|
||||||
"six-hourly": "6-Hourly",
|
"six-hourly": "6-Hourly",
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"hourly": "Hourly",
|
"hourly": "Hourly",
|
||||||
"largest-perp-positions": "Largest Positions",
|
"largest-perp-positions": "Largest Positions",
|
||||||
"perp-details": "{{market}} Stats",
|
"perp-details": "{{market}} Stats",
|
||||||
|
"perp-volume": "Perp Volume",
|
||||||
"pnl-liquidation-fee": "Positive PnL Liquidation Fee",
|
"pnl-liquidation-fee": "Positive PnL Liquidation Fee",
|
||||||
"settle-pnl-factor": "Settle PnL Factor",
|
"settle-pnl-factor": "Settle PnL Factor",
|
||||||
"six-hourly": "6-Hourly",
|
"six-hourly": "6-Hourly",
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"hourly": "Hourly",
|
"hourly": "Hourly",
|
||||||
"largest-perp-positions": "Largest Positions",
|
"largest-perp-positions": "Largest Positions",
|
||||||
"perp-details": "{{market}}统计",
|
"perp-details": "{{market}}统计",
|
||||||
|
"perp-volume": "Perp Volume",
|
||||||
"pnl-liquidation-fee": "Positive PnL Liquidation Fee",
|
"pnl-liquidation-fee": "Positive PnL Liquidation Fee",
|
||||||
"settle-pnl-factor": "Settle PnL Factor",
|
"settle-pnl-factor": "Settle PnL Factor",
|
||||||
"six-hourly": "6-Hourly",
|
"six-hourly": "6-Hourly",
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
"hourly": "小時",
|
"hourly": "小時",
|
||||||
"largest-perp-positions": "Largest Positions",
|
"largest-perp-positions": "Largest Positions",
|
||||||
"perp-details": "{{market}}統計",
|
"perp-details": "{{market}}統計",
|
||||||
|
"perp-volume": "Perp Volume",
|
||||||
"pnl-liquidation-fee": "正數盈虧清算費用",
|
"pnl-liquidation-fee": "正數盈虧清算費用",
|
||||||
"settle-pnl-factor": "結清盈虧因素",
|
"settle-pnl-factor": "結清盈虧因素",
|
||||||
"six-hourly": "6-小時",
|
"six-hourly": "6-小時",
|
||||||
|
|
Loading…
Reference in New Issue