2022-03-01 11:06:02 -08:00
|
|
|
import { useEffect, useMemo, useState } from 'react'
|
|
|
|
import dayjs from 'dayjs'
|
|
|
|
import utc from 'dayjs/plugin/utc'
|
|
|
|
import { ExclamationIcon } from '@heroicons/react/solid'
|
|
|
|
import { useTranslation } from 'next-i18next'
|
|
|
|
|
|
|
|
import useMangoStore from '../../stores/useMangoStore'
|
2021-09-03 05:11:21 -07:00
|
|
|
import { formatUsdValue } from '../../utils'
|
|
|
|
import BalancesTable from '../BalancesTable'
|
2021-09-05 17:20:21 -07:00
|
|
|
import Switch from '../Switch'
|
|
|
|
import useLocalStorageState from '../../hooks/useLocalStorageState'
|
2022-03-01 11:06:02 -08:00
|
|
|
import ButtonGroup from '../ButtonGroup'
|
|
|
|
import PerformanceChart from './PerformanceChart'
|
|
|
|
import PositionsTable from '../PerpPositionsTable'
|
|
|
|
|
|
|
|
dayjs.extend(utc)
|
2021-07-25 06:54:25 -07:00
|
|
|
|
2021-09-05 17:20:21 -07:00
|
|
|
const SHOW_ZERO_BALANCE_KEY = 'showZeroAccountBalances-0.2'
|
2021-07-25 06:54:25 -07:00
|
|
|
|
2022-03-01 11:06:02 -08:00
|
|
|
const performanceRangePresets = [
|
|
|
|
{ label: '24h', value: 1 },
|
|
|
|
{ label: '7d', value: 7 },
|
|
|
|
{ label: '30d', value: 30 },
|
|
|
|
{ label: '3m', value: 90 },
|
|
|
|
]
|
|
|
|
const performanceRangePresetLabels = performanceRangePresets.map((x) => x.label)
|
|
|
|
|
2022-03-06 15:18:22 -08:00
|
|
|
export const fetchHourlyPerformanceStats = async (
|
2022-03-01 18:25:23 -08:00
|
|
|
mangoAccountPk: string,
|
|
|
|
range: number
|
|
|
|
) => {
|
2022-03-01 11:06:02 -08:00
|
|
|
const response = await fetch(
|
|
|
|
`https://mango-transaction-log.herokuapp.com/v3/stats/account-performance-detailed?mango-account=${mangoAccountPk}&start-date=${dayjs()
|
|
|
|
.subtract(range, 'day')
|
|
|
|
.format('YYYY-MM-DD')}`
|
|
|
|
)
|
|
|
|
const parsedResponse = await response.json()
|
|
|
|
const entries: any = Object.entries(parsedResponse)
|
|
|
|
|
|
|
|
const stats = entries
|
|
|
|
.map(([key, value]) => {
|
|
|
|
return { ...value, time: key }
|
|
|
|
})
|
|
|
|
.filter((x) => x)
|
|
|
|
.reverse()
|
|
|
|
|
|
|
|
return stats
|
|
|
|
}
|
|
|
|
|
2021-07-25 06:54:25 -07:00
|
|
|
export default function AccountOverview() {
|
2021-10-20 05:42:40 -07:00
|
|
|
const { t } = useTranslation('common')
|
2021-07-25 06:54:25 -07:00
|
|
|
const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current)
|
|
|
|
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
|
|
|
|
const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache)
|
2021-09-05 17:20:21 -07:00
|
|
|
const [showZeroBalances, setShowZeroBalances] = useLocalStorageState(
|
|
|
|
SHOW_ZERO_BALANCE_KEY,
|
|
|
|
true
|
|
|
|
)
|
2021-07-29 06:19:32 -07:00
|
|
|
|
2022-03-01 11:06:02 -08:00
|
|
|
const [pnl, setPnl] = useState(0)
|
|
|
|
const [performanceRange, setPerformanceRange] = useState('30d')
|
|
|
|
const [hourlyPerformanceStats, setHourlyPerformanceStats] = useState([])
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const fetchData = async () => {
|
|
|
|
const stats = await fetchHourlyPerformanceStats(
|
2022-03-01 18:25:23 -08:00
|
|
|
mangoAccount.publicKey.toString(),
|
|
|
|
performanceRangePresets[performanceRangePresets.length - 1].value
|
2022-03-01 11:06:02 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
setPnl(stats?.length ? stats?.[0]?.['pnl'] : 0)
|
|
|
|
setHourlyPerformanceStats(stats)
|
|
|
|
}
|
2022-03-01 22:02:49 -08:00
|
|
|
if (mangoAccount) {
|
|
|
|
fetchData()
|
|
|
|
}
|
|
|
|
}, [mangoAccount?.publicKey])
|
2022-03-01 11:06:02 -08:00
|
|
|
|
2021-08-05 07:07:29 -07:00
|
|
|
const maintHealthRatio = useMemo(() => {
|
|
|
|
return mangoAccount
|
|
|
|
? mangoAccount.getHealthRatio(mangoGroup, mangoCache, 'Maint')
|
|
|
|
: 100
|
|
|
|
}, [mangoAccount, mangoGroup, mangoCache])
|
|
|
|
|
|
|
|
const initHealthRatio = useMemo(() => {
|
|
|
|
return mangoAccount
|
|
|
|
? mangoAccount.getHealthRatio(mangoGroup, mangoCache, 'Init')
|
|
|
|
: 100
|
|
|
|
}, [mangoAccount, mangoGroup, mangoCache])
|
|
|
|
|
2022-03-01 11:06:02 -08:00
|
|
|
const mangoAccountValue = useMemo(() => {
|
2022-03-01 22:02:49 -08:00
|
|
|
return mangoAccount ? +mangoAccount.computeValue(mangoGroup, mangoCache) : 0
|
2021-08-05 07:07:29 -07:00
|
|
|
}, [mangoAccount])
|
|
|
|
|
2021-07-25 06:54:25 -07:00
|
|
|
return mangoAccount ? (
|
|
|
|
<>
|
2022-03-01 11:06:02 -08:00
|
|
|
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between pb-4">
|
|
|
|
<h2 className="mb-4 sm:mb-0">{t('summary')}</h2>
|
|
|
|
<div className="w-full sm:w-56">
|
|
|
|
<ButtonGroup
|
|
|
|
activeValue={performanceRange}
|
|
|
|
onChange={(p) => setPerformanceRange(p)}
|
|
|
|
values={performanceRangePresetLabels}
|
|
|
|
/>
|
2021-08-01 05:48:15 -07:00
|
|
|
</div>
|
2022-03-01 11:06:02 -08:00
|
|
|
</div>
|
|
|
|
<div className="flex flex-col lg:flex-row lg:space-x-6 pb-8 lg:pb-12">
|
|
|
|
<div className="border-t border-th-bkg-4 pb-6 lg:pb-0 w-full lg:w-1/4">
|
|
|
|
<div className="border-b border-th-bkg-4 p-3 sm:p-4">
|
|
|
|
<div className="pb-0.5 text-th-fgd-3 text-xs sm:text-sm">
|
|
|
|
{t('account-value')}
|
|
|
|
</div>
|
2022-03-01 16:08:18 -08:00
|
|
|
<div className="font-bold text-th-fgd-1 text-xl sm:text-2xl">
|
2022-03-01 11:06:02 -08:00
|
|
|
{formatUsdValue(mangoAccountValue)}
|
2021-09-19 17:36:02 -07:00
|
|
|
</div>
|
2021-08-01 05:48:15 -07:00
|
|
|
</div>
|
2022-03-01 11:06:02 -08:00
|
|
|
<div className="border-b border-th-bkg-4 p-3 sm:p-4">
|
2022-03-01 17:47:06 -08:00
|
|
|
<div className="flex items-center justify-between">
|
|
|
|
<div className="pb-0.5 text-th-fgd-3 text-xs sm:text-sm">
|
|
|
|
{t('pnl')}{' '}
|
|
|
|
{hourlyPerformanceStats?.length ? (
|
|
|
|
<div className="text-th-fgd-4 text-xs">
|
|
|
|
{dayjs(hourlyPerformanceStats[0]['time']).format(
|
|
|
|
'MMM D YYYY, h:mma'
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
) : null}
|
|
|
|
</div>
|
2022-03-01 11:06:02 -08:00
|
|
|
</div>
|
2022-03-01 16:08:18 -08:00
|
|
|
<div className="font-bold text-th-fgd-1 text-xl sm:text-2xl">
|
2022-03-01 11:06:02 -08:00
|
|
|
{formatUsdValue(pnl)}
|
|
|
|
</div>
|
2021-09-19 17:36:02 -07:00
|
|
|
</div>
|
2022-03-01 11:06:02 -08:00
|
|
|
<div className="border-b border-th-bkg-4 p-3 sm:p-4">
|
|
|
|
<div className="pb-0.5 text-th-fgd-3 text-xs sm:text-sm">
|
|
|
|
{t('leverage')}
|
|
|
|
</div>
|
2022-03-01 16:08:18 -08:00
|
|
|
<div className="font-bold text-th-fgd-1 text-xl sm:text-2xl">
|
2021-08-16 10:00:43 -07:00
|
|
|
{mangoAccount.getLeverage(mangoGroup, mangoCache).toFixed(2)}x
|
2021-09-19 17:36:02 -07:00
|
|
|
</div>
|
2021-08-16 10:00:43 -07:00
|
|
|
</div>
|
2022-03-01 11:06:02 -08:00
|
|
|
<div className="p-3 sm:p-4">
|
|
|
|
<div className="pb-0.5 text-th-fgd-3 text-xs sm:text-sm">
|
|
|
|
{t('health-ratio')}
|
|
|
|
</div>
|
2022-03-01 16:08:18 -08:00
|
|
|
<div className={`font-bold text-th-fgd-1 text-xl sm:text-2xl`}>
|
2021-10-04 18:55:29 -07:00
|
|
|
{maintHealthRatio < 1000 ? maintHealthRatio.toFixed(2) : '>100'}%
|
2021-09-19 17:36:02 -07:00
|
|
|
</div>
|
2022-03-01 11:06:02 -08:00
|
|
|
{mangoAccount.beingLiquidated ? (
|
|
|
|
<div className="pt-0.5 sm:pt-2 text-xs sm:text-sm flex items-center">
|
|
|
|
<ExclamationIcon className="flex-shrink-0 h-5 w-5 sm:h-7 sm:w-7 mr-1.5 text-th-red" />
|
|
|
|
<span className="text-th-red">{t('being-liquidated')}</span>
|
|
|
|
</div>
|
|
|
|
) : null}
|
2021-07-25 06:54:25 -07:00
|
|
|
</div>
|
2022-03-01 11:06:02 -08:00
|
|
|
<div className="h-1 flex rounded bg-th-bkg-3">
|
2021-08-05 07:07:29 -07:00
|
|
|
<div
|
|
|
|
style={{
|
|
|
|
width: `${maintHealthRatio}%`,
|
|
|
|
}}
|
|
|
|
className={`flex rounded ${
|
|
|
|
maintHealthRatio > 30
|
|
|
|
? 'bg-th-green'
|
|
|
|
: initHealthRatio > 0
|
|
|
|
? 'bg-th-orange'
|
|
|
|
: 'bg-th-red'
|
|
|
|
}`}
|
|
|
|
></div>
|
2021-07-25 06:54:25 -07:00
|
|
|
</div>
|
|
|
|
</div>
|
2022-03-01 16:08:18 -08:00
|
|
|
<div className="lg:border-t border-th-bkg-4 h-80 lg:h-auto w-full lg:w-3/4">
|
2022-03-01 11:06:02 -08:00
|
|
|
<PerformanceChart
|
|
|
|
hourlyPerformanceStats={hourlyPerformanceStats}
|
|
|
|
performanceRange={performanceRange}
|
|
|
|
accountValue={mangoAccountValue}
|
|
|
|
/>
|
2021-07-25 06:54:25 -07:00
|
|
|
</div>
|
|
|
|
</div>
|
2022-03-01 16:08:18 -08:00
|
|
|
<div className="pb-8 pt-16 lg:pt-0">
|
2022-02-20 19:55:13 -08:00
|
|
|
<h2 className="mb-4">{t('perp-positions')}</h2>
|
2021-07-29 06:19:32 -07:00
|
|
|
<PositionsTable />
|
|
|
|
</div>
|
2022-02-20 19:55:13 -08:00
|
|
|
<h2 className="mb-4">{t('assets-liabilities')}</h2>
|
2021-08-05 07:07:29 -07:00
|
|
|
|
2022-03-01 16:08:18 -08:00
|
|
|
<div className="grid grid-flow-col grid-cols-1 grid-rows-2 md:grid-cols-2 md:grid-rows-1 lg:gap-4 pb-8 lg:pb-12">
|
|
|
|
<div className="border-t lg:border-b border-th-bkg-4 p-3 sm:p-4 rounded-md sm:rounded-lg">
|
|
|
|
<div className="pb-0.5 text-th-fgd-3">{t('total-assets')}</div>
|
2021-08-05 07:07:29 -07:00
|
|
|
<div className="flex items-center">
|
2022-03-01 16:08:18 -08:00
|
|
|
<div className="font-bold text-2xl text-th-fgd-1">
|
2021-08-15 06:31:59 -07:00
|
|
|
{formatUsdValue(
|
2021-08-05 07:07:29 -07:00
|
|
|
+mangoAccount.getAssetsVal(mangoGroup, mangoCache)
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2022-03-01 16:08:18 -08:00
|
|
|
<div className="border-b border-t border-th-bkg-4 p-3 sm:p-4 rounded-md sm:rounded-lg">
|
|
|
|
<div className="pb-0.5 text-th-fgd-3">{t('total-liabilities')}</div>
|
2021-08-05 07:07:29 -07:00
|
|
|
<div className="flex items-center">
|
2022-03-01 16:08:18 -08:00
|
|
|
<div className="font-bold text-2xl text-th-fgd-1">
|
2021-08-15 06:31:59 -07:00
|
|
|
{formatUsdValue(
|
2021-08-05 07:07:29 -07:00
|
|
|
+mangoAccount.getLiabsVal(mangoGroup, mangoCache)
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-12-07 20:00:02 -08:00
|
|
|
<div className="flex justify-between pb-4">
|
2022-02-20 19:55:13 -08:00
|
|
|
<h2>{t('balances')}</h2>
|
2021-09-05 17:20:21 -07:00
|
|
|
<Switch
|
|
|
|
checked={showZeroBalances}
|
|
|
|
className="text-xs"
|
|
|
|
onChange={() => setShowZeroBalances(!showZeroBalances)}
|
|
|
|
>
|
2021-10-20 05:42:40 -07:00
|
|
|
{t('show-zero')}
|
2021-09-05 17:20:21 -07:00
|
|
|
</Switch>
|
|
|
|
</div>
|
2022-01-21 12:42:23 -08:00
|
|
|
<BalancesTable showZeroBalances={showZeroBalances} showDepositWithdraw />
|
2021-07-25 06:54:25 -07:00
|
|
|
</>
|
|
|
|
) : null
|
|
|
|
}
|