Compute funding rate from L2 data
This commit is contained in:
parent
56ca927c40
commit
f751882026
|
@ -8,6 +8,7 @@ import { MANGO_DATA_API_URL } from 'utils/constants'
|
|||
import Tooltip from '@components/shared/Tooltip'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import mangoStore from '@store/mangoStore'
|
||||
import { OrderbookL2 } from 'types'
|
||||
|
||||
const fetchFundingRate = async (groupPk: string | undefined) => {
|
||||
const res = await fetch(
|
||||
|
@ -38,6 +39,57 @@ export const formatFunding = Intl.NumberFormat('en', {
|
|||
style: 'percent',
|
||||
})
|
||||
|
||||
function getImpactPriceL2(
|
||||
bookside: number[][],
|
||||
baseDepth: number
|
||||
): number | undefined {
|
||||
let total = 0
|
||||
for (const level of bookside) {
|
||||
total += level[1]
|
||||
if (total >= baseDepth) {
|
||||
return level[0]
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
function getInstantaneousFundingRateL2(
|
||||
market: PerpMarket,
|
||||
orderbook: OrderbookL2
|
||||
) {
|
||||
const MIN_FUNDING = market.minFunding.toNumber()
|
||||
const MAX_FUNDING = market.maxFunding.toNumber()
|
||||
|
||||
const bid = getImpactPriceL2(
|
||||
orderbook.bids,
|
||||
market.baseLotsToUi(market.impactQuantity)
|
||||
)
|
||||
console.log(bid)
|
||||
const ask = getImpactPriceL2(
|
||||
orderbook.asks,
|
||||
market.baseLotsToUi(market.impactQuantity)
|
||||
)
|
||||
console.log(ask)
|
||||
const indexPrice = market._uiPrice
|
||||
|
||||
let funding
|
||||
if (bid !== undefined && ask !== undefined) {
|
||||
const bookPrice = (bid + ask) / 2
|
||||
funding = Math.min(
|
||||
Math.max(bookPrice / indexPrice - 1, MIN_FUNDING),
|
||||
MAX_FUNDING
|
||||
)
|
||||
} else if (bid !== undefined) {
|
||||
funding = MAX_FUNDING
|
||||
} else if (ask !== undefined) {
|
||||
funding = MIN_FUNDING
|
||||
} else {
|
||||
funding = 0
|
||||
}
|
||||
|
||||
return funding
|
||||
}
|
||||
|
||||
const PerpFundingRate = () => {
|
||||
const { selectedMarket } = useSelectedMarket()
|
||||
const rate = usePerpFundingRate()
|
||||
|
@ -45,6 +97,7 @@ const PerpFundingRate = () => {
|
|||
|
||||
const bids = mangoStore((s) => s.selectedMarket.bidsAccount)
|
||||
const asks = mangoStore((s) => s.selectedMarket.asksAccount)
|
||||
const orderbook = mangoStore((s) => s.selectedMarket.orderbook)
|
||||
|
||||
const fundingRate = useMemo(() => {
|
||||
if (rate.isSuccess && selectedMarket instanceof PerpMarket) {
|
||||
|
@ -56,6 +109,25 @@ const PerpFundingRate = () => {
|
|||
}
|
||||
}, [rate, selectedMarket])
|
||||
|
||||
const instantaneousRate = useMemo(() => {
|
||||
if (!(selectedMarket instanceof PerpMarket)) return undefined
|
||||
if (bids instanceof BookSide && asks instanceof BookSide) {
|
||||
return selectedMarket.getInstantaneousFundingRateUi(bids, asks).toFixed(4)
|
||||
}
|
||||
|
||||
console.log(orderbook.bids.length, orderbook.asks.length)
|
||||
if (orderbook.asks.length && orderbook.bids.length) {
|
||||
console.log(
|
||||
getInstantaneousFundingRateL2(selectedMarket, orderbook).toFixed(4)
|
||||
)
|
||||
return (
|
||||
getInstantaneousFundingRateL2(selectedMarket, orderbook) * 100
|
||||
).toFixed(4)
|
||||
}
|
||||
|
||||
return undefined
|
||||
}, [orderbook, bids, asks, selectedMarket])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="ml-6 flex-col whitespace-nowrap">
|
||||
|
@ -76,15 +148,9 @@ const PerpFundingRate = () => {
|
|||
{formatFunding.format(fundingRate * 8760)}.
|
||||
</div>
|
||||
) : null}
|
||||
{selectedMarket instanceof PerpMarket &&
|
||||
bids instanceof BookSide &&
|
||||
asks instanceof BookSide ? (
|
||||
{instantaneousRate ? (
|
||||
<div className="mt-1">
|
||||
The latest instantaneous rate is{' '}
|
||||
{selectedMarket
|
||||
.getInstantaneousFundingRateUi(bids, asks)
|
||||
.toFixed(4)}
|
||||
%
|
||||
The latest instantaneous rate is {instantaneousRate}%
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
|
|
Loading…
Reference in New Issue