From 579f4ddd5804b335b444a850e13c333c7e96605a Mon Sep 17 00:00:00 2001 From: tjs Date: Mon, 16 Jan 2023 23:57:52 -0500 Subject: [PATCH 1/3] brighter red orderbook on dark theme --- styles/colors.ts | 2 +- tailwind.config.js | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/styles/colors.ts b/styles/colors.ts index 34e73214..33936d5f 100644 --- a/styles/colors.ts +++ b/styles/colors.ts @@ -60,7 +60,7 @@ export const COLORS: any = { Olive: '#acaa8b', }, UP: { - 'Mango Classic': '#A6CD03', + 'Mango Classic': '#89B92A', Dark: '#4aa13a', Light: '#60bf4f', 'High Contrast': '#50f434', diff --git a/tailwind.config.js b/tailwind.config.js index 11deb72f..47f4fd04 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -35,17 +35,17 @@ module.exports = { }, link: { DEFAULT: 'hsl(33, 100%, 57%)', hover: 'hsl(33, 100%, 52%)' }, down: { - DEFAULT: 'hsl(4, 93%, 60%)', + DEFAULT: 'hsl(4, 63%, 55%)', dark: 'hsl(4, 93%, 55%)', - muted: 'hsl(4, 53%, 55%)', + muted: 'hsl(4, 43%, 38%)', }, up: { - DEFAULT: 'hsl(72, 97%, 41%)', - dark: 'hsl(72, 97%, 36%)', - muted: 'hsl(72, 57%, 36%)', + DEFAULT: 'hsl(77, 63%, 40%)', + dark: 'hsl(85, 50%, 36%)', + muted: 'hsl(84, 40%, 32%)', }, error: 'hsl(4, 93%, 60%)', - success: 'hsl(72, 97%, 41%)', + success: 'hsl(82, 97%, 41%)', warning: 'hsl(33, 100%, 57%)', 'bkg-1': 'hsl(256, 18%, 12%)', 'bkg-2': 'hsl(256, 18%, 17%)', @@ -110,8 +110,8 @@ module.exports = { link: { DEFAULT: 'hsl(45, 86%, 62%)', hover: 'hsl(45, 86%, 57%)' }, down: { DEFAULT: 'hsl(358, 55%, 50%)', - dark: 'hsl(0, 59%, 53%)', - muted: 'hsl(0, 45%, 26%)', + dark: 'hsl(0, 45%, 26%)', + muted: 'hsl(0, 45%, 30%)', }, up: { DEFAULT: 'hsl(111, 47%, 43%)', From e5dff1c8c3fc2deeadc0046c5006a3b8bd1e5b7b Mon Sep 17 00:00:00 2001 From: tjs Date: Tue, 17 Jan 2023 18:31:58 -0500 Subject: [PATCH 2/3] use latest client; update perp positions table with new pnl calcs --- components/trade/PerpPositions.tsx | 28 ++++++++++++++-------------- components/trade/UnsettledTrades.tsx | 2 +- hooks/useUnsettledPerpPositions.ts | 4 ++-- pages/dashboard/index.tsx | 24 ++++++++++++++++-------- yarn.lock | 11 +++++++++-- 5 files changed, 42 insertions(+), 27 deletions(-) diff --git a/components/trade/PerpPositions.tsx b/components/trade/PerpPositions.tsx index da26ec48..b667178a 100644 --- a/components/trade/PerpPositions.tsx +++ b/components/trade/PerpPositions.tsx @@ -8,6 +8,7 @@ import useMangoGroup from 'hooks/useMangoGroup' import useSelectedMarket from 'hooks/useSelectedMarket' import { useTranslation } from 'next-i18next' import { + formatDecimal, formatFixedDecimals, getDecimalCount, numberFormat, @@ -66,8 +67,8 @@ const PerpPositions = () => { {t('trade:size')} {t('trade:notional')} {t('trade:entry-price')} - Redeemable PnL - Realized PnL + Unsettled PnL + PnL @@ -86,7 +87,11 @@ const PerpPositions = () => { if (!basePosition) return null - const unsettledPnl = position.getEquityUi(group, market) + const unsettledPnl = position.getUnsettledPnlUi(group, market) + const cummulativePnl = position.cumulativePnlOverPositionLifetimeUi( + group, + market + ) return ( @@ -96,7 +101,7 @@ const PerpPositions = () => { - +

{isSelectedMarket ? ( { )} + +

{formatDecimal(unsettledPnl, market.baseDecimals)}
+ 0 ? 'text-th-up' : 'text-th-down' + cummulativePnl > 0 ? 'text-th-up' : 'text-th-down' }`} > -
{formatFixedDecimals(unsettledPnl, true)}
- - -
- $ - {/* {numberFormat.format( - position.perpSpotTransfers.toNumber() - )} */} -
+
{formatFixedDecimals(cummulativePnl, true)}
) diff --git a/components/trade/UnsettledTrades.tsx b/components/trade/UnsettledTrades.tsx index 8a106fd8..677c0177 100644 --- a/components/trade/UnsettledTrades.tsx +++ b/components/trade/UnsettledTrades.tsx @@ -204,7 +204,7 @@ const UnsettledTrades = ({ {formatDecimal( - position.getEquityUi(group, market), + position.getUnsettledPnlUi(group, market), market.baseDecimals )} diff --git a/hooks/useUnsettledPerpPositions.ts b/hooks/useUnsettledPerpPositions.ts index 4de44901..88c95a66 100644 --- a/hooks/useUnsettledPerpPositions.ts +++ b/hooks/useUnsettledPerpPositions.ts @@ -7,8 +7,8 @@ const useUnsettledPerpPositions = () => { return perpPositions.filter((p) => { const market = group?.getPerpMarketByMarketIndex(p.marketIndex) - if (!market) return false - return p.getPnl(market).toNumber() > 0 + if (!market || !group) return false + return p.getUnsettledPnlUi(group, market) !== 0 }) } diff --git a/pages/dashboard/index.tsx b/pages/dashboard/index.tsx index d443f5fa..b3d6434f 100644 --- a/pages/dashboard/index.tsx +++ b/pages/dashboard/index.tsx @@ -441,17 +441,29 @@ const Dashboard: NextPage = () => { /> + + { label="Oracle: Max Staleness" value={`${perpMarket.oracleConfig.maxStalenessSlots} slots`} /> - Date: Wed, 18 Jan 2023 10:38:33 +1100 Subject: [PATCH 3/3] add chart range buttons to mango stats charts --- components/stats/MangoStats.tsx | 131 +------------- components/stats/TotalDepositBorrowCharts.tsx | 170 ++++++++++++++++++ 2 files changed, 178 insertions(+), 123 deletions(-) create mode 100644 components/stats/TotalDepositBorrowCharts.tsx diff --git a/components/stats/MangoStats.tsx b/components/stats/MangoStats.tsx index 9553f8e7..1586ddec 100644 --- a/components/stats/MangoStats.tsx +++ b/components/stats/MangoStats.tsx @@ -1,31 +1,15 @@ -import SheenLoader from '@components/shared/SheenLoader' -import mangoStore, { TokenStatsItem } from '@store/mangoStore' -import useMangoGroup from 'hooks/useMangoGroup' -import { useTranslation } from 'next-i18next' -import dynamic from 'next/dynamic' -import { useMemo } from 'react' -import dayjs from 'dayjs' -import { numberCompacter } from 'utils/numbers' +import mangoStore from '@store/mangoStore' +import TotalDepositBorrowCharts from './TotalDepositBorrowCharts' +// import { useTranslation } from 'next-i18next' // import { PerpMarket } from '@blockworks-foundation/mango-v4' -const DetailedAreaChart = dynamic( - () => import('@components/shared/DetailedAreaChart'), - { ssr: false } -) - -interface TotalValueItem { - date: string - borrowValue: number - depositValue: number -} const MangoStats = () => { - const { t } = useTranslation(['common', 'token', 'trade']) + // const { t } = useTranslation(['common', 'token', 'trade']) const tokenStats = mangoStore((s) => s.tokenStats.data) const loadingStats = mangoStore((s) => s.tokenStats.loading) // const perpStats = mangoStore((s) => s.perpStats.data) // const loadingPerpStats = mangoStore((s) => s.perpStats.loading) // const perpMarkets = mangoStore((s) => s.perpMarkets) - const { group } = useMangoGroup() // const totalFeeValues = useMemo(() => { // if (!perpStats.length) return [] @@ -72,111 +56,12 @@ const MangoStats = () => { // }, 0) // }, [perpMarkets]) - const totalDepositBorrowValues = useMemo(() => { - if (!tokenStats) return [] - const values: TotalValueItem[] = tokenStats.reduce( - (a: TotalValueItem[], c: TokenStatsItem) => { - const hasDate = a.find((d: TotalValueItem) => d.date === c.date_hour) - if (!hasDate) { - a.push({ - date: c.date_hour, - depositValue: Math.floor(c.total_deposits * c.price), - borrowValue: Math.floor(c.total_borrows * c.price), - }) - } else { - hasDate.depositValue = - hasDate.depositValue + Math.floor(c.total_deposits * c.price) - hasDate.borrowValue = - hasDate.borrowValue + Math.floor(c.total_borrows * c.price) - } - return a - }, - [] - ) - return values.reverse() - }, [tokenStats]) - - const banks = useMemo(() => { - if (group) { - const rawBanks = Array.from(group?.banksMapByName, ([key, value]) => ({ - key, - value, - })) - return rawBanks - } - return [] - }, [group]) - - const [currentTotalDepositValue, currentTotalBorrowValue] = useMemo(() => { - if (banks.length) { - return [ - banks.reduce( - (a, c) => a + c.value[0].uiPrice * c.value[0].uiDeposits(), - 0 - ), - banks.reduce( - (a, c) => a + c.value[0].uiPrice * c.value[0].uiBorrows(), - 0 - ), - ] - } - return [0, 0] - }, [banks]) - return (
- {loadingStats ? ( -
- -
- -
- ) : totalDepositBorrowValues.length ? ( -
- `$${numberCompacter.format(x)}`} - title={t('total-deposit-value')} - xKey="date" - yKey={'depositValue'} - /> -
- ) : null} - {loadingStats ? ( -
- -
- -
- ) : totalDepositBorrowValues.length ? ( -
- `$${numberCompacter.format(x)}`} - title={t('total-borrow-value')} - xKey="date" - yKey={'borrowValue'} - /> -
- ) : null} + {/* uncomment below when perps launch */} {/* {loadingPerpStats ? ( diff --git a/components/stats/TotalDepositBorrowCharts.tsx b/components/stats/TotalDepositBorrowCharts.tsx new file mode 100644 index 00000000..d7487954 --- /dev/null +++ b/components/stats/TotalDepositBorrowCharts.tsx @@ -0,0 +1,170 @@ +import SheenLoader from '@components/shared/SheenLoader' +import { TokenStatsItem } from '@store/mangoStore' +import useMangoGroup from 'hooks/useMangoGroup' +import { useTranslation } from 'next-i18next' +import dynamic from 'next/dynamic' +import { useMemo, useState } from 'react' +import dayjs from 'dayjs' +import { numberCompacter } from 'utils/numbers' +const DetailedAreaChart = dynamic( + () => import('@components/shared/DetailedAreaChart'), + { ssr: false } +) + +interface TotalValueItem { + date: string + borrowValue: number + depositValue: number +} + +const TotalDepositBorrowCharts = ({ + tokenStats, + loadingStats, +}: { + tokenStats: TokenStatsItem[] | null + loadingStats: boolean +}) => { + const { t } = useTranslation(['common', 'token', 'trade']) + const [borrowDaysToShow, setBorrowDaysToShow] = useState('30') + const [depositDaysToShow, setDepositDaysToShow] = useState('30') + const { group } = useMangoGroup() + + const totalDepositBorrowValues = useMemo(() => { + if (!tokenStats) return [] + const values: TotalValueItem[] = tokenStats.reduce( + (a: TotalValueItem[], c: TokenStatsItem) => { + const hasDate = a.find((d: TotalValueItem) => d.date === c.date_hour) + if (!hasDate) { + a.push({ + date: c.date_hour, + depositValue: Math.floor(c.total_deposits * c.price), + borrowValue: Math.floor(c.total_borrows * c.price), + }) + } else { + hasDate.depositValue = + hasDate.depositValue + Math.floor(c.total_deposits * c.price) + hasDate.borrowValue = + hasDate.borrowValue + Math.floor(c.total_borrows * c.price) + } + return a + }, + [] + ) + return values.reverse() + }, [tokenStats]) + + const filteredBorrowValues = useMemo(() => { + if (!totalDepositBorrowValues) return [] + if (borrowDaysToShow !== '30') { + const seconds = Number(borrowDaysToShow) * 86400 + const data = totalDepositBorrowValues.filter((d) => { + const dataTime = new Date(d.date).getTime() / 1000 + const now = new Date().getTime() / 1000 + const limit = now - seconds + return dataTime >= limit + }) + return data + } + return totalDepositBorrowValues + }, [totalDepositBorrowValues, borrowDaysToShow]) + + const filteredDepositValues = useMemo(() => { + if (!totalDepositBorrowValues) return [] + if (depositDaysToShow !== '30') { + const seconds = Number(depositDaysToShow) * 86400 + const data = totalDepositBorrowValues.filter((d) => { + const dataTime = new Date(d.date).getTime() / 1000 + const now = new Date().getTime() / 1000 + const limit = now - seconds + return dataTime >= limit + }) + return data + } + return totalDepositBorrowValues + }, [totalDepositBorrowValues, depositDaysToShow]) + + const banks = useMemo(() => { + if (group) { + const rawBanks = Array.from(group?.banksMapByName, ([key, value]) => ({ + key, + value, + })) + return rawBanks + } + return [] + }, [group]) + + const [currentTotalDepositValue, currentTotalBorrowValue] = useMemo(() => { + if (banks.length) { + return [ + banks.reduce( + (a, c) => a + c.value[0].uiPrice * c.value[0].uiDeposits(), + 0 + ), + banks.reduce( + (a, c) => a + c.value[0].uiPrice * c.value[0].uiBorrows(), + 0 + ), + ] + } + return [0, 0] + }, [banks]) + + return loadingStats ? ( + <> +
+ +
+ +
+
+ +
+ +
+ + ) : totalDepositBorrowValues.length ? ( + <> +
+ `$${numberCompacter.format(x)}`} + title={t('total-deposit-value')} + xKey="date" + yKey={'depositValue'} + /> +
+
+ `$${numberCompacter.format(x)}`} + title={t('total-borrow-value')} + xKey="date" + yKey={'borrowValue'} + /> +
+ + ) : null +} + +export default TotalDepositBorrowCharts