fix: orderbook decimal formats (#996)
* fix: orderbook decimal formats * fix: format position pnl by market asset decimal * fix: update depth chart with new volume format prop * fix: format * fix: update orderbook row with new criteria * fix: revert positions table change * fix: revert price decimal * fix: revert other price thing * fix: add price formatting to depth chart * fix: rename format to parse * fix: format volume numbers with the correct decimals to have the right ratios on the depth chart * fix: format * fix: deal ticket price decimals * fix: lint
This commit is contained in:
parent
dac9b8b015
commit
c31841f56e
@ -100,7 +100,6 @@ export const DealTicketSteps = ({
|
||||
}, [maxTrade, market.positionDecimalPlaces]);
|
||||
|
||||
const { message: invalidText, isDisabled } = useOrderValidation({
|
||||
step,
|
||||
market,
|
||||
orderType,
|
||||
orderTimeInForce,
|
||||
|
@ -3,10 +3,11 @@ import { VegaWalletOrderType } from '@vegaprotocol/wallet';
|
||||
import type { Order } from '@vegaprotocol/orders';
|
||||
import { DealTicketMarketAmount } from './deal-ticket-market-amount';
|
||||
import { DealTicketLimitAmount } from './deal-ticket-limit-amount';
|
||||
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
|
||||
|
||||
export interface DealTicketAmountProps {
|
||||
orderType: VegaWalletOrderType;
|
||||
step: number;
|
||||
market: DealTicketQuery_market;
|
||||
register: UseFormRegister<Order>;
|
||||
quoteName: string;
|
||||
price?: string;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { t, toDecimal } from '@vegaprotocol/react-helpers';
|
||||
import { validateSize } from '@vegaprotocol/orders';
|
||||
import type { DealTicketAmountProps } from './deal-ticket-amount';
|
||||
|
||||
@ -10,9 +10,12 @@ export type DealTicketLimitAmountProps = Omit<
|
||||
|
||||
export const DealTicketLimitAmount = ({
|
||||
register,
|
||||
step,
|
||||
market,
|
||||
quoteName,
|
||||
}: DealTicketLimitAmountProps) => {
|
||||
const priceStep = toDecimal(market.decimalPlaces);
|
||||
const sizeStep = toDecimal(market.positionDecimalPlaces);
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-8">
|
||||
<div className="flex-1">
|
||||
@ -21,13 +24,13 @@ export const DealTicketLimitAmount = ({
|
||||
id="input-order-size-limit"
|
||||
className="w-full"
|
||||
type="number"
|
||||
step={step}
|
||||
min={step}
|
||||
step={sizeStep}
|
||||
min={sizeStep}
|
||||
data-testid="order-size"
|
||||
{...register('size', {
|
||||
required: true,
|
||||
min: step,
|
||||
validate: validateSize(step),
|
||||
min: sizeStep,
|
||||
validate: validateSize(sizeStep),
|
||||
})}
|
||||
/>
|
||||
</FormGroup>
|
||||
@ -43,7 +46,7 @@ export const DealTicketLimitAmount = ({
|
||||
id="input-price-quote"
|
||||
className="w-full"
|
||||
type="number"
|
||||
step={step}
|
||||
step={priceStep}
|
||||
defaultValue={0}
|
||||
data-testid="order-price"
|
||||
{...register('price', { required: true, min: 0 })}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { t, toDecimal } from '@vegaprotocol/react-helpers';
|
||||
import { validateSize } from '@vegaprotocol/orders';
|
||||
import type { DealTicketAmountProps } from './deal-ticket-amount';
|
||||
|
||||
@ -11,9 +11,10 @@ export type DealTicketMarketAmountProps = Omit<
|
||||
export const DealTicketMarketAmount = ({
|
||||
register,
|
||||
price,
|
||||
step,
|
||||
market,
|
||||
quoteName,
|
||||
}: DealTicketMarketAmountProps) => {
|
||||
const sizeStep = toDecimal(market.positionDecimalPlaces);
|
||||
return (
|
||||
<div className="flex items-center gap-8">
|
||||
<div className="flex-1">
|
||||
@ -22,13 +23,13 @@ export const DealTicketMarketAmount = ({
|
||||
id="input-order-size-market"
|
||||
className="w-full"
|
||||
type="number"
|
||||
step={step}
|
||||
min={step}
|
||||
step={sizeStep}
|
||||
min={sizeStep}
|
||||
data-testid="order-size"
|
||||
{...register('size', {
|
||||
required: true,
|
||||
min: step,
|
||||
validate: validateSize(step),
|
||||
min: sizeStep,
|
||||
validate: validateSize(sizeStep),
|
||||
})}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
@ -4,11 +4,7 @@ import {
|
||||
VegaWalletOrderType,
|
||||
VegaWalletOrderTimeInForce,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import {
|
||||
t,
|
||||
toDecimal,
|
||||
addDecimalsFormatNumber,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { t, addDecimalsFormatNumber } from '@vegaprotocol/react-helpers';
|
||||
import { Button, InputError } from '@vegaprotocol/ui-toolkit';
|
||||
import { TypeSelector } from './type-selector';
|
||||
import { SideSelector } from './side-selector';
|
||||
@ -45,11 +41,9 @@ export const DealTicket = ({
|
||||
defaultValues: getDefaultOrder(market),
|
||||
});
|
||||
|
||||
const step = toDecimal(market.positionDecimalPlaces);
|
||||
const orderType = watch('type');
|
||||
const orderTimeInForce = watch('timeInForce');
|
||||
const { message, isDisabled: disabled } = useOrderValidation({
|
||||
step,
|
||||
market,
|
||||
orderType,
|
||||
orderTimeInForce,
|
||||
@ -94,7 +88,7 @@ export const DealTicket = ({
|
||||
/>
|
||||
<DealTicketAmount
|
||||
orderType={orderType}
|
||||
step={step}
|
||||
market={market}
|
||||
register={register}
|
||||
price={
|
||||
market.depth.lastTrade
|
||||
|
@ -4,6 +4,7 @@ import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
useDataProvider,
|
||||
addDecimal,
|
||||
addDecimalsFormatNumber,
|
||||
ThemeContext,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import dataProvider from './market-depth-data-provider';
|
||||
@ -35,12 +36,13 @@ interface PriceLevel {
|
||||
volume: number;
|
||||
}
|
||||
|
||||
const formatLevel = (
|
||||
const parseLevel = (
|
||||
priceLevel: MarketDepth_market_depth_buy | MarketDepth_market_depth_sell,
|
||||
decimalPlaces: number
|
||||
priceDecimalPlaces = 0,
|
||||
volumeDecimalPlaces = 0
|
||||
): PriceLevel => ({
|
||||
price: Number(addDecimal(priceLevel.price, decimalPlaces)),
|
||||
volume: Number(priceLevel.volume),
|
||||
price: Number(addDecimal(priceLevel.price, priceDecimalPlaces)),
|
||||
volume: Number(addDecimal(priceLevel.volume, volumeDecimalPlaces)),
|
||||
});
|
||||
|
||||
const updateLevels = (
|
||||
@ -50,10 +52,15 @@ const updateLevels = (
|
||||
| MarketDepthSubscription_marketDepthUpdate_sell
|
||||
)[],
|
||||
decimalPlaces: number,
|
||||
positionDecimalPlaces: number,
|
||||
reverse = false
|
||||
) => {
|
||||
updates.forEach((update) => {
|
||||
const updateLevel = formatLevel(update, decimalPlaces);
|
||||
const updateLevel = parseLevel(
|
||||
update,
|
||||
decimalPlaces,
|
||||
positionDecimalPlaces
|
||||
);
|
||||
let index = levels.findIndex((level) => level.price === updateLevel.price);
|
||||
if (index !== -1) {
|
||||
if (update.volume === '0') {
|
||||
@ -86,7 +93,8 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
const theme = useContext(ThemeContext);
|
||||
const variables = useMemo(() => ({ marketId }), [marketId]);
|
||||
const [depthData, setDepthData] = useState<DepthData | null>(null);
|
||||
const decimalPlacesRef = useRef<number>(0);
|
||||
const [decimalPlaces, setDecimalPlaces] = useState<number>(0);
|
||||
const [positionDecimalPlaces, setPositionDecimalPlaces] = useState<number>(0);
|
||||
const dataRef = useRef<DepthData | null>(null);
|
||||
const setDepthDataThrottledRef = useRef(throttle(setDepthData, 1000));
|
||||
|
||||
@ -99,17 +107,15 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
dataRef.current = {
|
||||
...dataRef.current,
|
||||
midPrice: delta.market.data?.staticMidPrice
|
||||
? formatMidPrice(
|
||||
delta.market.data?.staticMidPrice,
|
||||
decimalPlacesRef.current
|
||||
)
|
||||
? formatMidPrice(delta.market.data?.staticMidPrice, decimalPlaces)
|
||||
: undefined,
|
||||
data: {
|
||||
buy: delta.buy
|
||||
? updateLevels(
|
||||
dataRef.current.data.buy,
|
||||
delta.buy,
|
||||
decimalPlacesRef.current,
|
||||
decimalPlaces,
|
||||
positionDecimalPlaces,
|
||||
true
|
||||
)
|
||||
: dataRef.current.data.buy,
|
||||
@ -117,7 +123,8 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
? updateLevels(
|
||||
dataRef.current.data.sell,
|
||||
delta.sell,
|
||||
decimalPlacesRef.current
|
||||
decimalPlaces,
|
||||
positionDecimalPlaces
|
||||
)
|
||||
: dataRef.current.data.sell,
|
||||
},
|
||||
@ -125,7 +132,7 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
setDepthDataThrottledRef.current(dataRef.current);
|
||||
return true;
|
||||
},
|
||||
[]
|
||||
[decimalPlaces, positionDecimalPlaces]
|
||||
);
|
||||
|
||||
const { data, error, loading } = useDataProvider({
|
||||
@ -147,21 +154,41 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
data: {
|
||||
buy:
|
||||
data.depth.buy?.map((priceLevel) =>
|
||||
formatLevel(priceLevel, data.decimalPlaces)
|
||||
parseLevel(
|
||||
priceLevel,
|
||||
data.decimalPlaces,
|
||||
data.positionDecimalPlaces
|
||||
)
|
||||
) ?? [],
|
||||
sell:
|
||||
data.depth.sell?.map((priceLevel) =>
|
||||
formatLevel(priceLevel, data.decimalPlaces)
|
||||
parseLevel(
|
||||
priceLevel,
|
||||
data.decimalPlaces,
|
||||
data.positionDecimalPlaces
|
||||
)
|
||||
) ?? [],
|
||||
},
|
||||
};
|
||||
setDepthData(dataRef.current);
|
||||
decimalPlacesRef.current = data.decimalPlaces;
|
||||
setDecimalPlaces(data.decimalPlaces);
|
||||
setPositionDecimalPlaces(data.positionDecimalPlaces);
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
{depthData && <DepthChart {...depthData} theme={theme} />}
|
||||
{depthData && (
|
||||
<DepthChart
|
||||
{...depthData}
|
||||
theme={theme}
|
||||
volumeFormat={(volume) =>
|
||||
addDecimalsFormatNumber(volume, data?.positionDecimalPlaces || 0)
|
||||
}
|
||||
priceFormat={(price) =>
|
||||
addDecimalsFormatNumber(price, data?.decimalPlaces || 0)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</AsyncRenderer>
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { FieldErrors } from 'react-hook-form';
|
||||
import { useMemo } from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { t, toDecimal } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
useVegaWallet,
|
||||
VegaWalletOrderTimeInForce as OrderTimeInForce,
|
||||
@ -11,7 +11,6 @@ import { ERROR_SIZE_DECIMAL } from '../utils/validate-size';
|
||||
import type { Order } from './use-order-submit';
|
||||
|
||||
export type ValidationArgs = {
|
||||
step: number;
|
||||
market: {
|
||||
state: MarketState;
|
||||
tradingMode: MarketTradingMode;
|
||||
@ -32,13 +31,13 @@ export const marketTranslations = (marketState: MarketState) => {
|
||||
};
|
||||
|
||||
export const useOrderValidation = ({
|
||||
step,
|
||||
market,
|
||||
fieldErrors = {},
|
||||
orderType,
|
||||
orderTimeInForce,
|
||||
}: ValidationArgs) => {
|
||||
const { keypair } = useVegaWallet();
|
||||
const minSize = toDecimal(market.positionDecimalPlaces);
|
||||
|
||||
const { message, isDisabled } = useMemo(() => {
|
||||
if (!keypair) {
|
||||
@ -182,7 +181,7 @@ export const useOrderValidation = ({
|
||||
if (fieldErrors?.size?.type === 'min') {
|
||||
return {
|
||||
isDisabled: true,
|
||||
message: t(`The amount cannot be lower than "${step}"`),
|
||||
message: t(`The amount cannot be lower than "${minSize}"`),
|
||||
};
|
||||
}
|
||||
|
||||
@ -220,8 +219,8 @@ export const useOrderValidation = ({
|
||||
|
||||
return { isDisabled: false, message: '' };
|
||||
}, [
|
||||
minSize,
|
||||
keypair,
|
||||
step,
|
||||
market,
|
||||
fieldErrors?.size?.type,
|
||||
fieldErrors?.size?.message,
|
||||
|
@ -55,7 +55,7 @@
|
||||
"js-sha3": "^0.8.0",
|
||||
"lodash": "^4.17.21",
|
||||
"next": "12.0.9",
|
||||
"pennant": "^0.4.12",
|
||||
"pennant": "^0.4.14",
|
||||
"react": "18.2.0",
|
||||
"react-copy-to-clipboard": "^5.0.4",
|
||||
"react-dom": "^18.2.0",
|
||||
|
24
yarn.lock
24
yarn.lock
@ -7259,19 +7259,7 @@ ajv@^8.0.0, ajv@^8.0.1, ajv@^8.8.0:
|
||||
require-from-string "^2.0.2"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
allotment@1.14.2:
|
||||
version "1.14.2"
|
||||
resolved "https://registry.yarnpkg.com/allotment/-/allotment-1.14.2.tgz#b89364ede0b3fbeb2927f7c1f80bc90f13248bbf"
|
||||
integrity sha512-Gqfl2DW2hQ3RT22uiJs2yK1bSwwFbDMC4drTe3uWEjKMmwlAZmS7/vqLD1v25kqbAqdjWSzr+aqgHsRXT51BPQ==
|
||||
dependencies:
|
||||
classnames "^2.3.0"
|
||||
eventemitter3 "^4.0.0"
|
||||
lodash.clamp "^4.0.0"
|
||||
lodash.debounce "^4.0.0"
|
||||
lodash.isequal "^4.5.0"
|
||||
use-resize-observer "^9.0.0"
|
||||
|
||||
allotment@^1.14.5:
|
||||
allotment@1.15.0, allotment@^1.14.5:
|
||||
version "1.15.0"
|
||||
resolved "https://registry.yarnpkg.com/allotment/-/allotment-1.15.0.tgz#3e27eb0d048b8da3d1acb8bc53610b63f84d5c5a"
|
||||
integrity sha512-9JXAm59/XD5Djfpso0rgGZdA23n3v5XeicwjNoInp2qlBa/HFZtnMDujm6NHOSjOCQPWhkOt4ybYgz8H3ed+8A==
|
||||
@ -17186,10 +17174,10 @@ pend@~1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
|
||||
|
||||
pennant@^0.4.12:
|
||||
version "0.4.12"
|
||||
resolved "https://registry.yarnpkg.com/pennant/-/pennant-0.4.12.tgz#c37860fcea96b79114c2ee4f22c5c18bd8e9d5a2"
|
||||
integrity sha512-3j7YIsEcIceWIDT5A8WdkBdTPK0rzqcUzFKK3UfFYAv0xGPI7aJyyX2Gu5QfEML01A0oGtgLsjbWoxHdiSp7Hw==
|
||||
pennant@^0.4.14:
|
||||
version "0.4.14"
|
||||
resolved "https://registry.yarnpkg.com/pennant/-/pennant-0.4.14.tgz#9d51fc47faf9b51efee965c6df8a0746c70bdce6"
|
||||
integrity sha512-O0a5uPGrQfX8eDULVJVuSsYloLjPl/91kdmbaZbc3bq+N9nYIRNu5uRdxAm0LPaqVhNU+Tp1dwNPeL6JFF73xw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@d3fc/d3fc-technical-indicator" "^8.0.1"
|
||||
@ -17209,7 +17197,7 @@ pennant@^0.4.12:
|
||||
"@types/react" "^18.0.14"
|
||||
"@types/react-dom" "^18.0.5"
|
||||
"@types/react-virtualized-auto-sizer" "^1.0.0"
|
||||
allotment "1.14.2"
|
||||
allotment "1.15.0"
|
||||
classnames "^2.2.6"
|
||||
d3-array "2.3.3"
|
||||
d3-delaunay "^6.0.2"
|
||||
|
Loading…
Reference in New Issue
Block a user