wire up slippage estimator

This commit is contained in:
Maximilian Schneider 2021-10-01 17:32:15 +02:00
parent 28af7ef2cf
commit 2cf097976a
3 changed files with 75 additions and 33 deletions

View File

@ -31,12 +31,12 @@ export default function MarketFee() {
}
return (
<div className="block sm:flex mx-auto text-center">
<>
<div className="flex text-xs text-th-fgd-4 px-6 mt-2.5">
<div className="block sm:flex mx-auto text-center">
<div>Maker Fee: {percentFormat.format(makerFee)}</div>
<div className="hidden sm:block px-2">|</div>
<div>Taker Fee: {percentFormat.format(takerFee)}</div>
</>
</div>
</div>
)
}

View File

@ -10,7 +10,7 @@ import {
import { notify } from '../../utils/notifications'
import { calculateTradePrice, getDecimalCount } from '../../utils'
import { floorToDecimal } from '../../utils/index'
import useMangoStore from '../../stores/useMangoStore'
import useMangoStore, { Orderbook } from '../../stores/useMangoStore'
import Button from '../Button'
import TradeType from './TradeType'
import Input from '../Input'
@ -394,6 +394,51 @@ export default function AdvancedTradeForm({
)} ${marketConfig.baseSymbol} short`
: `${percentToClose(baseSize, roundedBorrows).toFixed(0)}% close position`
let priceImpact = {}
let estimatedPrice = price
if (tradeType === 'Market') {
const estimateMarketPrice = (
orderBook: Orderbook,
size: number,
side: 'buy' | 'sell'
): number => {
const orders = side === 'buy' ? orderBook.asks : orderBook.bids
let accSize = 0
let accPrice = 0
for (const [orderPrice, orderSize] of orders) {
const remainingSize = size - accSize
if (remainingSize <= orderSize) {
accSize += remainingSize
accPrice += remainingSize * orderPrice
break
}
accSize += orderSize
accPrice += orderSize * orderPrice
}
if (!accSize) {
console.error('Orderbook empty no market price available')
return markPrice
}
return accPrice / accSize
}
estimatedPrice = estimateMarketPrice(orderbook, baseSize, side)
const slippageAbs = Math.abs(estimatedPrice - markPrice)
const slippageRel = (100 * slippageAbs) / markPrice
const takerFeeRel = 0.13
const takerFeeAbs = 0.01 * takerFeeRel * estimatedPrice
priceImpact = {
slippage: [slippageAbs, slippageRel],
takerFee: [takerFeeAbs, takerFeeRel],
}
console.log('estimated price', estimatedPrice, priceImpact)
}
async function onSubmit() {
if (!price && isLimitOrder) {
notify({
@ -743,11 +788,14 @@ export default function AdvancedTradeForm({
</div>
) : null}
</div>
{tradeType === 'Market' ? (
<div className="col-span-12 md:col-span-10 md:col-start-3 pt-2">
<EstPriceImpact />
</div>
) : null}
<div className="col-span-12 md:col-span-10 md:col-start-3 pt-2">
{tradeType === 'Market' ? (
<EstPriceImpact priceImpact={priceImpact} />
) : (
<MarketFee />
)}
</div>
<div className={`flex pt-4`}>
{ipAllowed ? (
<Button

View File

@ -2,19 +2,13 @@ import { InformationCircleIcon } from '@heroicons/react/outline'
import Tippy from '@tippyjs/react'
import 'tippy.js/animations/scale.css'
const priceImpact = {
slippage: [10.1, 0.2],
makerFee: [0.0, 0.0],
takerFee: [2.3, 0.13],
}
const EstPriceImpact = () => {
const priceImpactTotal = Object.values(priceImpact).reduce(
(t, c) => t + c[0],
0
)
const priceImpactPercent =
Object.values(priceImpact).reduce((t, c) => t + c[1], 0) / 3
const EstPriceImpact = ({
priceImpact,
}: {
priceImpact: { slippage: number[]; takerFee: number[] }
}) => {
const priceImpactAbs = priceImpact.slippage[0] + priceImpact.takerFee[0]
const priceImpactRel = priceImpact.slippage[1] + priceImpact.takerFee[1]
return (
<div
className={`border-t border-th-bkg-4 flex items-center justify-center mt-2 pt-2 text-th-fgd-3 text-xs`}
@ -22,16 +16,16 @@ const EstPriceImpact = () => {
Est. Price Impact:
<span
className={`font-bold ml-2 ${
priceImpactPercent <= 0.5
priceImpactRel <= 0.5
? 'text-th-green'
: priceImpactPercent > 0.5 && priceImpactPercent <= 2
: priceImpactRel > 0.5 && priceImpactRel <= 1
? 'text-th-orange'
: 'text-th-red'
}`}
>
${priceImpactTotal.toFixed(2)}
${priceImpactAbs.toFixed(2)}
<span className="mx-2 text-th-fgd-4">|</span>
{priceImpactPercent.toFixed(2)}%
{priceImpactRel.toFixed(2)}%
</span>
<Tippy
animation="scale"
@ -47,25 +41,25 @@ const EstPriceImpact = () => {
<div className="flex justify-between">
Est. Slippage:
<span className="text-th-fgd-1">
${priceImpact.slippage[0]}
${priceImpact.slippage[0].toFixed(2)}
<span className="px-1 text-th-fgd-4">|</span>
{priceImpact.slippage[1]}%
{priceImpact.slippage[1].toFixed(2)}%
</span>
</div>
<div className="flex justify-between">
{/* <div className="flex justify-between">
Maker Fee:
<span className="text-th-fgd-1">
${priceImpact.makerFee[0]}
<span className="px-1 text-th-fgd-4">|</span>
{priceImpact.makerFee[1]}%
{priceImpact.makerFee[1].toFixed(2)}%
</span>
</div>
</div> */}
<div className="flex justify-between">
Taker Fee:
<span className="text-th-fgd-1">
${priceImpact.takerFee[0]}
${priceImpact.takerFee[0].toFixed(2)}
<span className="px-1 text-th-fgd-4">|</span>
{priceImpact.takerFee[1]}%
{priceImpact.takerFee[1].toFixed(2)}%
</span>
</div>
</div>