import { PerpMarket } from '@blockworks-foundation/mango-client' import { useState } from 'react' import useMangoGroupConfig from '../../hooks/useMangoGroupConfig' import useMangoStore from '../../stores/useMangoStore' import Chart from '../Chart' import BN from 'bn.js' const icons = { 'BTC-PERP': '/assets/icons/btc.svg', 'ETH-PERP': '/assets/icons/eth.svg', 'SOL-PERP': '/assets/icons/sol.svg', 'SRM-PERP': '/assets/icons/srm.svg', 'USDT-PERP': '/assets/icons/usdt.svg', 'MNGO-PERP': '/assets/icons/mngo.svg', } function calculateFundingRate( oldestLongFunding, oldestShortFunding, latestLongFunding, latestShortFunding, perpMarket, oraclePrice ) { if (!perpMarket || !oraclePrice) return 0.0 // Averaging long and short funding excludes socialized loss const startFunding = (parseFloat(oldestLongFunding) + parseFloat(oldestShortFunding)) / 2 const endFunding = (parseFloat(latestLongFunding) + parseFloat(latestShortFunding)) / 2 const fundingDifference = endFunding - startFunding const fundingInQuoteDecimals = fundingDifference / Math.pow(10, perpMarket.quoteDecimals) // TODO - use avgPrice and discard oraclePrice once stats are better // const avgPrice = (latestStat.baseOraclePrice + oldestStat.baseOraclePrice) / 2 const basePriceInBaseLots = oraclePrice * perpMarket.baseLotsToNumber(new BN(1)) return (fundingInQuoteDecimals / basePriceInBaseLots) * 100 } export default function StatsPerps({ perpStats }) { const [selectedAsset, setSelectedAsset] = useState('BTC-PERP') const marketConfigs = useMangoGroupConfig().perpMarkets const selectedMarketConfig = marketConfigs.find( (m) => m.name === selectedAsset ) const markets = Object.values( useMangoStore.getState().selectedMangoGroup.markets ).filter((m) => m instanceof PerpMarket) as PerpMarket[] const selectedMarket = markets.find((m) => m.publicKey.equals(selectedMarketConfig.publicKey) ) let selectedStatsData = perpStats.filter( (stat) => stat.name === selectedAsset ) if (selectedAsset == 'SOL-PERP') { const startTimestamp = 1632160800000 selectedStatsData = selectedStatsData.filter( (stat) => new Date(stat.hourly).getTime() >= startTimestamp ) } const perpsData = selectedStatsData.map((x) => { return { fundingRate: calculateFundingRate( x.oldestLongFunding, x.oldestShortFunding, x.latestLongFunding, x.latestShortFunding, selectedMarket, x.baseOraclePrice ), openInterest: selectedMarket.baseLotsToNumber(x.openInterest) / 2, time: x.hourly, } }) return ( <>
{marketConfigs.map((market) => (
setSelectedAsset(market.name)} key={market.name as string} > {market.name}
))}
`${x.toFixed(4)}%`} type="area" />
x && x.toLocaleString(undefined, { maximumFractionDigits: selectedMarketConfig.baseDecimals, }) + selectedMarketConfig.baseSymbol } type="area" />
) } const AssetHeader = ({ asset }) => { switch (asset) { case 'BTC-PERP': return (
{icons[asset]} Bitcoin Perpetual Futures
) case 'ETH-PERP': return (
{icons[asset]} Ethereum Perpetual Futures
) case 'SOL-PERP': return (
{icons[asset]} Solana Perpetual Futures
) case 'SRM': return (
{icons[asset]} Serum Perpetual Futures
) default: return (
{icons[asset]} Bitcoin Perpetual Futures
) } }