import useMangoStore, { mangoClient } from '../stores/useMangoStore' import { Table, Thead, Tbody, Tr, Th, Td } from 'react-super-responsive-table' import { getMarketByPublicKey, nativeI80F48ToUi, PerpAccount, PerpMarket, QUOTE_INDEX, ZERO_I80F48, } from '@blockworks-foundation/mango-client' import { useMemo } from 'react' import Button from './Button' import { notify } from '../utils/notifications' import BN from 'bn.js' import SideBadge from './SideBadge' import { useState } from 'react' import Loading from './Loading' import { usdFormatter } from '../utils' import useTradeHistory from '../hooks/useTradeHistory' function getAvgEntryPrice( mangoAccount, perpAccount, perpMarket, perpTradeHistory ) { let avgEntryPrice = '--' if (perpTradeHistory.length) { try { avgEntryPrice = perpAccount .getAverageOpenPrice(mangoAccount, perpMarket, perpTradeHistory) .toFixed(2) } catch { avgEntryPrice = '--' } } return avgEntryPrice } function getBreakEvenPrice( mangoAccount, perpAccount, perpMarket, perpTradeHistory ) { let breakEvenPrice = '--' if (perpTradeHistory.length) { try { breakEvenPrice = perpAccount .getBreakEvenPrice(mangoAccount, perpMarket, perpTradeHistory) .toFixed(2) } catch { breakEvenPrice = '--' } } return breakEvenPrice } const PositionsTable = () => { const actions = useMangoStore((s) => s.actions) const groupConfig = useMangoStore((s) => s.selectedMangoGroup.config) const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current) const mangoAccount = useMangoStore((s) => s.selectedMangoAccount.current) const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache) const allMarkets = useMangoStore((s) => s.selectedMangoGroup.markets) const [settlingPerpAcc, setSettlingPerpAcc] = useState(null) const tradeHistory = useTradeHistory() const perpMarkets = useMemo( () => mangoGroup ? groupConfig.perpMarkets.map( (m) => mangoGroup.perpMarkets[m.marketIndex] ) : [], [mangoGroup] ) const perpAccounts = mangoAccount ? groupConfig.perpMarkets.map((m) => { return { perpAccount: mangoAccount.perpAccounts[m.marketIndex], marketIndex: m.marketIndex, } }) : [] const filteredPerpAccounts = perpAccounts.filter( ({ perpAccount }) => !( perpAccount.quotePosition.eq(ZERO_I80F48) && perpAccount.basePosition.eq(new BN(0)) && perpAccount.mngoAccrued.eq(new BN(0)) ) ) const handleSettlePnl = async ( perpMarket: PerpMarket, perpAccount: PerpAccount ) => { const mangoAccount = useMangoStore.getState().selectedMangoAccount.current const mangoGroup = useMangoStore.getState().selectedMangoGroup.current const wallet = useMangoStore.getState().wallet.current const marketIndex = mangoGroup.getPerpMarketIndex(perpMarket.publicKey) setSettlingPerpAcc(perpAccount) try { const txid = await mangoClient.settlePnl( mangoGroup, mangoAccount, perpMarket, mangoGroup.rootBankAccounts[QUOTE_INDEX], mangoCache.priceCache[marketIndex].price, wallet ) actions.fetchMangoAccounts() notify({ title: 'Successfully settled PNL', description: '', txid, }) } catch (e) { console.log('Error settling PNL: ', `${e}`, `${perpAccount}`) notify({ title: 'Error settling PNL', description: e.message, txid: e.txid, type: 'error', }) } finally { setSettlingPerpAcc(null) } } return (
{filteredPerpAccounts.length ? (
{filteredPerpAccounts.map( ({ perpAccount, marketIndex }, index) => { const perpMarketInfo = perpMarkets[marketIndex] const marketConfig = getMarketByPublicKey( groupConfig, perpMarketInfo.perpMarket ) const price = mangoCache.priceCache[marketIndex].price const perpMarket = allMarkets[ marketConfig.publicKey.toString() ] as PerpMarket const perpTradeHistory = tradeHistory.filter( (t) => t.marketName === marketConfig.name ) return ( ) } )}
Market Side Position Size Notional Size Avg entry price Break-even price Unsettled PnL Edit
{marketConfig.name}
{perpMarket.baseLotsToNumber( perpAccount.basePosition )} {usdFormatter.format( perpMarket.baseLotsToNumber( perpAccount.basePosition ) * mangoGroup .getPrice(marketIndex, mangoCache) .toNumber() )} $ {getAvgEntryPrice( mangoAccount, perpAccount, perpMarket, perpTradeHistory )} $ {getBreakEvenPrice( mangoAccount, perpAccount, perpMarket, perpTradeHistory )} {usdFormatter.format( +nativeI80F48ToUi( perpAccount.getPnl(perpMarketInfo, price), marketConfig.quoteDecimals ) )}
) : (
No perp positions
)}
) } export default PositionsTable