add market close to positions table (#365)

* add market close to positions table

* fix variable reference

* use secondary buttons
This commit is contained in:
saml33 2022-07-20 20:19:59 +10:00 committed by GitHub
parent dd1c0fab1d
commit f226e210ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 90 additions and 41 deletions

View File

@ -1,6 +1,10 @@
import { FunctionComponent, useState } from 'react'
import useMangoStore from '../stores/useMangoStore'
import { PerpMarket, ZERO_BN } from '@blockworks-foundation/mango-client'
import {
MarketConfig,
PerpMarket,
ZERO_BN,
} from '@blockworks-foundation/mango-client'
import Button, { LinkButton } from './Button'
import { notify } from '../utils/notifications'
import Loading from './Loading'
@ -12,26 +16,26 @@ import { useWallet } from '@solana/wallet-adapter-react'
interface MarketCloseModalProps {
onClose: () => void
isOpen: boolean
market: PerpMarket
marketIndex: number
position: {
marketConfig: MarketConfig
perpMarket: PerpMarket
}
}
const MarketCloseModal: FunctionComponent<MarketCloseModalProps> = ({
onClose,
isOpen,
market,
marketIndex,
position,
}) => {
const { t } = useTranslation('common')
const [submitting, setSubmitting] = useState(false)
const { wallet } = useWallet()
const actions = useMangoStore((s) => s.actions)
const config = useMangoStore.getState().selectedMarket.config
const { marketConfig, perpMarket } = position
async function handleMarketClose() {
const mangoAccount = useMangoStore.getState().selectedMangoAccount.current
const mangoGroup = useMangoStore.getState().selectedMangoGroup.current
const marketConfig = useMangoStore.getState().selectedMarket.config
const mangoClient = useMangoStore.getState().connection.client
const askInfo =
useMangoStore.getState().accountInfos[marketConfig.asksKey.toString()]
@ -51,11 +55,11 @@ const MarketCloseModal: FunctionComponent<MarketCloseModalProps> = ({
setSubmitting(true)
try {
const perpAccount = mangoAccount.perpAccounts[marketIndex]
const perpAccount = mangoAccount.perpAccounts[marketConfig.marketIndex]
const side = perpAccount.basePosition.gt(ZERO_BN) ? 'sell' : 'buy'
// send a large size to ensure we are reducing the entire position
const size =
Math.abs(market.baseLotsToNumber(perpAccount.basePosition)) * 2
Math.abs(perpMarket.baseLotsToNumber(perpAccount.basePosition)) * 2
// hard coded for now; market orders are very dangerous and fault prone
const maxSlippage: number | undefined = 0.025
@ -63,7 +67,7 @@ const MarketCloseModal: FunctionComponent<MarketCloseModalProps> = ({
const txid = await mangoClient.placePerpOrder2(
mangoGroup,
mangoAccount,
market,
perpMarket,
wallet?.adapter,
side,
referencePrice * (1 + (side === 'buy' ? 1 : -1) * maxSlippage),
@ -93,9 +97,9 @@ const MarketCloseModal: FunctionComponent<MarketCloseModalProps> = ({
return (
<Modal onClose={onClose} isOpen={isOpen}>
<div className="pb-2 text-lg text-th-fgd-1">
{t('close-confirm', { config_name: config.name })}
</div>
<h2 className="mb-2">
{t('close-confirm', { config_name: marketConfig.name })}
</h2>
<div className="pb-6 text-th-fgd-3">{t('price-expect')}</div>
<div className="flex items-center">
<Button onClick={handleMarketClose}>

View File

@ -390,6 +390,7 @@ export default function MarketPosition() {
<Button
onClick={() => setShowMarketCloseModal(true)}
className="mt-2.5 w-full"
primary={false}
>
<span>{t('market-close')}</span>
</Button>
@ -399,8 +400,7 @@ export default function MarketPosition() {
<MarketCloseModal
isOpen={showMarketCloseModal}
onClose={handleCloseWarning}
market={selectedMarket}
marketIndex={marketIndex}
position={{ marketConfig: marketConfig, perpMarket: selectedMarket }}
/>
) : null}
</>

View File

@ -143,7 +143,7 @@ const DesktopTable = ({
)} $${order.triggerPrice.toFixed(2)}`}
</Td>
<Td className="w-[14.286%]">
<div className={`flex justify-end space-x-3`}>
<div className={`flex justify-end space-x-2`}>
{editOrderIndex !== index ? (
<>
{!order.perpTrigger ? (
@ -157,6 +157,7 @@ const DesktopTable = ({
<Button
onClick={() => handleCancelOrder(order, market.account)}
className="-my-1 h-7 pt-0 pb-0 pl-3 pr-3 text-xs"
primary={false}
>
{cancelledOrderId + '' === order.orderId + '' ? (
<Loading />
@ -170,6 +171,7 @@ const DesktopTable = ({
<Button
onClick={() => handleCancelAllOrders(market.account)}
className="-my-1 h-7 pt-0 pb-0 pl-3 pr-3 text-xs text-th-red"
primary={false}
>
{t('cancel-all') + ' ' + market.config.name}
</Button>
@ -335,9 +337,7 @@ const MobileTable = ({
/>
</div>
<Button
className={`${
index % 2 === 0 ? 'bg-th-bkg-4' : 'bg-th-bkg-3'
} mt-4 h-8 pt-0 pb-0 pl-3 pr-3 text-xs`}
className={`mt-4 h-8 pt-0 pb-0 pl-3 pr-3 text-xs`}
onClick={() =>
handleModifyOrder(
order,

View File

@ -5,7 +5,7 @@ import { useTranslation } from 'next-i18next'
import { ExclamationIcon } from '@heroicons/react/solid'
import { ZERO_I80F48 } from '@blockworks-foundation/mango-client'
import useMangoStore from '../stores/useMangoStore'
import { LinkButton } from '../components/Button'
import Button, { LinkButton } from '../components/Button'
import { useViewport } from '../hooks/useViewport'
import { breakpoints } from './TradePageGrid'
import { ExpandableRow, Table, Td, Th, TrBody, TrHead } from './TableElements'
@ -33,6 +33,7 @@ const PositionsTable: React.FC = () => {
const { t } = useTranslation('common')
const [showShareModal, setShowShareModal] = useState(false)
const [showMarketCloseModal, setShowMarketCloseModal] = useState(false)
const [positionToClose, setPositionToClose] = useState<any>(null)
const [positionToShare, setPositionToShare] = useState<any>(null)
const [settleSinglePos, setSettleSinglePos] = useState(null)
@ -61,8 +62,20 @@ const PositionsTable: React.FC = () => {
}
}, [openPositions])
useEffect(() => {
if (positionToClose) {
const updatedPosition = openPositions.find(
(p) => p.marketConfig === positionToClose.marketConfig
)
if (updatedPosition) {
setPositionToClose(updatedPosition)
}
}
}, [openPositions])
const handleCloseWarning = useCallback(() => {
setShowMarketCloseModal(false)
setPositionToClose(null)
}, [])
const handleSizeClick = (size, indexPrice) => {
@ -87,6 +100,11 @@ const PositionsTable: React.FC = () => {
setShowShareModal(true)
}
const handleShowMarketCloseModal = (position) => {
setPositionToClose(position)
setShowMarketCloseModal(true)
}
const handleSettlePnl = async (perpMarket, perpAccount, index) => {
if (wallet) {
setSettleSinglePos(index)
@ -177,7 +195,6 @@ const PositionsTable: React.FC = () => {
<Th>{t('market')}</Th>
<Th>{t('side')}</Th>
<Th>{t('position-size')}</Th>
<Th>{t('notional-size')}</Th>
<Th>{t('average-entry')}</Th>
<Th>{t('break-even')}</Th>
<Th>{t('estimated-liq-price')}</Th>
@ -260,15 +277,18 @@ const PositionsTable: React.FC = () => {
handleSizeClick(basePosition, indexPrice)
}
>
{`${basePositionUi} ${marketConfig.baseSymbol}`}
{`${basePositionUi} (${formatUsdValue(
Math.abs(notionalSize)
)})`}
</span>
) : (
<span>
{`${basePositionUi} ${marketConfig.baseSymbol}`}
{`${basePositionUi} (${formatUsdValue(
Math.abs(notionalSize)
)})`}
</span>
)}
</Td>
<Td>{formatUsdValue(Math.abs(notionalSize))}</Td>
<Td>
{avgEntryPrice
? formatUsdValue(avgEntryPrice)
@ -322,23 +342,28 @@ const PositionsTable: React.FC = () => {
)}
</Td>
<Td>
<LinkButton
onClick={() =>
handleShowShare(openPositions[index])
}
disabled={!avgEntryPrice ? true : false}
>
<TwitterIcon className="h-4 w-4" />
</LinkButton>
<div className="flex items-center space-x-3">
<Button
className="h-8 pt-0 pb-0 pl-3 pr-3 text-xs"
primary={false}
onClick={() =>
handleShowMarketCloseModal(
openPositions[index]
)
}
>
{t('market-close')}
</Button>
<LinkButton
onClick={() =>
handleShowShare(openPositions[index])
}
disabled={!avgEntryPrice ? true : false}
>
<TwitterIcon className="h-4 w-4" />
</LinkButton>
</div>
</Td>
{showMarketCloseModal ? (
<MarketCloseModal
isOpen={showMarketCloseModal}
onClose={handleCloseWarning}
market={perpMarket}
marketIndex={marketConfig.marketIndex}
/>
) : null}
</TrBody>
)
}
@ -489,6 +514,19 @@ const PositionsTable: React.FC = () => {
? usdFormatter(liquidationPrice)
: 'N/A'}
</div>
<div className="col-span-2">
<Button
className="w-full"
primary={false}
onClick={() =>
handleShowMarketCloseModal(
openPositions[index]
)
}
>
{t('market-close')}
</Button>
</div>
</div>
}
/>
@ -513,6 +551,13 @@ const PositionsTable: React.FC = () => {
position={positionToShare!}
/>
) : null}
{showMarketCloseModal ? (
<MarketCloseModal
isOpen={showMarketCloseModal}
onClose={handleCloseWarning}
position={positionToClose!}
/>
) : null}
</div>
)
}

View File

@ -69,6 +69,7 @@ const RedeemButtons: React.FC = () => {
<Button
className="flex h-7 items-center justify-center pt-0 pb-0 pl-3 pr-3 text-xs"
onClick={handleSettleAll}
primary={false}
>
{settling ? <Loading /> : t('redeem-all')}
</Button>

View File

@ -5,7 +5,6 @@ import {
createRef,
useState,
} from 'react'
// import { getWeights, MarketConfig } from '@blockworks-foundation/mango-client'
import { MarketConfig } from '@blockworks-foundation/mango-client'
import useMangoStore from '../stores/useMangoStore'