From d6ca73b08a4a27a2a9d71e8648c461f57a5ebe44 Mon Sep 17 00:00:00 2001 From: tiagosiebler Date: Sat, 12 Nov 2022 11:26:53 +0000 Subject: [PATCH] feat(#195): add contract client for REST endpoints --- README.md | 4 +- examples/rest-contract-private.ts | 24 ++ src/contract-client.ts | 377 ++++++++++++++++++++++++++++++ src/index.ts | 1 + src/types/request/contract.ts | 67 ++++++ src/types/request/index.ts | 1 + 6 files changed, 472 insertions(+), 2 deletions(-) create mode 100644 examples/rest-contract-private.ts create mode 100644 src/contract-client.ts create mode 100644 src/types/request/contract.ts diff --git a/README.md b/README.md index 2a845a8..4866680 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,10 @@ Node.js connector for the Bybit APIs and WebSockets: ## Related projects Check out my related projects: - Try my connectors: - - [ftx-api](https://www.npmjs.com/package/ftx-api) - - [bybit-api](https://www.npmjs.com/package/bybit-api) - [binance](https://www.npmjs.com/package/binance) + - [bybit-api](https://www.npmjs.com/package/bybit-api) - [okx-api](https://www.npmjs.com/package/okx-api) + - [ftx-api](https://www.npmjs.com/package/ftx-api) - Try my misc utilities: - [orderbooks](https://www.npmjs.com/package/orderbooks) - Check out my examples: diff --git a/examples/rest-contract-private.ts b/examples/rest-contract-private.ts new file mode 100644 index 0000000..8a0801b --- /dev/null +++ b/examples/rest-contract-private.ts @@ -0,0 +1,24 @@ +import { ContractClient } from '../src/index'; + +// or +// import { ContractClient } from 'bybit-api'; + +const key = process.env.API_KEY_COM; +const secret = process.env.API_SECRET_COM; + +const client = new ContractClient({ + key, + secret, + strict_param_validation: true, +}); + +(async () => { + try { + const getPositions = await client.getPositions({ + settleCoin: 'USDT', + }); + console.log('getPositions:', getPositions); + } catch (e) { + console.error('request failed: ', e); + } +})(); diff --git a/src/contract-client.ts b/src/contract-client.ts new file mode 100644 index 0000000..6878194 --- /dev/null +++ b/src/contract-client.ts @@ -0,0 +1,377 @@ +import { + APIResponseWithTime, + APIResponseV3, + InternalTransferRequest, + UM7DayTradingHistoryRequest, + UMBorrowHistoryRequest, + UMCandlesRequest, + UMCategory, + UMExchangeCoinsRequest, + UMFundingRateHistoryRequest, + UMInstrumentInfoRequest, + UMOpenInterestRequest, + UMOptionDeliveryPriceRequest, + UMOptionsSettlementHistoryRequest, + UMPerpSettlementHistoryRequest, + UMPublicTradesRequest, + UMSetTPSLRequest, + UMTransactionLogRequest, + ContractOrderRequest, + ContractHistoricOrdersRequest, + ContractCancelOrderRequest, + ContractModifyOrderRequest, + ContractActiveOrdersRequest, + ContractPositionsRequest, +} from './types'; +import { REST_CLIENT_TYPE_ENUM } from './util'; +import BaseRestClient from './util/BaseRestClient'; + +/** + * REST API client for Derivatives V3 Contract APIs + */ +export class ContractClient extends BaseRestClient { + getClientType() { + // Follows the same authentication mechanism as other v3 APIs (e.g. USDC) + return REST_CLIENT_TYPE_ENUM.v3; + } + + async fetchServerTime(): Promise { + const res = await this.getServerTime(); + return Number(res.time_now); + } + + /** + * + * Market Data Endpoints : these seem exactly the same as the unified margin market data endpoints + * + */ + + /** Query order book info. Each side has a depth of 25 orders. */ + getOrderBook( + symbol: string, + category: string, + limit?: number + ): Promise> { + return this.get('/derivatives/v3/public/order-book/L2', { + category, + symbol, + limit, + }); + } + + /** Get candles/klines */ + getCandles(params: UMCandlesRequest): Promise> { + return this.get('/derivatives/v3/public/kline', params); + } + + /** Get a symbol price/statistics ticker */ + getSymbolTicker( + category: UMCategory, + symbol?: string + ): Promise> { + return this.get('/derivatives/v3/public/tickers', { category, symbol }); + } + + /** Get trading rules per symbol/contract, incl price/amount/value/leverage filters */ + getInstrumentInfo( + params: UMInstrumentInfoRequest + ): Promise> { + return this.get('/derivatives/v3/public/instruments-info', params); + } + + /** Query mark price kline (like getCandles() but for mark price). */ + getMarkPriceCandles(params: UMCandlesRequest): Promise> { + return this.get('/derivatives/v3/public/mark-price-kline', params); + } + + /** Query Index Price Kline */ + getIndexPriceCandles(params: UMCandlesRequest): Promise> { + return this.get('/derivatives/v3/public/index-price-kline', params); + } + + /** + * The funding rate is generated every 8 hours at 00:00 UTC, 08:00 UTC and 16:00 UTC. + * For example, if a request is sent at 12:00 UTC, the funding rate generated earlier that day at 08:00 UTC will be sent. + */ + getFundingRateHistory( + params: UMFundingRateHistoryRequest + ): Promise> { + return this.get( + '/derivatives/v3/public/funding/history-funding-rate', + params + ); + } + + /** Get Risk Limit */ + getRiskLimit( + category: UMCategory, + symbol: string + ): Promise> { + return this.get('/derivatives/v3/public/risk-limit/list', { + category, + symbol, + }); + } + + /** Get option delivery price */ + getOptionDeliveryPrice( + params: UMOptionDeliveryPriceRequest + ): Promise> { + return this.get('/derivatives/v3/public/delivery-price', params); + } + + /** Get public trading history */ + getTrades(params: UMPublicTradesRequest): Promise> { + return this.get('/derivatives/v3/public/recent-trade', params); + } + + /** + * Gets the total amount of unsettled contracts. + * In other words, the total number of contracts held in open positions. + */ + getOpenInterest(params: UMOpenInterestRequest): Promise> { + return this.get('/derivatives/v3/public/open-interest', params); + } + + /** + * + * Contract Account Endpoints + * + */ + + /** -> Order API */ + + /** Place an order */ + submitOrder(params: ContractOrderRequest): Promise> { + return this.postPrivate('/contract/v3/private/order/create', params); + } + + /** Query order history. As order creation/cancellation is asynchronous, the data returned from the interface may be delayed. To access order information in real-time, call getActiveOrders() */ + getHistoricOrders( + params: ContractHistoricOrdersRequest + ): Promise> { + return this.getPrivate('/contract/v3/private/order/list', params); + } + + /** Cancel order */ + cancelOrder(params: ContractCancelOrderRequest): Promise> { + return this.postPrivate('/contract/v3/private/order/cancel', params); + } + + /** Cancel all orders */ + cancelAllOrders(symbol: string): Promise> { + return this.postPrivate('/contract/v3/private/order/cancel-all', { + symbol, + }); + } + + /** Replace order : Active order parameters (such as quantity, price) and stop order parameters cannot be modified in one request at the same time. Please request modification separately. */ + modifyOrder(params: ContractModifyOrderRequest): Promise> { + return this.postPrivate('/contract/v3/private/order/replace', params); + } + + /** Query Open Order(s) (real-time) */ + getActiveOrders( + params: ContractActiveOrdersRequest + ): Promise> { + return this.getPrivate( + '/contract/v3/private/order/unfilled-orders', + params + ); + } + + /** -> Positions API */ + + /** + * Query my positions real-time. Accessing personal list of positions. + * Either symbol or settleCoin is required. + * Users can access their position holding information through this interface, such as the number of position holdings and wallet balance. + */ + getPositions(params?: ContractPositionsRequest): Promise> { + return this.getPrivate('/contract/v3/private/position/list', params); + } + + /** Set auto add margin, or Auto-Margin Replenishment. */ + setAuthAddMargin(params: { + symbol: string; + side: string; + autoAddMargin: 1 | 0; + positionIdx?: 0 | 1 | 2; + }): Promise> { + return this.postPrivate( + '/contract/v3/private/position/set-auto-add-margin', + params + ); + } + + /** Switch cross margin mode/isolated margin mode */ + setMarginSwitch(params: { + symbol: string; + tradeMode: 0 | 1; + buyLeverage: string; + sellLeverage: string; + }): Promise> { + return this.postPrivate( + '/contract/v3/private/position/switch-isolated', + params + ); + } + + /** Supports switching between One-Way Mode and Hedge Mode at the coin level. */ + setPositionMode(params: { + symbol?: string; + coin?: string; + mode: 0 | 3; + }): Promise> { + return this.postPrivate( + '/contract/v3/private/position/switch-mode', + params + ); + } + + /** + * Switch mode between Full or Partial + */ + setTPSLMode( + symbol: string, + tpSlMode: 'Full' | 'Partial' + ): Promise> { + return this.postPrivate('/contract/v3/private/position/switch-tpsl-mode', { + symbol, + tpSlMode, + }); + } + + /** Leverage setting. */ + setLeverage( + symbol: string, + buyLeverage: string, + sellLeverage: string + ): Promise> { + return this.postPrivate('/contract/v3/private/position/set-leverage', { + symbol, + buyLeverage, + sellLeverage, + }); + } + + /** + * Set take profit, stop loss, and trailing stop for your open position. + * If using partial mode, TP/SL/TS orders will not close your entire position. + */ + setTPSL(params: { + symbol: string; + takeProfit?: string; + stopLoss?: string; + activePrice?: string; + trailingStop?: string; + tpTriggerBy?: string; + slTriggerBy?: string; + slSize?: string; + tpSize?: string; + /** 0-one-way, 1-buy side, 2-sell side */ + positionIdx?: 0 | 1 | 2; + }): Promise> { + return this.postPrivate( + '/contract/v3/private/position/trading-stop', + params + ); + } + + /** Set risk limit */ + setRiskLimit( + symbol: string, + riskId: number, + /** 0-one-way, 1-buy side, 2-sell side */ + positionIdx: 0 | 1 | 2 + ): Promise> { + return this.postPrivate('/contract/v3/private/position/set-risk-limit', { + symbol, + riskId, + positionIdx, + }); + } + + /** + * Get user's trading records. + * The results are ordered in descending order (the first item is the latest). Returns records up to 2 years old. + */ + getUserExecutionHistory(params: { + symbol: string; + orderId?: string; + startTime?: number; + endTime?: number; + execType?: 'Trade' | 'AdlTrade' | 'Funding' | 'BustTrade'; + limit?: number; + cursor?: string; + }): Promise> { + return this.getPrivate('/contract/v3/private/execution/list', params); + } + + /** + * Get user's closed profit and loss records. + * The results are ordered in descending order (the first item is the latest). + */ + getClosedProfitAndLoss(params: { + symbol: string; + startTime?: number; + endTime?: number; + limit?: number; + cursor?: string; + }): Promise> { + return this.getPrivate('/contract/v3/private/position/closed-pnl', params); + } + + /** Get the information of open interest limit. */ + getOpenInterestLimitInfo(symbol: string): Promise> { + return this.getPrivate('/contract/v3/private/position/closed-pnl', { + symbol, + }); + } + + /** -> Account API */ + + /** Query wallet balance */ + getBalances(coin?: string): Promise> { + return this.getPrivate('/contract/v3/private/account/wallet/balance', { + coin, + }); + } + + /** Get user trading fee rate */ + getTradingFeeRate(symbol?: string): Promise> { + return this.getPrivate('/contract/v3/private/account/fee-rate', { + symbol, + }); + } + + /** + * Get wallet fund records. + * This endpoint also shows exchanges from the Asset Exchange, where the types for the exchange are ExchangeOrderWithdraw and ExchangeOrderDeposit. + * This endpoint returns incomplete information for transfers involving the derivatives wallet. + * Use the account asset API for creating and querying internal transfers. + */ + getWalletFundRecords(params?: { + startTime?: string; + endTime?: string; + coin?: string; + walletFundType?: string; + limit?: string; + cursor?: string; + }): Promise> { + return this.getPrivate( + '/contract/v3/private/account/wallet/fund-records', + params + ); + } + + /** + * + * API Data Endpoints + * + */ + + getServerTime(): Promise { + return this.get('/v2/public/time'); + } +} diff --git a/src/index.ts b/src/index.ts index 4f8c4c4..62836ec 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,7 @@ export * from './spot-client-v3'; export * from './usdc-option-client'; export * from './usdc-perpetual-client'; export * from './unified-margin-client'; +export * from './contract-client'; export * from './websocket-client'; export * from './util/logger'; export * from './util'; diff --git a/src/types/request/contract.ts b/src/types/request/contract.ts new file mode 100644 index 0000000..7b4ce52 --- /dev/null +++ b/src/types/request/contract.ts @@ -0,0 +1,67 @@ +import { OrderSide } from '../shared'; +import { UMOrderType } from './unified-margin'; +import { USDCOrderFilter, USDCTimeInForce } from './usdc-shared'; + +export interface ContractOrderRequest { + symbol: string; + side: OrderSide; + positionIdx?: '0' | '1' | '2'; + orderType: UMOrderType; + qty: string; + price?: string; + triggerDirection?: '1' | '2'; + triggerPrice?: string; + triggerBy?: string; + tpTriggerBy?: string; + slTriggerBy?: string; + timeInForce: USDCTimeInForce; + orderLinkId?: string; + takeProfit?: number; + stopLoss?: number; + reduceOnly?: boolean; + closeOnTrigger?: boolean; +} + +export interface ContractHistoricOrdersRequest { + orderId?: string; + orderLinkId?: string; + symbol: string; + orderStatus?: string; + orderFilter?: USDCOrderFilter; + limit?: number; + cursor?: string; +} + +export interface ContractCancelOrderRequest { + symbol: string; + orderId?: string; + orderLinkId?: string; +} + +export interface ContractModifyOrderRequest { + orderId?: string; + orderLinkId?: string; + symbol: string; + qty?: string; + price?: string; + takeProfit?: number; + stopLoss?: number; + tpTriggerBy?: string; + slTriggerBy?: string; + triggerBy?: string; +} + +export interface ContractActiveOrdersRequest { + symbol?: string; + orderId?: string; + orderLinkId?: string; + settleCoin?: string; + orderFilter?: USDCOrderFilter; + limit?: number; +} + +export interface ContractPositionsRequest { + symbol?: string; + settleCoin?: string; + dataFilter?: string; +} diff --git a/src/types/request/index.ts b/src/types/request/index.ts index fb11d51..bfbba68 100644 --- a/src/types/request/index.ts +++ b/src/types/request/index.ts @@ -7,3 +7,4 @@ export * from './usdc-perp'; export * from './usdc-options'; export * from './usdc-shared'; export * from './unified-margin'; +export * from './contract';