From 6f5867ecae78a06253d9a754802385f83d0d6a73 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Tue, 7 Jan 2025 17:33:30 +0100 Subject: [PATCH 1/5] add buy, sell and global price --- .../RangeSelector/RangeSelector.tsx | 40 +++++++++++++++++-- .../NewPosition/RangeSelector/style.ts | 4 ++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/components/NewPosition/RangeSelector/RangeSelector.tsx b/src/components/NewPosition/RangeSelector/RangeSelector.tsx index c28ed25c..9c0dc77a 100644 --- a/src/components/NewPosition/RangeSelector/RangeSelector.tsx +++ b/src/components/NewPosition/RangeSelector/RangeSelector.tsx @@ -19,6 +19,7 @@ import { } from '@utils/utils' import { getMaxTick, getMinTick } from '@invariant-labs/sdk/lib/utils' import { Button, Grid, Tooltip, Typography } from '@mui/material' +import { colors } from '@static/theme' export interface IRangeSelector { data: PlotTickData[] midPrice: TickPlotPositionData @@ -415,9 +416,42 @@ export const RangeSelector: React.FC = ({ Price range {poolIndex !== null && ( - - {formatNumber(midPrice.x, false, 4)} {tokenBSymbol} per {tokenASymbol} - + <> +
+ + {formatNumber(midPrice.x, false, 4)} {tokenBSymbol} per {tokenASymbol} + +
+
+ {globalPrice && ( + + {formatNumber(globalPrice, false, 4)} {tokenBSymbol} per {tokenASymbol} + + )} +
+
+ {tokenAPriceData?.lastBuyPrice && ( + + {formatNumber(tokenAPriceData?.lastBuyPrice, false, 4)} {tokenBSymbol} per{' '} + {tokenASymbol} + + )} +
+
+ {tokenAPriceData?.lastSellPrice && ( + + {formatNumber(tokenAPriceData?.lastSellPrice, false, 4)} {tokenBSymbol} per{' '} + {tokenASymbol} + + )} +
+ )}
diff --git a/src/components/NewPosition/RangeSelector/style.ts b/src/components/NewPosition/RangeSelector/style.ts index d1676bb8..49b0a3a7 100644 --- a/src/components/NewPosition/RangeSelector/style.ts +++ b/src/components/NewPosition/RangeSelector/style.ts @@ -256,6 +256,10 @@ const useStyles = makeStyles()(theme => { ...typography.caption2, textAlign: 'right', marginLeft: 4 + }, + priceBlock: { + height: 17, + margin: 0 } } }) From aebd936dbae9c5326967478ee710a9deea6d1d96 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Tue, 7 Jan 2025 17:40:08 +0100 Subject: [PATCH 2/5] update prices --- .../NewPosition/RangeSelector/RangeSelector.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/NewPosition/RangeSelector/RangeSelector.tsx b/src/components/NewPosition/RangeSelector/RangeSelector.tsx index 9c0dc77a..60fe2116 100644 --- a/src/components/NewPosition/RangeSelector/RangeSelector.tsx +++ b/src/components/NewPosition/RangeSelector/RangeSelector.tsx @@ -419,7 +419,7 @@ export const RangeSelector: React.FC = ({ <>
- {formatNumber(midPrice.x, false, 4)} {tokenBSymbol} per {tokenASymbol} + {formatNumber(midPrice.x, false, 4)} {tokenBSymbol}/{tokenASymbol}
@@ -427,7 +427,7 @@ export const RangeSelector: React.FC = ({ - {formatNumber(globalPrice, false, 4)} {tokenBSymbol} per {tokenASymbol} + {formatNumber(globalPrice, false, 4)} {tokenBSymbol}/{tokenASymbol} )}
@@ -436,7 +436,7 @@ export const RangeSelector: React.FC = ({ - {formatNumber(tokenAPriceData?.lastBuyPrice, false, 4)} {tokenBSymbol} per{' '} + {formatNumber(tokenAPriceData?.lastBuyPrice, false, 4)} {tokenBSymbol}/ {tokenASymbol} )} @@ -446,7 +446,7 @@ export const RangeSelector: React.FC = ({ - {formatNumber(tokenAPriceData?.lastSellPrice, false, 4)} {tokenBSymbol} per{' '} + {formatNumber(tokenAPriceData?.lastSellPrice, false, 4)} {tokenBSymbol}/ {tokenASymbol} )} From ab44fa983ce3d05a096e1e308d65ffd0ce79fa31 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Tue, 7 Jan 2025 17:43:04 +0100 Subject: [PATCH 3/5] reverse price --- .../NewPosition/RangeSelector/RangeSelector.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/NewPosition/RangeSelector/RangeSelector.tsx b/src/components/NewPosition/RangeSelector/RangeSelector.tsx index 60fe2116..c97e525e 100644 --- a/src/components/NewPosition/RangeSelector/RangeSelector.tsx +++ b/src/components/NewPosition/RangeSelector/RangeSelector.tsx @@ -419,7 +419,7 @@ export const RangeSelector: React.FC = ({ <>
- {formatNumber(midPrice.x, false, 4)} {tokenBSymbol}/{tokenASymbol} + {formatNumber(midPrice.x, false, 4)} {tokenASymbol}/{tokenBSymbol}
@@ -427,7 +427,7 @@ export const RangeSelector: React.FC = ({ - {formatNumber(globalPrice, false, 4)} {tokenBSymbol}/{tokenASymbol} + {formatNumber(globalPrice, false, 4)} {tokenASymbol}/{tokenBSymbol} )}
@@ -436,8 +436,8 @@ export const RangeSelector: React.FC = ({ - {formatNumber(tokenAPriceData?.lastBuyPrice, false, 4)} {tokenBSymbol}/ - {tokenASymbol} + {formatNumber(tokenAPriceData?.lastBuyPrice, false, 4)} {tokenASymbol}/ + {tokenBSymbol} )} @@ -446,8 +446,8 @@ export const RangeSelector: React.FC = ({ - {formatNumber(tokenAPriceData?.lastSellPrice, false, 4)} {tokenBSymbol}/ - {tokenASymbol} + {formatNumber(tokenAPriceData?.lastSellPrice, false, 4)} {tokenASymbol}/ + {tokenBSymbol} )} From ea6d30f76e9ef9ec4b0fa1c94c84106af388aefa Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Tue, 7 Jan 2025 18:52:02 +0100 Subject: [PATCH 4/5] percentage price of sell and buy --- .../RangeSelector/RangeSelector.tsx | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/components/NewPosition/RangeSelector/RangeSelector.tsx b/src/components/NewPosition/RangeSelector/RangeSelector.tsx index c97e525e..d79e7e81 100644 --- a/src/components/NewPosition/RangeSelector/RangeSelector.tsx +++ b/src/components/NewPosition/RangeSelector/RangeSelector.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from 'react' +import React, { useState, useEffect, useRef, useMemo } from 'react' import PriceRangePlot, { TickPlotPositionData } from '@components/PriceRangePlot/PriceRangePlot' import RangeInput from '@components/Inputs/RangeInput/RangeInput' import activeLiquidity from '@static/svg/activeLiquidity.svg' @@ -409,6 +409,28 @@ export const RangeSelector: React.FC = ({ autoZoomHandler(leftRange, rightRange, true) }, [tokenASymbol, tokenBSymbol]) + const buyPercentageDifference = useMemo(() => { + if ( + tokenAPriceData?.buyPrice === undefined || + globalPrice === undefined || + tokenBPriceData?.price === undefined + ) { + return + } + return ((tokenAPriceData.buyPrice / tokenBPriceData?.price - globalPrice) / globalPrice) * 100 + }, [tokenAPriceData?.buyPrice, globalPrice, tokenBPriceData?.price]) + + const sellPercentageDifference = useMemo(() => { + if ( + tokenAPriceData?.sellPrice === undefined || + globalPrice === undefined || + tokenBPriceData?.price === undefined + ) { + return + } + return ((tokenAPriceData.sellPrice / tokenBPriceData?.price - globalPrice) / globalPrice) * 100 + }, [tokenAPriceData?.sellPrice, globalPrice, tokenBPriceData?.price]) + return ( @@ -432,22 +454,22 @@ export const RangeSelector: React.FC = ({ )}
- {tokenAPriceData?.lastBuyPrice && ( + {buyPercentageDifference && ( - {formatNumber(tokenAPriceData?.lastBuyPrice, false, 4)} {tokenASymbol}/ - {tokenBSymbol} + {buyPercentageDifference < 0 ? '-' : '+'} + {formatNumber(Math.abs(buyPercentageDifference), false, 2)}% )}
- {tokenAPriceData?.lastSellPrice && ( + {sellPercentageDifference && ( - {formatNumber(tokenAPriceData?.lastSellPrice, false, 4)} {tokenASymbol}/ - {tokenBSymbol} + {sellPercentageDifference < 0 ? '-' : '+'}{' '} + {formatNumber(Math.abs(sellPercentageDifference), false, 2)}% )}
From c4fb50732662aeb25f384dec709e9093cf99d379 Mon Sep 17 00:00:00 2001 From: Piotr Matlak Date: Wed, 8 Jan 2025 08:56:41 +0100 Subject: [PATCH 5/5] add chart prices on position details --- .../NewPosition/RangeSelector/style.ts | 2 +- .../SinglePositionPlot/SinglePositionPlot.tsx | 68 ++++++++++++++++++- .../SinglePositionPlot/style.ts | 13 +++- 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/components/NewPosition/RangeSelector/style.ts b/src/components/NewPosition/RangeSelector/style.ts index 49b0a3a7..d938b9d1 100644 --- a/src/components/NewPosition/RangeSelector/style.ts +++ b/src/components/NewPosition/RangeSelector/style.ts @@ -15,7 +15,7 @@ const useStyles = makeStyles()(theme => { } }, headerContainer: { - marginBottom: 12 + paddingBottom: 12 }, header: { ...typography.heading4, diff --git a/src/components/PositionDetails/SinglePositionPlot/SinglePositionPlot.tsx b/src/components/PositionDetails/SinglePositionPlot/SinglePositionPlot.tsx index f06cfaf4..729c1654 100644 --- a/src/components/PositionDetails/SinglePositionPlot/SinglePositionPlot.tsx +++ b/src/components/PositionDetails/SinglePositionPlot/SinglePositionPlot.tsx @@ -6,15 +6,17 @@ import activeLiquidity from '@static/svg/activeLiquidity.svg' import { calcPriceByTickIndex, calcTicksAmountInRange, + formatNumber, numberToString, spacingMultiplicityGte, TokenPriceData } from '@utils/utils' import { PlotTickData } from '@store/reducers/positions' -import React, { useEffect, useState } from 'react' +import React, { useEffect, useMemo, useState } from 'react' import { ILiquidityToken } from '../SinglePositionInfo/consts' import useStyles from './style' import { getMinTick } from '@invariant-labs/sdk/lib/utils' +import { colors } from '@static/theme' export interface ISinglePositionPlot { data: PlotTickData[] @@ -147,10 +149,72 @@ const SinglePositionPlot: React.FC = ({ } } + const buyPercentageDifference = useMemo(() => { + if ( + tokenAPriceData?.buyPrice === undefined || + globalPrice === undefined || + tokenBPriceData?.price === undefined + ) { + return + } + return ((tokenAPriceData.buyPrice / tokenBPriceData?.price - globalPrice) / globalPrice) * 100 + }, [tokenAPriceData?.buyPrice, globalPrice, tokenBPriceData?.price]) + + const sellPercentageDifference = useMemo(() => { + if ( + tokenAPriceData?.sellPrice === undefined || + globalPrice === undefined || + tokenBPriceData?.price === undefined + ) { + return + } + return ((tokenAPriceData.sellPrice / tokenBPriceData?.price - globalPrice) / globalPrice) * 100 + }, [tokenAPriceData?.sellPrice, globalPrice, tokenBPriceData?.price]) + return ( - Price range + + Price range + { + <> +
+ + {formatNumber(midPrice.x, false, 4)} {tokenX.name}/{tokenY.name} + +
+
+ {globalPrice && ( + + {formatNumber(globalPrice, false, 4)} {tokenX.name}/{tokenY.name} + + )} +
+
+ {buyPercentageDifference && ( + + {buyPercentageDifference < 0 ? '-' : '+'} + {formatNumber(Math.abs(buyPercentageDifference), false, 2)}% + + )} +
+
+ {sellPercentageDifference && ( + + {sellPercentageDifference < 0 ? '-' : '+'}{' '} + {formatNumber(Math.abs(sellPercentageDifference), false, 2)}% + + )} +
+ + } +
({ }, headerContainer: { ...typography.heading4, - color: '#FFFFFF' + color: '#FFFFFF', + paddingBottom: 12 }, header: { - paddingBottom: 30 + ...typography.heading4, + color: colors.white.main }, plotWrapper: { paddingBottom: 29 @@ -86,6 +88,7 @@ export const useStyles = makeStyles()((theme: Theme) => ({ marginBottom: 16 }, activeLiquidity: { + height: 24, color: colors.invariant.text, ...typography.caption2, display: 'flex', @@ -142,6 +145,7 @@ export const useStyles = makeStyles()((theme: Theme) => ({ marginLeft: 16 }, currentPrice: { + display: 'inline-block', color: colors.invariant.yellow, ...typography.caption2, textAlign: 'right' @@ -166,6 +170,11 @@ export const useStyles = makeStyles()((theme: Theme) => ({ ...typography.caption2, textAlign: 'right', marginLeft: 4 + }, + priceBlock: { + height: 17, + margin: 0, + textAlign: 'left' } }))