update endpoints and format data
This commit is contained in:
parent
bee6b7449b
commit
6f61ec17a1
|
@ -42,9 +42,10 @@ import FormatNumericValue from '@components/shared/FormatNumericValue'
|
|||
import HealthBar from './HealthBar'
|
||||
import AssetsLiabilities from './AssetsLiabilities'
|
||||
import {
|
||||
AccountVolumeTotalData,
|
||||
FormattedHourlyAccountVolumeData,
|
||||
HourlyAccountVolumeData,
|
||||
PerformanceDataItem,
|
||||
PerpVolumeData,
|
||||
SpotVolumeData,
|
||||
TotalAccountFundingItem,
|
||||
} from 'types'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
|
@ -79,25 +80,87 @@ const fetchFundingTotals = async (mangoAccountPk: string) => {
|
|||
}
|
||||
}
|
||||
|
||||
const fetchPerpVolume = async (mangoAccountPk: string) => {
|
||||
const fetchVolumeTotals = async (mangoAccountPk: string) => {
|
||||
try {
|
||||
const data = await fetch(
|
||||
`${MANGO_DATA_API_URL}/stats/daily-perp-volume?mango-account=${mangoAccountPk}&start-date=2022-06-30`
|
||||
)
|
||||
const res = await data.json()
|
||||
return res
|
||||
const [perpTotal, spotTotal] = await Promise.all([
|
||||
fetch(
|
||||
`${MANGO_DATA_API_URL}/stats/perp-volume-total?mango-account=${mangoAccountPk}`
|
||||
),
|
||||
fetch(
|
||||
`${MANGO_DATA_API_URL}/stats/spot-volume-total?mango-account=${mangoAccountPk}`
|
||||
),
|
||||
])
|
||||
|
||||
const [perpTotalData, spotTotalData] = await Promise.all([
|
||||
perpTotal.json(),
|
||||
spotTotal.json(),
|
||||
])
|
||||
|
||||
const combinedData = [perpTotalData, spotTotalData]
|
||||
if (combinedData.length) {
|
||||
return combinedData.reduce((a, c) => {
|
||||
const entries: AccountVolumeTotalData[] = Object.entries(c)
|
||||
const marketVol = entries.reduce((a, c) => {
|
||||
return a + c[1].volume_usd
|
||||
}, 0)
|
||||
return a + marketVol
|
||||
}, 0)
|
||||
}
|
||||
return 0
|
||||
} catch (e) {
|
||||
console.log('Failed to fetch perp volume', e)
|
||||
console.log('Failed to fetch spot volume', e)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
const fetchSpotVolume = async (mangoAccountPk: string) => {
|
||||
const formatHourlyVolumeData = (data: HourlyAccountVolumeData[]) => {
|
||||
if (!data || !data.length) return []
|
||||
const formattedData: FormattedHourlyAccountVolumeData[] = []
|
||||
|
||||
// Loop through each object in the original data array
|
||||
for (const obj of data) {
|
||||
// Loop through the keys (markets) in each object
|
||||
for (const market in obj) {
|
||||
// Loop through the timestamps in each market
|
||||
for (const timestamp in obj[market]) {
|
||||
// Find the corresponding entry in the formatted data array based on the timestamp
|
||||
let entry = formattedData.find((item) => item.time === timestamp)
|
||||
|
||||
// If the entry doesn't exist, create a new entry
|
||||
if (!entry) {
|
||||
entry = { time: timestamp, total_volume_usd: 0, markets: {} }
|
||||
formattedData.push(entry)
|
||||
}
|
||||
|
||||
// Increment the total_volume_usd by the volume_usd value
|
||||
entry.total_volume_usd += obj[market][timestamp].volume_usd
|
||||
|
||||
// Add or update the market entry in the markets object
|
||||
entry.markets[market] = obj[market][timestamp].volume_usd
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return formattedData
|
||||
}
|
||||
|
||||
const fetchHourlyVolume = async (mangoAccountPk: string) => {
|
||||
try {
|
||||
const data = await fetch(
|
||||
`${MANGO_DATA_API_URL}/stats/daily-spot-volume?mango-account=${mangoAccountPk}&start-date=2022-06-30`
|
||||
)
|
||||
const res = await data.json()
|
||||
return res
|
||||
const [perpHourly, spotHourly] = await Promise.all([
|
||||
fetch(
|
||||
`${MANGO_DATA_API_URL}/stats/perp-volume-hourly?mango-account=${mangoAccountPk}`
|
||||
),
|
||||
fetch(
|
||||
`${MANGO_DATA_API_URL}/stats/spot-volume-hourly?mango-account=${mangoAccountPk}`
|
||||
),
|
||||
])
|
||||
|
||||
const [perpHourlyData, spotHourlyData] = await Promise.all([
|
||||
perpHourly.json(),
|
||||
spotHourly.json(),
|
||||
])
|
||||
const hourlyVolume = [perpHourlyData, spotHourlyData]
|
||||
return formatHourlyVolumeData(hourlyVolume)
|
||||
} catch (e) {
|
||||
console.log('Failed to fetch spot volume', e)
|
||||
}
|
||||
|
@ -164,15 +227,13 @@ const AccountPage = () => {
|
|||
}
|
||||
)
|
||||
|
||||
console.log(fundingData)
|
||||
|
||||
const {
|
||||
data: perpVolumeData,
|
||||
isLoading: loadingPerpVolumeData,
|
||||
isFetching: fetchingPerpVolumeData,
|
||||
data: volumeTotalData,
|
||||
isLoading: loadingVolumeTotalData,
|
||||
isFetching: fetchingVolumeTotalData,
|
||||
} = useQuery(
|
||||
['perp-volume', mangoAccountAddress],
|
||||
() => fetchPerpVolume(mangoAccountAddress),
|
||||
['total-volume', mangoAccountAddress],
|
||||
() => fetchVolumeTotals(mangoAccountAddress),
|
||||
{
|
||||
cacheTime: 1000 * 60 * 10,
|
||||
staleTime: 1000 * 60,
|
||||
|
@ -182,27 +243,13 @@ const AccountPage = () => {
|
|||
}
|
||||
)
|
||||
|
||||
const perpVolumeTotal = useMemo(() => {
|
||||
if (!perpVolumeData) return 0
|
||||
const entries: PerpVolumeData[] = Object.entries(perpVolumeData)
|
||||
console.log(entries)
|
||||
return entries
|
||||
.map(([, value]) => {
|
||||
const volume = Object.values(value).reduce((a, c) => {
|
||||
return a + c.volume_usd
|
||||
}, 0)
|
||||
return volume
|
||||
})
|
||||
.reduce((a, c) => a + c)
|
||||
}, [perpVolumeData])
|
||||
|
||||
const {
|
||||
data: spotVolumeData,
|
||||
isLoading: loadingSpotVolumeData,
|
||||
isFetching: fetchingSpotVolumeData,
|
||||
data: hourlyVolumeData,
|
||||
isLoading: loadingHourlyVolumeData,
|
||||
isFetching: fetchingHourlyVolumeData,
|
||||
} = useQuery(
|
||||
['spot-volume', mangoAccountAddress],
|
||||
() => fetchSpotVolume(mangoAccountAddress),
|
||||
['hourly-volume', mangoAccountAddress],
|
||||
() => fetchHourlyVolume(mangoAccountAddress),
|
||||
{
|
||||
cacheTime: 1000 * 60 * 10,
|
||||
staleTime: 1000 * 60,
|
||||
|
@ -212,25 +259,23 @@ const AccountPage = () => {
|
|||
}
|
||||
)
|
||||
|
||||
const spotVolumeTotal = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
if (!spotVolumeData || !group) return 0
|
||||
const entries: SpotVolumeData[] = Object.entries(spotVolumeData)
|
||||
return entries
|
||||
.map(([key, value]) => {
|
||||
const quoteSymbol = key.split('/')[1]
|
||||
const quoteBank = group.banksMapByName.get(quoteSymbol)?.[0]
|
||||
let quotePrice = 1
|
||||
if (quoteBank && quoteBank.name !== 'USDC') {
|
||||
quotePrice = quoteBank.uiPrice
|
||||
}
|
||||
const volume = Object.values(value).reduce((a, c) => {
|
||||
return a + c.volume_quote * quotePrice
|
||||
}, 0)
|
||||
return volume
|
||||
})
|
||||
.reduce((a, c) => a + c)
|
||||
}, [spotVolumeData])
|
||||
const dailyVolume = useMemo(() => {
|
||||
if (!hourlyVolumeData || !hourlyVolumeData.length) return 0
|
||||
// Calculate the current time in milliseconds
|
||||
const currentTime = new Date().getTime()
|
||||
|
||||
// Calculate the start time for the last 24 hours in milliseconds
|
||||
const last24HoursStartTime = currentTime - 24 * 60 * 60 * 1000
|
||||
|
||||
// Filter the formatted data based on the timestamp
|
||||
const last24HoursData = hourlyVolumeData.filter((entry) => {
|
||||
const timestampMs = new Date(entry.time).getTime()
|
||||
return timestampMs >= last24HoursStartTime && timestampMs <= currentTime
|
||||
})
|
||||
|
||||
const volume = last24HoursData.reduce((a, c) => a + c.total_volume_usd, 0)
|
||||
return volume
|
||||
}, [hourlyVolumeData])
|
||||
|
||||
const oneDayPerformanceData: PerformanceDataItem[] | [] = useMemo(() => {
|
||||
if (!performanceData || !performanceData.length) return []
|
||||
|
@ -385,11 +430,9 @@ const AccountPage = () => {
|
|||
]
|
||||
}, [accountPnl, accountValue, performanceData])
|
||||
|
||||
const loadingVolume =
|
||||
fetchingPerpVolumeData ||
|
||||
fetchingSpotVolumeData ||
|
||||
loadingPerpVolumeData ||
|
||||
loadingSpotVolumeData
|
||||
const loadingTotalVolume = fetchingVolumeTotalData || loadingVolumeTotalData
|
||||
const loadingHourlyVolume =
|
||||
fetchingHourlyVolumeData || loadingHourlyVolumeData
|
||||
|
||||
return !chartToShow ? (
|
||||
<>
|
||||
|
@ -694,21 +737,34 @@ const AccountPage = () => {
|
|||
</div>
|
||||
<div className="col-span-6 border-t border-th-bkg-3 py-3 pl-6 pr-4 md:col-span-3 md:border-l lg:col-span-2 lg:border-l-0 xl:col-span-1 xl:border-l xl:border-t-0">
|
||||
<div id="account-step-six">
|
||||
<p className="tooltip-underline text-sm text-th-fgd-3 xl:text-base">
|
||||
{t('trade:trade-volume')}
|
||||
<p className="text-sm text-th-fgd-3 xl:text-base">
|
||||
{t('account:lifetime-volume')}
|
||||
</p>
|
||||
{loadingVolume && mangoAccountAddress ? (
|
||||
<SheenLoader className="mt-2">
|
||||
{loadingTotalVolume && mangoAccountAddress ? (
|
||||
<SheenLoader className="mt-1">
|
||||
<div className="h-7 w-16 bg-th-bkg-2" />
|
||||
</SheenLoader>
|
||||
) : (
|
||||
<p className="mt-1 text-2xl font-bold text-th-fgd-1 lg:text-xl xl:text-2xl">
|
||||
<FormatNumericValue
|
||||
value={spotVolumeTotal + perpVolumeTotal}
|
||||
isUsd
|
||||
/>
|
||||
<FormatNumericValue value={volumeTotalData || 0} isUsd />
|
||||
</p>
|
||||
)}
|
||||
<span className="flex items-center text-xs font-normal text-th-fgd-4">
|
||||
<span>{t('account:daily-volume')}</span>:
|
||||
{loadingHourlyVolume && mangoAccountAddress ? (
|
||||
<SheenLoader className="ml-1">
|
||||
<div className="h-3.5 w-10 bg-th-bkg-2" />
|
||||
</SheenLoader>
|
||||
) : (
|
||||
<span className="ml-1 font-mono text-th-fgd-2">
|
||||
<FormatNumericValue
|
||||
value={dailyVolume}
|
||||
decimals={2}
|
||||
isUsd={true}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-6 border-t border-th-bkg-3 py-3 pl-6 pr-4 text-left md:col-span-3 lg:col-span-2 lg:border-l xl:col-span-1 xl:border-t-0">
|
||||
|
|
|
@ -2,7 +2,10 @@ import { useMemo } from 'react'
|
|||
|
||||
const HealthBar = ({ health }: { health: number }) => {
|
||||
const [barWidths, fillColor] = useMemo(() => {
|
||||
if (!health) return [[2, 0, 0, 0], 'var(--down)']
|
||||
if (!health) return [[0, 0, 0, 0], 'var(--down)']
|
||||
if (health < 5) {
|
||||
return [[16, 0, 0, 0], 'var(--down)']
|
||||
}
|
||||
if (health <= 25) {
|
||||
const fillWidth = (health / 25) * 100
|
||||
return [[fillWidth, 0, 0, 0], 'var(--down)']
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
{
|
||||
"assets": "Assets",
|
||||
"assets-liabilities": "Assets & Liabilities",
|
||||
"daily-volume": "24h Volume",
|
||||
"export": "Export {{dataType}}",
|
||||
"liabilities": "Liabilities",
|
||||
"lifetime-volume": "Lifetime Trade Volume",
|
||||
"no-pnl-history": "No PnL History",
|
||||
"pnl-chart": "PnL Chart",
|
||||
"pnl-history": "PnL History",
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
{
|
||||
"assets": "Assets",
|
||||
"assets-liabilities": "Assets & Liabilities",
|
||||
"daily-volume": "24h Volume",
|
||||
"export": "Export {{dataType}}",
|
||||
"liabilities": "Liabilities",
|
||||
"lifetime-volume": "Lifetime Trade Volume",
|
||||
"no-pnl-history": "No PnL History",
|
||||
"pnl-chart": "PnL Chart",
|
||||
"pnl-history": "PnL History",
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
{
|
||||
"assets": "Assets",
|
||||
"assets-liabilities": "Assets & Liabilities",
|
||||
"daily-volume": "24h Volume",
|
||||
"export": "Export {{dataType}}",
|
||||
"liabilities": "Liabilities",
|
||||
"lifetime-volume": "Lifetime Trade Volume",
|
||||
"no-pnl-history": "No PnL History",
|
||||
"pnl-chart": "PnL Chart",
|
||||
"pnl-history": "PnL History",
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
{
|
||||
"assets": "资产",
|
||||
"export": "导出{{dataType}}",
|
||||
"assets-liabilities": "资产和债务",
|
||||
"liabilities": "债务",
|
||||
"no-pnl-history": "无盈亏历史",
|
||||
"pnl-chart": "盈亏图表",
|
||||
"pnl-history": "盈亏历史",
|
||||
"tooltip-free-collateral": "你可用于交易和借贷的余额。当你可用的质押品达到0元时,你将不能交易、借贷或取款",
|
||||
"tooltip-leverage": "总资价值除以账户余额",
|
||||
"tooltip-pnl": "你帐户的盈亏",
|
||||
"tooltip-total-collateral": "可用于交易和借贷的质押品(包括未结清的盈亏)",
|
||||
"tooltip-total-funding": "赚取和支付的合约资金费总和",
|
||||
"tooltip-total-interest": "你获取的利息(存款)减你付出的利息(借贷)",
|
||||
"total-funding-earned": "总资金费",
|
||||
"week-starting": "从{{week}}来算的一周"
|
||||
"assets": "Assets",
|
||||
"assets-liabilities": "Assets & Liabilities",
|
||||
"daily-volume": "24h Volume",
|
||||
"export": "Export {{dataType}}",
|
||||
"liabilities": "Liabilities",
|
||||
"lifetime-volume": "Lifetime Trade Volume",
|
||||
"no-pnl-history": "No PnL History",
|
||||
"pnl-chart": "PnL Chart",
|
||||
"pnl-history": "PnL History",
|
||||
"tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw",
|
||||
"tooltip-leverage": "Total assets value divided by account equity value",
|
||||
"tooltip-pnl": "The amount your account has profited or lost",
|
||||
"tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)",
|
||||
"tooltip-total-funding": "The sum of perp position funding earned and paid",
|
||||
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
|
||||
"total-funding-earned": "Total Funding Earned",
|
||||
"week-starting": "Week starting {{week}}"
|
||||
}
|
|
@ -1,17 +1,19 @@
|
|||
{
|
||||
"assets": "資產",
|
||||
"export": "導出{{dataType}}",
|
||||
"assets-liabilities": "資產和債務",
|
||||
"liabilities": "債務",
|
||||
"no-pnl-history": "無盈虧歷史",
|
||||
"pnl-chart": "盈虧圖表",
|
||||
"pnl-history": "盈虧歷史",
|
||||
"tooltip-free-collateral": "你可用於交易和借貸的餘額。當你可用的質押品達到0元時,你將不能交易、借貸或取款",
|
||||
"tooltip-leverage": "總資價值除以賬戶餘額",
|
||||
"tooltip-pnl": "你帳戶的盈虧",
|
||||
"tooltip-total-collateral": "可用於交易和借貸的質押品(包括未結清的盈虧)",
|
||||
"tooltip-total-funding": "賺取和支付的合約資金費總和",
|
||||
"tooltip-total-interest": "你獲取的利息(存款)減你付出的利息(借貸)",
|
||||
"total-funding-earned": "總資金費",
|
||||
"week-starting": "從{{week}}來算的一周"
|
||||
"assets": "Assets",
|
||||
"assets-liabilities": "Assets & Liabilities",
|
||||
"daily-volume": "24h Volume",
|
||||
"export": "Export {{dataType}}",
|
||||
"liabilities": "Liabilities",
|
||||
"lifetime-volume": "Lifetime Trade Volume",
|
||||
"no-pnl-history": "No PnL History",
|
||||
"pnl-chart": "PnL Chart",
|
||||
"pnl-history": "PnL History",
|
||||
"tooltip-free-collateral": "The amount of capital you have to use for trades and loans. When your free collateral reaches $0 you won't be able to trade, borrow or withdraw",
|
||||
"tooltip-leverage": "Total assets value divided by account equity value",
|
||||
"tooltip-pnl": "The amount your account has profited or lost",
|
||||
"tooltip-total-collateral": "Total value of collateral for trading and borrowing (including unsettled PnL)",
|
||||
"tooltip-total-funding": "The sum of perp position funding earned and paid",
|
||||
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
|
||||
"total-funding-earned": "Total Funding Earned",
|
||||
"week-starting": "Week starting {{week}}"
|
||||
}
|
|
@ -610,7 +610,7 @@ input[type='range']::-webkit-slider-runnable-track {
|
|||
}
|
||||
|
||||
.tooltip-underline {
|
||||
@apply default-transition w-max border-b border-dashed border-current leading-tight hover:cursor-help hover:border-transparent;
|
||||
@apply default-transition w-max border-b border-dashed border-current hover:cursor-help hover:border-transparent;
|
||||
}
|
||||
|
||||
.radial-gradient-bg {
|
||||
|
|
|
@ -140,12 +140,21 @@ export interface HourlyFundingChartData extends Record<string, any> {
|
|||
time: string
|
||||
}
|
||||
|
||||
export type PerpVolumeData = [string, { [key: string]: { volume_usd: number } }]
|
||||
export type AccountVolumeTotalData = [string, { volume_usd: number }]
|
||||
|
||||
export type SpotVolumeData = [
|
||||
string,
|
||||
{ [key: string]: { volume_quote: number } }
|
||||
]
|
||||
export type HourlyAccountVolumeData = {
|
||||
[market: string]: {
|
||||
[timestamp: string]: {
|
||||
volume_usd: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type FormattedHourlyAccountVolumeData = {
|
||||
time: string
|
||||
total_volume_usd: number
|
||||
markets: Record<string, number>
|
||||
}
|
||||
|
||||
export interface TotalInterestDataItem {
|
||||
borrow_interest: number
|
||||
|
|
Loading…
Reference in New Issue