ccxt 4.2.29__py2.py3-none-any.whl → 4.2.31__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. ccxt/__init__.py +3 -3
  2. ccxt/abstract/bybit.py +2 -2
  3. ccxt/abstract/coinbase.py +10 -0
  4. ccxt/abstract/okx.py +12 -1
  5. ccxt/ascendex.py +5 -5
  6. ccxt/async_support/__init__.py +3 -3
  7. ccxt/async_support/ascendex.py +5 -5
  8. ccxt/async_support/base/exchange.py +3 -3
  9. ccxt/async_support/bigone.py +2 -2
  10. ccxt/async_support/binance.py +892 -218
  11. ccxt/async_support/bingx.py +1 -1
  12. ccxt/async_support/bitfinex.py +1 -1
  13. ccxt/async_support/bitfinex2.py +421 -86
  14. ccxt/async_support/bitforex.py +3 -0
  15. ccxt/async_support/bitget.py +8 -4
  16. ccxt/async_support/bitmart.py +3 -3
  17. ccxt/async_support/bitmex.py +4 -4
  18. ccxt/async_support/bitrue.py +1 -1
  19. ccxt/async_support/bitso.py +1 -1
  20. ccxt/async_support/bitteam.py +2 -2
  21. ccxt/async_support/btcalpha.py +1 -1
  22. ccxt/async_support/bybit.py +3 -3
  23. ccxt/async_support/coinbase.py +20 -5
  24. ccxt/async_support/coincheck.py +1 -1
  25. ccxt/async_support/coinex.py +2 -2
  26. ccxt/async_support/coinlist.py +1 -1
  27. ccxt/async_support/coinmate.py +1 -1
  28. ccxt/async_support/coinmetro.py +2 -2
  29. ccxt/async_support/coinsph.py +1 -1
  30. ccxt/async_support/cryptocom.py +3 -3
  31. ccxt/async_support/deribit.py +1 -0
  32. ccxt/async_support/digifinex.py +6 -4
  33. ccxt/async_support/exmo.py +2 -2
  34. ccxt/async_support/gate.py +5 -5
  35. ccxt/async_support/gemini.py +3 -3
  36. ccxt/async_support/hitbtc.py +13 -17
  37. ccxt/async_support/hollaex.py +2 -2
  38. ccxt/async_support/htx.py +6 -6
  39. ccxt/async_support/huobijp.py +1 -1
  40. ccxt/async_support/kraken.py +3 -1
  41. ccxt/async_support/krakenfutures.py +4 -1
  42. ccxt/async_support/kucoin.py +17 -17
  43. ccxt/async_support/kucoinfutures.py +3 -3
  44. ccxt/async_support/lbank.py +4 -3
  45. ccxt/async_support/mexc.py +7 -7
  46. ccxt/async_support/novadax.py +1 -1
  47. ccxt/async_support/okcoin.py +2 -2
  48. ccxt/async_support/okx.py +22 -8
  49. ccxt/async_support/p2b.py +1 -0
  50. ccxt/async_support/phemex.py +3 -3
  51. ccxt/async_support/poloniexfutures.py +6 -3
  52. ccxt/async_support/probit.py +1 -1
  53. ccxt/async_support/timex.py +2 -2
  54. ccxt/async_support/tokocrypto.py +3 -3
  55. ccxt/async_support/wavesexchange.py +2 -2
  56. ccxt/async_support/whitebit.py +3 -3
  57. ccxt/async_support/woo.py +3 -3
  58. ccxt/async_support/yobit.py +1 -1
  59. ccxt/async_support/zaif.py +1 -1
  60. ccxt/async_support/zonda.py +3 -3
  61. ccxt/base/errors.py +13 -12
  62. ccxt/base/exchange.py +36 -26
  63. ccxt/bigone.py +2 -2
  64. ccxt/binance.py +892 -218
  65. ccxt/bingx.py +1 -1
  66. ccxt/bitfinex.py +1 -1
  67. ccxt/bitfinex2.py +421 -86
  68. ccxt/bitforex.py +3 -0
  69. ccxt/bitget.py +8 -4
  70. ccxt/bitmart.py +3 -3
  71. ccxt/bitmex.py +4 -4
  72. ccxt/bitrue.py +1 -1
  73. ccxt/bitso.py +1 -1
  74. ccxt/bitteam.py +2 -2
  75. ccxt/btcalpha.py +1 -1
  76. ccxt/bybit.py +3 -3
  77. ccxt/coinbase.py +20 -5
  78. ccxt/coincheck.py +1 -1
  79. ccxt/coinex.py +2 -2
  80. ccxt/coinlist.py +1 -1
  81. ccxt/coinmate.py +1 -1
  82. ccxt/coinmetro.py +2 -2
  83. ccxt/coinsph.py +1 -1
  84. ccxt/cryptocom.py +3 -3
  85. ccxt/deribit.py +1 -0
  86. ccxt/digifinex.py +6 -4
  87. ccxt/exmo.py +2 -2
  88. ccxt/gate.py +5 -5
  89. ccxt/gemini.py +3 -3
  90. ccxt/hitbtc.py +13 -17
  91. ccxt/hollaex.py +2 -2
  92. ccxt/htx.py +6 -6
  93. ccxt/huobijp.py +1 -1
  94. ccxt/kraken.py +3 -1
  95. ccxt/krakenfutures.py +4 -1
  96. ccxt/kucoin.py +17 -17
  97. ccxt/kucoinfutures.py +3 -3
  98. ccxt/lbank.py +4 -3
  99. ccxt/mexc.py +7 -7
  100. ccxt/novadax.py +1 -1
  101. ccxt/okcoin.py +2 -2
  102. ccxt/okx.py +22 -8
  103. ccxt/p2b.py +1 -0
  104. ccxt/phemex.py +3 -3
  105. ccxt/poloniexfutures.py +6 -3
  106. ccxt/pro/__init__.py +3 -1
  107. ccxt/pro/alpaca.py +1 -1
  108. ccxt/pro/binance.py +4 -4
  109. ccxt/pro/bitget.py +1 -1
  110. ccxt/pro/bitmart.py +1 -1
  111. ccxt/pro/bitmex.py +43 -7
  112. ccxt/pro/bitvavo.py +1 -1
  113. ccxt/pro/bybit.py +2 -2
  114. ccxt/pro/cex.py +2 -2
  115. ccxt/pro/independentreserve.py +1 -1
  116. ccxt/pro/okx.py +1 -1
  117. ccxt/pro/onetrading.py +2 -2
  118. ccxt/pro/p2b.py +407 -0
  119. ccxt/pro/probit.py +5 -5
  120. ccxt/pro/whitebit.py +1 -1
  121. ccxt/probit.py +1 -1
  122. ccxt/timex.py +2 -2
  123. ccxt/tokocrypto.py +3 -3
  124. ccxt/wavesexchange.py +2 -2
  125. ccxt/whitebit.py +3 -3
  126. ccxt/woo.py +3 -3
  127. ccxt/yobit.py +1 -1
  128. ccxt/zaif.py +1 -1
  129. ccxt/zonda.py +3 -3
  130. {ccxt-4.2.29.dist-info → ccxt-4.2.31.dist-info}/METADATA +6 -7
  131. {ccxt-4.2.29.dist-info → ccxt-4.2.31.dist-info}/RECORD +133 -132
  132. {ccxt-4.2.29.dist-info → ccxt-4.2.31.dist-info}/WHEEL +0 -0
  133. {ccxt-4.2.29.dist-info → ccxt-4.2.31.dist-info}/top_level.txt +0 -0
