Compute funding rate from L2 data

This commit is contained in:
Riordan Panayides 2023-04-24 19:03:11 +01:00
parent 56ca927c40
commit f751882026
1 changed files with 74 additions and 8 deletions

View File

@ -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}
</>