diff --git a/ts/src/binance.ts b/ts/src/binance.ts index 193ea74a2121..7679e0ab924e 100644 --- a/ts/src/binance.ts +++ b/ts/src/binance.ts @@ -4,7 +4,7 @@ import Exchange from './abstract/binance.js'; import { ExchangeError, ArgumentsRequired, OperationFailed, OperationRejected, InsufficientFunds, OrderNotFound, InvalidOrder, DDoSProtection, InvalidNonce, AuthenticationError, RateLimitExceeded, PermissionDenied, NotSupported, BadRequest, BadSymbol, AccountSuspended, OrderImmediatelyFillable, OnMaintenance, BadResponse, RequestTimeout, OrderNotFillable, MarginModeAlreadySet } from './base/errors.js'; import { Precise } from './base/Precise.js'; -import type { TransferEntry, Int, OrderSide, Balances, OrderType, Trade, OHLCV, Order, FundingRateHistory, OpenInterest, Liquidation, OrderRequest, Str, Transaction, Ticker, OrderBook, Tickers, Market, Greeks, Strings, Currency, MarketInterface, MarginMode, MarginModes, Leverage, Leverages, Num, Option, MarginModification, TradingFeeInterface, Currencies, TradingFees, Conversion, CrossBorrowRate } from './base/types.js'; +import type { TransferEntry, Int, OrderSide, Balances, OrderType, Trade, OHLCV, Order, FundingRateHistory, OpenInterest, Liquidation, OrderRequest, Str, Transaction, Ticker, OrderBook, Tickers, Market, Greeks, Strings, Currency, MarketInterface, MarginMode, MarginModes, Leverage, Leverages, Num, Option, MarginModification, TradingFeeInterface, Currencies, TradingFees, Conversion, CrossBorrowRate, IsolatedBorrowRates, IsolatedBorrowRate } from './base/types.js'; import { TRUNCATE, DECIMAL_PLACES } from './base/functions/number.js'; import { sha256 } from './static_dependencies/noble-hashes/sha256.js'; import { rsa } from './base/functions/rsa.js'; @@ -95,8 +95,8 @@ export default class binance extends Exchange { 'fetchFundingRates': true, 'fetchGreeks': true, 'fetchIndexOHLCV': true, - 'fetchIsolatedBorrowRate': false, - 'fetchIsolatedBorrowRates': false, + 'fetchIsolatedBorrowRate': 'emulated', + 'fetchIsolatedBorrowRates': true, 'fetchL3OrderBook': false, 'fetchLastPrices': true, 'fetchLedger': true, @@ -11164,6 +11164,72 @@ export default class binance extends Exchange { return this.parseBorrowRate (rate); } + async fetchIsolatedBorrowRate (symbol: string, params = {}): Promise { + /** + * @method + * @name binance#fetchIsolatedBorrowRate + * @description fetch the rate of interest to borrow a currency for margin trading + * @see https://binance-docs.github.io/apidocs/spot/en/#query-isolated-margin-fee-data-user_data + * @param {string} symbol unified market symbol + * @param {object} [params] extra parameters specific to the exchange API endpoint + * + * EXCHANGE SPECIFIC PARAMETERS + * @param {object} [params.vipLevel] user's current specific margin data will be returned if viplevel is omitted + * @returns {object} an [isolated borrow rate structure]{@link https://docs.ccxt.com/#/?id=isolated-borrow-rate-structure} + */ + const request = { + 'symbol': symbol, + }; + const borrowRates = await this.fetchIsolatedBorrowRates (this.extend (request, params)); + return this.safeDict (borrowRates, symbol) as IsolatedBorrowRate; + } + + async fetchIsolatedBorrowRates (params = {}): Promise { + /** + * @method + * @name binance#fetchIsolatedBorrowRates + * @description fetch the borrow interest rates of all currencies + * @see https://binance-docs.github.io/apidocs/spot/en/#query-isolated-margin-fee-data-user_data + * @param {object} [params] extra parameters specific to the exchange API endpoint + * @param {object} [params.symbol] unified market symbol + * + * EXCHANGE SPECIFIC PARAMETERS + * @param {object} [params.vipLevel] user's current specific margin data will be returned if viplevel is omitted + * @returns {object} a [borrow rate structure]{@link https://docs.ccxt.com/#/?id=borrow-rate-structure} + */ + await this.loadMarkets (); + const request = {}; + const symbol = this.safeString (params, 'symbol'); + params = this.omit (params, 'symbol'); + if (symbol !== undefined) { + const market = this.market (symbol); + request['symbol'] = market['id']; + } + const response = await this.sapiGetMarginIsolatedMarginData (this.extend (request, params)); + // + // [ + // { + // "vipLevel": 0, + // "symbol": "BTCUSDT", + // "leverage": "10", + // "data": [ + // { + // "coin": "BTC", + // "dailyInterest": "0.00026125", + // "borrowLimit": "270" + // }, + // { + // "coin": "USDT", + // "dailyInterest": "0.000475", + // "borrowLimit": "2100000" + // } + // ] + // } + // ] + // + return this.parseIsolatedBorrowRates (response); + } + async fetchBorrowRateHistory (code: string, since: Int = undefined, limit: Int = undefined, params = {}) { /** * @method @@ -11240,6 +11306,44 @@ export default class binance extends Exchange { }; } + parseIsolatedBorrowRate (info, market: Market = undefined) { + // + // { + // "vipLevel": 0, + // "symbol": "BTCUSDT", + // "leverage": "10", + // "data": [ + // { + // "coin": "BTC", + // "dailyInterest": "0.00026125", + // "borrowLimit": "270" + // }, + // { + // "coin": "USDT", + // "dailyInterest": "0.000475", + // "borrowLimit": "2100000" + // } + // ] + // } + // + const marketId = this.safeString (info, 'symbol'); + market = this.safeMarket (marketId, market, undefined, 'spot'); + const data = this.safeList (info, 'data'); + const baseInfo = this.safeDict (data, 0); + const quoteInfo = this.safeDict (data, 1); + return { + 'info': info, + 'symbol': this.safeString (market, 'symbol'), + 'base': this.safeString (baseInfo, 'coin'), + 'baseRate': this.safeNumber (baseInfo, 'dailyInterest'), + 'quote': this.safeString (quoteInfo, 'coin'), + 'quoteRate': this.safeNumber (quoteInfo, 'dailyInterest'), + 'period': 86400000, + 'timestamp': undefined, + 'datetime': undefined, + }; + } + async createGiftCode (code: string, amount, params = {}) { /** * @method diff --git a/ts/src/test/static/request/binance.json b/ts/src/test/static/request/binance.json index f097d667086c..39639244c5cf 100644 --- a/ts/src/test/static/request/binance.json +++ b/ts/src/test/static/request/binance.json @@ -3077,6 +3077,24 @@ ], "output": "timestamp=1713536455384"eId=844f131de9994643a0b6ce7805d08cfb&recvWindow=10000&signature=39e6351a5061356643aa48f6e335b6d3c903710206f2543bd9443af07885948b" } + ], + "fetchIsolatedBorrowRate": [ + { + "description": "fetchIsolatedBorrowRate", + "method": "fetchIsolatedBorrowRate", + "url": "https://api.binance.com/sapi/v1/margin/isolatedMarginData?timestamp=1714664548704&symbol=BTCUSDT&recvWindow=10000&signature=6bed3101b0139a52896c5ac2cba8c9c16371153e133ecdef782c7cd398bb470f", + "input": [ + "BTC/USDT" + ] + } + ], + "fetchIsolatedBorrowRates": [ + { + "description": "fetchIsolatedBorrowRates", + "method": "fetchIsolatedBorrowRates", + "url": "https://api.binance.com/sapi/v1/margin/isolatedMarginData?timestamp=1714664627834&recvWindow=10000&signature=9b4fa07568a385ee7a642e31375bb1c6e0640d1491508b2f5bbd4e36ce31f117", + "input": [] + } ] } } \ No newline at end of file