ccxt/bitfinex2.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.bitfinex2 import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Market, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
9
+ from ccxt.base.types import Balances, Currency, Int, Market, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import PermissionDenied
@@ -45,32 +45,42 @@ class bitfinex2(Exchange, ImplicitAPI):
45
45
  'CORS': None,
46
46
  'spot': True,
47
47
  'margin': None, # has but unimplemented
48
- 'swap': None, # has but unimplemented
48
+ 'swap': True,
49
49
  'future': None,
50
50
  'option': None,
51
+ 'addMargin': False,
51
52
  'cancelAllOrders': True,
52
53
  'cancelOrder': True,
54
+ 'cancelOrders': True,
53
55
  'createDepositAddress': True,
54
56
  'createLimitOrder': True,
55
57
  'createMarketOrder': True,
56
58
  'createOrder': True,
59
+ 'createReduceOnlyOrder': True,
57
60
  'createStopLimitOrder': True,
58
61
  'createStopMarketOrder': True,
59
62
  'createStopOrder': True,
60
- 'editOrder': False,
63
+ 'createTrailingAmountOrder': True,
64
+ 'createTrailingPercentOrder': False,
65
+ 'createTriggerOrder': True,
66
+ 'editOrder': True,
61
67
  'fetchBalance': True,
62
68
  'fetchClosedOrder': True,
63
69
  'fetchClosedOrders': True,
64
70
  'fetchCurrencies': True,
65
71
  'fetchDepositAddress': True,
66
72
  'fetchDepositsWithdrawals': True,
73
+ 'fetchFundingHistory': False,
67
74
  'fetchFundingRate': True,
68
75
  'fetchFundingRateHistory': True,
69
76
  'fetchFundingRates': True,
70
77
  'fetchIndexOHLCV': False,
71
78
  'fetchLedger': True,
79
+ 'fetchLeverage': False,
80
+ 'fetchLeverageTiers': False,
72
81
  'fetchLiquidations': True,
73
82
  'fetchMarginMode': False,
83
+ 'fetchMarketLeverageTiers': False,
74
84
  'fetchMarkOHLCV': False,
75
85
  'fetchMyTrades': True,
76
86
  'fetchOHLCV': True,
@@ -80,7 +90,10 @@ class bitfinex2(Exchange, ImplicitAPI):
80
90
  'fetchOpenOrders': True,
81
91
  'fetchOrder': True,
82
92
  'fetchOrderTrades': True,
93
+ 'fetchPosition': False,
83
94
  'fetchPositionMode': False,
95
+ 'fetchPositions': True,
96
+ 'fetchPremiumIndexOHLCV': False,
84
97
  'fetchStatus': True,
85
98
  'fetchTickers': True,
86
99
  'fetchTime': False,
@@ -88,7 +101,11 @@ class bitfinex2(Exchange, ImplicitAPI):
88
101
  'fetchTradingFees': True,
89
102
  'fetchTransactionFees': None,
90
103
  'fetchTransactions': 'emulated',
104
+ 'reduceMargin': False,
105
+ 'setLeverage': False,
91
106
  'setMargin': True,
