diff --git a/package.json b/package.json index 719472f..77b759b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bybit-api", - "version": "3.10.1", + "version": "3.10.2", "description": "Complete & robust Node.js SDK for Bybit's REST APIs and WebSockets, with TypeScript & strong end to end tests.", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/types/response/v5-position.ts b/src/types/response/v5-position.ts index 66fd0a6..6c66be1 100644 --- a/src/types/response/v5-position.ts +++ b/src/types/response/v5-position.ts @@ -4,6 +4,8 @@ import { OrderSideV5, OrderTypeV5, PositionIdx, + PositionSideV5, + PositionStatusV5, StopOrderTypeV5, TPSLModeV5, TradeModeV5, @@ -14,16 +16,16 @@ export interface PositionV5 { riskId: number; riskLimitValue: string; symbol: string; - side: 'Buy' | 'Sell' | 'None'; + side: PositionSideV5; size: string; avgPrice: string; positionValue: string; tradeMode: TradeModeV5; autoAddMargin?: number; - positionStatus: 'Normal' | 'Liq' | 'Adl'; + positionStatus: PositionStatusV5; leverage?: string; markPrice: string; - liqPrice: string; + liqPrice: string | ''; bustPrice?: string; positionIM?: string; positionMM?: string; @@ -31,10 +33,21 @@ export interface PositionV5 { takeProfit?: string; stopLoss?: string; trailingStop?: string; + sessionAvgPrice: string | ''; + delta?: string; + gamma?: string; + vega?: string; + theta?: string; unrealisedPnl: string; + curRealisedPnl: string; cumRealisedPnl: string; + adlRankIndicator: number; + isReduceOnly: boolean; + mmrSysUpdatedTime: string | ''; + leverageSysUpdatedTime: string | ''; createdTime: string; updatedTime: string; + seq: number; } export interface SetRiskLimitResultV5 { @@ -57,7 +70,7 @@ export interface AddOrReduceMarginResultV5 { positionValue: string; leverage: string; autoAddMargin: 0 | 1; - positionStatus: 'Normal' | 'Liq' | 'Adl'; + positionStatus: PositionStatusV5; positionIM: string; positionMM: string; takeProfit: string; diff --git a/src/types/v5-shared.ts b/src/types/v5-shared.ts index 7714548..1eb3864 100644 --- a/src/types/v5-shared.ts +++ b/src/types/v5-shared.ts @@ -95,7 +95,9 @@ export type OrderCreateTypeV5 = /** Order created by Ice berg strategy - web/app. */ | 'CreateByIceBerg' /** Order created by arbitrage - web/app. */ - | 'CreateByArbitrage'; + | 'CreateByArbitrage' + /** Option dynamic delta hedge order - web/app */ + | 'CreateByDdh'; export type OrderCancelTypeV5 = | 'CancelByUser' @@ -151,6 +153,16 @@ export type StopOrderTypeV5 = */ export type PositionIdx = 0 | 1 | 2; +/** + * Position status. + * + * - 'Normal' + * - 'Liq' in the liquidation progress + * - 'Adl' in the auto-deleverage progress + */ +export type PositionStatusV5 = 'Normal' | 'Liq' | 'Adl'; +export type PositionSideV5 = 'Buy' | 'Sell' | 'None' | ''; + export type OptionTypeV5 = 'Call' | 'Put'; /** @@ -221,7 +233,10 @@ export type ExecTypeV5 = | 'AdlTrade' | 'Funding' | 'BustTrade' - | 'Settle'; + | 'Settle' + | 'BlockTrade' + | 'MovePosition' + | 'UNKNOWN'; /** * Withdraw type. 0(default): on chain. 1: off chain. 2: all. diff --git a/src/types/websocket.events.ts b/src/types/websocket.events.ts index b55d964..cb11da5 100644 --- a/src/types/websocket.events.ts +++ b/src/types/websocket.events.ts @@ -1,6 +1,9 @@ import { CategoryV5, + ExecTypeV5, OCOTriggerTypeV5, + OrderCancelTypeV5, + OrderCreateTypeV5, OrderRejectReasonV5, OrderSMPTypeV5, OrderSideV5, @@ -8,30 +11,24 @@ import { OrderTimeInForceV5, OrderTriggerByV5, OrderTypeV5, + PositionIdx, + PositionSideV5, + PositionStatusV5, StopOrderTypeV5, TPSLModeV5, + TradeModeV5, } from './v5-shared'; import { WsKey } from './websockets'; -export interface WSOrderbookEventV5 { - topic: string; +export interface WSPublicTopicEventV5 { + id?: string; + topic: TTopic; + type: TType; + /** Cross sequence */ + cs?: number; /** Event timestamp */ ts: number; - type: 'delta' | 'snapshot'; - data: { - /** Symbol */ - s: string; - /** [price, qty][] */ - b: [string, string][]; - /** [price, qty][] */ - a: [string, string][]; - /** Update ID */ - u: number; - /** - * Cross sequence - */ - seq: number; - }; + data: TData; /** * matching engine timestamp (correlated with T from public trade channel) */ @@ -42,57 +39,154 @@ export interface WSOrderbookEventV5 { wsKey: WsKey; } -export interface WSAccountOrderV5 { - qty: string; - price: string; - symbol: string; - orderId: string; - orderIv: string; - stopLoss: string; - smpGroup: number; - side: OrderSideV5; - placeType: string; - avgPrice?: string; - leavesQty?: string; - isLeverage: string; - cancelType: string; - cumExecQty: string; - cumExecFee: string; - smpOrderId: string; - takeProfit: string; - reduceOnly: boolean; - orderLinkId: string; - positionIdx: number; - tpTriggerBy: string; - slTriggerBy: string; - createdTime: string; - updatedTime: string; - feeCurrency: string; - triggerPrice: string; - category: CategoryV5; - cumExecValue: string; - blockTradeId: string; - leavesValue?: string; - slLimitPrice?: string; - tpLimitPrice?: string; - tpslMode?: TPSLModeV5; - orderType: OrderTypeV5; - smpType: OrderSMPTypeV5; - closeOnTrigger: boolean; - triggerDirection: number; - orderStatus: OrderStatusV5; - lastPriceOnCreated: string; - triggerBy: OrderTriggerByV5; - stopOrderType: StopOrderTypeV5; - timeInForce: OrderTimeInForceV5; - ocoTriggerType?: OCOTriggerTypeV5; - rejectReason?: OrderRejectReasonV5; +export interface WSPrivateTopicEventV5 { + id?: string; + topic: TTopic; + creationTime: number; + data: TData; + wsKey: WsKey; } -export interface WSAccountOrderEventV5 { - id: string; - wsKey: WsKey; - topic: 'order'; - creationTime: number; - data: WSAccountOrderV5[]; +export interface WSOrderbookV5 { + /** Symbol */ + s: string; + /** [price, qty][] */ + b: [string, string][]; + /** [price, qty][] */ + a: [string, string][]; + /** Update ID */ + u: number; + /** Cross sequence */ + seq: number; } + +export type WSOrderbookEventV5 = WSPublicTopicEventV5; + +export interface WSPositionV5 { + category: string; + symbol: string; + side: PositionSideV5; + size: string; + positionIdx: PositionIdx; + tradeMode: TradeModeV5; + positionValue: string; + riskId: number; + riskLimitValue: string; + entryPrice: string; + markPrice: string; + leverage: string; + positionBalance: string; + autoAddMargin: number; + positionMM: string; + positionIM: string; + liqPrice: string; + bustPrice: string; + tpslMode: string; + takeProfit: string; + stopLoss: string; + trailingStop: string; + unrealisedPnl: string; + curRealisedPnl: string; + sessionAvgPrice: string; + delta: string; + gamma: string; + vega: string; + theta: string; + cumRealisedPnl: string; + positionStatus: PositionStatusV5; + adlRankIndicator: number; + isReduceOnly: boolean; + mmrSysUpdatedTime: string; + leverageSysUpdatedTime: string; + createdTime: string; + updatedTime: string; + seq: number; +} + +export type WSPositionEventV5 = WSPrivateTopicEventV5<'position', WSPositionV5[]>; + +export interface WSAccountOrderV5 { + category: CategoryV5; + orderId: string; + orderLinkId: string; + isLeverage: string; + blockTradeId: string; + symbol: string; + price: string; + qty: string; + side: OrderSideV5; + positionIdx: PositionIdx; + orderStatus: OrderStatusV5; + createType: OrderCreateTypeV5; + cancelType: OrderCancelTypeV5; + rejectReason?: OrderRejectReasonV5; + avgPrice?: string; + leavesQty?: string; + leavesValue?: string; + cumExecQty: string; + cumExecValue: string; + cumExecFee: string; + feeCurrency: string; + timeInForce: OrderTimeInForceV5; + orderType: OrderTypeV5; + stopOrderType: StopOrderTypeV5; + ocoTriggerType?: OCOTriggerTypeV5; + orderIv: string; + marketUnit?: 'baseCoin' | 'quoteCoin'; + triggerPrice: string; + takeProfit: string; + stopLoss: string; + tpslMode?: TPSLModeV5; + tpLimitPrice?: string; + slLimitPrice?: string; + tpTriggerBy: string; + slTriggerBy: string; + triggerDirection: number; + triggerBy: OrderTriggerByV5; + lastPriceOnCreated: string; + reduceOnly: boolean; + closeOnTrigger: boolean; + placeType: string; + smpType: OrderSMPTypeV5; + smpGroup: number; + smpOrderId: string; + createdTime: string; + updatedTime: string; +} + +export type WSAccountOrderEventV5 = WSPrivateTopicEventV5<'order', WSAccountOrderV5[]>; + +export interface WSExecutionV5 { + category: CategoryV5; + symbol: string; + isLeverage: string; + orderId: string; + orderLinkId: string; + side: OrderSideV5; + orderPrice: string; + orderQty: string; + leavesQty: string; + createType: OrderCreateTypeV5; + orderType: OrderTypeV5; + stopOrderType: StopOrderTypeV5; + execFee: string; + execId: string; + execPrice: string; + execQty: string; + execType: ExecTypeV5; + execValue: string; + execTime: string; + isMaker: boolean; + feeRate: string; + tradeIv: string; + markIv: string; + markPrice: string; + indexPrice: string; + underlyingPrice: string; + blockTradeId: string; + closedSize: string; + seq: number; + marketUnit: string; +} + +export type WSExecutionEventV5 = WSPrivateTopicEventV5<'execution', WSExecutionV5[]>; \ No newline at end of file diff --git a/src/util/typeGuards.ts b/src/util/typeGuards.ts index e6de059..44308f8 100644 --- a/src/util/typeGuards.ts +++ b/src/util/typeGuards.ts @@ -2,7 +2,7 @@ * Use type guards to narrow down types with minimal efforts. */ -import { WSOrderbookEventV5 } from '../types/websocket.events'; +import { WSAccountOrderEventV5, WSExecutionEventV5, WSOrderbookEventV5, WSPositionEventV5 } from '../types/websocket.events'; /** * Type guard to detect a V5 orderbook event (delta & snapshots) @@ -27,3 +27,63 @@ export function isWsOrderbookEventV5( event['topic'].startsWith('orderbook') ); } + +/** + * Type guard to detect a V5 position event. + * + * @param event + * @returns + */ +export function isWsPositionEventV5( + event: unknown, +): event is WSPositionEventV5 { + if ( + typeof event !== 'object' || + !event || + typeof event['topic'] !== 'string' + ) { + return false; + } + + return event['topic'] === 'position'; +} + +/** + * Type guard to detect a V5 order event. + * + * @param event + * @returns + */ +export function isWsAccountOrderEventV5( + event: unknown, +): event is WSAccountOrderEventV5 { + if ( + typeof event !== 'object' || + !event || + typeof event['topic'] !== 'string' + ) { + return false; + } + + return event['topic'] === 'order'; +} + +/** + * Type guard to detect a V5 execution event. + * + * @param event + * @returns + */ +export function isWsExecutionEventV5( + event: unknown, +): event is WSExecutionEventV5 { + if ( + typeof event !== 'object' || + !event || + typeof event['topic'] !== 'string' + ) { + return false; + } + + return event['topic'] === 'execution'; +} \ No newline at end of file