From 27f03bfd668cdeb6addecafd1860b6fab5760695 Mon Sep 17 00:00:00 2001 From: saml33 Date: Wed, 19 Jul 2023 10:48:49 +1000 Subject: [PATCH] add total perp volume to mango stats --- components/stats/MangoPerpStatsCharts.tsx | 149 ++++++++++++++-------- public/locales/en/stats.json | 1 + public/locales/es/stats.json | 1 + public/locales/ru/stats.json | 1 + public/locales/zh/stats.json | 1 + public/locales/zh_tw/stats.json | 1 + 6 files changed, 103 insertions(+), 51 deletions(-) diff --git a/components/stats/MangoPerpStatsCharts.tsx b/components/stats/MangoPerpStatsCharts.tsx index ed1ec166..16ff94eb 100644 --- a/components/stats/MangoPerpStatsCharts.tsx +++ b/components/stats/MangoPerpStatsCharts.tsx @@ -3,6 +3,7 @@ import { useMemo, useState } from 'react' import mangoStore from '@store/mangoStore' import { PerpStatsItem } from 'types' import DetailedAreaOrBarChart from '@components/shared/DetailedAreaOrBarChart' +import { formatYAxis } from 'utils/formatting' interface OiValueItem { date: string @@ -14,97 +15,143 @@ interface FeeValueItem { feeValue: number } +interface VolumeValueItem { + date: string + volume: number +} + +interface PerpStatsData { + feeValues: FeeValueItem[] + openInterestValues: OiValueItem[] + volumeValues: VolumeValueItem[] +} + const MangoPerpStatsCharts = () => { const { t } = useTranslation(['common', 'token', 'trade']) const loadingPerpStats = mangoStore((s) => s.perpStats.loading) const perpStats = mangoStore((s) => s.perpStats.data) - const [oiDaysToShow, setOiDaysToShow] = 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(() => { - // if (!perpMarkets.length) return 0 - // return perpMarkets.reduce((a: number, c: PerpMarket) => { - // const value = a + c.openInterest.toNumber() * c.uiPrice - // return value - // }, 0) - // }, [perpMarkets]) + const [feeValues, openInterestValues, volumeValues] = useMemo(() => { + if (!perpStats || !perpStats.length) return [[], [], []] + const data = perpStats.reduce( + (a: PerpStatsData, c: PerpStatsItem) => { + const hasDateFee = a.feeValues.find( + (d: FeeValueItem) => d.date === c.date_hour + ) - const totalFeeValues = useMemo(() => { - if (!perpStats || !perpStats.length) return [] - 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 hasDateOpenInterest = a.openInterestValues.find( + (d: OiValueItem) => d.date === c.date_hour + ) - const totalOpenInterestValues = useMemo(() => { - if (!perpStats || !perpStats.length) return [] - const values = perpStats.reduce((a: OiValueItem[], c: PerpStatsItem) => { - const hasDate = a.find((d: OiValueItem) => d.date === c.date_hour) - if (!hasDate) { - a.push({ - date: c.date_hour, - openInterest: Math.floor(c.open_interest * c.price), - }) - } else { - hasDate.openInterest = - hasDate.openInterest + Math.floor(c.open_interest * c.price) - } - return a.sort( - (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime() - ) - }, []) - return values + const hasDateVolume = a.volumeValues.find( + (d: VolumeValueItem) => d.date === c.date_hour + ) + + if (!hasDateFee) { + a.feeValues.push({ + date: c.date_hour, + feeValue: c.total_fees, + }) + } else { + hasDateFee.feeValue += c.total_fees + } + + if (!hasDateOpenInterest) { + a.openInterestValues.push({ + date: c.date_hour, + openInterest: Math.floor(c.open_interest * c.price), + }) + } 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]) return ( <> - {totalFeeValues.length ? ( + {feeValues.length ? (
`$${x.toFixed(2)}`} + tickFormat={(x) => `$${formatYAxis(x)}`} title="Perp Fees" xKey="date" yKey={'feeValue'} />
) : null} - {totalOpenInterestValues.length ? ( + {openInterestValues.length ? (
`$${Math.floor(x)}`} + tickFormat={(x) => `$${formatYAxis(x)}`} title={t('trade:open-interest')} xKey="date" yKey={'openInterest'} />
) : null} + {volumeValues.length ? ( +
+ `$${formatYAxis(x)}`} + title={t('stats:perp-volume')} + xKey="date" + yKey={'volume'} + /> +
+ ) : null} ) } diff --git a/public/locales/en/stats.json b/public/locales/en/stats.json index e46ab2ae..abe73351 100644 --- a/public/locales/en/stats.json +++ b/public/locales/en/stats.json @@ -5,6 +5,7 @@ "hourly": "Hourly", "largest-perp-positions": "Largest Positions", "perp-details": "{{market}} Stats", + "perp-volume": "Perp Volume", "pnl-liquidation-fee": "Positive PnL Liquidation Fee", "settle-pnl-factor": "Settle PnL Factor", "six-hourly": "6-Hourly", diff --git a/public/locales/es/stats.json b/public/locales/es/stats.json index e46ab2ae..abe73351 100644 --- a/public/locales/es/stats.json +++ b/public/locales/es/stats.json @@ -5,6 +5,7 @@ "hourly": "Hourly", "largest-perp-positions": "Largest Positions", "perp-details": "{{market}} Stats", + "perp-volume": "Perp Volume", "pnl-liquidation-fee": "Positive PnL Liquidation Fee", "settle-pnl-factor": "Settle PnL Factor", "six-hourly": "6-Hourly", diff --git a/public/locales/ru/stats.json b/public/locales/ru/stats.json index e46ab2ae..abe73351 100644 --- a/public/locales/ru/stats.json +++ b/public/locales/ru/stats.json @@ -5,6 +5,7 @@ "hourly": "Hourly", "largest-perp-positions": "Largest Positions", "perp-details": "{{market}} Stats", + "perp-volume": "Perp Volume", "pnl-liquidation-fee": "Positive PnL Liquidation Fee", "settle-pnl-factor": "Settle PnL Factor", "six-hourly": "6-Hourly", diff --git a/public/locales/zh/stats.json b/public/locales/zh/stats.json index 6187185e..def3ee73 100644 --- a/public/locales/zh/stats.json +++ b/public/locales/zh/stats.json @@ -5,6 +5,7 @@ "hourly": "Hourly", "largest-perp-positions": "Largest Positions", "perp-details": "{{market}}统计", + "perp-volume": "Perp Volume", "pnl-liquidation-fee": "Positive PnL Liquidation Fee", "settle-pnl-factor": "Settle PnL Factor", "six-hourly": "6-Hourly", diff --git a/public/locales/zh_tw/stats.json b/public/locales/zh_tw/stats.json index da7ebe31..9609a68e 100644 --- a/public/locales/zh_tw/stats.json +++ b/public/locales/zh_tw/stats.json @@ -5,6 +5,7 @@ "hourly": "小時", "largest-perp-positions": "Largest Positions", "perp-details": "{{market}}統計", + "perp-volume": "Perp Volume", "pnl-liquidation-fee": "正數盈虧清算費用", "settle-pnl-factor": "結清盈虧因素", "six-hourly": "6-小時",