107
+ 'setMarginMode': False,
108
+ 'setPositionMode': False,
92
109
  'withdraw': True,
93
110
  },
94
111
  'timeframes': {
@@ -356,6 +373,7 @@ class bitfinex2(Exchange, ImplicitAPI):
356
373
  'margin': 'margin',
357
374
  'derivatives': 'margin',
358
375
  'future': 'margin',
376
+ 'swap': 'margin',
359
377
  },
360
378
  'withdraw': {
361
379
  'includeFee': False,
@@ -977,7 +995,7 @@ class bitfinex2(Exchange, ImplicitAPI):
977
995
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
978
996
  :see: https://docs.bitfinex.com/reference/rest-public-book
979
997
  :param str symbol: unified symbol of the market to fetch the order book for
980
- :param int [limit]: the maximum amount of order book entries to return
998
+ :param int [limit]: the maximum amount of order book entries to return, bitfinex only allows 1, 25, or 100
981
999
  :param dict [params]: extra parameters specific to the exchange API endpoint
982
1000
  :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
983
1001
  """
@@ -989,7 +1007,7 @@ class bitfinex2(Exchange, ImplicitAPI):
989
1007
  'precision': precision,
990
1008
  }
991
1009
  if limit is not None:
992
- request['len'] = limit # 25 or 100
1010
+ request['len'] = limit
993
1011
  fullRequest = self.extend(request, params)
994
1012
  orderbook = self.publicGetBookSymbolPrecision(fullRequest)
995
1013
  timestamp = self.milliseconds()
@@ -1247,9 +1265,9 @@ class bitfinex2(Exchange, ImplicitAPI):
1247
1265
  :see: https://docs.bitfinex.com/reference/rest-public-trades
1248
1266
  :param str symbol: unified symbol of the market to fetch trades for
1249
1267
  :param int [since]: timestamp in ms of the earliest trade to fetch
1250
- :param int [limit]: the maximum amount of trades to fetch
1268
+ :param int [limit]: the maximum amount of trades to fetch, default 120, max 10000
1251
1269
  :param dict [params]: extra parameters specific to the exchange API endpoint
1252
- :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
1270
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
1253
1271
  :param int [params.until]: the latest time in ms to fetch entries for
1254
1272
  :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
1255
1273
  """
@@ -1291,11 +1309,11 @@ class bitfinex2(Exchange, ImplicitAPI):
1291
1309
  :param str symbol: unified symbol of the market to fetch OHLCV data for
1292
1310
  :param str timeframe: the length of time each candle represents
1293
1311
  :param int [since]: timestamp in ms of the earliest candle to fetch
1294
- :param int [limit]: the maximum amount of candles to fetch
1312
+ :param int [limit]: the maximum amount of candles to fetch, default 100 max 10000
1295
1313
  :param dict [params]: extra parameters specific to the exchange API endpoint
1296
1314
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
1297
1315
  :param int [params.until]: timestamp in ms of the latest candle to fetch
1298
- :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
1316
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
1299
1317
  """
1300
1318
  self.load_markets()
1301
1319
  paginate = False
@@ -1304,7 +1322,7 @@ class bitfinex2(Exchange, ImplicitAPI):
1304
1322
  return self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 10000)
1305
1323
  market = self.market(symbol)
1306
1324
  if limit is None:
1307
- limit = 10000 # default 100, max 5000
1325
+ limit = 10000
1308
1326
  request = {
1309
1327
  'symbol': market['id'],
1310
1328
  'timeframe': self.safe_string(self.timeframes, timeframe, timeframe),
@@ -1444,87 +1462,62 @@ class bitfinex2(Exchange, ImplicitAPI):
1444
1462
  'trades': None,
1445
1463
  }, market)
1446
1464
 
1447
- def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
1465
+ def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
1448
1466
  """
1449
- Create an order on the exchange
1450
- :see: https://docs.bitfinex.com/reference/rest-auth-submit-order
1451
- :param str symbol: Unified CCXT market symbol
1452
- :param str type: 'limit' or 'market'
1467
+ * @ignore
1468
+ helper function to build an order request
1469
+ :param str symbol: unified symbol of the market to create an order in
1470
+ :param str type: 'market' or 'limit'
1453
1471
  :param str side: 'buy' or 'sell'
1454
- :param float amount: the amount of currency to trade
1455
- :param float [price]: price of order
1456
- :param dict [params]: extra parameters specific to the exchange API endpoint
1457
- :param float [params.stopPrice]: The price at which a trigger order is triggered at
1458
- :param str [params.timeInForce]: "GTC", "IOC", "FOK", or "PO"
1459
- :param bool params.postOnly:
1460
- :param bool [params.reduceOnly]: Ensures that the executed order does not flip the opened position.
1461
- :param int [params.flags]: additional order parameters: 4096(Post Only), 1024(Reduce Only), 16384(OCO), 64(Hidden), 512(Close), 524288(No Var Rates)
1462
- :param int [params.lev]: leverage for a derivative order, supported by derivative symbol orders only. The value should be between 1 and 100 inclusive.
1463
- :param str [params.price_traling]: The trailing price for a trailing stop order
1464
- :param str [params.price_aux_limit]: Order price for stop limit orders
1465
- :param str [params.price_oco_stop]: OCO stop price
1466
- :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1472
+ :param float amount: how much you want to trade in units of the base currency
1473
+ :param float [price]: the price of the order, in units of the quote currency, ignored in market orders
1474
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1475
+ :returns dict: request to be sent to the exchange
1467
1476
  """
1468
- self.load_markets()
1469
1477
  market = self.market(symbol)
1470
- # order types "limit" and "market" immediatley parsed "EXCHANGE LIMIT" and "EXCHANGE MARKET"
1471
- # note: same order types exist for margin orders without the EXCHANGE prefix
1472
- orderTypes = self.safe_value(self.options, 'orderTypes', {})
1473
- orderType = type.upper()
1474
- if market['spot']:
1475
- # although they claim that type needs to be 'exchange limit' or 'exchange market'
1476
- # in fact that's not the case for swap markets
1477
- orderType = self.safe_string_upper(orderTypes, type, type)
1478
- stopPrice = self.safe_string_2(params, 'stopPrice', 'triggerPrice')
1479
- timeInForce = self.safe_string(params, 'timeInForce')
1480
- postOnlyParam = self.safe_value(params, 'postOnly', False)
1481
- reduceOnly = self.safe_value(params, 'reduceOnly', False)
1482
- clientOrderId = self.safe_value_2(params, 'cid', 'clientOrderId')
1483
- params = self.omit(params, ['triggerPrice', 'stopPrice', 'timeInForce', 'postOnly', 'reduceOnly', 'price_aux_limit'])
1484
1478
  amountString = self.amount_to_precision(symbol, amount)
1485
1479
  amountString = amountString if (side == 'buy') else Precise.string_neg(amountString)
1486
1480
  request = {
1487
- # 'gid': 0123456789, # int32, optional group id for the order
1488
- # 'cid': 0123456789, # int32 client order id
1489
- 'type': orderType,
1490
1481
  'symbol': market['id'],
1491
- # 'price': self.number_to_string(price),
1492
1482
  'amount': amountString,
1493
- # 'flags': 0, # int32, https://docs.bitfinex.com/v2/docs/flag-values
1494
- # 'lev': 10, # leverage for a derivative orders, the value should be between 1 and 100 inclusive, optional, 10 by default
1495
- # 'price_trailing': self.number_to_string(priceTrailing),
1496
- # 'price_aux_limit': self.number_to_string(stopPrice),
1497
- # 'price_oco_stop': self.number_to_string(ocoStopPrice),
1498
- # 'tif': '2020-01-01 10:45:23', # datetime for automatic order cancellation
1499
- # 'meta': {
1500
- # 'aff_code': 'AFF_CODE_HERE'
1501
- # },
1502
1483
  }
1503
- stopLimit = ((orderType == 'EXCHANGE STOP LIMIT') or ((orderType == 'EXCHANGE LIMIT') and (stopPrice is not None)))
1504
- exchangeStop = (orderType == 'EXCHANGE STOP')
1505
- exchangeMarket = (orderType == 'EXCHANGE MARKET')
1506
- stopMarket = (exchangeStop or (exchangeMarket and (stopPrice is not None)))
1507
- ioc = ((orderType == 'EXCHANGE IOC') or (timeInForce == 'IOC'))
1508
- fok = ((orderType == 'EXCHANGE FOK') or (timeInForce == 'FOK'))
1484
+ stopPrice = self.safe_string_2(params, 'stopPrice', 'triggerPrice')
1485
+ trailingAmount = self.safe_string(params, 'trailingAmount')
1486
+ timeInForce = self.safe_string(params, 'timeInForce')
1487
+ postOnlyParam = self.safe_bool(params, 'postOnly', False)
1488
+ reduceOnly = self.safe_bool(params, 'reduceOnly', False)
1489
+ clientOrderId = self.safe_value_2(params, 'cid', 'clientOrderId')
1490
+ orderType = type.upper()
1491
+ if trailingAmount is not None:
1492
+ orderType = 'TRAILING STOP'
1493
+ request['price_trailing'] = trailingAmount
1494
+ elif stopPrice is not None:
1495
+ # request['price'] is taken for stop orders
1496
+ request['price'] = self.price_to_precision(symbol, stopPrice)
1497
+ if type == 'limit':
1498
+ orderType = 'STOP LIMIT'
1499
+ request['price_aux_limit'] = self.price_to_precision(symbol, price)
1500
+ else:
1501
+ orderType = 'STOP'
1502
+ ioc = (timeInForce == 'IOC')
1503
+ fok = (timeInForce == 'FOK')
1509
1504
  postOnly = (postOnlyParam or (timeInForce == 'PO'))
1510
1505
  if (ioc or fok) and (price is None):
1511
1506
  raise InvalidOrder(self.id + ' createOrder() requires a price argument with IOC and FOK orders')
1512
- if (ioc or fok) and exchangeMarket:
1507
+ if (ioc or fok) and (type == 'market'):
1513
1508
  raise InvalidOrder(self.id + ' createOrder() does not allow market IOC and FOK orders')
1514
- if (orderType != 'MARKET') and (not exchangeMarket) and (not exchangeStop):
1509
+ if (type != 'market') and (stopPrice is None):
1515
1510
  request['price'] = self.price_to_precision(symbol, price)
1516
- if stopLimit or stopMarket:
1517
- # request['price'] is taken for stop orders
1518
- request['price'] = self.price_to_precision(symbol, stopPrice)
1519
- if stopMarket:
1520
- request['type'] = 'EXCHANGE STOP'
1521
- elif stopLimit:
1522
- request['type'] = 'EXCHANGE STOP LIMIT'
1523
- request['price_aux_limit'] = self.price_to_precision(symbol, price)
1524
1511
  if ioc:
1525
- request['type'] = 'EXCHANGE IOC'
1512
+ orderType = 'IOC'
1526
1513
  elif fok:
1527
- request['type'] = 'EXCHANGE FOK'
1514
+ orderType = 'FOK'
1515
+ marginMode = None
1516
+ marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
1517
+ if market['spot'] and (marginMode is None):
1518
+ # The EXCHANGE prefix is only required for non margin spot markets
1519
+ orderType = 'EXCHANGE ' + orderType
1520
+ request['type'] = orderType
1528
1521
  # flag values may be summed to combine flags
1529
1522
  flags = 0
1530
1523
  if postOnly:
@@ -1535,8 +1528,34 @@ class bitfinex2(Exchange, ImplicitAPI):
1535
1528
  request['flags'] = flags
1536
1529
  if clientOrderId is not None:
1537
1530
  request['cid'] = clientOrderId
1538
- params = self.omit(params, ['cid', 'clientOrderId'])
1539
- response = self.privatePostAuthWOrderSubmit(self.extend(request, params))
1531
+ params = self.omit(params, ['triggerPrice', 'stopPrice', 'timeInForce', 'postOnly', 'reduceOnly', 'trailingAmount', 'clientOrderId'])
1532
+ return self.extend(request, params)
1533
+
1534
+ def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
1535
+ """
1536
+ create an order on the exchange
1537
+ :see: https://docs.bitfinex.com/reference/rest-auth-submit-order
1538
+ :param str symbol: unified CCXT market symbol
1539
+ :param str type: 'limit' or 'market'
1540
+ :param str side: 'buy' or 'sell'
1541
+ :param float amount: the amount of currency to trade
1542
+ :param float [price]: price of the order
1543
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1544
+ :param float [params.stopPrice]: the price that triggers a trigger order
1545
+ :param str [params.timeInForce]: "GTC", "IOC", "FOK", or "PO"
1546
+ :param boolean [params.postOnly]: set to True if you want to make a post only order
1547
+ :param boolean [params.reduceOnly]: indicates that the order is to reduce the size of a position
1548
+ :param int [params.flags]: additional order parameters: 4096(Post Only), 1024(Reduce Only), 16384(OCO), 64(Hidden), 512(Close), 524288(No Var Rates)
1549
+ :param int [params.lev]: leverage for a derivative order, supported by derivative symbol orders only. The value should be between 1 and 100 inclusive.
1550
+ :param str [params.price_aux_limit]: order price for stop limit orders
1551
+ :param str [params.price_oco_stop]: OCO stop price
1552
+ :param str [params.trailingAmount]: *swap only* the quote amount to trail away from the current market price
1553
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1554
+ """
1555
+ self.load_markets()
1556
+ market = self.market(symbol)
1557
+ request = self.create_order_request(symbol, type, side, amount, price, params)
1558
+ response = self.privatePostAuthWOrderSubmit(request)
1540
1559
  #
1541
1560
  # [
1542
1561
  # 1653325121, # Timestamp in milliseconds
@@ -1589,10 +1608,67 @@ class bitfinex2(Exchange, ImplicitAPI):
1589
1608
  errorCode = response[5]
1590
1609
  errorText = response[7]
1591
1610
  raise ExchangeError(self.id + ' ' + response[6] + ': ' + errorText + '(#' + errorCode + ')')
1592
- orders = self.safe_value(response, 4, [])
1593
- order = self.safe_value(orders, 0)
1611
+ orders = self.safe_list(response, 4, [])
1612
+ order = self.safe_list(orders, 0)
1594
1613
  return self.parse_order(order, market)
1595
1614
 
1615
+ def create_orders(self, orders: List[OrderRequest], params={}):
1616
+ """
1617
+ create a list of trade orders
1618
+ :see: https://docs.bitfinex.com/reference/rest-auth-order-multi
1619
+ :param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
1620
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1621
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1622
+ """
1623
+ self.load_markets()
1624
+ ordersRequests = []
1625
+ for i in range(0, len(orders)):
1626
+ rawOrder = orders[i]
1627
+ symbol = self.safe_string(rawOrder, 'symbol')
1628
+ type = self.safe_string(rawOrder, 'type')
1629
+ side = self.safe_string(rawOrder, 'side')
1630
+ amount = self.safe_number(rawOrder, 'amount')
1631
+ price = self.safe_number(rawOrder, 'price')
1632
+ orderParams = self.safe_dict(rawOrder, 'params', {})
1633
+ orderRequest = self.create_order_request(symbol, type, side, amount, price, orderParams)
1634
+ ordersRequests.append(['on', orderRequest])
1635
+ request = {
1636
+ 'ops': ordersRequests,
1637
+ }
1638
+ response = self.privatePostAuthWOrderMulti(request)
1639
+ #
1640
+ # [
1641
+ # 1706762515553,
1642
+ # "ox_multi-req",
1643
+ # null,
1644
+ # null,
1645
+ # [
1646
+ # [
1647
+ # 1706762515,
1648
+ # "on-req",
1649
+ # null,
1650
+ # null,
1651
+ # [
1652
+ # [139567428547,null,1706762515551,"tBTCUST",1706762515551,1706762515551,0.0001,0.0001,"EXCHANGE LIMIT",null,null,null,0,"ACTIVE",null,null,35000,0,0,0,null,null,null,0,0,null,null,null,"API>BFX",null,null,{}]
1653
+ # ],
1654
+ # null,
1655
+ # "SUCCESS",
1656
+ # "Submitting 1 orders."
1657
+ # ],
1658
+ # ],
1659
+ # null,
1660
+ # "SUCCESS",
1661
+ # "Submitting 2 order operations."
1662
+ # ]
1663
+ #
1664
+ results = []
1665
+ data = self.safe_list(response, 4, [])
1666
+ for i in range(0, len(data)):
1667
+ entry = data[i]
1668
+ individualOrder = entry[4]
1669
+ results.append(individualOrder[0])
1670
+ return self.parse_orders(results)
1671
+
1596
1672
  def cancel_all_orders(self, symbol: Str = None, params={}):
1597
1673
  """
1598
1674
  cancel all open orders
@@ -1601,6 +1677,7 @@ class bitfinex2(Exchange, ImplicitAPI):
1601
1677
  :param dict [params]: extra parameters specific to the exchange API endpoint
1602
1678
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1603
1679
  """
1680
+ self.load_markets()
1604
1681
  request = {
1605
1682
  'all': 1,
1606
1683
  }
@@ -1617,6 +1694,7 @@ class bitfinex2(Exchange, ImplicitAPI):
1617
1694
  :param dict [params]: extra parameters specific to the exchange API endpoint
1618
1695
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1619
1696
  """
1697
+ self.load_markets()
1620
1698
  cid = self.safe_value_2(params, 'cid', 'clientOrderId') # client order id
1621
1699
  request = None
1622
1700
  if cid is not None:
@@ -1636,6 +1714,78 @@ class bitfinex2(Exchange, ImplicitAPI):
1636
1714
  order = self.safe_value(response, 4)
1637
1715
  return self.parse_order(order)
1638
1716
 
1717
+ def cancel_orders(self, ids, symbol: Str = None, params={}):
1718
+ """
1719
+ cancel multiple orders at the same time
1720
+ :see: https://docs.bitfinex.com/reference/rest-auth-cancel-orders-multiple
1721
+ :param str[] ids: order ids
1722
+ :param str symbol: unified market symbol, default is None
1723
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1724
+ :returns dict: an array of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1725
+ """
1726
+ self.load_markets()
1727
+ for i in range(0, len(ids)):
1728
+ ids[i] = self.parse_to_numeric(ids[i])
1729
+ request = {
1730
+ 'id': ids,
1731
+ }
1732
+ market = None
1733
+ if symbol is not None:
1734
+ market = self.market(symbol)
1735
+ response = self.privatePostAuthWOrderCancelMulti(self.extend(request, params))
1736
+ #
1737
+ # [
1738
+ # 1706740198811,
1739
+ # "oc_multi-req",
1740
+ # null,
1741
+ # null,
1742
+ # [
1743
+ # [
1744
+ # 139530205057,
1745
+ # null,
1746
+ # 1706740132275,
1747
+ # "tBTCF0:USTF0",
1748
+ # 1706740132276,
1749
+ # 1706740132276,
1750
+ # 0.0001,
1751
+ # 0.0001,
1752
+ # "LIMIT",
1753
+ # null,
1754
+ # null,
1755
+ # null,
1756
+ # 0,
1757
+ # "ACTIVE",
1758
+ # null,
1759
+ # null,
1760
+ # 39000,
1761
+ # 0,
1762
+ # 0,
1763
+ # 0,
1764
+ # null,
1765
+ # null,
1766
+ # null,
1767
+ # 0,
1768
+ # 0,
1769
+ # null,
1770
+ # null,
1771
+ # null,
1772
+ # "API>BFX",
1773
+ # null,
1774
+ # null,
1775
+ # {
1776
+ # "lev": 10,
1777
+ # "$F33": 10
1778
+ # }
1779
+ # ],
1780
+ # ],
1781
+ # null,
1782
+ # "SUCCESS",
1783
+ # "Submitting 2 order cancellations."
1784
+ # ]
1785
+ #
1786
+ orders = self.safe_list(response, 4, [])
1787
+ return self.parse_orders(orders, market)
1788
+
1639
1789
  def fetch_open_order(self, id: str, symbol: Str = None, params={}):
1640
1790
  """
1641
1791
  fetch an open order by it's id
@@ -2275,7 +2425,7 @@ class bitfinex2(Exchange, ImplicitAPI):
2275
2425
  if tag is not None:
2276
2426
  request['payment_id'] = tag
2277
2427
  withdrawOptions = self.safe_value(self.options, 'withdraw', {})
2278
- includeFee = self.safe_value(withdrawOptions, 'includeFee', False)
2428
+ includeFee = self.safe_bool(withdrawOptions, 'includeFee', False)
2279
2429
  if includeFee:
2280
2430
  request['fee_deduct'] = 1
2281
2431
  response = self.privatePostAuthWWithdraw(self.extend(request, params))
@@ -2563,14 +2713,13 @@ class bitfinex2(Exchange, ImplicitAPI):
2563
2713
  :see: https://docs.bitfinex.com/reference/rest-auth-ledgers
2564
2714
  :param str code: unified currency code, default is None
2565
2715
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
2566
- :param int [limit]: max number of ledger entrys to return, default is None
2716
+ :param int [limit]: max number of ledger entrys to return, default is None max is 2500
2567
2717
  :param dict [params]: extra parameters specific to the exchange API endpoint
2568
2718
  :param int [params.until]: timestamp in ms of the latest ledger entry
2569
- :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2719
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2570
2720
  :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
2571
2721
  """
2572
2722
  self.load_markets()
2573
- self.load_markets()
2574
2723
  paginate = False
2575
2724
  paginate, params = self.handle_option_and_params(params, 'fetchLedger', 'paginate')
2576
2725
  if paginate:
@@ -2580,7 +2729,7 @@ class bitfinex2(Exchange, ImplicitAPI):
2580
2729
  if since is not None:
2581
2730
  request['start'] = since
2582
2731
  if limit is not None:
2583
- request['limit'] = limit # max 2500
2732
+ request['limit'] = limit
2584
2733
  request, params = self.handle_until_option('end', request, params)
2585
2734
  response = None
2586
2735
  if code is not None:
@@ -2669,9 +2818,11 @@ class bitfinex2(Exchange, ImplicitAPI):
2669
2818
  fetches historical funding rate prices
2670
2819
  :see: https://docs.bitfinex.com/reference/rest-public-derivatives-status-history
2671
2820
  :param str symbol: unified market symbol
2821
+ :param int [since]: timestamp in ms of the earliest funding rate entry
2822
+ :param int [limit]: max number of funding rate entrys to return
2672
2823
  :param dict [params]: extra parameters specific to the exchange API endpoint
2673
2824
  :param int [params.until]: timestamp in ms of the latest funding rate
2674
- :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2825
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2675
2826
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
2676
2827
  """
2677
2828
  if symbol is None:
@@ -2724,7 +2875,14 @@ class bitfinex2(Exchange, ImplicitAPI):
2724
2875
  fr = response[i]
2725
2876
  rate = self.parse_funding_rate_history(fr, market)
2726
2877
  rates.append(rate)
2727
- return self.filter_by_symbol_since_limit(rates, symbol, since, limit)
2878
+ reversedArray = []
2879
+ rawRates = self.filter_by_symbol_since_limit(rates, symbol, since, limit)
2880
+ rawRatesLength = len(rawRates)
2881
+ ratesLength = max(rawRatesLength - 1, 0)
2882
+ for i in range(ratesLength, 0):
2883
+ valueAtIndex = rawRates[i]
2884
+ reversedArray.append(valueAtIndex)
2885
+ return reversedArray
2728
2886
 
2729
2887
  def parse_funding_rate(self, contract, market: Market = None):
2730
2888
  #
@@ -2872,7 +3030,8 @@ class bitfinex2(Exchange, ImplicitAPI):
2872
3030
  # ]
2873
3031
  # ]
2874
3032
  #
2875
- return self.parse_open_interest(response[0], market)
3033
+ oi = self.safe_list(response, 0)
3034
+ return self.parse_open_interest(oi, market)
2876
3035
 
2877
3036
  def fetch_open_interest_history(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}):
2878
3037
  """
@@ -3129,3 +3288,179 @@ class bitfinex2(Exchange, ImplicitAPI):
3129
3288
  'symbol': market['symbol'],
3130
3289
  'status': marginStatus,
3131
3290
  }
