import { ReactNode, useEffect, useMemo, useState } from 'react' import { CurrencyDollarIcon, ChartBarIcon, ChartPieIcon, ScaleIcon, } from '@heroicons/react/outline' import { nativeToUi } from '@blockworks-foundation/mango-client/lib/utils' import { groupBy } from '../utils' import useMangoStore from '../stores/useMangoStore' import useTradeHistory from '../hooks/useTradeHistory' const calculatePNL = (tradeHistory, prices, mangoGroup) => { if (!tradeHistory.length) return '0.00' const profitAndLoss = {} const groupedTrades = groupBy(tradeHistory, (trade) => trade.marketName) if (!prices.length) return '-' const assetIndex = { 'BTC/USDC': 0, 'ETH/USDC': 1, 'SOL/USDC': 2, 'SRM/USDC': 3, USDC: 4, } groupedTrades.forEach((val, key) => { profitAndLoss[key] = val.reduce( (acc, current) => (current.side === 'sell' ? current.size * -1 : current.size) + acc, 0 ) }) const totalNativeUSDC = tradeHistory.reduce((acc, current) => { const usdtAmount = current.side === 'sell' ? parseInt(current.nativeQuantityReleased) : parseInt(current.nativeQuantityPaid) * -1 return usdtAmount + acc }, 0) profitAndLoss['USDC'] = nativeToUi( totalNativeUSDC, mangoGroup.mintDecimals[assetIndex['USDC']] ) let total = 0 for (const assetName in profitAndLoss) { total = total + profitAndLoss[assetName] * prices[assetIndex[assetName]] } return total.toFixed(2) } const useMarginInfo = () => { const connection = useMangoStore((s) => s.connection.current) const selectedMangoGroup = useMangoStore((s) => s.selectedMangoGroup.current) const selectedMarginAccount = useMangoStore( (s) => s.selectedMarginAccount.current ) const tradeHistory = useTradeHistory() const tradeHistoryLength = useMemo(() => tradeHistory.length, [tradeHistory]) const [mAccountInfo, setMAccountInfo] = useState< | { label: string value: string unit: string desc: string currency: string icon: ReactNode }[] | null >(null) useEffect(() => { if (selectedMangoGroup) { selectedMangoGroup.getPrices(connection).then((prices) => { const collateralRatio = selectedMarginAccount ? selectedMarginAccount.getCollateralRatio( selectedMangoGroup, prices ) || 200 : 200 const accountEquity = selectedMarginAccount ? selectedMarginAccount.computeValue(selectedMangoGroup, prices) : 0 let leverage if (selectedMarginAccount) { leverage = accountEquity ? ( 1 / (selectedMarginAccount.getCollateralRatio( selectedMangoGroup, prices ) - 1) ).toFixed(2) : '0' } else { leverage = '0' } setMAccountInfo([ { label: 'Account Value', value: accountEquity.toFixed(2), unit: '', currency: '$', desc: 'The value of the account', icon: ( ), }, { label: 'Total PNL', value: calculatePNL(tradeHistory, prices, selectedMangoGroup), unit: '', currency: '$', desc: 'Total PNL reflects trades placed after March 15th 2021 04:00 AM UTC. Visit the Learn link in the top menu for more information.', icon: ( ), }, { label: 'Leverage', value: leverage, unit: 'x', currency: '', desc: 'Total position size divided by account value', icon: ( ), }, { // TODO: Get collaterization ratio label: 'Collateral Ratio', value: collateralRatio > 2 ? '>200' : (100 * collateralRatio).toFixed(0), unit: '%', currency: '', desc: 'The current collateral ratio', icon: ( ), }, ]) }) } }, [selectedMarginAccount, selectedMangoGroup, tradeHistoryLength]) return mAccountInfo } export default useMarginInfo