mango-ui-v3/hooks/usePerpPositions.tsx

137 lines
3.8 KiB
TypeScript
Raw Normal View History

2021-08-22 05:45:10 -07:00
import useMangoStore from '../stores/useMangoStore'
import BN from 'bn.js'
import {
MangoAccount,
MangoCache,
MangoGroup,
nativeI80F48ToUi,
PerpMarket,
PerpMarketConfig,
} from '@blockworks-foundation/mango-client'
import useTradeHistory from './useTradeHistory'
2021-12-05 17:13:23 -08:00
import {
mangoCacheSelector,
mangoGroupConfigSelector,
mangoGroupSelector,
marketsSelector,
} from '../stores/selectors'
2022-01-27 19:57:18 -08:00
import { useEffect } from 'react'
import useMangoAccount from './useMangoAccount'
export const collectPerpPosition = (
mangoAccount: MangoAccount,
mangoGroup: MangoGroup,
mangoCache: MangoCache,
marketConfig: PerpMarketConfig,
perpMarket: PerpMarket,
tradeHistory: any
) => {
if (
!mangoAccount ||
!mangoGroup ||
!mangoCache ||
!perpMarket ||
!tradeHistory
)
return {}
2022-01-27 19:57:18 -08:00
const perpMarketInfo = mangoGroup.perpMarkets[marketConfig.marketIndex]
const perpAccount = mangoAccount.perpAccounts[marketConfig.marketIndex]
let avgEntryPrice = 0,
breakEvenPrice = 0
try {
const perpTradeHistory = tradeHistory.filter(
(t) => t.marketName === marketConfig.name
)
avgEntryPrice = perpAccount
.getAverageOpenPrice(mangoAccount, perpMarket, perpTradeHistory)
.toNumber()
breakEvenPrice = perpAccount
.getBreakEvenPrice(mangoAccount, perpMarket, perpTradeHistory)
.toNumber()
} catch (e) {
2022-01-27 19:57:18 -08:00
// console.error(e)
}
2022-01-12 14:46:41 -08:00
const basePosition = perpMarket?.baseLotsToNumber(perpAccount.basePosition)
2022-01-27 19:57:18 -08:00
const indexPrice = mangoGroup
.getPrice(marketConfig.marketIndex, mangoCache)
.toNumber()
const notionalSize = Math.abs(basePosition * indexPrice)
const unrealizedPnl = basePosition * (indexPrice - breakEvenPrice)
const unsettledPnl = +nativeI80F48ToUi(
perpAccount.getPnl(
2022-01-27 19:57:18 -08:00
perpMarketInfo,
mangoCache.perpMarketCache[marketConfig.marketIndex],
mangoCache.priceCache[marketConfig.marketIndex].price
),
marketConfig.quoteDecimals
).toNumber()
return {
perpMarketInfo,
marketConfig,
perpMarket,
perpAccount,
basePosition,
indexPrice,
avgEntryPrice,
breakEvenPrice,
notionalSize,
unrealizedPnl,
unsettledPnl,
}
}
2021-08-22 05:45:10 -07:00
const usePerpPositions = () => {
2022-01-27 19:57:18 -08:00
const setMangoStore = useMangoStore((s) => s.set)
const { mangoAccount } = useMangoAccount()
2021-12-05 17:13:23 -08:00
const groupConfig = useMangoStore(mangoGroupConfigSelector)
const mangoGroup = useMangoStore(mangoGroupSelector)
const mangoCache = useMangoStore(mangoCacheSelector)
const allMarkets = useMangoStore(marketsSelector)
const tradeHistory = useTradeHistory()
2021-08-22 05:45:10 -07:00
2022-01-27 19:57:18 -08:00
useEffect(() => {
if (mangoAccount) {
const perpAccounts = mangoAccount
? groupConfig.perpMarkets.map((m) =>
collectPerpPosition(
mangoAccount,
mangoGroup,
mangoCache,
m,
allMarkets[m.publicKey.toBase58()] as PerpMarket,
tradeHistory
)
)
: []
2022-01-27 19:57:18 -08:00
const openPerpPositions = perpAccounts.filter(
({ perpAccount }) =>
perpAccount?.basePosition && !perpAccount.basePosition.eq(new BN(0))
)
2021-08-22 05:45:10 -07:00
2022-01-27 19:57:18 -08:00
setMangoStore((state) => {
state.selectedMangoAccount.perpAccounts = perpAccounts
state.selectedMangoAccount.openPerpPositions = openPerpPositions
if (
openPerpPositions.length !==
state.selectedMangoAccount.totalOpenPerpPositions
) {
state.selectedMangoAccount.totalOpenPerpPositions =
openPerpPositions.length
}
state.selectedMangoAccount.unsettledPerpPositions = perpAccounts.filter(
({ perpAccount, unsettledPnl }) =>
perpAccount?.basePosition?.eq(new BN(0)) && unsettledPnl != 0
)
})
}
}, [mangoAccount, mangoCache])
2021-08-22 05:45:10 -07:00
}
export default usePerpPositions