3291
+
3292
+ def fetch_order(self, id: str, symbol: str = None, params={}):
3293
+ """
3294
+ fetches information on an order made by the user
3295
+ :see: https://docs.bitfinex.com/reference/rest-auth-retrieve-orders
3296
+ :see: https://docs.bitfinex.com/reference/rest-auth-retrieve-orders-by-symbol
3297
+ :param str id: the order id
3298
+ :param str [symbol]: unified symbol of the market the order was made in
3299
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3300
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3301
+ """
3302
+ self.load_markets()
3303
+ request = {
3304
+ 'id': [self.parse_to_numeric(id)],
3305
+ }
3306
+ market = None
3307
+ response = None
3308
+ if symbol is None:
3309
+ response = self.privatePostAuthROrders(self.extend(request, params))
3310
+ else:
3311
+ market = self.market(symbol)
3312
+ request['symbol'] = market['id']
3313
+ response = self.privatePostAuthROrdersSymbol(self.extend(request, params))
3314
+ #
3315
+ # [
3316
+ # [
3317
+ # 139658969116,
3318
+ # null,
3319
+ # 1706843908637,
3320
+ # "tBTCUST",
3321
+ # 1706843908637,
3322
+ # 1706843908638,
3323
+ # 0.0001,
3324
+ # 0.0001,
3325
+ # "EXCHANGE LIMIT",
3326
+ # null,
3327
+ # null,
3328
+ # null,
3329
+ # 0,
3330
+ # "ACTIVE",
3331
+ # null,
3332
+ # null,
3333
+ # 35000,
3334
+ # 0,
3335
+ # 0,
3336
+ # 0,
3337
+ # null,
3338
+ # null,
3339
+ # null,
3340
+ # 0,
3341
+ # 0,
3342
+ # null,
3343
+ # null,
3344
+ # null,
3345
+ # "API>BFX",
3346
+ # null,
3347
+ # null,
3348
+ # {}
3349
+ # ]
3350
+ # ]
3351
+ #
3352
+ order = self.safe_list(response, 0)
3353
+ return self.parse_order(order, market)
3354
+
3355
+ def edit_order(self, id: str, symbol, type, side, amount=None, price=None, params={}):
3356
+ """
3357
+ edit a trade order
3358
+ :see: https://docs.bitfinex.com/reference/rest-auth-update-order
3359
+ :param str id: edit order id
3360
+ :param str symbol: unified symbol of the market to edit an order in
3361
+ :param str type: 'market' or 'limit'
3362
+ :param str side: 'buy' or 'sell'
3363
+ :param float amount: how much you want to trade in units of the base currency
3364
+ :param float [price]: the price that the order is to be fullfilled, in units of the quote currency, ignored in market orders
3365
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3366
+ :param float [params.stopPrice]: the price that triggers a trigger order
3367
+ :param boolean [params.postOnly]: set to True if you want to make a post only order
3368
+ :param boolean [params.reduceOnly]: indicates that the order is to reduce the size of a position
3369
+ :param int [params.flags]: additional order parameters: 4096(Post Only), 1024(Reduce Only), 16384(OCO), 64(Hidden), 512(Close), 524288(No Var Rates)
3370
+ :param int [params.leverage]: leverage for a derivative order, supported by derivative symbol orders only, the value should be between 1 and 100 inclusive
3371
+ :param int [params.clientOrderId]: a unique client order id for the order
3372
+ :param float [params.trailingAmount]: *swap only* the quote amount to trail away from the current market price
3373
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
3374
+ """
3375
+ self.load_markets()
3376
+ market = self.market(symbol)
3377
+ request = {
3378
+ 'id': self.parse_to_numeric(id),
3379
+ }
3380
+ if amount is not None:
3381
+ amountString = self.amount_to_precision(symbol, amount)
3382
+ amountString = amountString if (side == 'buy') else Precise.string_neg(amountString)
3383
+ request['amount'] = amountString
3384
+ stopPrice = self.safe_string_2(params, 'stopPrice', 'triggerPrice')
3385
+ trailingAmount = self.safe_string(params, 'trailingAmount')
3386
+ timeInForce = self.safe_string(params, 'timeInForce')
3387
+ postOnlyParam = self.safe_bool(params, 'postOnly', False)
3388
+ reduceOnly = self.safe_bool(params, 'reduceOnly', False)
3389
+ clientOrderId = self.safe_integer_2(params, 'cid', 'clientOrderId')
3390
+ if trailingAmount is not None:
3391
+ request['price_trailing'] = trailingAmount
3392
+ elif stopPrice is not None:
3393
+ # request['price'] is taken for stop orders
3394
+ request['price'] = self.price_to_precision(symbol, stopPrice)
3395
+ if type == 'limit':
3396
+ request['price_aux_limit'] = self.price_to_precision(symbol, price)
3397
+ postOnly = (postOnlyParam or (timeInForce == 'PO'))
3398
+ if (type != 'market') and (stopPrice is None):
3399
+ request['price'] = self.price_to_precision(symbol, price)
3400
+ # flag values may be summed to combine flags
3401
+ flags = 0
3402
+ if postOnly:
3403
+ flags = self.sum(flags, 4096)
3404
+ if reduceOnly:
3405
+ flags = self.sum(flags, 1024)
3406
+ if flags != 0:
3407
+ request['flags'] = flags
3408
+ if clientOrderId is not None:
3409
+ request['cid'] = clientOrderId
3410
+ leverage = self.safe_integer_2(params, 'leverage', 'lev')
3411
+ if leverage is not None:
3412
+ request['lev'] = leverage
3413
+ params = self.omit(params, ['triggerPrice', 'stopPrice', 'timeInForce', 'postOnly', 'reduceOnly', 'trailingAmount', 'clientOrderId', 'leverage'])
3414
+ response = self.privatePostAuthWOrderUpdate(self.extend(request, params))
3415
+ #
3416
+ # [
3417
+ # 1706845376402,
3418
+ # "ou-req",
3419
+ # null,
3420
+ # null,
3421
+ # [
3422
+ # 139658969116,
3423
+ # null,
3424
+ # 1706843908637,
3425
+ # "tBTCUST",
3426
+ # 1706843908637,
3427
+ # 1706843908638,
3428
+ # 0.0002,
3429
+ # 0.0002,
3430
+ # "EXCHANGE LIMIT",
3431
+ # null,
3432
+ # null,
3433
+ # null,
3434
+ # 0,
3435
+ # "ACTIVE",
3436
+ # null,
3437
+ # null,
3438
+ # 35000,
3439
+ # 0,
3440
+ # 0,
3441
+ # 0,
3442
+ # null,
3443
+ # null,
3444
+ # null,
3445
+ # 0,
3446
+ # 0,
3447
+ # null,
3448
+ # null,
3449
+ # null,
3450
+ # "API>BFX",
3451
+ # null,
3452
+ # null,
3453
+ # {}
3454
+ # ],
3455
+ # null,
3456
+ # "SUCCESS",
3457
+ # "Submitting update to exchange limit buy order for 0.0002 BTC."
3458
+ # ]
3459
+ #
3460
+ status = self.safe_string(response, 6)
3461
+ if status != 'SUCCESS':
3462
+ errorCode = response[5]
3463
+ errorText = response[7]
3464
+ raise ExchangeError(self.id + ' ' + response[6] + ': ' + errorText + '(#' + errorCode + ')')
3465
+ order = self.safe_list(response, 4, [])
3466
+ return self.parse_order(order, market)