From 5011ea23659596eedea2dac939ab70ea1d5d8fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Brzezin=CC=81ski?= Date: Wed, 24 May 2023 13:50:23 +0200 Subject: [PATCH] calc tick and min order --- .../modals/CreateOpenbookMarketModal.tsx | 36 +++++++-- utils/governance/listingTools.ts | 78 +++++++++++++++---- 2 files changed, 91 insertions(+), 23 deletions(-) diff --git a/components/modals/CreateOpenbookMarketModal.tsx b/components/modals/CreateOpenbookMarketModal.tsx index 1e04f340..a3f4158f 100644 --- a/components/modals/CreateOpenbookMarketModal.tsx +++ b/components/modals/CreateOpenbookMarketModal.tsx @@ -3,6 +3,8 @@ import { ModalProps } from '../../types/modal' import Modal from '../shared/Modal' import { OPENBOOK_PROGRAM_ID } from '@blockworks-foundation/mango-v4' import useMangoGroup from 'hooks/useMangoGroup' +import { useMemo } from 'react' +import { calculateTradingParameters } from 'utils/governance/listingTools' type CreateOpenbookMarketModalProps = { quoteSymbol: string @@ -17,18 +19,36 @@ const CreateOpenbookMarketModal = ({ }: ModalProps & CreateOpenbookMarketModalProps) => { const { group } = useMangoGroup() - const baseMint = group?.banksMapByName.get(baseSymbol)?.length - ? group.banksMapByName.get(baseSymbol)![0].mint.toBase58() - : '' - const quoteMint = group?.banksMapByName.get(quoteSymbol)?.length - ? group.banksMapByName.get(quoteSymbol)![0].mint.toBase58() - : '' + const baseBank = group?.banksMapByName.get(baseSymbol)?.length + ? group.banksMapByName.get(baseSymbol)![0] + : null + const quoteBank = group?.banksMapByName.get(quoteSymbol)?.length + ? group.banksMapByName.get(quoteSymbol)![0] + : null + + const tradingParams = useMemo(() => { + if (baseBank && quoteBank) { + return calculateTradingParameters( + baseBank.uiPrice, + quoteBank.uiPrice, + baseBank.mintDecimals, + quoteBank.mintDecimals + ) + } + return { + minOrder: 0, + priceTick: 0, + baseLotSize: 0, + } + }, [baseBank, quoteBank]) return (

OpenBook Program id: {OPENBOOK_PROGRAM_ID[CLUSTER].toBase58()}

-

Base mint: {baseMint}

-

Quote mint: {quoteMint}

+

Base mint: {baseBank?.mint.toBase58()}

+

Quote mint: {quoteBank?.mint.toBase58()}

+

Minimum order size: {tradingParams.minOrder}

+

Minimum price tick size: {tradingParams.priceTick}

) } diff --git a/utils/governance/listingTools.ts b/utils/governance/listingTools.ts index 70988dcb..21df7ba9 100644 --- a/utils/governance/listingTools.ts +++ b/utils/governance/listingTools.ts @@ -167,7 +167,7 @@ export const getBestMarket = async ({ ]) const bestMarket = marketsData.sort((a, b) => b.volume24h - a.volume24h) - + console.log(bestMarket) return new PublicKey(bestMarket[0].id) } catch (e) { notify({ @@ -178,25 +178,73 @@ export const getBestMarket = async ({ } } -export const calculateTradingParameters = ( +// definitions: +// baseLots = 10 ^ baseLotExponent +// quoteLots = 10 ^ quoteLotExponent +// minOrderSize = 10^(baseLotExponent - baseDecimals) +// minOrderValue = basePrice * minOrderSize +// priceIncrement = 10^(quoteLotExponent + baseDecimals - baseLotExponent - quoteDecimals) + +// derive: baseLotExponent <= max[ basePrice * minOrderSize < 0.5] (start high -> go low until condition is met) +// baseLotExponent = 20 +// While (baseLotExponent > 0): +// minOrderSize = 10^(baseLotExponent - baseDecimals) +// minOrderValue = basePrice * minOrderSize +// if minOrderValue < 0.5: +// break; + +// Derive: quoteLotExponent <= max[ priceIncrement * basePrice / quotePrice < 0.0001 ] +// quoteLotExponent = 20 +// While (quoteLotExponent > 0): +// priceIncrement = 10^(quoteLotExponent + baseDecimals - baseLotExponent - quoteDecimals) +// priceIncrementRelative = priceIncrement * basePrice / quotePrice +// if priceIncrementRelative < 0.0002: +// break; + +export function calculateTradingParameters( basePrice: number, - quotePrice: number -) => { - // Calculate the actual price (quote price/base price) - const actualPrice = quotePrice / basePrice + quotePrice: number, + baseDecimals: number, + quoteDecimals: number +) { + const MAX_MIN_ORDER_VALUE = 0.5 + const MIN_PRICE_INCREMENT_RELATIVE = 0.0002 - // Minimum order: $1 worth of base, rounded down to the next 10^(-x) - const minOrder = - Math.floor((1 / basePrice) * Math.pow(10, 4)) / Math.pow(10, 4) + let minOrderSize = 0 + let priceIncrement = 0 + let baseLotExponent = 20 + let quoteLotExponent = 20 - // Price tick: e-4 of the current price, rounded down to the next 10^(-y) - const priceTick = Math.floor( - (actualPrice * Math.pow(10, 4)) / Math.pow(10, 4) - ) + // Calculate minimum order size + do { + minOrderSize = Math.pow(10, baseLotExponent - baseDecimals) + const minOrderValue = basePrice * minOrderSize + + if (minOrderValue < MAX_MIN_ORDER_VALUE) { + break + } + + baseLotExponent-- + } while (baseLotExponent > 0) + + // Calculate price increment + do { + priceIncrement = Math.pow( + 10, + quoteLotExponent + baseDecimals - baseLotExponent - quoteDecimals + ) + const priceIncrementRelative = (priceIncrement * basePrice) / quotePrice + + if (priceIncrementRelative < MIN_PRICE_INCREMENT_RELATIVE) { + break + } + + quoteLotExponent-- + } while (quoteLotExponent > 0) return { - minOrder: minOrder, - priceTick: priceTick, + minOrder: minOrderSize, + priceTick: priceIncrement, } }