import { useCallback, useState } from 'react' import useMangoStore from '../stores/useMangoStore' import { Table, Thead, Tbody, Tr, Th, Td } from 'react-super-responsive-table' import { getMarketByPublicKey, PerpMarket, ZERO_BN, } from '@blockworks-foundation/mango-client' import SideBadge from './SideBadge' import { formatUsdValue, usdFormatter } from '../utils' import useTradeHistory from '../hooks/useTradeHistory' import usePerpPositions from '../hooks/usePerpPositions' import MarketCloseModal from './MarketCloseModal' export function getAvgEntryPrice( mangoAccount, perpAccount, perpMarket, perpTradeHistory ) { let avgEntryPrice = '--' if (perpTradeHistory.length) { try { avgEntryPrice = formatUsdValue( perpAccount.getAverageOpenPrice( mangoAccount, perpMarket, perpTradeHistory ) ) } catch { avgEntryPrice = '--' } } return avgEntryPrice } export function getBreakEvenPrice( mangoAccount, perpAccount, perpMarket, perpTradeHistory ) { let breakEvenPrice = '--' if (perpTradeHistory.length) { try { breakEvenPrice = formatUsdValue( perpAccount.getBreakEvenPrice( mangoAccount, perpMarket, perpTradeHistory ) ) } catch { breakEvenPrice = '--' } } return breakEvenPrice } const PositionsTable = () => { 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 [showMarketCloseModal, setShowMarketCloseModal] = useState(false) const tradeHistory = useTradeHistory() const setMangoStore = useMangoStore((s) => s.set) const perpPositions = usePerpPositions() const handleCloseWarning = useCallback(() => { setShowMarketCloseModal(false) }, []) const handleSizeClick = (size) => { setMangoStore((state) => { state.tradeForm.baseSize = size }) } return (
{perpPositions.length ? (
{perpPositions.map(({ perpAccount, marketIndex }, index) => { const perpMarketInfo = mangoGroup.perpMarkets[marketIndex] const marketConfig = getMarketByPublicKey( groupConfig, perpMarketInfo.perpMarket ) const perpMarket = allMarkets[ perpMarketInfo.perpMarket.toString() ] as PerpMarket const perpTradeHistory = tradeHistory.filter( (t) => t.marketName === marketConfig.name ) let breakEvenPrice try { breakEvenPrice = perpAccount.getBreakEvenPrice( mangoAccount, perpMarket, perpTradeHistory ) } catch (e) { breakEvenPrice = null } const pnl = breakEvenPrice !== null ? perpMarket.baseLotsToNumber( perpAccount.basePosition ) * (mangoGroup .getPrice(marketIndex, mangoCache) .toNumber() - parseFloat(breakEvenPrice)) : null return ( {showMarketCloseModal ? ( ) : null} ) })}
Market Side Position size Notional size Avg entry price Break-even price PnL
{marketConfig.name}
{!perpAccount.basePosition.eq(ZERO_BN) ? ( ) : ( '-' )} {perpAccount && Math.abs( perpMarket.baseLotsToNumber( perpAccount.basePosition ) ) > 0 ? ( handleSizeClick( Math.abs( perpMarket.baseLotsToNumber( perpAccount.basePosition ) ) ) } > {`${Math.abs( perpMarket.baseLotsToNumber( perpAccount.basePosition ) )} ${marketConfig.baseSymbol}`} ) : ( `0 ${marketConfig.baseSymbol}` )} {usdFormatter( Math.abs( perpMarket.baseLotsToNumber( perpAccount.basePosition ) * mangoGroup .getPrice(marketIndex, mangoCache) .toNumber() ) )} {getAvgEntryPrice( mangoAccount, perpAccount, perpMarket, perpTradeHistory )} {getBreakEvenPrice( mangoAccount, perpAccount, perpMarket, perpTradeHistory )} = 0 ? 'text-th-green' : 'text-th-red' }`} > {pnl !== null ? usdFormatter(pnl) : '--'}
) : (
No perp positions
)}
) } export default PositionsTable