Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement ws order type refactoring #320

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions src/client/webSocket/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,8 @@ const transformL2orderbookMessage = (
indexPrice: short.ip,
});

const transformOrderFill = (
short: idex.WebSocketResponseOrderFillShort,
): idex.IDEXOrderFillEventData =>
removeUndefinedFromObj({
function transformOrderFill(short: idex.WebSocketResponseOrderFillShort) {
return removeUndefinedFromObj({
type: short.y,
fillId: short.i,
price: short.p,
Expand All @@ -142,20 +140,20 @@ const transformOrderFill = (
txId: short.T,
txStatus: short.S,
});
}

const transformOrdersMessage = (
function transformOrdersMessage(
short: idex.WebSocketResponseOrderShort,
): idex.IDEXOrderEventData => {
if (!('o' in short)) {
): idex.IDEXOrderEventData {
if (!short.o) {
return removeUndefinedFromObj({
market: short.m,
wallet: short.w,
executionTime: short.t,
side: short.s,
...(short.F && { fills: short.F.map(transformOrderFill) }),
} satisfies
| idex.IDEXOrderEventDataLiquidation
| idex.IDEXOrderEventDataDeleverage);
// should only include a single fill but we map for future compat
fills: short.F.map(transformOrderFill),
} satisfies idex.IDEXOrderEventDataSystemFill);
}

return removeUndefinedFromObj({
Expand Down Expand Up @@ -188,7 +186,7 @@ const transformOrdersMessage = (
isLiquidationAcquisitionOnly: short.la,
...(short.F && { fills: short.F.map(transformOrderFill) }),
} satisfies idex.IDEXOrderEventDataGeneral);
};
}

const transformDepositsMessage = (
short: idex.WebSocketResponseDepositsShort,
Expand Down
67 changes: 36 additions & 31 deletions src/types/enums/response.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {
OrderType,
SubscriptionNameAuthenticated,
SubscriptionNamePublic,
} from '#types/enums/request';
Expand Down Expand Up @@ -28,21 +27,10 @@ export const PositionSide = Object.freeze({
export type PositionSide = (typeof PositionSide)[keyof typeof PositionSide];

/**
* Whether the fill increases or decreases the notional value of the position
*
*
* @category Enums - Response Properties
* @enum
* Specialized fill types which do not include orders and may produce different
* messaging / types in various places within the code.
*/
export const FillType = Object.freeze({
/**
* Fills resulting from any type of market order.
*/
market: 'market',
/**
* Fills resulting from any type of limit order.
*/
limit: 'limit',
export const FillTypeSystem = Object.freeze({
/**
* Position closures resulting from forced liquidation or ADL.
*/
Expand All @@ -57,6 +45,39 @@ export const FillType = Object.freeze({
closure: 'closure',
} as const);

export type FillTypeSystem =
(typeof FillTypeSystem)[keyof typeof FillTypeSystem];

/**
* Fill types associated with an order.
*/
export const FillTypeOrder = Object.freeze({
/**
* Fills resulting from any type of market order.
*/
market: 'market',
/**
* Fills resulting from any type of limit order.
*/
limit: 'limit',
} as const);

export type FillTypeOrder = (typeof FillTypeOrder)[keyof typeof FillTypeOrder];

/**
* Whether the fill increases or decreases the notional value of the position.
*
* - Includes {@link FillTypeSysem} properties which may produce different
* message types in places like the WebSocket API.
*
* @category Enums - Response Properties
* @enum
*/
export const FillType = Object.freeze({
...FillTypeOrder,
...FillTypeSystem,
});

export type FillType = (typeof FillType)[keyof typeof FillType];

/**
Expand Down Expand Up @@ -244,22 +265,6 @@ export const OrderBookLevelType = Object.freeze({
export type OrderBookLevelType =
(typeof OrderBookLevelType)[keyof typeof OrderBookLevelType];

/**
* Can be used as a convenience when specifying your orders for WebSocket
* to benefit from inline documentation and auto-complete.
*
* @category Enums - Response Properties
* @enum
*
* @see docs [API Documentation: Order Types](https://api-docs-v4.idex.io/#order-types)
*/
export const OrderEventType = Object.freeze({
...OrderType,
} as const);

export type OrderEventType =
(typeof OrderEventType)[keyof typeof OrderEventType];

/**
* Can be used as a convenience when specifying your orders for WebSocket
* to benefit from inline documentation and auto-complete.
Expand Down
101 changes: 52 additions & 49 deletions src/types/webSocket/response/orders.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type * as idex from '#index';
import type { MessageEventType } from '#types/enums/index';
import type { OrderEventType, OrderStateChange } from '#types/enums/response';
import type { MessageEventType, OrderType } from '#types/enums/index';
import type { OrderStateChange } from '#types/enums/response';
import type { IDEXOrder } from '#types/rest/endpoints/GetOrders';
import type { IDEXSubscriptionEventBase } from '#types/webSocket/base';
import type { IDEXOrderFillEventData } from './ordersFill.js';

/**
* - `orders` updates provided to the message handler when subscribed.
*
Expand Down Expand Up @@ -59,10 +60,9 @@ export interface IDEXOrderEventDataBase
/**
* - When `undefined`, indicates the message is a `liquidation` or `deleverage`
* where `fills` will include a single {@link IDEXOrderFillEventData.type} of
* {@link idex.FillType.liquidation liquidation} or
* {@link idex.FillType.deleverage deleverage}.
* {@link idex.FillTypeSystem FillTypeSystem}.
*/
type?: OrderEventType;
readonly type?: OrderType;
/**
* Timestamp of the most recent update
*/
Expand All @@ -72,29 +72,25 @@ export interface IDEXOrderEventDataBase
*
* @see type {@link IDEXOrderFillEventData}
*/
fills?: IDEXOrderFillEventData[];
readonly fills?: IDEXOrderFillEventData[];
}

/**
* {@link OrderEventType.deleverage} and {@link OrderEventType.liquidation} updates do not
* {@link idex.IDEXOrderFillEventDataSystem IDEXOrderFillEventDataSystem} updates do not
* include many of the standard order update properties
*
* @category IDEX - Get Orders
*/
export interface IDEXOrderEventDataDeleverage extends IDEXOrderEventDataBase {}

/**
* {@link OrderEventType.deleverage} and {@link OrderEventType.liquidation} updates do not
* include many of the standard order update properties
* - Note that these types include a single {@link IDEXOrderFillEventDataSystem}.
*
* @category IDEX - Get Orders
*/
export interface IDEXOrderEventDataLiquidation extends IDEXOrderEventDataBase {}
export interface IDEXOrderEventDataSystemFill extends IDEXOrderEventDataBase {
readonly type?: undefined;
readonly fills: IDEXOrderFillEventData[];
}

/**
* All types other than {@link OrderEventType.deleverage deleverage}
* and {@link OrderEventType.liquidation liquidation} include extra
* properties representing the order update.
* All types other than {@link IDEXOrderEventDataSystemFill} include
* most properties from {@link IDEXOrder}
*
* @category IDEX - Get Orders
*/
Expand All @@ -104,7 +100,7 @@ export interface IDEXOrderEventDataGeneral
/**
* @inheritDoc
*/
readonly type: OrderEventType;
readonly type: OrderType;
/**
* Type of order update
*
Expand All @@ -117,31 +113,34 @@ export interface IDEXOrderEventDataGeneral
* @see related {@link idex.IDEXOrderBook.sequence}
*/
sequence?: idex.IDEXOrderBook['sequence'];
readonly fills?: IDEXOrderFillEventData[];
}

/**
* Order updates received from the WebSocket differ from orders retreived from the
* REST API in several ways.
*
* - In addition to the order types received when getting orders from the REST API, WebSocket update events
* may also provide the following types:
* - {@link OrderEventType.deleverage OrderEventType.deleverage}
* - {@link OrderEventType.liquidation OrderEventType.liquidation}
* may also provide the following `undefined` type indicating a {@link IDEXOrderEventDataSystemFill}
* where the `fills` property will include a {@link idex.FillTypeSystem FillTypeSystem} fill matching
* {@link idex.IDEXOrderFillEventDataSystem IDEXOrderFillEventDataSystem}
* - It is best to narrow on the `type` property between these types and all the
* others as shown in the example below.
* - This is made easiest by using the {@link OrderEventType} enum as shown.
* - This is made easiest by using the {@link OrderType} enum as shown.
*
* @example
* ```typescript
* import { OrderEventType } from '@idexio/idex-sdk';
* import { OrderType } from '@idexio/idex-sdk';
*
* if (
* orderEventData.type === OrderEventType.liquidation ||
* orderEventData.type === OrderEventType.deleverage
* ) {
* // orderLong is of type IDEXOrderEventDataLiquidation | IDEXOrderEventDataDeleverage
* if (!orderEventData.type) {
* // orderLong is of type IIDEXOrderEventDataSystemFill
* } else {
* // orderLong is of type IDEXOrderEventDataGeneral
* switch(orderEventData.type) {
* case OrderType.fill:
* break;
* // ...etc
* }
* }
* ```
*
Expand All @@ -153,14 +152,12 @@ export interface IDEXOrderEventDataGeneral
* @category WebSocket - Message Types
*
* @see union {@link IDEXOrderEventDataGeneral}
* @see union {@link IDEXOrderEventDataLiquidation}
* @see union {@link IDEXOrderEventDataDeleverage}
* @see union {@link IDEXOrderEventDataSystemFill}
* @see parent {@link IDEXOrderEvent}
*/
export type IDEXOrderEventData =
| IDEXOrderEventDataGeneral
| IDEXOrderEventDataLiquidation
| IDEXOrderEventDataDeleverage;
| IDEXOrderEventDataSystemFill
| IDEXOrderEventDataGeneral;

export interface WebSocketResponseSubscriptionMessageShortOrders
extends IDEXSubscriptionEventBase {
Expand All @@ -169,6 +166,11 @@ export interface WebSocketResponseSubscriptionMessageShortOrders
}

export interface WebSocketResponseOrderShortBase {
/**
* @see related {@link IDEXOrder.type}
* @see inflated {@link IDEXOrderEventDataGeneral.type}
*/
o?: IDEXOrderEventDataGeneral['type'];
/**
* @see related {@link IDEXOrder.market}
* @see inflated {@link IDEXOrderEventDataGeneral.market}
Expand Down Expand Up @@ -204,18 +206,17 @@ export interface WebSocketResponseOrderShortBase {
/**
* @internal
*
* `liquidation` types do not include many of the properties of other order types
*/
export interface WebSocketResponseOrderShortDeleverage
extends WebSocketResponseOrderShortBase {}

/**
* @internal
*
* `liquidation` types do not include many of the properties of other order types
* `liquidation`, `deleverage`, and `closure` types do not include many of the
* properties of other order types
*/
export interface WebSocketResponseOrderShortLiquidation
extends WebSocketResponseOrderShortBase {}
export interface WebSocketResponseOrderShortSystem
extends WebSocketResponseOrderShortBase {
/**
* @inheritDoc
*/
readonly o?: undefined;
readonly F: idex.WebSocketResponseOrderFillShort[];
}

/**
* @internal
Expand All @@ -224,6 +225,9 @@ export interface WebSocketResponseOrderShortLiquidation
*/
export interface WebSocketResponseOrderShortGeneral
extends WebSocketResponseOrderShortBase {
/**
* @inheritDoc
*/
o: IDEXOrderEventDataGeneral['type'];
/**
* @see related {@link IDEXOrder.orderId}
Expand Down Expand Up @@ -345,9 +349,9 @@ export interface WebSocketResponseOrderShortGeneral
*
* This type is a discriminated union by property `o` of two types:
* - {@link WebSocketResponseOrderShortGeneral}
* - {@link WebSocketResponseOrderShortLiquidation}
* - {@link WebSocketResponseOrderShortSystem}
*
* When `o` is `liquidation`, the type is {@link WebSocketResponseOrderShortLiquidation} and
* When `o` is `liquidation`, the type is {@link WebSocketResponseOrderShortSystem} and
* will not include many of the properties that are included when `o` is not `liquidation`.
*
* @example
Expand All @@ -361,5 +365,4 @@ export interface WebSocketResponseOrderShortGeneral
*/
export type WebSocketResponseOrderShort =
| WebSocketResponseOrderShortGeneral
| WebSocketResponseOrderShortDeleverage
| WebSocketResponseOrderShortLiquidation;
| WebSocketResponseOrderShortSystem;
Loading
Loading