From 503baf3107aaa49ac73604934d9f99e2de154472 Mon Sep 17 00:00:00 2001 From: JJ-Cro Date: Thu, 27 Feb 2025 12:20:36 +0100 Subject: [PATCH] chore(): updated all examples to use v2 clients --- README.md | 4 +- examples/rest-private-futures.ts | 2 +- examples/rest-private-spot.ts | 2 +- examples/rest-public-futures.ts | 4 +- examples/rest-trade-futures.ts | 104 ++++++++++++++----------------- examples/rest-trade-spot.ts | 52 ++++++++-------- examples/ws-private.ts | 2 +- examples/ws-public.ts | 2 +- 8 files changed, 81 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index f345910..22c2245 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Each REST API group has a dedicated REST client. To avoid confusion, here are th | Class | Description | |:------------------------------------: |:---------------------------------------------------------------------------------------------: | | [RestClientV2](src/rest-client-v2.ts) | [V2 REST APIs](https://www.bitget.com/api-doc/common/intro) | -| [WebsocketClient](src/websocket-client-v2.ts) | Universal client for all Bitget's V2 Websockets | +| [WebsocketClientV2](src/websocket-client-v2.ts) | Universal client for all Bitget's V2 Websockets | | [~~SpotClient~~ (deprecated, use RestClientV2)](src/spot-client.ts) | [~~Spot APIs~~](https://bitgetlimited.github.io/apidoc/en/spot/#introduction) | | [~~FuturesClient~~ (deprecated, use RestClientV2)](src/futures-client.ts) | [~~Futures APIs~~](https://bitgetlimited.github.io/apidoc/en/mix/#introduction) | | [~~BrokerClient~~ (deprecated, use RestClientV2)](src/broker-client.ts) | [~~Broker APIs~~](https://bitgetlimited.github.io/apidoc/en/broker/#introduction) | @@ -164,7 +164,7 @@ For more examples, including how to use websockets with Bitget, check the [examp Pass a custom logger which supports the log methods `silly`, `debug`, `notice`, `info`, `warning` and `error`, or override methods from the default logger as desired. ```javascript -const { WebsocketClient, DefaultLogger } = require('bitget-api'); +const { WebsocketClientV2, DefaultLogger } = require('bitget-api'); // Disable all logging on the silly level (less console logs) const customLogger = { diff --git a/examples/rest-private-futures.ts b/examples/rest-private-futures.ts index 49a9b2f..6874f44 100644 --- a/examples/rest-private-futures.ts +++ b/examples/rest-private-futures.ts @@ -1,4 +1,4 @@ -import { RestClientV2, WebsocketClient } from '../src/index'; +import { RestClientV2 } from '../src/index'; // or // import { RestClientV2 } from 'bitget-api'; diff --git a/examples/rest-private-spot.ts b/examples/rest-private-spot.ts index 94f50db..28c8310 100644 --- a/examples/rest-private-spot.ts +++ b/examples/rest-private-spot.ts @@ -1,4 +1,4 @@ -import { RestClientV2, WebsocketClient } from '../src/index'; +import { RestClientV2 } from '../src/index'; // or // import { RestClientV2 } from 'bitget-api'; diff --git a/examples/rest-public-futures.ts b/examples/rest-public-futures.ts index d9ef39b..5c6c02d 100644 --- a/examples/rest-public-futures.ts +++ b/examples/rest-public-futures.ts @@ -1,7 +1,7 @@ -import { RestClientV2, SpotClient } from '../src/index'; +import { RestClientV2 } from '../src/index'; // or -// import { SpotClient } from 'bitget-api'; +// import { RestClientV2 } from 'bitget-api'; const restClient = new RestClientV2(); diff --git a/examples/rest-trade-futures.ts b/examples/rest-trade-futures.ts index 58ca502..1f2eb5d 100644 --- a/examples/rest-trade-futures.ts +++ b/examples/rest-trade-futures.ts @@ -1,26 +1,18 @@ import { - FuturesClient, - isWsFuturesAccountSnapshotEvent, - isWsFuturesPositionsSnapshotEvent, - NewFuturesOrder, - WebsocketClient, + FuturesPlaceOrderRequestV2, + RestClientV2, + WebsocketClientV2, } from '../src'; // or -// import { -// FuturesClient, -// isWsFuturesAccountSnapshotEvent, -// isWsFuturesPositionsSnapshotEvent, -// NewFuturesOrder, -// WebsocketClient, -// } from 'bitget-api'; +// import { FuturesPlaceOrderRequestV2, RestClientV2, WebsocketClientV2 } from '../src'; // read from environmental variables const API_KEY = process.env.API_KEY_COM; const API_SECRET = process.env.API_SECRET_COM; const API_PASS = process.env.API_PASS_COM; -const client = new FuturesClient({ +const client = new RestClientV2({ apiKey: API_KEY, apiSecret: API_SECRET, apiPass: API_PASS, @@ -29,7 +21,7 @@ const client = new FuturesClient({ // apiPass: 'apiPassHere', }); -const wsClient = new WebsocketClient({ +const wsClient = new WebsocketClientV2({ apiKey: API_KEY, apiSecret: API_SECRET, apiPass: API_PASS, @@ -44,28 +36,6 @@ function promiseSleep(milliseconds) { return new Promise((resolve) => setTimeout(resolve, milliseconds)); } -// WARNING: for sensitive math you should be using a library such as decimal.js! -function roundDown(value, decimals) { - return Number( - Math.floor(parseFloat(value + 'e' + decimals)) + 'e-' + decimals, - ); -} - -/** WS event handler that uses type guards to narrow down event type */ -async function handleWsUpdate(event) { - if (isWsFuturesAccountSnapshotEvent(event)) { - console.log(new Date(), 'ws update (account balance):', event); - return; - } - - if (isWsFuturesPositionsSnapshotEvent(event)) { - console.log(new Date(), 'ws update (positions):', event); - return; - } - - logWSEvent('update (unhandled)', event); -} - /** * This is a simple script wrapped in a immediately invoked function expression (to execute the below workflow immediately). * @@ -77,12 +47,11 @@ async function handleWsUpdate(event) { * - immediately send closing orders for any active futures positions * - check positions again * - * The corresponding UI for this is at https://www.bitget.com/en/mix/usdt/BTCUSDT_UMCBL */ (async () => { try { // Add event listeners to log websocket events on account - wsClient.on('update', (data) => handleWsUpdate(data)); + wsClient.on('update', (data) => logWSEvent('update', data)); wsClient.on('open', (data) => logWSEvent('open', data)); wsClient.on('response', (data) => logWSEvent('response', data)); @@ -91,23 +60,34 @@ async function handleWsUpdate(event) { wsClient.on('authenticated', (data) => logWSEvent('authenticated', data)); wsClient.on('exception', (data) => logWSEvent('exception', data)); - // Subscribe to private account topics - wsClient.subscribeTopic('UMCBL', 'account'); + // futures private + // : account updates + wsClient.subscribeTopic('USDT-FUTURES', 'account'); + // : position updates - wsClient.subscribeTopic('UMCBL', 'positions'); + wsClient.subscribeTopic('USDT-FUTURES', 'positions'); + // : order updates - wsClient.subscribeTopic('UMCBL', 'orders'); + wsClient.subscribeTopic('USDT-FUTURES', 'orders'); // wait briefly for ws to be ready (could also use the response or authenticated events, to make sure topics are subscribed to before starting) await promiseSleep(2.5 * 1000); - const symbol = 'BTCUSDT_UMCBL'; + const symbol = 'BTCUSDT'; const marginCoin = 'USDT'; - const balanceResult = await client.getAccount(symbol, marginCoin); + const balanceResult = await client.getFuturesAccountAssets({ + productType: 'USDT-FUTURES', + }); const accountBalance = balanceResult.data; // const balances = allBalances.filter((bal) => Number(bal.available) != 0); - const usdtAmount = accountBalance.available; + const assetList = accountBalance.find( + (bal) => bal.marginCoin === marginCoin, + )?.assetList; + const usdtAmount = assetList?.find( + (asset) => asset.coin === 'USDT', + )?.balance; + console.log('USDT balance: ', usdtAmount); if (!usdtAmount) { @@ -115,7 +95,10 @@ async function handleWsUpdate(event) { return; } - const symbolRulesResult = await client.getSymbols('umcbl'); + const symbolRulesResult = await client.getFuturesContractConfig({ + symbol, + productType: 'USDT-FUTURES', + }); const bitcoinUSDFuturesRule = symbolRulesResult.data.find( (row) => row.symbol === symbol, ); @@ -126,21 +109,25 @@ async function handleWsUpdate(event) { return; } - const order: NewFuturesOrder = { - marginCoin, + const order: FuturesPlaceOrderRequestV2 = { + marginCoin: marginCoin, + marginMode: 'crossed', + productType: 'USDT-FUTURES', orderType: 'market', - side: 'open_long', + side: 'buy', size: bitcoinUSDFuturesRule.minTradeNum, - symbol, + symbol: symbol, } as const; console.log('placing order: ', order); - const result = await client.submitOrder(order); + const result = await client.futuresSubmitOrder(order); console.log('order result: ', result); - const positionsResult = await client.getPositions('umcbl'); + const positionsResult = await client.getFuturesPositions({ + productType: 'USDT-FUTURES', + }); const positionsToClose = positionsResult.data.filter( (pos) => pos.total !== '0', ); @@ -149,10 +136,11 @@ async function handleWsUpdate(event) { // Loop through any active positions and send a closing market order on each position for (const position of positionsToClose) { - const closingSide = - position.holdSide === 'long' ? 'close_long' : 'close_short'; - const closingOrder: NewFuturesOrder = { + const closingSide = position.holdSide === 'long' ? 'sell' : 'buy'; + const closingOrder: FuturesPlaceOrderRequestV2 = { marginCoin: position.marginCoin, + marginMode: 'crossed', + productType: 'USDT-FUTURES', orderType: 'market', side: closingSide, size: position.available, @@ -161,13 +149,15 @@ async function handleWsUpdate(event) { console.log('closing position with market order: ', closingOrder); - const result = await client.submitOrder(closingOrder); + const result = await client.futuresSubmitOrder(closingOrder); console.log('position closing order result: ', result); } console.log( 'positions after closing all: ', - await client.getPositions('umcbl'), + await client.getFuturesPositions({ + productType: 'USDT-FUTURES', + }), ); } catch (e) { console.error('request failed: ', e); diff --git a/examples/rest-trade-spot.ts b/examples/rest-trade-spot.ts index a990097..25f5eee 100644 --- a/examples/rest-trade-spot.ts +++ b/examples/rest-trade-spot.ts @@ -1,14 +1,17 @@ -import { SpotClient, WebsocketClient } from '../src/index'; +import { + RestClientV2, + SpotOrderRequestV2, + WebsocketClientV2, +} from '../src/index'; -// or -// import { SpotClient } from 'bitget-api'; +// import { RestClientV2, WebsocketClient } from '../src/index'; // read from environmental variables const API_KEY = process.env.API_KEY_COM; const API_SECRET = process.env.API_SECRET_COM; const API_PASS = process.env.API_PASS_COM; -const client = new SpotClient({ +const client = new RestClientV2({ apiKey: API_KEY, apiSecret: API_SECRET, apiPass: API_PASS, @@ -17,7 +20,7 @@ const client = new SpotClient({ // apiPass: 'apiPassHere', }); -const wsClient = new WebsocketClient({ +const wsClient = new WebsocketClientV2({ apiKey: API_KEY, apiSecret: API_SECRET, apiPass: API_PASS, @@ -32,13 +35,6 @@ function promiseSleep(milliseconds) { return new Promise((resolve) => setTimeout(resolve, milliseconds)); } -// WARNING: for sensitive math you should be using a library such as decimal.js! -function roundDown(value, decimals) { - return Number( - Math.floor(parseFloat(value + 'e' + decimals)) + 'e-' + decimals, - ); -} - /** This is a simple script wrapped in a immediately invoked function expression, designed to check for any available BTC balance and immediately sell the full amount for USDT */ (async () => { try { @@ -52,16 +48,22 @@ function roundDown(value, decimals) { wsClient.on('exception', (data) => logWSEvent('exception', data)); // Subscribe to private account topics - wsClient.subscribeTopic('SPBL', 'account'); - wsClient.subscribeTopic('SPBL', 'orders'); + // spot private + // : account updates + wsClient.subscribeTopic('SPOT', 'account'); + + // : order updates (note: symbol is required) + wsClient.subscribeTopic('SPOT', 'orders', 'BTCUSDT'); // wait briefly for ws to be ready (could also use the response or authenticated events, to make sure topics are subscribed to before starting) await promiseSleep(2.5 * 1000); - const balanceResult = await client.getBalance(); + const balanceResult = await client.getSpotAccountAssets(); const allBalances = balanceResult.data; - // const balances = allBalances.filter((bal) => Number(bal.available) != 0); - const balanceBTC = allBalances.find((bal) => bal.coinName === 'BTC'); + + const balanceBTC = allBalances.find( + (bal) => bal.coin === 'BTC' || bal.coin === 'btc', + ); const btcAmount = balanceBTC ? Number(balanceBTC.available) : 0; // console.log('balance: ', JSON.stringify(balances, null, 2)); console.log('BTC balance result: ', balanceBTC); @@ -72,30 +74,28 @@ function roundDown(value, decimals) { } console.log(`BTC available: ${btcAmount}`); - const symbol = 'BTCUSDT_SPBL'; + const symbol = 'BTCUSDT'; - const symbolsResult = await client.getSymbols(); + const symbolsResult = await client.getSpotSymbolInfo(); const btcRules = symbolsResult.data.find((rule) => rule.symbol === symbol); console.log('btc trading rules: ', btcRules); if (!btcRules) { return console.log('no rules found for trading ' + symbol); } - const quantityScale = Number(btcRules.quantityScale); - // const quantityRoundedDown = btcAmount - btcAmount % 0.01 - const quantity = roundDown(btcAmount, quantityScale); + const quantity = btcRules.minTradeAmount; - const order = { + const order: SpotOrderRequestV2 = { symbol: symbol, side: 'sell', - force: 'normal', orderType: 'market', - quantity: String(quantity), + force: 'gtc', + size: quantity, } as const; console.log('submitting order: ', order); - const sellResult = await client.submitOrder(order); + const sellResult = await client.spotSubmitOrder(order); console.log('sell result: ', sellResult); } catch (e) { diff --git a/examples/ws-private.ts b/examples/ws-private.ts index f9975cf..c623275 100644 --- a/examples/ws-private.ts +++ b/examples/ws-private.ts @@ -1,4 +1,4 @@ -import { WebsocketClientV2, DefaultLogger } from '../src'; +import { DefaultLogger, WebsocketClientV2 } from '../src'; // or // import { DefaultLogger, WS_KEY_MAP, WebsocketClientV2 } from 'bitget-api'; diff --git a/examples/ws-public.ts b/examples/ws-public.ts index 19dc48e..2a0df55 100644 --- a/examples/ws-public.ts +++ b/examples/ws-public.ts @@ -1,4 +1,4 @@ -import { DefaultLogger, WS_KEY_MAP, WebsocketClientV2 } from '../src'; +import { DefaultLogger, WebsocketClientV2, WS_KEY_MAP } from '../src'; // or // import { DefaultLogger, WS_KEY_MAP, WebsocketClientV2 } from 'bitget-api';