From b0ce488278e6090cabe39a5c23b03cd4c6c2886d Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Sun, 28 Apr 2024 11:59:28 -0400 Subject: [PATCH] Borrow rate types and parsers (#22205) * chore: new type IsolatedBorrowRate * refactor: changed BorrowRate type to CrossBorrowRate * feat(base/exchange): parseIsolatedBorrowRates, parseIsolatedBorrowRate * feat: new types - CrossBorrowRate, IsolatedBorrowRate * fetchCrossBorrowRate(s) return type * fetch(Cross|Isolated)BorrowRate(s) return types * base/Exchange import CrossBorrowRate * Exchange.ts removed BorrowRate type * types.py linting * fix crossborrowRates transpiling * bybit minor fix --------- Co-authored-by: carlosmiei <43336371+carlosmiei@users.noreply.github.com> --- build/transpile.js | 7 +- cs/ccxt/base/Exchange.Types.cs | 122 ++++++++++++++++++++++++++++++--- python/ccxt/base/types.py | 25 +++++++ ts/src/base/Exchange.ts | 29 ++++++-- ts/src/base/types.ts | 24 ++++++- ts/src/binance.ts | 4 +- ts/src/bitget.ts | 8 +-- ts/src/bitmart.ts | 15 ++-- ts/src/bybit.ts | 4 +- ts/src/coinex.ts | 14 ++-- ts/src/digifinex.ts | 6 +- ts/src/htx.ts | 12 ++-- ts/src/okx.ts | 6 +- 13 files changed, 215 insertions(+), 61 deletions(-) diff --git a/build/transpile.js b/build/transpile.js index b0e2671d9ea6..fa422b48b940 100644 --- a/build/transpile.js +++ b/build/transpile.js @@ -994,13 +994,16 @@ class Transpiler { 'Balances': /-> Balances:/, 'Bool': /: Bool =/, 'Conversion': /-> Conversion:/, + 'CrossBorrowRate': /-> CrossBorrowRate:/, + 'CrossBorrowRates': /-> CrossBorrowRates:/, 'Currencies': /-> Currencies:/, 'Currency': /(-> Currency:|: Currency)/, 'FundingHistory': /\[FundingHistory/, 'Greeks': /-> Greeks:/, 'IndexType': /: IndexType/, 'Int': /: Int =/, - 'Liquidation': /-> (?:List\[)?Liquidation/, + 'IsolatedBorrowRate': /-> IsolatedBorrowRate:/, + 'IsolatedBorrowRates': /-> IsolatedBorrowRates:/, 'LastPrice': /-> LastPrice:/, 'LastPrices': /-> LastPrices:/, 'Leverage': /-> Leverage:/, @@ -1683,7 +1686,7 @@ class Transpiler { 'Dictionary': 'array', 'Dict': 'array', } - const phpArrayRegex = /^(?:Market|Currency|Account|AccountStructure|BalanceAccount|object|OHLCV|Order|OrderBook|Tickers?|Trade|Transaction|Balances?|MarketInterface|TransferEntry|Leverages|Leverage|Greeks|MarginModes|MarginMode|MarginModification|LastPrice|LastPrices|TradingFeeInterface|Currencies|TradingFees)( \| undefined)?$|\w+\[\]/ + const phpArrayRegex = /^(?:Market|Currency|Account|AccountStructure|BalanceAccount|object|OHLCV|Order|OrderBook|Tickers?|Trade|Transaction|Balances?|MarketInterface|TransferEntry|Leverages|Leverage|Greeks|MarginModes|MarginMode|MarginModification|LastPrice|LastPrices|TradingFeeInterface|Currencies|TradingFees|CrossBorrowRate|IsolatedBorrowRate)( \| undefined)?$|\w+\[\]/ let phpArgs = args.map (x => { const parts = x.split (':') if (parts.length === 1) { diff --git a/cs/ccxt/base/Exchange.Types.cs b/cs/ccxt/base/Exchange.Types.cs index 712f71c8db19..fff4812feb8b 100644 --- a/cs/ccxt/base/Exchange.Types.cs +++ b/cs/ccxt/base/Exchange.Types.cs @@ -758,7 +758,7 @@ public DepositAddressResponse(object depositAddressResponse2) } } -public struct BorrowRate +public struct CrossBorrowRate { public string? currency; public double? rate; @@ -766,17 +766,123 @@ public struct BorrowRate public string? datetime; public Dictionary info; - public BorrowRate(object borrowRate) + public CrossBorrowRate(object crossBorrowRate) { - var borrowRate2 = (Dictionary)borrowRate; - currency = Exchange.SafeString(borrowRate2, "currency"); - rate = Exchange.SafeFloat(borrowRate2, "rate"); - timestamp = Exchange.SafeInteger(borrowRate2, "timestamp"); - datetime = Exchange.SafeString(borrowRate2, "datetime"); - info = borrowRate2.ContainsKey("info") ? (Dictionary)borrowRate2["info"] : null; + var crossBorrowRate2 = (Dictionary)crossBorrowRate; + currency = Exchange.SafeString(crossBorrowRate2, "currency"); + rate = Exchange.SafeFloat(crossBorrowRate2, "rate"); + timestamp = Exchange.SafeInteger(crossBorrowRate2, "timestamp"); + datetime = Exchange.SafeString(crossBorrowRate2, "datetime"); + info = crossBorrowRate2.ContainsKey("info") ? (Dictionary)crossBorrowRate2["info"] : null; } } +public struct CrossBorrowRates +{ + public Dictionary info; + public Dictionary crossBorrowRates; + + public CrossBorrowRates(object crossBorrowRates2) + { + var crossBorrowRates = (Dictionary)crossBorrowRates2; + + info = crossBorrowRates.ContainsKey("info") ? (Dictionary)crossBorrowRates["info"] : null; + this.crossBorrowRates = new Dictionary(); + foreach (var crossBorrowRate in crossBorrowRates) + { + if (crossBorrowRate.Key != "info") + this.crossBorrowRates.Add(crossBorrowRate.Key, new CrossBorrowRate(crossBorrowRate.Value)); + } + } + + // Indexer + public CrossBorrowRate this[string key] + { + get + { + if (crossBorrowRates.ContainsKey(key)) + { + return crossBorrowRates[key]; + } + else + { + throw new KeyNotFoundException($"The key '{key}' was not found in the isolatedBorrowRates."); + } + } + set + { + crossBorrowRates[key] = value; + } + } +} + +public struct IsolatedBorrowRate +{ + public string symbol; + // public string base; + public double? baseRate; + public string quote; + public double? quoteRate; + public double? rate; + public Int64? timestamp; + public string? datetime; + public Dictionary info; + + public IsolatedBorrowRate(object isolatedBorrowRate) + { + var isolatedBorrowRate2 = (Dictionary)isolatedBorrowRate; + symbol = Exchange.SafeString (isolatedBorrowRate2, "symbol"); + // base = Exchange.SafeString (isolatedBorrowRate2, "base"); + baseRate = Exchange.SafeFloat (isolatedBorrowRate2, "baseRate"); + quote = Exchange.SafeString (isolatedBorrowRate2, "quote"); + quoteRate = Exchange.SafeFloat (isolatedBorrowRate2, "quoteRate"); + rate = Exchange.SafeFloat(isolatedBorrowRate2, "rate"); + timestamp = Exchange.SafeInteger(isolatedBorrowRate2, "timestamp"); + datetime = Exchange.SafeString(isolatedBorrowRate2, "datetime"); + info = isolatedBorrowRate2.ContainsKey("info") ? (Dictionary)isolatedBorrowRate2["info"] : null; + } +} + +public struct IsolatedBorrowRates +{ + public Dictionary info; + public Dictionary isolatedBorrowRates; + + public IsolatedBorrowRates(object isolatedBorrowRates2) + { + var isolatedBorrowRates = (Dictionary)isolatedBorrowRates2; + + info = isolatedBorrowRates.ContainsKey("info") ? (Dictionary)isolatedBorrowRates["info"] : null; + this.isolatedBorrowRates = new Dictionary(); + foreach (var isolatedBorrowRate in isolatedBorrowRates) + { + if (isolatedBorrowRate.Key != "info") + this.isolatedBorrowRates.Add(isolatedBorrowRate.Key, new IsolatedBorrowRate(isolatedBorrowRate.Value)); + } + } + + // Indexer + public IsolatedBorrowRate this[string key] + { + get + { + if (isolatedBorrowRates.ContainsKey(key)) + { + return isolatedBorrowRates[key]; + } + else + { + throw new KeyNotFoundException($"The key '{key}' was not found in the isolatedBorrowRates."); + } + } + set + { + isolatedBorrowRates[key] = value; + } + } +} + + public struct BorrowInterest { public string? account; diff --git a/python/ccxt/base/types.py b/python/ccxt/base/types.py index 3715e4f7e3ac..48348bce67e8 100644 --- a/python/ccxt/base/types.py +++ b/python/ccxt/base/types.py @@ -148,11 +148,13 @@ class OrderRequest(TypedDict): price: Union[None, float] params: Dict[str, Any] + class CancellationRequest(TypedDict): id: Str symbol: Str clientOrderId: Str + class Order(TypedDict): info: Dict[str, Any] id: Str @@ -437,9 +439,32 @@ class MarginModification(TypedDict): datetime: Str +class CrossBorrowRate(TypedDict): + info: Dict[str, any] + currency: Str + rate: float + period: Optional[float] + timestamp: Int + datetime: Str + + +class IsolatedBorrowRate(TypedDict): + info: Dict[str, any] + symbol: str + base: str + baseRate: float + quote: str + quoteRate: float + period: Int + timestamp: Int + datetime: Str + + LastPrices = Dict[Str, LastPrice] Currencies = Dict[Str, CurrencyInterface] TradingFees = Dict[Str, TradingFeeInterface] +IsolatedBorrowRates = Dict[Str, IsolatedBorrowRate] +CrossBorrowRates = Dict[Str, CrossBorrowRate] Market = Optional[MarketInterface] Currency = Optional[CurrencyInterface] diff --git a/ts/src/base/Exchange.ts b/ts/src/base/Exchange.ts index c4f8656fe74c..8890a869e32e 100644 --- a/ts/src/base/Exchange.ts +++ b/ts/src/base/Exchange.ts @@ -146,10 +146,10 @@ import { OrderBook as WsOrderBook, IndexedOrderBook, CountedOrderBook } from './ // import { axolotl } from './functions/crypto.js'; // import types -import type { Market, Trade, Fee, Ticker, OHLCV, OHLCVC, Order, OrderBook, Balance, Balances, Dictionary, Transaction, DepositAddressResponse, Currency, MinMax, IndexType, Int, OrderType, OrderSide, Position, FundingRate, DepositWithdrawFeeNetwork, LedgerEntry, BorrowInterest, OpenInterest, LeverageTier, TransferEntry, BorrowRate, FundingRateHistory, Liquidation, FundingHistory, OrderRequest, MarginMode, Tickers, Greeks, Option, OptionChain, Str, Num, MarketInterface, CurrencyInterface, BalanceAccount, MarginModes, MarketType, Leverage, Leverages, LastPrice, LastPrices, Account, Strings, MarginModification, TradingFeeInterface, Currencies, TradingFees, Conversion, CancellationRequest } from './types.js'; +import type { Market, Trade, Fee, Ticker, OHLCV, OHLCVC, Order, OrderBook, Balance, Balances, Dictionary, Transaction, DepositAddressResponse, Currency, MinMax, IndexType, Int, OrderType, OrderSide, Position, FundingRate, DepositWithdrawFeeNetwork, LedgerEntry, BorrowInterest, OpenInterest, LeverageTier, TransferEntry, FundingRateHistory, Liquidation, FundingHistory, OrderRequest, MarginMode, Tickers, Greeks, Option, OptionChain, Str, Num, MarketInterface, CurrencyInterface, BalanceAccount, MarginModes, MarketType, Leverage, Leverages, LastPrice, LastPrices, Account, Strings, MarginModification, TradingFeeInterface, Currencies, TradingFees, Conversion, CancellationRequest, IsolatedBorrowRate, IsolatedBorrowRates, CrossBorrowRates, CrossBorrowRate } from './types.js'; // export {Market, Trade, Fee, Ticker, OHLCV, OHLCVC, Order, OrderBook, Balance, Balances, Dictionary, Transaction, DepositAddressResponse, Currency, MinMax, IndexType, Int, OrderType, OrderSide, Position, FundingRateHistory, Liquidation, FundingHistory} from './types.js' // import { Market, Trade, Fee, Ticker, OHLCV, OHLCVC, Order, OrderBook, Balance, Balances, Dictionary, Transaction, DepositAddressResponse, Currency, MinMax, IndexType, Int, OrderType, OrderSide, Position, FundingRateHistory, OpenInterest, Liquidation, OrderRequest, FundingHistory, MarginMode, Tickers, Greeks, Str, Num, MarketInterface, CurrencyInterface, Account } from './types.js'; -export type { Market, Trade, Fee, Ticker, OHLCV, OHLCVC, Order, OrderBook, Balance, Balances, Dictionary, Transaction, DepositAddressResponse, Currency, MinMax, IndexType, Int, OrderType, OrderSide, Position, LedgerEntry, BorrowInterest, OpenInterest, LeverageTier, TransferEntry, BorrowRate, FundingRateHistory, Liquidation, FundingHistory, OrderRequest, MarginMode, Tickers, Greeks, Option, OptionChain, Str, Num, MarketInterface, CurrencyInterface, BalanceAccount, MarginModes, MarketType, Leverage, Leverages, LastPrice, LastPrices, Account, Strings, Conversion } from './types.js' +export type { Market, Trade, Fee, Ticker, OHLCV, OHLCVC, Order, OrderBook, Balance, Balances, Dictionary, Transaction, DepositAddressResponse, Currency, MinMax, IndexType, Int, OrderType, OrderSide, Position, LedgerEntry, BorrowInterest, OpenInterest, LeverageTier, TransferEntry, CrossBorrowRate, FundingRateHistory, Liquidation, FundingHistory, OrderRequest, MarginMode, Tickers, Greeks, Option, OptionChain, Str, Num, MarketInterface, CurrencyInterface, BalanceAccount, MarginModes, MarketType, Leverage, Leverages, LastPrice, LastPrices, Account, Strings, Conversion } from './types.js' // ---------------------------------------------------------------------------- // move this elsewhere. @@ -2337,11 +2337,11 @@ export default class Exchange { throw new NotSupported (this.id + ' parseOrder() is not supported yet'); } - async fetchCrossBorrowRates (params = {}): Promise<{}> { + async fetchCrossBorrowRates (params = {}): Promise { throw new NotSupported (this.id + ' fetchCrossBorrowRates() is not supported yet'); } - async fetchIsolatedBorrowRates (params = {}): Promise<{}> { + async fetchIsolatedBorrowRates (params = {}): Promise { throw new NotSupported (this.id + ' fetchIsolatedBorrowRates() is not supported yet'); } @@ -2365,6 +2365,10 @@ export default class Exchange { throw new NotSupported (this.id + ' parseBorrowInterest() is not supported yet'); } + parseIsolatedBorrowRate (info, market: Market = undefined): IsolatedBorrowRate { + throw new NotSupported (this.id + ' parseIsolatedBorrowRate() is not supported yet'); + } + parseWsTrade (trade, market: Market = undefined): Trade { throw new NotSupported (this.id + ' parseWsTrade() is not supported yet'); } @@ -4455,7 +4459,7 @@ export default class Exchange { } } - async fetchCrossBorrowRate (code: string, params = {}): Promise<{}> { + async fetchCrossBorrowRate (code: string, params = {}): Promise { await this.loadMarkets (); if (!this.has['fetchBorrowRates']) { throw new NotSupported (this.id + ' fetchCrossBorrowRate() is not supported yet'); @@ -4468,13 +4472,13 @@ export default class Exchange { return rate; } - async fetchIsolatedBorrowRate (symbol: string, params = {}): Promise<{}> { + async fetchIsolatedBorrowRate (symbol: string, params = {}): Promise { await this.loadMarkets (); if (!this.has['fetchBorrowRates']) { throw new NotSupported (this.id + ' fetchIsolatedBorrowRate() is not supported yet'); } const borrowRates = await this.fetchIsolatedBorrowRates (params); - const rate = this.safeDict (borrowRates, symbol); + const rate = this.safeDict (borrowRates, symbol) as IsolatedBorrowRate; if (rate === undefined) { throw new ExchangeError (this.id + ' fetchIsolatedBorrowRate() could not find the borrow rate for market symbol ' + symbol); } @@ -5834,6 +5838,17 @@ export default class Exchange { return interests; } + parseIsolatedBorrowRates (info: any): IsolatedBorrowRates { + const result = {}; + for (let i = 0; i < info.length; i++) { + const item = info[i]; + const borrowRate = this.parseIsolatedBorrowRate (item); + const symbol = this.safeString (borrowRate, 'symbol'); + result[symbol] = borrowRate; + } + return result as any; + } + parseFundingRateHistories (response, market = undefined, since: Int = undefined, limit: Int = undefined): FundingRateHistory[] { const rates = []; for (let i = 0; i < response.length; i++) { diff --git a/ts/src/base/types.ts b/ts/src/base/types.ts index e7086fb0363f..15aa470f26e6 100644 --- a/ts/src/base/types.ts +++ b/ts/src/base/types.ts @@ -389,13 +389,25 @@ export interface TransferEntry { status?: Str; } -export interface BorrowRate { +export interface CrossBorrowRate { + info: any; currency?: Str; - rate?: number; + rate: number; period?: number; timestamp?: number; datetime?: Str; - info: any; +} + +export interface IsolatedBorrowRate { + info: any, + symbol: string, + base: string, + baseRate: number, + quote: string, + quoteRate: number, + period?: Int, + timestamp?: Int, + datetime?: Str, } export interface FundingRateHistory { @@ -560,6 +572,12 @@ export interface MarginModes extends Dictionary { export interface OptionChain extends Dictionary