chore(deal-ticket): remove not used code (#3406)
This commit is contained in:
parent
8ab7ac8414
commit
fd7940c4cf
@ -1,6 +1,2 @@
|
|||||||
export * from './__generated__/EstimateOrder';
|
export * from './__generated__/EstimateOrder';
|
||||||
export * from './use-calculate-slippage';
|
|
||||||
export * from './use-fee-deal-ticket-details';
|
export * from './use-fee-deal-ticket-details';
|
||||||
export * from './use-market-positions';
|
|
||||||
export * from './use-maximum-position-size';
|
|
||||||
export * from './use-order-closeout';
|
|
||||||
|
@ -1,144 +0,0 @@
|
|||||||
import { MockedProvider } from '@apollo/client/testing';
|
|
||||||
import { renderHook } from '@testing-library/react';
|
|
||||||
import * as Schema from '@vegaprotocol/types';
|
|
||||||
import type { Market } from '@vegaprotocol/market-list';
|
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|
||||||
import { useCalculateSlippage } from './use-calculate-slippage';
|
|
||||||
|
|
||||||
const mockData = {
|
|
||||||
decimalPlaces: 0,
|
|
||||||
positionDecimalPlaces: 0,
|
|
||||||
depth: {
|
|
||||||
buy: [
|
|
||||||
{
|
|
||||||
price: '5',
|
|
||||||
volume: '2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '4',
|
|
||||||
volume: '3',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '3',
|
|
||||||
volume: '2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '2',
|
|
||||||
volume: '1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '1',
|
|
||||||
volume: '1',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
sell: [
|
|
||||||
{
|
|
||||||
price: '6',
|
|
||||||
volume: '1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '7',
|
|
||||||
volume: '3',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '8',
|
|
||||||
volume: '2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '9',
|
|
||||||
volume: '1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
price: '10',
|
|
||||||
volume: '2',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let mockOrderBookData = {
|
|
||||||
data: mockData,
|
|
||||||
};
|
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/react-helpers', () => ({
|
|
||||||
...jest.requireActual('@vegaprotocol/react-helpers'),
|
|
||||||
useDataProvider: jest.fn(() => ({
|
|
||||||
data: {
|
|
||||||
marketsConnection: [],
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
useThrottledDataProvider: jest.fn(() => mockOrderBookData),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('useCalculateSlippage Hook', () => {
|
|
||||||
describe('calculate proper result', () => {
|
|
||||||
afterEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
const market = {
|
|
||||||
id: 'marketId',
|
|
||||||
decimalPlaces: 0,
|
|
||||||
positionDecimalPlaces: 0,
|
|
||||||
} as Market;
|
|
||||||
|
|
||||||
it('long order', () => {
|
|
||||||
const { result } = renderHook(
|
|
||||||
() =>
|
|
||||||
useCalculateSlippage({
|
|
||||||
market,
|
|
||||||
order: {
|
|
||||||
size: '10',
|
|
||||||
side: Schema.Side.SIDE_BUY,
|
|
||||||
} as OrderSubmissionBody['orderSubmission'],
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
wrapper: MockedProvider,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expect(result.current).toEqual('33.33');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('short order', () => {
|
|
||||||
const { result } = renderHook(
|
|
||||||
() =>
|
|
||||||
useCalculateSlippage({
|
|
||||||
market,
|
|
||||||
order: {
|
|
||||||
size: '10',
|
|
||||||
side: Schema.Side.SIDE_SELL,
|
|
||||||
} as OrderSubmissionBody['orderSubmission'],
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
wrapper: MockedProvider,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expect(result.current).toEqual('31.11');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('when no order book result should be null', () => {
|
|
||||||
mockOrderBookData = {
|
|
||||||
data: {
|
|
||||||
...mockData,
|
|
||||||
depth: {
|
|
||||||
...mockData.depth,
|
|
||||||
buy: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const { result } = renderHook(
|
|
||||||
() =>
|
|
||||||
useCalculateSlippage({
|
|
||||||
market,
|
|
||||||
order: {
|
|
||||||
size: '10',
|
|
||||||
side: Schema.Side.SIDE_SELL,
|
|
||||||
} as OrderSubmissionBody['orderSubmission'],
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
wrapper: MockedProvider,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expect(result.current).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,63 +0,0 @@
|
|||||||
import { marketDepthProvider } from '@vegaprotocol/market-depth';
|
|
||||||
import * as Schema from '@vegaprotocol/types';
|
|
||||||
import type { Market } from '@vegaprotocol/market-list';
|
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|
||||||
import { BigNumber } from 'bignumber.js';
|
|
||||||
import { formatNumber, toBigNum } from '@vegaprotocol/utils';
|
|
||||||
import { useThrottledDataProvider } from '@vegaprotocol/react-helpers';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
market: Market;
|
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useCalculateSlippage = ({ market, order }: Props) => {
|
|
||||||
const { data } = useThrottledDataProvider(
|
|
||||||
{
|
|
||||||
dataProvider: marketDepthProvider,
|
|
||||||
variables: { marketId: market.id },
|
|
||||||
},
|
|
||||||
1000
|
|
||||||
);
|
|
||||||
const volPriceArr =
|
|
||||||
data?.depth[order.side === Schema.Side.SIDE_BUY ? 'sell' : 'buy'] || [];
|
|
||||||
if (volPriceArr.length && market) {
|
|
||||||
const decimals = market.decimalPlaces ?? 0;
|
|
||||||
const positionDecimals = market.positionDecimalPlaces ?? 0;
|
|
||||||
const bestPrice = toBigNum(volPriceArr[0].price, decimals);
|
|
||||||
const { size } = order;
|
|
||||||
let descSize = new BigNumber(size);
|
|
||||||
let i = 0;
|
|
||||||
const volPricePairs: Array<[BigNumber, BigNumber]> = [];
|
|
||||||
while (!descSize.isZero() && i < volPriceArr.length) {
|
|
||||||
const price = toBigNum(volPriceArr[i].price, decimals);
|
|
||||||
const amount = BigNumber.min(
|
|
||||||
descSize,
|
|
||||||
toBigNum(volPriceArr[i].volume, positionDecimals)
|
|
||||||
);
|
|
||||||
volPricePairs.push([price, amount]);
|
|
||||||
descSize = BigNumber.max(0, descSize.minus(amount));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (volPricePairs.length) {
|
|
||||||
const volWeightAvPricePair = volPricePairs.reduce(
|
|
||||||
(agg, item) => {
|
|
||||||
agg[0] = agg[0].plus(item[0].multipliedBy(item[1]));
|
|
||||||
agg[1] = agg[1].plus(item[1]);
|
|
||||||
return agg;
|
|
||||||
},
|
|
||||||
[new BigNumber(0), new BigNumber(0)]
|
|
||||||
);
|
|
||||||
const volWeightAvPrice = volWeightAvPricePair[0].dividedBy(
|
|
||||||
volWeightAvPricePair[1]
|
|
||||||
);
|
|
||||||
const slippage = volWeightAvPrice
|
|
||||||
.minus(bestPrice)
|
|
||||||
.absoluteValue()
|
|
||||||
.dividedBy(bestPrice)
|
|
||||||
.multipliedBy(100);
|
|
||||||
return formatNumber(slippage, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
@ -18,7 +18,6 @@ import {
|
|||||||
DEDUCTION_FROM_COLLATERAL_TOOLTIP_TEXT,
|
DEDUCTION_FROM_COLLATERAL_TOOLTIP_TEXT,
|
||||||
TOTAL_MARGIN_AVAILABLE,
|
TOTAL_MARGIN_AVAILABLE,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
import { useOrderCloseOut } from './use-order-closeout';
|
|
||||||
import { useMarketAccountBalance } from '@vegaprotocol/accounts';
|
import { useMarketAccountBalance } from '@vegaprotocol/accounts';
|
||||||
import { getDerivedPrice } from '../utils/get-price';
|
import { getDerivedPrice } from '../utils/get-price';
|
||||||
import { useEstimateOrderQuery } from './__generated__/EstimateOrder';
|
import { useEstimateOrderQuery } from './__generated__/EstimateOrder';
|
||||||
@ -49,12 +48,6 @@ export const useFeeDealTicketDetails = (
|
|||||||
skip: !pubKey || !market || !order.size || !price,
|
skip: !pubKey || !market || !order.size || !price,
|
||||||
});
|
});
|
||||||
|
|
||||||
const estCloseOut = useOrderCloseOut({
|
|
||||||
order,
|
|
||||||
market,
|
|
||||||
marketData,
|
|
||||||
});
|
|
||||||
|
|
||||||
const notionalSize = useMemo(() => {
|
const notionalSize = useMemo(() => {
|
||||||
if (price && order.size) {
|
if (price && order.size) {
|
||||||
return toBigNum(order.size, market.positionDecimalPlaces)
|
return toBigNum(order.size, market.positionDecimalPlaces)
|
||||||
@ -74,16 +67,8 @@ export const useFeeDealTicketDetails = (
|
|||||||
notionalSize,
|
notionalSize,
|
||||||
accountBalance,
|
accountBalance,
|
||||||
estimateOrder: estMargin?.estimateOrder,
|
estimateOrder: estMargin?.estimateOrder,
|
||||||
estCloseOut,
|
|
||||||
};
|
};
|
||||||
}, [
|
}, [market, assetSymbol, notionalSize, accountBalance, estMargin]);
|
||||||
market,
|
|
||||||
assetSymbol,
|
|
||||||
notionalSize,
|
|
||||||
accountBalance,
|
|
||||||
estMargin,
|
|
||||||
estCloseOut,
|
|
||||||
]);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface FeeDetails {
|
export interface FeeDetails {
|
||||||
@ -92,7 +77,6 @@ export interface FeeDetails {
|
|||||||
market: Market;
|
market: Market;
|
||||||
assetSymbol: string;
|
assetSymbol: string;
|
||||||
notionalSize: string | null;
|
notionalSize: string | null;
|
||||||
estCloseOut: string | null;
|
|
||||||
estimateOrder: EstimateOrderQuery['estimateOrder'] | undefined;
|
estimateOrder: EstimateOrderQuery['estimateOrder'] | undefined;
|
||||||
estimatedInitialMargin: string;
|
estimatedInitialMargin: string;
|
||||||
estimatedTotalInitialMargin: string;
|
estimatedTotalInitialMargin: string;
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
import { renderHook } from '@testing-library/react';
|
|
||||||
import { MockedProvider } from '@apollo/client/testing';
|
|
||||||
import { useMarketPositions } from './use-market-positions';
|
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/wallet', () => ({
|
|
||||||
...jest.requireActual('@vegaprotocol/wallet'),
|
|
||||||
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
|
||||||
}));
|
|
||||||
let mockMarketAccountBalance: {
|
|
||||||
accountBalance: string;
|
|
||||||
accountDecimals: number | null;
|
|
||||||
} = { accountBalance: '50001000000', accountDecimals: 5 };
|
|
||||||
jest.mock('@vegaprotocol/accounts', () => ({
|
|
||||||
...jest.requireActual('@vegaprotocol/accounts'),
|
|
||||||
useMarketAccountBalance: jest.fn(() => mockMarketAccountBalance),
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/positions', () => ({
|
|
||||||
...jest.requireActual('@vegaprotocol/positions'),
|
|
||||||
useMarketPositionOpenVolume: jest.fn(() => '100002'),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('useOrderPosition Hook', () => {
|
|
||||||
afterEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
it('should return proper positive value', () => {
|
|
||||||
const { result } = renderHook(
|
|
||||||
() => useMarketPositions({ marketId: 'marketId' }),
|
|
||||||
{ wrapper: MockedProvider }
|
|
||||||
);
|
|
||||||
expect(result.current?.openVolume).toEqual('100002');
|
|
||||||
expect(result.current?.balance).toEqual('50001000000');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('if balance equal 0 return null', () => {
|
|
||||||
mockMarketAccountBalance = { accountBalance: '0', accountDecimals: 5 };
|
|
||||||
const { result } = renderHook(
|
|
||||||
() => useMarketPositions({ marketId: 'marketId' }),
|
|
||||||
{ wrapper: MockedProvider }
|
|
||||||
);
|
|
||||||
expect(result.current).toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('if no markets return null', () => {
|
|
||||||
mockMarketAccountBalance = { accountBalance: '', accountDecimals: null };
|
|
||||||
const { result } = renderHook(
|
|
||||||
() => useMarketPositions({ marketId: 'marketId' }),
|
|
||||||
{ wrapper: MockedProvider }
|
|
||||||
);
|
|
||||||
expect(result.current).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,34 +0,0 @@
|
|||||||
import { useMemo } from 'react';
|
|
||||||
import { BigNumber } from 'bignumber.js';
|
|
||||||
import { useMarketAccountBalance } from '@vegaprotocol/accounts';
|
|
||||||
import { useMarketPositionOpenVolume } from '@vegaprotocol/positions';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
marketId: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PositionMargin = {
|
|
||||||
openVolume: string;
|
|
||||||
balance: string;
|
|
||||||
balanceDecimals?: number;
|
|
||||||
} | null;
|
|
||||||
|
|
||||||
export const useMarketPositions = ({ marketId }: Props): PositionMargin => {
|
|
||||||
const { accountBalance, accountDecimals } = useMarketAccountBalance(marketId);
|
|
||||||
const openVolume = useMarketPositionOpenVolume(marketId);
|
|
||||||
|
|
||||||
return useMemo(() => {
|
|
||||||
if (accountBalance && accountDecimals) {
|
|
||||||
const balance = new BigNumber(accountBalance);
|
|
||||||
const volume = new BigNumber(openVolume);
|
|
||||||
if (!balance.isZero() && !volume.isZero()) {
|
|
||||||
return {
|
|
||||||
balance: accountBalance,
|
|
||||||
balanceDecimals: accountDecimals,
|
|
||||||
openVolume,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}, [accountBalance, accountDecimals, openVolume]);
|
|
||||||
};
|
|
@ -1,120 +0,0 @@
|
|||||||
import { renderHook } from '@testing-library/react';
|
|
||||||
import { MockedProvider } from '@apollo/client/testing';
|
|
||||||
import * as Schema from '@vegaprotocol/types';
|
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|
||||||
import type { PositionMargin } from './use-market-positions';
|
|
||||||
import { useMaximumPositionSize } from './use-maximum-position-size';
|
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/wallet', () => ({
|
|
||||||
...jest.requireActual('@vegaprotocol/wallet'),
|
|
||||||
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
|
||||||
}));
|
|
||||||
|
|
||||||
let mockAccountBalance: {
|
|
||||||
accountBalance: string;
|
|
||||||
accountDecimals: number | null;
|
|
||||||
} = { accountBalance: '200000', accountDecimals: 5 };
|
|
||||||
jest.mock('@vegaprotocol/accounts', () => ({
|
|
||||||
...jest.requireActual('@vegaprotocol/accounts'),
|
|
||||||
useAccountBalance: jest.fn(() => mockAccountBalance),
|
|
||||||
}));
|
|
||||||
|
|
||||||
const defaultMockMarketPositions = {
|
|
||||||
openVolume: '1',
|
|
||||||
balance: '100000',
|
|
||||||
};
|
|
||||||
|
|
||||||
let mockMarketPositions: PositionMargin | null = defaultMockMarketPositions;
|
|
||||||
|
|
||||||
const mockOrder: OrderSubmissionBody['orderSubmission'] = {
|
|
||||||
type: Schema.OrderType.TYPE_MARKET,
|
|
||||||
size: '1',
|
|
||||||
side: Schema.Side.SIDE_BUY,
|
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_IOC,
|
|
||||||
marketId: 'market-id',
|
|
||||||
};
|
|
||||||
|
|
||||||
jest.mock('./use-market-positions', () => ({
|
|
||||||
useMarketPositions: ({
|
|
||||||
marketId,
|
|
||||||
partyId,
|
|
||||||
}: {
|
|
||||||
marketId: string;
|
|
||||||
partyId: string;
|
|
||||||
}) => mockMarketPositions,
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('useMaximumPositionSize', () => {
|
|
||||||
it('should return correct size when no open positions', () => {
|
|
||||||
mockMarketPositions = null;
|
|
||||||
const price = '50';
|
|
||||||
const expected = 4000;
|
|
||||||
const { result } = renderHook(
|
|
||||||
() =>
|
|
||||||
useMaximumPositionSize({
|
|
||||||
marketId: '',
|
|
||||||
price,
|
|
||||||
settlementAssetId: '',
|
|
||||||
order: mockOrder,
|
|
||||||
}),
|
|
||||||
{ wrapper: MockedProvider }
|
|
||||||
);
|
|
||||||
expect(result.current).toBe(expected);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return correct size when open positions and same side', () => {
|
|
||||||
const price = '50';
|
|
||||||
mockMarketPositions = defaultMockMarketPositions;
|
|
||||||
const expected = 3999;
|
|
||||||
const { result } = renderHook(
|
|
||||||
() =>
|
|
||||||
useMaximumPositionSize({
|
|
||||||
marketId: '',
|
|
||||||
price,
|
|
||||||
settlementAssetId: '',
|
|
||||||
order: mockOrder,
|
|
||||||
}),
|
|
||||||
{ wrapper: MockedProvider }
|
|
||||||
);
|
|
||||||
expect(result.current).toBe(expected);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return correct size when open positions and opposite side', () => {
|
|
||||||
const price = '50';
|
|
||||||
mockOrder.side = Schema.Side.SIDE_SELL;
|
|
||||||
mockMarketPositions = defaultMockMarketPositions;
|
|
||||||
const expected = 4001;
|
|
||||||
const { result } = renderHook(
|
|
||||||
() =>
|
|
||||||
useMaximumPositionSize({
|
|
||||||
marketId: '',
|
|
||||||
price,
|
|
||||||
settlementAssetId: '',
|
|
||||||
order: mockOrder,
|
|
||||||
}),
|
|
||||||
{ wrapper: MockedProvider }
|
|
||||||
);
|
|
||||||
expect(result.current).toBe(expected);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return zero if no account balance', () => {
|
|
||||||
mockAccountBalance = {
|
|
||||||
accountBalance: '0',
|
|
||||||
accountDecimals: 5,
|
|
||||||
};
|
|
||||||
const price = '50';
|
|
||||||
mockMarketPositions = defaultMockMarketPositions;
|
|
||||||
const expected = 0;
|
|
||||||
const { result } = renderHook(
|
|
||||||
() =>
|
|
||||||
useMaximumPositionSize({
|
|
||||||
marketId: '',
|
|
||||||
price,
|
|
||||||
settlementAssetId: '',
|
|
||||||
order: mockOrder,
|
|
||||||
}),
|
|
||||||
{ wrapper: MockedProvider }
|
|
||||||
);
|
|
||||||
expect(result.current).toBe(expected);
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,46 +0,0 @@
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|
||||||
import { useAccountBalance } from '@vegaprotocol/accounts';
|
|
||||||
import { BigNumber } from 'bignumber.js';
|
|
||||||
import { useMarketPositions } from './use-market-positions';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
marketId: string;
|
|
||||||
price?: string;
|
|
||||||
settlementAssetId: string;
|
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
|
||||||
}
|
|
||||||
|
|
||||||
const getSize = (balance: string, price: string) =>
|
|
||||||
new BigNumber(balance).dividedBy(new BigNumber(price));
|
|
||||||
|
|
||||||
export const useMaximumPositionSize = ({
|
|
||||||
marketId,
|
|
||||||
price,
|
|
||||||
settlementAssetId,
|
|
||||||
order,
|
|
||||||
}: Props): number => {
|
|
||||||
const { accountBalance } = useAccountBalance(settlementAssetId) || {};
|
|
||||||
const marketPositions = useMarketPositions({ marketId: marketId });
|
|
||||||
if (!accountBalance || new BigNumber(accountBalance || 0).isZero()) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size = getSize(accountBalance, price || '');
|
|
||||||
|
|
||||||
if (!marketPositions) {
|
|
||||||
return size.toNumber() || 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isSameSide =
|
|
||||||
(new BigNumber(marketPositions.openVolume).isPositive() &&
|
|
||||||
order.side === Schema.Side.SIDE_BUY) ||
|
|
||||||
(new BigNumber(marketPositions.openVolume).isNegative() &&
|
|
||||||
order.side === Schema.Side.SIDE_SELL);
|
|
||||||
|
|
||||||
const adjustedForVolume = new BigNumber(size)[isSameSide ? 'minus' : 'plus'](
|
|
||||||
marketPositions.openVolume
|
|
||||||
);
|
|
||||||
|
|
||||||
return adjustedForVolume.isNegative() ? 0 : adjustedForVolume.toNumber();
|
|
||||||
};
|
|
@ -1,117 +0,0 @@
|
|||||||
import { renderHook } from '@testing-library/react';
|
|
||||||
import { MockedProvider } from '@apollo/client/testing';
|
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|
||||||
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
|
||||||
import { useOrderCloseOut } from './use-order-closeout';
|
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/wallet', () => ({
|
|
||||||
...jest.requireActual('@vegaprotocol/wallet'),
|
|
||||||
useVegaWallet: jest.fn().mockReturnValue('wallet-pub-key'),
|
|
||||||
}));
|
|
||||||
let mockMarketMargin: string | undefined = undefined;
|
|
||||||
jest.mock('@vegaprotocol/positions', () => ({
|
|
||||||
...jest.requireActual('@vegaprotocol/positions'),
|
|
||||||
useMarketMargin: () => mockMarketMargin,
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('useOrderCloseOut', () => {
|
|
||||||
const order = { size: '2', side: 'SIDE_BUY' };
|
|
||||||
const market = {
|
|
||||||
decimalPlaces: 5,
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
product: {
|
|
||||||
settlementAsset: {
|
|
||||||
id: 'assetId',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} as unknown as Market;
|
|
||||||
|
|
||||||
const marketData = {
|
|
||||||
markPrice: 100000,
|
|
||||||
} as unknown as MarketData;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return proper null value', () => {
|
|
||||||
mockMarketMargin = '-1';
|
|
||||||
const { result } = renderHook(
|
|
||||||
() =>
|
|
||||||
useOrderCloseOut({
|
|
||||||
order: order as OrderSubmissionBody['orderSubmission'],
|
|
||||||
market,
|
|
||||||
marketData: {
|
|
||||||
markPrice: '0',
|
|
||||||
} as MarketData,
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
wrapper: MockedProvider,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expect(result.current).toEqual(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return proper sell value', () => {
|
|
||||||
mockMarketMargin = '0';
|
|
||||||
const { result } = renderHook(
|
|
||||||
() =>
|
|
||||||
useOrderCloseOut({
|
|
||||||
order: {
|
|
||||||
...order,
|
|
||||||
side: 'SIDE_SELL',
|
|
||||||
} as OrderSubmissionBody['orderSubmission'],
|
|
||||||
market,
|
|
||||||
marketData,
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
wrapper: MockedProvider,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expect(result.current).toEqual('1');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return proper sell value on limit order', () => {
|
|
||||||
mockMarketMargin = '0';
|
|
||||||
const { result } = renderHook(
|
|
||||||
() =>
|
|
||||||
useOrderCloseOut({
|
|
||||||
order: {
|
|
||||||
...order,
|
|
||||||
price: '1000000',
|
|
||||||
type: 'TYPE_LIMIT',
|
|
||||||
side: 'SIDE_SELL',
|
|
||||||
} as OrderSubmissionBody['orderSubmission'],
|
|
||||||
market,
|
|
||||||
marketData,
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
wrapper: MockedProvider,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expect(result.current).toEqual('1000000');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return proper empty value', () => {
|
|
||||||
const { result } = renderHook(
|
|
||||||
() =>
|
|
||||||
useOrderCloseOut({
|
|
||||||
order: {
|
|
||||||
...order,
|
|
||||||
side: 'SIDE_SELL',
|
|
||||||
} as OrderSubmissionBody['orderSubmission'],
|
|
||||||
market,
|
|
||||||
marketData: {
|
|
||||||
markPrice: '0',
|
|
||||||
} as MarketData,
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
wrapper: MockedProvider,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expect(result.current).toEqual('0');
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,61 +0,0 @@
|
|||||||
import { BigNumber } from 'bignumber.js';
|
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|
||||||
import { addDecimal } from '@vegaprotocol/utils';
|
|
||||||
import * as Schema from '@vegaprotocol/types';
|
|
||||||
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
|
||||||
import {
|
|
||||||
useAccountBalance,
|
|
||||||
useMarketAccountBalance,
|
|
||||||
} from '@vegaprotocol/accounts';
|
|
||||||
import { useMarketMargin } from '@vegaprotocol/positions';
|
|
||||||
import { useMarketPositions } from './use-market-positions';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
|
||||||
market: Market;
|
|
||||||
marketData: MarketData;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useOrderCloseOut = ({
|
|
||||||
order,
|
|
||||||
market,
|
|
||||||
marketData,
|
|
||||||
}: Props): string | null => {
|
|
||||||
const { accountBalance, accountDecimals } = useAccountBalance(
|
|
||||||
market.tradableInstrument.instrument.product.settlementAsset.id
|
|
||||||
);
|
|
||||||
const { accountBalance: positionBalance, accountDecimals: positionDecimals } =
|
|
||||||
useMarketAccountBalance(market.id);
|
|
||||||
const maintenanceLevel = useMarketMargin(market.id);
|
|
||||||
|
|
||||||
const marginMaintenanceLevel = new BigNumber(
|
|
||||||
addDecimal(maintenanceLevel || 0, market.decimalPlaces)
|
|
||||||
);
|
|
||||||
const positionAccountBalance = new BigNumber(
|
|
||||||
addDecimal(positionBalance || 0, positionDecimals || 0)
|
|
||||||
);
|
|
||||||
const generalAccountBalance = new BigNumber(
|
|
||||||
addDecimal(accountBalance || 0, accountDecimals || 0)
|
|
||||||
);
|
|
||||||
const { openVolume } =
|
|
||||||
useMarketPositions({
|
|
||||||
marketId: market.id,
|
|
||||||
}) || {};
|
|
||||||
|
|
||||||
const volume = new BigNumber(
|
|
||||||
addDecimal(openVolume || '0', market.positionDecimalPlaces)
|
|
||||||
)[order.side === Schema.Side.SIDE_BUY ? 'plus' : 'minus'](order.size);
|
|
||||||
const price =
|
|
||||||
order.type === Schema.OrderType.TYPE_LIMIT && order.price
|
|
||||||
? new BigNumber(order.price)
|
|
||||||
: new BigNumber(addDecimal(marketData.markPrice, market.decimalPlaces));
|
|
||||||
// regarding formula (marginMaintenanceLevel - positionAccountBalance - generalAccountBalance) / volume + markPrice
|
|
||||||
const marginDifference = marginMaintenanceLevel
|
|
||||||
.minus(positionAccountBalance)
|
|
||||||
.minus(generalAccountBalance);
|
|
||||||
const closeOut = marginDifference.div(volume).plus(price);
|
|
||||||
if (closeOut.isPositive()) {
|
|
||||||
return closeOut.toString();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
@ -5,6 +5,5 @@ export * from './lib/margin-data-provider';
|
|||||||
export * from './lib/margin-calculator';
|
export * from './lib/margin-calculator';
|
||||||
export * from './lib/positions-table';
|
export * from './lib/positions-table';
|
||||||
export * from './lib/use-market-margin';
|
export * from './lib/use-market-margin';
|
||||||
export * from './lib/use-market-position-open-volume';
|
|
||||||
export * from './lib/use-open-volume';
|
export * from './lib/use-open-volume';
|
||||||
export * from './lib/use-positions-data';
|
export * from './lib/use-positions-data';
|
||||||
|
@ -354,10 +354,7 @@ export const volumeAndMarginProvider = makeDerivedDataProvider<
|
|||||||
partyId,
|
partyId,
|
||||||
marketIds: [marketId],
|
marketIds: [marketId],
|
||||||
filter: {
|
filter: {
|
||||||
status: [
|
status: [OrderStatus.STATUS_ACTIVE, OrderStatus.STATUS_PARKED],
|
||||||
OrderStatus.STATUS_ACTIVE,
|
|
||||||
OrderStatus.STATUS_PARTIALLY_FILLED,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
(callback, client, variables) =>
|
(callback, client, variables) =>
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
import { useCallback, useState } from 'react';
|
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
|
||||||
import { positionsDataProvider } from './positions-data-providers';
|
|
||||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
|
||||||
import type { PositionFieldsFragment } from './__generated__/Positions';
|
|
||||||
|
|
||||||
export const useMarketPositionOpenVolume = (marketId: string) => {
|
|
||||||
const { pubKey } = useVegaWallet();
|
|
||||||
const [openVolume, setOpenVolume] = useState<string>('');
|
|
||||||
const update = useCallback(
|
|
||||||
({ data }: { data: PositionFieldsFragment[] | null }) => {
|
|
||||||
const position = data?.find((node) => node.market.id === marketId);
|
|
||||||
if (position?.openVolume) {
|
|
||||||
setOpenVolume(position?.openVolume || '');
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
[setOpenVolume, marketId]
|
|
||||||
);
|
|
||||||
|
|
||||||
useDataProvider({
|
|
||||||
dataProvider: positionsDataProvider,
|
|
||||||
variables: { partyId: pubKey || '' },
|
|
||||||
skip: !pubKey || !marketId,
|
|
||||||
update,
|
|
||||||
});
|
|
||||||
|
|
||||||
return openVolume;
|
|
||||||
};
|
|
Loading…
Reference in New Issue
Block a user