diff --git a/examples/apidoc/V5/Spread-Trading/amend-spread-order.js b/examples/apidoc/V5/Spread-Trading/amend-spread-order.js new file mode 100644 index 0000000..7ff9d0f --- /dev/null +++ b/examples/apidoc/V5/Spread-Trading/amend-spread-order.js @@ -0,0 +1,21 @@ +const { RestClientV5 } = require('bybit-api'); + +const client = new RestClientV5({ + testnet: true, + key: 'apiKey', + secret: 'apiSecret', +}); + +client + .amendSpreadOrder({ + symbol: 'SOLUSDT_SOL/USDT', + orderLinkId: '1744072052193428475', + price: '14', + qty: '0.2', + }) + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.error(error); + }); diff --git a/examples/apidoc/V5/Spread-Trading/cancel-all-spread-orders.js b/examples/apidoc/V5/Spread-Trading/cancel-all-spread-orders.js new file mode 100644 index 0000000..6f7ca2f --- /dev/null +++ b/examples/apidoc/V5/Spread-Trading/cancel-all-spread-orders.js @@ -0,0 +1,16 @@ +const { RestClientV5 } = require('bybit-api'); + +const client = new RestClientV5({ + testnet: true, + key: 'apiKey', + secret: 'apiSecret', +}); + +client + .cancelAllSpreadOrders() + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.error(error); + }); diff --git a/examples/apidoc/V5/Spread-Trading/cancel-spread-order.js b/examples/apidoc/V5/Spread-Trading/cancel-spread-order.js new file mode 100644 index 0000000..06a1ac7 --- /dev/null +++ b/examples/apidoc/V5/Spread-Trading/cancel-spread-order.js @@ -0,0 +1,18 @@ +const { RestClientV5 } = require('bybit-api'); + +const client = new RestClientV5({ + testnet: true, + key: 'apiKey', + secret: 'apiSecret', +}); + +client + .cancelSpreadOrder({ + orderLinkId: '1744072052193428476', + }) + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.error(error); + }); \ No newline at end of file diff --git a/examples/apidoc/V5/Spread-Trading/create-spread-order.js b/examples/apidoc/V5/Spread-Trading/create-spread-order.js new file mode 100644 index 0000000..450653b --- /dev/null +++ b/examples/apidoc/V5/Spread-Trading/create-spread-order.js @@ -0,0 +1,24 @@ +const { RestClientV5 } = require('bybit-api'); + +const client = new RestClientV5({ + testnet: true, + key: 'apiKey', + secret: 'apiSecret', +}); + +client + .submitSpreadOrder({ + symbol: 'SOLUSDT_SOL/USDT', + side: 'Buy', + orderType: 'Limit', + qty: '0.1', + price: '21', + orderLinkId: '1744072052193428479', + timeInForce: 'PostOnly', + }) + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.error(error); + }); diff --git a/examples/apidoc/V5/Spread-Trading/get-spread-instruments-info.js b/examples/apidoc/V5/Spread-Trading/get-spread-instruments-info.js new file mode 100644 index 0000000..47edf17 --- /dev/null +++ b/examples/apidoc/V5/Spread-Trading/get-spread-instruments-info.js @@ -0,0 +1,14 @@ +const { RestClientV5 } = require('bybit-api'); + +const client = new RestClientV5({ + testnet: true, +}); + +client + .getSpreadInstrumentsInfo() + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.error(error); + }); diff --git a/examples/apidoc/V5/Spread-Trading/get-spread-open-orders.js b/examples/apidoc/V5/Spread-Trading/get-spread-open-orders.js new file mode 100644 index 0000000..dee4cb0 --- /dev/null +++ b/examples/apidoc/V5/Spread-Trading/get-spread-open-orders.js @@ -0,0 +1,16 @@ +const { RestClientV5 } = require('bybit-api'); + +const client = new RestClientV5({ + testnet: true, + key: 'apiKey', + secret: 'apiSecret', +}); + +client + .getSpreadOpenOrders() + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.error(error); + }); diff --git a/examples/apidoc/V5/Spread-Trading/get-spread-order-history.js b/examples/apidoc/V5/Spread-Trading/get-spread-order-history.js new file mode 100644 index 0000000..3b502b9 --- /dev/null +++ b/examples/apidoc/V5/Spread-Trading/get-spread-order-history.js @@ -0,0 +1,18 @@ +const { RestClientV5 } = require('bybit-api'); + +const client = new RestClientV5({ + testnet: true, + key: 'apiKey', + secret: 'apiSecret', +}); + +client + .getSpreadOrderHistory({ + orderId: '5e010c35-2b44-4f03-8081-8fa31fb73376', + }) + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.error(error); + }); diff --git a/examples/apidoc/V5/Spread-Trading/get-spread-orderbook.js b/examples/apidoc/V5/Spread-Trading/get-spread-orderbook.js new file mode 100644 index 0000000..a5240a2 --- /dev/null +++ b/examples/apidoc/V5/Spread-Trading/get-spread-orderbook.js @@ -0,0 +1,17 @@ +const { RestClientV5 } = require('bybit-api'); + +const client = new RestClientV5({ + testnet: true, +}); + +client + .getSpreadOrderbook({ + symbol: 'SOLUSDT_SOL/USDT', + limit: 1, // Show 5 levels of depth + }) + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.error(error); + }); diff --git a/examples/apidoc/V5/Spread-Trading/get-spread-tickers.js b/examples/apidoc/V5/Spread-Trading/get-spread-tickers.js new file mode 100644 index 0000000..575aeef --- /dev/null +++ b/examples/apidoc/V5/Spread-Trading/get-spread-tickers.js @@ -0,0 +1,16 @@ +const { RestClientV5 } = require('bybit-api'); + +const client = new RestClientV5({ + testnet: true, +}); + +client + .getSpreadTickers({ + symbol: 'SOLUSDT_SOL/USDT', + }) + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.error(error); + }); diff --git a/examples/apidoc/V5/Spread-Trading/get-spread-trade-history.js b/examples/apidoc/V5/Spread-Trading/get-spread-trade-history.js new file mode 100644 index 0000000..42e2033 --- /dev/null +++ b/examples/apidoc/V5/Spread-Trading/get-spread-trade-history.js @@ -0,0 +1,18 @@ +const { RestClientV5 } = require('bybit-api'); + +const client = new RestClientV5({ + testnet: true, + key: 'apiKey', + secret: 'apiSecret', +}); + +client + .getSpreadTradeHistory({ + orderId: '5e010c35-2b44-4f03-8081-8fa31fb73376', + }) + .then((response) => { + console.log(response); + }) + .catch((error) => { + console.error(error); + }); diff --git a/package-lock.json b/package-lock.json index 87243da..049f6cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bybit-api", - "version": "4.1.3", + "version": "4.1.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "bybit-api", - "version": "4.1.3", + "version": "4.1.4", "license": "MIT", "dependencies": { "axios": "^1.7.9", diff --git a/package.json b/package.json index d0b6d56..5c2bc79 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bybit-api", - "version": "4.1.3", + "version": "4.1.4", "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/rest-client-v5.ts b/src/rest-client-v5.ts index 695ef6c..b474354 100644 --- a/src/rest-client-v5.ts +++ b/src/rest-client-v5.ts @@ -16,6 +16,7 @@ import { AllCoinsBalanceV5, AllowedDepositCoinInfoV5, AmendOrderParamsV5, + AmendSpreadOrderParamsV5, ApiKeyInfoV5, AssetInfoV5, BatchAmendOrderParamsV5, @@ -125,6 +126,10 @@ import { GetRiskLimitParamsV5, GetSettlementRecordParamsV5, GetSpotLeveragedTokenOrderHistoryParamsV5, + GetSpreadInstrumentsInfoParamsV5, + GetSpreadOpenOrdersParamsV5, + GetSpreadOrderHistoryParamsV5, + GetSpreadTradeHistoryParamsV5, GetSubAccountAllApiKeysParamsV5, GetSubAccountDepositRecordParamsV5, GetTickersParamsV5, @@ -196,7 +201,15 @@ import { SpotBorrowCheckResultV5, SpotLeveragedTokenOrderHistoryV5, SpotMarginStateV5, + SpreadInstrumentInfoV5, + SpreadOpenOrderV5, + SpreadOrderHistoryV5, + SpreadOrderbookResponseV5, + SpreadRecentTradeV5, + SpreadTickerV5, + SpreadTradeV5, SubMemberV5, + SubmitSpreadOrderParamsV5, SubmitStakeRedeemParamsV5, SwitchIsolatedMarginParamsV5, SwitchPositionModeParamsV5, @@ -336,6 +349,163 @@ export class RestClientV5 extends BaseRestClient { return this.postPrivate('/v5/user/create-demo-member'); } + /** + * + ****** Spread Trading APIs + * + */ + + /** + * Get Spread Instruments Info + */ + getSpreadInstrumentsInfo(params?: GetSpreadInstrumentsInfoParamsV5): Promise< + APIResponseV3WithTime<{ + list: SpreadInstrumentInfoV5[]; + nextPageCursor: string; + }> + > { + return this.get('/v5/spread/instrument', params); + } + + /** + * Get Spread Orderbook + */ + getSpreadOrderbook(params: { + symbol: string; + limit?: number; + }): Promise> { + return this.get('/v5/spread/orderbook', params); + } + + /** + * Get Spread Tickers + */ + getSpreadTickers(params: { symbol: string }): Promise< + APIResponseV3WithTime<{ + list: SpreadTickerV5[]; + }> + > { + return this.get('/v5/spread/tickers', params); + } + + /** + * Get Spread Public Recent Trades + */ + getSpreadRecentTrades(params: { symbol: string; limit?: number }): Promise< + APIResponseV3WithTime<{ + list: SpreadRecentTradeV5[]; + }> + > { + return this.get('/v5/spread/recent-trade', params); + } + + /** + * Create Spread Order + */ + submitSpreadOrder(params: SubmitSpreadOrderParamsV5): Promise< + APIResponseV3WithTime<{ + orderId: string; + orderLinkId: string; + }> + > { + return this.postPrivate('/v5/spread/order/create', params); + } + + /** + * Amend Spread Order + * You can only modify unfilled or partially filled orders. + */ + amendSpreadOrder(params: AmendSpreadOrderParamsV5): Promise< + APIResponseV3WithTime<{ + orderId: string; + orderLinkId: string; + }> + > { + return this.postPrivate('/v5/spread/order/amend', params); + } + + /** + * Cancel Spread Order + */ + cancelSpreadOrder(params: { + orderId?: string; + orderLinkId?: string; + }): Promise< + APIResponseV3WithTime<{ + orderId: string; + orderLinkId: string; + }> + > { + return this.postPrivate('/v5/spread/order/cancel', params); + } + + /** + * Cancel All Spread Orders + * + * When a symbol is specified, all orders for that symbol will be canceled regardless of the cancelAll field. + * When symbol is not specified and cancelAll=true, all orders, regardless of the symbol, will be canceled. + */ + cancelAllSpreadOrders(params?: { + symbol?: string; + cancelAll?: boolean; + }): Promise< + APIResponseV3WithTime<{ + list: { + orderId: string; + orderLinkId: string; + }[]; + success: string; + }> + > { + return this.postPrivate('/v5/spread/order/cancel-all', params); + } + + /** + * Get Spread Open Orders + * Query unfilled or partially filled orders in real-time. + */ + getSpreadOpenOrders(params?: GetSpreadOpenOrdersParamsV5): Promise< + APIResponseV3WithTime<{ + list: SpreadOpenOrderV5[]; + nextPageCursor: string; + }> + > { + return this.getPrivate('/v5/spread/order/realtime', params); + } + + /** + * Get Spread Order History + * + * Note: + * - orderId & orderLinkId has a higher priority than startTime & endTime + * - Fully canceled orders are stored for up to 24 hours + * - Single leg orders can also be found with "createType"=CreateByFutureSpread via Get Order History + */ + getSpreadOrderHistory(params?: GetSpreadOrderHistoryParamsV5): Promise< + APIResponseV3WithTime<{ + list: SpreadOrderHistoryV5[]; + nextPageCursor: string; + }> + > { + return this.getPrivate('/v5/spread/order/history', params); + } + + /** + * Get Spread Trade History + * + * Note: + * - In self-trade cases, both the maker and taker single-leg trades will be returned in the same request + * - Single leg executions can also be found with "execType"=FutureSpread via Get Trade History + */ + getSpreadTradeHistory(params?: GetSpreadTradeHistoryParamsV5): Promise< + APIResponseV3WithTime<{ + list: SpreadTradeV5[]; + nextPageCursor: string; + }> + > { + return this.getPrivate('/v5/spread/execution/list', params); + } + /** * ****** Market APIs diff --git a/src/types/index.ts b/src/types/index.ts index c8094cd..5f8a7a0 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,5 +1,8 @@ -export * from './response'; export * from './request'; +export * from './request/v5-spreadtrading'; +export * from './response'; +export * from './response/v5-spreadtrading'; export * from './shared'; export * from './shared-v5'; export * from './websockets'; + diff --git a/src/types/request/v5-spreadtrading.ts b/src/types/request/v5-spreadtrading.ts new file mode 100644 index 0000000..76ebe15 --- /dev/null +++ b/src/types/request/v5-spreadtrading.ts @@ -0,0 +1,53 @@ +export interface GetSpreadInstrumentsInfoParamsV5 { + symbol?: string; + baseCoin?: string; + limit?: number; + cursor?: string; +} + +export interface SubmitSpreadOrderParamsV5 { + symbol: string; + side: 'Buy' | 'Sell'; + orderType: 'Limit' | 'Market'; + qty: string; + price: string; + orderLinkId: string; + timeInForce: 'IOC' | 'FOK' | 'GTC' | 'PostOnly'; +} + +export interface AmendSpreadOrderParamsV5 { + symbol: string; + orderId?: string; + orderLinkId?: string; + qty?: string; + price?: string; +} + +export interface GetSpreadOpenOrdersParamsV5 { + symbol?: string; + baseCoin?: string; + orderId?: string; + orderLinkId?: string; + limit?: number; + cursor?: string; +} +export interface GetSpreadOrderHistoryParamsV5 { + symbol?: string; + baseCoin?: string; + orderId?: string; + orderLinkId?: string; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; +} + +export interface GetSpreadTradeHistoryParamsV5 { + symbol?: string; + orderId?: string; + orderLinkId?: string; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; +} diff --git a/src/types/response/v5-spreadtrading.ts b/src/types/response/v5-spreadtrading.ts new file mode 100644 index 0000000..5a8f535 --- /dev/null +++ b/src/types/response/v5-spreadtrading.ts @@ -0,0 +1,124 @@ +export interface SpreadInstrumentInfoV5 { + symbol: string; + contractType: 'FundingRateArb' | 'CarryTrade' | 'FutureSpread' | 'PerpBasis'; + status: 'Trading' | 'Settling'; + baseCoin: string; + quoteCoin: string; + settleCoin: string; + tickSize: string; + minPrice: string; + maxPrice: string; + lotSize: string; + minSize: string; + maxSize: string; + launchTime: string; + deliveryTime: string; + legs: { + symbol: string; + contractType: 'LinearPerpetual' | 'LinearFutures' | 'Spot'; + }[]; +} + +export interface SpreadOrderbookResponseV5 { + s: string; // Symbol + b: [string, string][]; // Bids array [price, size] + a: [string, string][]; // Asks array [price, size] + u: number; // Update ID + ts: number; // Timestamp + seq: number; // Sequence + cts: number; // Cross timestamp +} + +export interface SpreadTickerV5 { + symbol: string; // Spread combination symbol name + bidPrice: string; // Bid 1 price + bidSize: string; // Bid 1 size + askPrice: string; // Ask 1 price + askSize: string; // Ask 1 size + lastPrice: string; // Last trade price + highPrice24h: string; // The highest price in the last 24 hours + lowPrice24h: string; // The lowest price in the last 24 hours + prevPrice24h: string; // Price 24 hours ago + volume24h: string; // Volume for 24h +} + +export interface SpreadRecentTradeV5 { + execId: string; // Execution ID + symbol: string; // Spread combination symbol name + price: string; // Trade price + size: string; // Trade size + side: 'Buy' | 'Sell'; // Side of taker + time: string; // Trade time (ms) +} + +export interface SpreadOpenOrderV5 { + symbol: string; + baseCoin: string; + orderType: 'Market' | 'Limit'; + orderLinkId: string; + side: 'Buy' | 'Sell'; + timeInForce: 'GTC' | 'FOK' | 'IOC' | 'PostOnly'; + orderId: string; + leavesQty: string; + orderStatus: 'New' | 'PartiallyFilled'; + cumExecQty: string; + price: string; + qty: string; + createdTime: string; + updatedTime: string; +} + +export interface SpreadOrderHistoryV5 { + symbol: string; + orderType: 'Market' | 'Limit'; + orderLinkId: string; + orderId: string; + contractType: 'FundingRateArb' | 'CarryTrade' | 'FutureSpread' | 'PerpBasis'; + orderStatus: 'Rejected' | 'Cancelled' | 'Filled'; + price: string; + orderQty: string; + orderPrice: string; + timeInForce: 'GTC' | 'FOK' | 'IOC' | 'PostOnly'; + baseCoin: string; + createdAt: string; + updatedAt: string; + side: 'Buy' | 'Sell'; + leavesQty: string; + settleCoin: string; + cumExecQty: string; + qty: string; + leg1Symbol: string; + leg1ProdType: 'Futures' | 'Spot'; + leg1OrderId: string; + leg1Side: string; + leg2ProdType: 'Futures' | 'Spot'; + leg2OrderId: string; + leg2Symbol: string; + leg2Side: string; +} + +export interface SpreadTradeLegV5 { + symbol: string; + side: 'Buy' | 'Sell'; + execPrice: string; + execTime: string; + execValue: string; + execType: string; + category: 'linear' | 'spot'; + execQty: string; + execFee: string; + execId: string; +} + +export interface SpreadTradeV5 { + symbol: string; + orderLinkId: string; + side: 'Buy' | 'Sell'; + orderId: string; + execPrice: string; + execTime: string; + execType: 'Trade'; + execQty: string; + execId: string; + legs: SpreadTradeLegV5[]; +} diff --git a/src/types/shared-v5.ts b/src/types/shared-v5.ts index f42352f..e4fcb8a 100644 --- a/src/types/shared-v5.ts +++ b/src/types/shared-v5.ts @@ -258,6 +258,7 @@ export interface PermissionsV5 { CopyTrading?: string[]; BlockTrade?: string[]; Exchange?: string[]; + /** @deprecated , always returns []*/ NFT?: string[]; } diff --git a/src/types/websockets/ws-events.ts b/src/types/websockets/ws-events.ts index 548fcef..8d073f6 100644 --- a/src/types/websockets/ws-events.ts +++ b/src/types/websockets/ws-events.ts @@ -383,3 +383,69 @@ export interface WSGreeksV5 { } export type WSGreeksEventV5 = WSPrivateTopicEventV5<'greeks', WSGreeksV5[]>; + +export interface WSSpreadOrderV5 { + category: 'combination' | 'spot_leg' | 'future_leg'; + symbol: string; + parentOrderId: string; + orderId: string; + orderLinkId: string; + side: OrderSideV5; + orderStatus: OrderStatusV5; + cancelType: OrderCancelTypeV5; + rejectReason: OrderRejectReasonV5; + timeInForce: OrderTimeInForceV5; + price: string; + qty: string; + avgPrice: string; + leavesQty: string; + leavesValue: string; + cumExecQty: string; + cumExecValue: string; + cumExecFee: string; + orderType: OrderTypeV5; + isLeverage: string; + createdTime: string; + updatedTime: string; + feeCurrency: string; + createType: OrderCreateTypeV5; + closedPnl: string; +} + +export type WSSpreadOrderEventV5 = WSPrivateTopicEventV5< + 'spread.order', + WSSpreadOrderV5[] +>; + +export interface WSSpreadExecutionV5 { + category: 'combination' | 'spot_leg' | 'future_leg'; + symbol: string; + isLeverage: string; + orderId: string; + orderLinkId: string; + side: OrderSideV5; + orderPrice: string; + orderQty: string; + leavesQty: string; + createType: OrderCreateTypeV5; + orderType: OrderTypeV5; + execFee: string; + parentExecId: string; + execId: string; + execPrice: string; + execQty: string; + execPnl: string; + execType: ExecTypeV5; + execValue: string; + execTime: string; + isMaker: boolean; + feeRate: string; + markPrice: string; + closedSize: string; + seq: number; +} + +export type WSSpreadExecutionEventV5 = WSPrivateTopicEventV5< + 'spread.execution', + WSSpreadExecutionV5[] +>;