feat(trading): close position stopped and IOC behaviour update (#5211)
This commit is contained in:
parent
568dcd5305
commit
2f7e53e282
@ -685,7 +685,7 @@ export const DealTicket = ({
|
|||||||
subLabel={`${formatValue(
|
subLabel={`${formatValue(
|
||||||
normalizedOrder.size,
|
normalizedOrder.size,
|
||||||
market.positionDecimalPlaces
|
market.positionDecimalPlaces
|
||||||
)} ${baseQuote} @ ${
|
)} ${baseQuote || ''} @ ${
|
||||||
type === Schema.OrderType.TYPE_MARKET
|
type === Schema.OrderType.TYPE_MARKET
|
||||||
? 'market'
|
? 'market'
|
||||||
: `${formatValue(
|
: `${formatValue(
|
||||||
|
@ -148,6 +148,7 @@ export const OrderListManager = ({
|
|||||||
expiresAt: editOrder.expiresAt,
|
expiresAt: editOrder.expiresAt,
|
||||||
side: editOrder.side,
|
side: editOrder.side,
|
||||||
marketId: editOrder.market.id,
|
marketId: editOrder.market.id,
|
||||||
|
remaining: editOrder.remaining,
|
||||||
};
|
};
|
||||||
create({ orderAmendment }, originalOrder);
|
create({ orderAmendment }, originalOrder);
|
||||||
setEditOrder(null);
|
setEditOrder(null);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
MAXGOINT64,
|
||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
getDateTimeFormat,
|
getDateTimeFormat,
|
||||||
isNumeric,
|
isNumeric,
|
||||||
@ -144,11 +145,22 @@ export const OrderListTable = memo<
|
|||||||
if (!data?.market || !isNumeric(data.size)) {
|
if (!data?.market || !isNumeric(data.size)) {
|
||||||
return '-';
|
return '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
const prefix = data
|
const prefix = data
|
||||||
? data.side === Schema.Side.SIDE_BUY
|
? data.side === Schema.Side.SIDE_BUY
|
||||||
? '+'
|
? '+'
|
||||||
: '-'
|
: '-'
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
|
if (
|
||||||
|
data.size === MAXGOINT64 &&
|
||||||
|
data.timeInForce ===
|
||||||
|
Schema.OrderTimeInForce.TIME_IN_FORCE_IOC &&
|
||||||
|
data.reduceOnly
|
||||||
|
) {
|
||||||
|
return t('MAX');
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
prefix +
|
prefix +
|
||||||
addDecimalsFormatNumber(
|
addDecimalsFormatNumber(
|
||||||
|
@ -65,6 +65,7 @@ fragment OrderTxUpdateFields on OrderUpdate {
|
|||||||
expiresAt
|
expiresAt
|
||||||
side
|
side
|
||||||
marketId
|
marketId
|
||||||
|
remaining
|
||||||
}
|
}
|
||||||
|
|
||||||
subscription OrderTxUpdate($partyId: ID!) {
|
subscription OrderTxUpdate($partyId: ID!) {
|
||||||
|
@ -21,14 +21,14 @@ export type WithdrawalBusEventSubscriptionVariables = Types.Exact<{
|
|||||||
|
|
||||||
export type WithdrawalBusEventSubscription = { __typename?: 'Subscription', busEvents?: Array<{ __typename?: 'BusEvent', event: { __typename?: 'Deposit' } | { __typename?: 'TimeUpdate' } | { __typename?: 'TransactionResult' } | { __typename?: 'Withdrawal', id: string, status: Types.WithdrawalStatus, amount: string, createdTimestamp: any, withdrawnTimestamp?: any | null, txHash?: string | null, pendingOnForeignChain: boolean, asset: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, status: Types.AssetStatus, source: { __typename?: 'BuiltinAsset' } | { __typename?: 'ERC20', contractAddress: string } }, details?: { __typename?: 'Erc20WithdrawalDetails', receiverAddress: string } | null } }> | null };
|
export type WithdrawalBusEventSubscription = { __typename?: 'Subscription', busEvents?: Array<{ __typename?: 'BusEvent', event: { __typename?: 'Deposit' } | { __typename?: 'TimeUpdate' } | { __typename?: 'TransactionResult' } | { __typename?: 'Withdrawal', id: string, status: Types.WithdrawalStatus, amount: string, createdTimestamp: any, withdrawnTimestamp?: any | null, txHash?: string | null, pendingOnForeignChain: boolean, asset: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, status: Types.AssetStatus, source: { __typename?: 'BuiltinAsset' } | { __typename?: 'ERC20', contractAddress: string } }, details?: { __typename?: 'Erc20WithdrawalDetails', receiverAddress: string } | null } }> | null };
|
||||||
|
|
||||||
export type OrderTxUpdateFieldsFragment = { __typename?: 'OrderUpdate', type?: Types.OrderType | null, id: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, createdAt: any, size: string, price: string, timeInForce: Types.OrderTimeInForce, expiresAt?: any | null, side: Types.Side, marketId: string };
|
export type OrderTxUpdateFieldsFragment = { __typename?: 'OrderUpdate', type?: Types.OrderType | null, id: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, createdAt: any, size: string, price: string, timeInForce: Types.OrderTimeInForce, expiresAt?: any | null, side: Types.Side, marketId: string, remaining: string };
|
||||||
|
|
||||||
export type OrderTxUpdateSubscriptionVariables = Types.Exact<{
|
export type OrderTxUpdateSubscriptionVariables = Types.Exact<{
|
||||||
partyId: Types.Scalars['ID'];
|
partyId: Types.Scalars['ID'];
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type OrderTxUpdateSubscription = { __typename?: 'Subscription', orders?: Array<{ __typename?: 'OrderUpdate', type?: Types.OrderType | null, id: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, createdAt: any, size: string, price: string, timeInForce: Types.OrderTimeInForce, expiresAt?: any | null, side: Types.Side, marketId: string }> | null };
|
export type OrderTxUpdateSubscription = { __typename?: 'Subscription', orders?: Array<{ __typename?: 'OrderUpdate', type?: Types.OrderType | null, id: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, createdAt: any, size: string, price: string, timeInForce: Types.OrderTimeInForce, expiresAt?: any | null, side: Types.Side, marketId: string, remaining: string }> | null };
|
||||||
|
|
||||||
export type DepositBusEventFieldsFragment = { __typename?: 'Deposit', id: string, status: Types.DepositStatus, amount: string, createdTimestamp: any, creditedTimestamp?: any | null, txHash?: string | null, asset: { __typename?: 'Asset', id: string, symbol: string, decimals: number } };
|
export type DepositBusEventFieldsFragment = { __typename?: 'Deposit', id: string, status: Types.DepositStatus, amount: string, createdTimestamp: any, creditedTimestamp?: any | null, txHash?: string | null, asset: { __typename?: 'Asset', id: string, symbol: string, decimals: number } };
|
||||||
|
|
||||||
@ -88,6 +88,7 @@ export const OrderTxUpdateFieldsFragmentDoc = gql`
|
|||||||
expiresAt
|
expiresAt
|
||||||
side
|
side
|
||||||
marketId
|
marketId
|
||||||
|
remaining
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
export const DepositBusEventFieldsFragmentDoc = gql`
|
export const DepositBusEventFieldsFragmentDoc = gql`
|
||||||
|
@ -56,6 +56,7 @@ describe('useVegaTransactionStore', () => {
|
|||||||
side: Side.SIDE_BUY,
|
side: Side.SIDE_BUY,
|
||||||
marketId:
|
marketId:
|
||||||
'3aa2a828687cc3d59e92445d294891cbbd40e2165bbfb15674158ef5d4e8848d',
|
'3aa2a828687cc3d59e92445d294891cbbd40e2165bbfb15674158ef5d4e8848d',
|
||||||
|
remaining: '12',
|
||||||
};
|
};
|
||||||
|
|
||||||
const processedTransactionUpdate = {
|
const processedTransactionUpdate = {
|
||||||
|
@ -193,6 +193,7 @@ const submitOrder: VegaStoredTxState = {
|
|||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
marketId: 'market-1',
|
marketId: 'market-1',
|
||||||
status: OrderStatus.STATUS_ACTIVE,
|
status: OrderStatus.STATUS_ACTIVE,
|
||||||
|
remaining: '10',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -249,6 +250,7 @@ const editOrder: VegaStoredTxState = {
|
|||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
marketId: 'market-1',
|
marketId: 'market-1',
|
||||||
status: OrderStatus.STATUS_ACTIVE,
|
status: OrderStatus.STATUS_ACTIVE,
|
||||||
|
remaining: '10',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -489,6 +491,7 @@ describe('getRejectionReason', () => {
|
|||||||
timeInForce: Types.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
timeInForce: Types.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||||
side: Types.Side.SIDE_BUY,
|
side: Types.Side.SIDE_BUY,
|
||||||
marketId: '',
|
marketId: '',
|
||||||
|
remaining: '',
|
||||||
})
|
})
|
||||||
).toBe('Insufficient asset balance');
|
).toBe('Insufficient asset balance');
|
||||||
});
|
});
|
||||||
@ -505,6 +508,7 @@ describe('getRejectionReason', () => {
|
|||||||
timeInForce: Types.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
timeInForce: Types.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||||
side: Types.Side.SIDE_BUY,
|
side: Types.Side.SIDE_BUY,
|
||||||
marketId: '',
|
marketId: '',
|
||||||
|
remaining: '',
|
||||||
})
|
})
|
||||||
).toBe(
|
).toBe(
|
||||||
'Your Fill or Kill (FOK) order was not filled and it has been stopped'
|
'Your Fill or Kill (FOK) order was not filled and it has been stopped'
|
||||||
|
@ -41,6 +41,7 @@ import {
|
|||||||
toBigNum,
|
toBigNum,
|
||||||
truncateByChars,
|
truncateByChars,
|
||||||
formatTrigger,
|
formatTrigger,
|
||||||
|
MAXGOINT64,
|
||||||
} from '@vegaprotocol/utils';
|
} from '@vegaprotocol/utils';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useAssetsMapProvider } from '@vegaprotocol/assets';
|
import { useAssetsMapProvider } from '@vegaprotocol/assets';
|
||||||
@ -585,6 +586,23 @@ export const VegaTransactionDetails = ({ tx }: { tx: VegaStoredTxState }) => {
|
|||||||
<Panel>
|
<Panel>
|
||||||
{t('Close position for')}{' '}
|
{t('Close position for')}{' '}
|
||||||
<strong>{market.tradableInstrument.instrument.code}</strong>
|
<strong>{market.tradableInstrument.instrument.code}</strong>
|
||||||
|
{tx.order?.remaining && (
|
||||||
|
<p>
|
||||||
|
{t('Filled')}{' '}
|
||||||
|
<SizeAtPrice
|
||||||
|
meta={{
|
||||||
|
positionDecimalPlaces: market.positionDecimalPlaces,
|
||||||
|
decimalPlaces: market.decimalPlaces,
|
||||||
|
asset: getAsset(market).symbol,
|
||||||
|
}}
|
||||||
|
side={tx.order.side}
|
||||||
|
size={(
|
||||||
|
BigInt(tx.order.size) - BigInt(tx.order.remaining)
|
||||||
|
).toString()}
|
||||||
|
price={tx.order.price}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
</Panel>
|
</Panel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -953,7 +971,19 @@ export const getVegaTransactionContentIntent = (tx: VegaStoredTxState) => {
|
|||||||
isWithdrawTransaction(tx.body) &&
|
isWithdrawTransaction(tx.body) &&
|
||||||
Intent.Warning;
|
Intent.Warning;
|
||||||
|
|
||||||
|
// Toast for an IOC should go green when it is stopped,
|
||||||
|
// because stopping an IOC once all available volume has filled is the correct behaviour (it is immediate or cancel),
|
||||||
|
// this behaviour should apply to all IOC, not just those created due to "Close position"
|
||||||
|
const intentForClosedPosition =
|
||||||
|
tx.order &&
|
||||||
|
tx.order.status === Schema.OrderStatus.STATUS_STOPPED &&
|
||||||
|
tx.order.timeInForce === Schema.OrderTimeInForce.TIME_IN_FORCE_IOC &&
|
||||||
|
tx.order.size === MAXGOINT64 &&
|
||||||
|
// isClosePositionTransaction(tx) &&
|
||||||
|
Intent.Success;
|
||||||
|
|
||||||
const intent =
|
const intent =
|
||||||
|
intentForClosedPosition ||
|
||||||
intentForRejectedOrder ||
|
intentForRejectedOrder ||
|
||||||
intentForCompletedWithdrawal ||
|
intentForCompletedWithdrawal ||
|
||||||
intentMap[tx.status];
|
intentMap[tx.status];
|
||||||
|
@ -76,6 +76,7 @@ const orderUpdate: OrderTxUpdateFieldsFragment = {
|
|||||||
createdAt: '2022-07-05T14:25:47.815283706Z',
|
createdAt: '2022-07-05T14:25:47.815283706Z',
|
||||||
expiresAt: '2022-07-05T14:25:47.815283706Z',
|
expiresAt: '2022-07-05T14:25:47.815283706Z',
|
||||||
size: '10',
|
size: '10',
|
||||||
|
remaining: '10',
|
||||||
price: '300000',
|
price: '300000',
|
||||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||||
side: Side.SIDE_BUY,
|
side: Side.SIDE_BUY,
|
||||||
|
Loading…
Reference in New Issue
Block a user