ccxt 4.3.69__py2.py3-none-any.whl → 4.3.71__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 (159) hide show
  1. ccxt/__init__.py +3 -1
  2. ccxt/abstract/coinbaseinternational.py +1 -1
  3. ccxt/abstract/paradex.py +40 -0
  4. ccxt/async_support/__init__.py +3 -1
  5. ccxt/async_support/base/exchange.py +1 -1
  6. ccxt/async_support/blofin.py +63 -6
  7. ccxt/async_support/bybit.py +1 -1
  8. ccxt/async_support/coinbaseinternational.py +155 -2
  9. ccxt/async_support/cryptocom.py +12 -1
  10. ccxt/async_support/paradex.py +1966 -0
  11. ccxt/async_support/poloniex.py +1 -0
  12. ccxt/async_support/woo.py +4 -2
  13. ccxt/base/exchange.py +63 -1
  14. ccxt/blofin.py +63 -6
  15. ccxt/bybit.py +1 -1
  16. ccxt/coinbaseinternational.py +155 -2
  17. ccxt/cryptocom.py +12 -1
  18. ccxt/paradex.py +1966 -0
  19. ccxt/poloniex.py +1 -0
  20. ccxt/pro/__init__.py +5 -1
  21. ccxt/pro/bequant.py +4 -0
  22. ccxt/pro/blofin.py +608 -0
  23. ccxt/pro/coinbaseinternational.py +142 -11
  24. ccxt/pro/cryptocom.py +4 -1
  25. ccxt/pro/hitbtc.py +20 -8
  26. ccxt/pro/okx.py +6 -0
  27. ccxt/pro/paradex.py +340 -0
  28. ccxt/pro/poloniex.py +32 -10
  29. ccxt/pro/woo.py +5 -4
  30. ccxt/static_dependencies/__init__.py +1 -1
  31. ccxt/static_dependencies/lark/__init__.py +38 -0
  32. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  33. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  34. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  35. ccxt/static_dependencies/lark/common.py +86 -0
  36. ccxt/static_dependencies/lark/exceptions.py +292 -0
  37. ccxt/static_dependencies/lark/grammar.py +130 -0
  38. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  39. ccxt/static_dependencies/lark/indenter.py +143 -0
  40. ccxt/static_dependencies/lark/lark.py +658 -0
  41. ccxt/static_dependencies/lark/lexer.py +678 -0
  42. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  43. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  44. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  45. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  46. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  47. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  48. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  49. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  50. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  51. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  52. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  53. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  54. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  55. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  56. ccxt/static_dependencies/lark/py.typed +0 -0
  57. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  58. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  59. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  60. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  61. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  62. ccxt/static_dependencies/lark/tree.py +267 -0
  63. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  64. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  65. ccxt/static_dependencies/lark/utils.py +343 -0
  66. ccxt/static_dependencies/lark/visitors.py +596 -0
  67. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  68. ccxt/static_dependencies/marshmallow/base.py +65 -0
  69. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  70. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  71. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  72. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  73. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  74. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  75. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  76. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  77. ccxt/static_dependencies/marshmallow/types.py +12 -0
  78. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  79. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  80. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  81. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  82. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  83. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  84. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  85. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  86. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  87. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  88. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  89. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  90. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  91. ccxt/static_dependencies/starknet/__init__.py +0 -0
  92. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  93. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  94. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  95. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  96. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  97. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  98. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  99. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  100. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  101. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  102. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  103. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  104. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  105. ccxt/static_dependencies/starknet/common.py +15 -0
  106. ccxt/static_dependencies/starknet/constants.py +39 -0
  107. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  108. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  109. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  110. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  111. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  112. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  113. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  114. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  115. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  116. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  117. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  118. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  119. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  120. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  121. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  122. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  123. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  124. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  125. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  126. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  127. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  128. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  129. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  130. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  131. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  132. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  133. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  134. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  135. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  136. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  137. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  138. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  139. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  140. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  141. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  142. ccxt/static_dependencies/sympy/__init__.py +0 -0
  143. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  144. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  145. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  146. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  147. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  148. ccxt/static_dependencies/typing_extensions/__init__.py +0 -0
  149. ccxt/static_dependencies/typing_extensions/typing_extensions.py +3839 -0
  150. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  151. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  152. ccxt/test/tests_async.py +43 -1
  153. ccxt/test/tests_sync.py +43 -1
  154. ccxt/woo.py +4 -2
  155. {ccxt-4.3.69.dist-info → ccxt-4.3.71.dist-info}/METADATA +8 -7
  156. {ccxt-4.3.69.dist-info → ccxt-4.3.71.dist-info}/RECORD +159 -33
  157. {ccxt-4.3.69.dist-info → ccxt-4.3.71.dist-info}/LICENSE.txt +0 -0
  158. {ccxt-4.3.69.dist-info → ccxt-4.3.71.dist-info}/WHEEL +0 -0
  159. {ccxt-4.3.69.dist-info → ccxt-4.3.71.dist-info}/top_level.txt +0 -0
@@ -359,6 +359,7 @@ class poloniex(Exchange, ImplicitAPI):
359
359
  '21350': InvalidOrder, # Amount must be greater than 1 USDT
360
360
  '21355': ExchangeError, # Interval between startTime and endTime in trade/order history has exceeded 7 day limit
361
361
  '21356': BadRequest, # Order size would cause too much price movement. Reduce order size.
362
+ '21721': InsufficientFunds,
362
363
  '24101': BadSymbol, # Invalid symbol
363
364
  '24102': InvalidOrder, # Invalid K-line type
364
365
  '24103': InvalidOrder, # Invalid endTime
ccxt/async_support/woo.py CHANGED
@@ -2464,11 +2464,13 @@ class woo(Exchange, ImplicitAPI):
2464
2464
  #
2465
2465
  marketId = self.safe_string(income, 'symbol')
2466
2466
  symbol = self.safe_symbol(marketId, market)
2467
- amount = self.safe_number(income, 'funding_fee')
2467
+ amount = self.safe_string(income, 'funding_fee')
2468
2468
  code = self.safe_currency_code('USD')
2469
2469
  id = self.safe_string(income, 'id')
2470
2470
  timestamp = self.safe_timestamp(income, 'updated_time')
2471
2471
  rate = self.safe_number(income, 'funding_rate')
2472
+ paymentType = self.safe_string(income, 'payment_type')
2473
+ amount = Precise.string_neg(amount) if (paymentType == 'Pay') else amount
2472
2474
  return {
2473
2475
  'info': income,
2474
2476
  'symbol': symbol,
@@ -2476,7 +2478,7 @@ class woo(Exchange, ImplicitAPI):
2476
2478
  'timestamp': timestamp,
2477
2479
  'datetime': self.iso8601(timestamp),
2478
2480
  'id': id,
2479
- 'amount': amount,
2481
+ 'amount': self.parse_number(amount),
2480
2482
  'rate': rate,
2481
2483
  }
2482
2484
 
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.69'
7
+ __version__ = '4.3.71'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -59,6 +59,12 @@ from ccxt.static_dependencies.ethereum import abi
59
59
  from ccxt.static_dependencies.ethereum import account
60
60
  from ccxt.static_dependencies.msgpack import packb
61
61
 
62
+ # starknet
63
+ from ccxt.static_dependencies.starknet.ccxt_utils import get_private_key_from_eth_signature
64
+ from ccxt.static_dependencies.starknet.hash.address import compute_address
65
+ from ccxt.static_dependencies.starknet.hash.selector import get_selector_from_name
66
+ from ccxt.static_dependencies.starknet.hash.utils import message_signature, private_to_stark_key
67
+ from ccxt.static_dependencies.starknet.utils.typed_data import TypedData as TypedDataDataclass
62
68
 
63
69
  # -----------------------------------------------------------------------------
64
70
 
@@ -1286,6 +1292,57 @@ class Exchange(object):
1286
1292
  encodedData = account.messages.encode_typed_data(domain, messageTypes, message)
1287
1293
  return Exchange.binary_concat(b"\x19\x01", encodedData.header, encodedData.body)
1288
1294
 
1295
+ @staticmethod
1296
+ def retrieve_stark_account (signature, accountClassHash, accountProxyClassHash):
1297
+ privateKey = get_private_key_from_eth_signature(signature)
1298
+ publicKey = private_to_stark_key(privateKey)
1299
+ calldata = [
1300
+ int(accountClassHash, 16),
1301
+ get_selector_from_name("initialize"),
1302
+ 2,
1303
+ publicKey,
1304
+ 0,
1305
+ ]
1306
+
1307
+ address = compute_address(
1308
+ class_hash=int(accountProxyClassHash, 16),
1309
+ constructor_calldata=calldata,
1310
+ salt=publicKey,
1311
+ )
1312
+ return {
1313
+ 'privateKey': privateKey,
1314
+ 'publicKey': publicKey,
1315
+ 'address': hex(address)
1316
+ }
1317
+
1318
+ @staticmethod
1319
+ def starknet_encode_structured_data (domain, messageTypes, messageData, address):
1320
+ types = list(messageTypes.keys())
1321
+ if len(types) > 1:
1322
+ raise NotSupported(this.id + 'starknetEncodeStructuredData only support single type')
1323
+
1324
+ request = {
1325
+ 'domain': domain,
1326
+ 'primaryType': types[0],
1327
+ 'types': Exchange.extend({
1328
+ 'StarkNetDomain': [
1329
+ {'name': "name", 'type': "felt"},
1330
+ {'name': "chainId", 'type': "felt"},
1331
+ {'name': "version", 'type': "felt"},
1332
+ ],
1333
+ }, messageTypes),
1334
+ 'message': messageData,
1335
+ }
1336
+ typedDataClass = TypedDataDataclass.from_dict(request)
1337
+ msgHash = typedDataClass.message_hash(int(address, 16))
1338
+ return msgHash
1339
+
1340
+ @staticmethod
1341
+ def starknet_sign (hash, pri):
1342
+ # // TODO: unify to ecdsa
1343
+ r, s = message_signature(hash, pri)
1344
+ return Exchange.json([hex(r), hex(s)])
1345
+
1289
1346
  @staticmethod
1290
1347
  def packb(o):
1291
1348
  return packb(o)
@@ -2117,6 +2174,11 @@ class Exchange(object):
2117
2174
  def handle_delta(self, bookside, delta):
2118
2175
  raise NotSupported(self.id + ' handleDelta not supported yet')
2119
2176
 
2177
+ def handle_deltas_with_keys(self, bookSide: Any, deltas, priceKey: IndexType = 0, amountKey: IndexType = 1, countOrIdKey: IndexType = 2):
2178
+ for i in range(0, len(deltas)):
2179
+ bidAsk = self.parse_bid_ask(deltas[i], priceKey, amountKey, countOrIdKey)
2180
+ bookSide.storeArray(bidAsk)
2181
+
2120
2182
  def get_cache_index(self, orderbook, deltas):
2121
2183
  # return the first index of the cache that can be applied to the orderbook or -1 if not possible
2122
2184
  return -1
ccxt/blofin.py CHANGED
@@ -29,6 +29,7 @@ class blofin(Exchange, ImplicitAPI):
29
29
  'countries': ['US'],
30
30
  'version': 'v1',
31
31
  'rateLimit': 100,
32
+ 'pro': True,
32
33
  'has': {
33
34
  'CORS': None,
34
35
  'spot': False,
@@ -103,7 +104,7 @@ class blofin(Exchange, ImplicitAPI):
103
104
  'fetchOpenInterestHistory': False,
104
105
  'fetchOpenOrder': None,
105
106
  'fetchOpenOrders': True,
106
- 'fetchOrder': True,
107
+ 'fetchOrder': None,
107
108
  'fetchOrderBook': True,
108
109
  'fetchOrderBooks': False,
109
110
  'fetchOrders': False,
@@ -153,11 +154,12 @@ class blofin(Exchange, ImplicitAPI):
153
154
  '2h': '2H',
154
155
  '4h': '4H',
155
156
  '6h': '6H',
157
+ '8h': '8H',
156
158
  '12h': '12H',
157
159
  '1d': '1D',
160
+ '3d': '3D',
158
161
  '1w': '1W',
159
162
  '1M': '1M',
160
- '3M': '3M',
161
163
  },
162
164
  'hostname': 'www.blofin.com',
163
165
  'urls': {
@@ -492,6 +494,25 @@ class blofin(Exchange, ImplicitAPI):
492
494
  return self.parse_order_book(first, symbol, timestamp)
493
495
 
494
496
  def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
497
+ #
498
+ # response similar for REST & WS
499
+ #
500
+ # {
501
+ # instId: "ADA-USDT",
502
+ # ts: "1707736811486",
503
+ # last: "0.5315",
504
+ # lastSize: "4",
505
+ # askPrice: "0.5318",
506
+ # askSize: "248",
507
+ # bidPrice: "0.5315",
508
+ # bidSize: "63",
509
+ # open24h: "0.5555",
510
+ # high24h: "0.5563",
511
+ # low24h: "0.5315",
512
+ # volCurrency24h: "198560100",
513
+ # vol24h: "1985601",
514
+ # }
515
+ #
495
516
  timestamp = self.safe_integer(ticker, 'ts')
496
517
  marketId = self.safe_string(ticker, 'instId')
497
518
  market = self.safe_market(marketId, market, '-')
@@ -560,7 +581,8 @@ class blofin(Exchange, ImplicitAPI):
560
581
 
561
582
  def parse_trade(self, trade: dict, market: Market = None) -> Trade:
562
583
  #
563
- # fetch trades
584
+ # fetch trades(response similar for REST & WS)
585
+ #
564
586
  # {
565
587
  # "tradeId": "3263934920",
566
588
  # "instId": "LTC-USDT",
@@ -569,6 +591,7 @@ class blofin(Exchange, ImplicitAPI):
569
591
  # "side": "buy",
570
592
  # "ts": "1707232020854"
571
593
  # }
594
+ #
572
595
  # my trades
573
596
  # {
574
597
  # "instId": "LTC-USDT",
@@ -825,9 +848,11 @@ class blofin(Exchange, ImplicitAPI):
825
848
  if type:
826
849
  return self.parse_funding_balance(response)
827
850
  else:
828
- return self.parse_trading_balance(response)
851
+ return self.parse_balance(response)
829
852
 
830
- def parse_trading_balance(self, response):
853
+ def parse_balance(self, response):
854
+ #
855
+ # "data" similar for REST & WS
831
856
  #
832
857
  # {
833
858
  # "code": "0",
@@ -849,7 +874,8 @@ class blofin(Exchange, ImplicitAPI):
849
874
  # "orderFrozen": "14920.994472632597427761",
850
875
  # "equityUsd": "10011254.077985990315787910",
851
876
  # "isolatedUnrealizedPnl": "-22.151999999999999999952",
852
- # "bonus": "0"
877
+ # "bonus": "0" # present only in REST
878
+ # "unrealizedPnl": "0" # present only in WS
853
879
  # }
854
880
  # ]
855
881
  # }
@@ -998,6 +1024,8 @@ class blofin(Exchange, ImplicitAPI):
998
1024
  return self.safe_string(statuses, status, status)
999
1025
 
1000
1026
  def parse_order(self, order: dict, market: Market = None) -> Order:
1027
+ #
1028
+ # response similar for REST & WS
1001
1029
  #
1002
1030
  # {
1003
1031
  # "orderId": "2075628533",
@@ -1026,6 +1054,9 @@ class blofin(Exchange, ImplicitAPI):
1026
1054
  # "cancelSource": "not_canceled",
1027
1055
  # "cancelSourceReason": null,
1028
1056
  # "brokerId": "ec6dd3a7dd982d0b"
1057
+ # "filled_amount": "1.000000000000000000", # filledAmount in "ws" watchOrders
1058
+ # "cancelSource": "", # only in WS
1059
+ # "instType": "SWAP", # only in WS
1029
1060
  # }
1030
1061
  #
1031
1062
  id = self.safe_string_2(order, 'tpslId', 'orderId')
@@ -1695,6 +1726,32 @@ class blofin(Exchange, ImplicitAPI):
1695
1726
  return self.filter_by_array_positions(result, 'symbol', symbols, False)
1696
1727
 
1697
1728
  def parse_position(self, position: dict, market: Market = None):
1729
+ #
1730
+ # response similar for REST & WS
1731
+ #
1732
+ # {
1733
+ # instType: 'SWAP',
1734
+ # instId: 'LTC-USDT',
1735
+ # marginMode: 'cross',
1736
+ # positionId: '644159',
1737
+ # positionSide: 'net',
1738
+ # positions: '1',
1739
+ # availablePositions: '1',
1740
+ # averagePrice: '68.16',
1741
+ # unrealizedPnl: '0.80631223',
1742
+ # unrealizedPnlRatio: '0.03548909463028169',
1743
+ # leverage: '3',
1744
+ # liquidationPrice: '10.116655172370356435',
1745
+ # markPrice: '68.96',
1746
+ # initialMargin: '22.988770743333333333',
1747
+ # margin: '', # self field might not exist in rest response
1748
+ # marginRatio: '152.523509620342499273',
1749
+ # maintenanceMargin: '0.34483156115',
1750
+ # adl: '4',
1751
+ # createTime: '1707235776528',
1752
+ # updateTime: '1707235776528'
1753
+ # }
1754
+ #
1698
1755
  marketId = self.safe_string(position, 'instId')
1699
1756
  market = self.safe_market(marketId, market)
1700
1757
  symbol = market['symbol']
ccxt/bybit.py CHANGED
@@ -7624,7 +7624,7 @@ class bybit(Exchange, ImplicitAPI):
7624
7624
  quoteValueString = Precise.string_mul(baseValueString, priceString)
7625
7625
  return self.safe_liquidation({
7626
7626
  'info': liquidation,
7627
- 'symbol': self.safe_symbol(marketId, market),
7627
+ 'symbol': self.safe_symbol(marketId, market, None, 'contract'),
7628
7628
  'contracts': self.parse_number(contractsString),
7629
7629
  'contractSize': self.parse_number(contractSizeString),
7630
7630
  'price': self.parse_number(priceString),
@@ -92,7 +92,7 @@ class coinbaseinternational(Exchange, ImplicitAPI):
92
92
  'fetchMyBuys': True,
93
93
  'fetchMySells': True,
94
94
  'fetchMyTrades': True,
95
- 'fetchOHLCV': False,
95
+ 'fetchOHLCV': True,
96
96
  'fetchOpenInterestHistory': False,
97
97
  'fetchOpenOrders': True,
98
98
  'fetchOrder': True,
@@ -111,6 +111,7 @@ class coinbaseinternational(Exchange, ImplicitAPI):
111
111
  'fetchTrades': False,
112
112
  'fetchTradingFee': False,
113
113
  'fetchTradingFees': False,
114
+ 'fetchTransfers': True,
114
115
  'fetchWithdrawals': True,
115
116
  'reduceMargin': False,
116
117
  'sandbox': True,
@@ -153,7 +154,7 @@ class coinbaseinternational(Exchange, ImplicitAPI):
153
154
  'instruments/{instrument}',
154
155
  'instruments/{instrument}/quote',
155
156
  'instruments/{instrument}/funding',
156
- '',
157
+ 'instruments/{instrument}/candles',
157
158
  ],
158
159
  },
159
160
  'private': {
@@ -351,6 +352,75 @@ class coinbaseinternational(Exchange, ImplicitAPI):
351
352
  'info': account,
352
353
  }
353
354
 
355
+ def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = 100, params={}) -> List[list]:
356
+ """
357
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
358
+ :see: https://docs.cdp.coinbase.com/intx/reference/getinstrumentcandles
359
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
360
+ :param str timeframe: the length of time each candle represents
361
+ :param int [since]: timestamp in ms of the earliest candle to fetch
362
+ :param int [limit]: the maximum amount of candles to fetch, default 100 max 10000
363
+ :param dict [params]: extra parameters specific to the exchange API endpoint
364
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
365
+ :param int [params.until]: timestamp in ms of the latest candle to fetch
366
+ :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)
367
+ """
368
+ self.load_markets()
369
+ paginate = False
370
+ paginate, params = self.handle_option_and_params(params, 'fetchOHLCV', 'paginate')
371
+ if paginate:
372
+ return self.fetch_paginated_call_deterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 10000)
373
+ market = self.market(symbol)
374
+ request: dict = {
375
+ 'instrument': market['id'],
376
+ 'granularity': self.safe_string(self.timeframes, timeframe, timeframe),
377
+ }
378
+ if since is not None:
379
+ request['start'] = self.iso8601(since)
380
+ else:
381
+ raise ArgumentsRequired(self.id + ' fetchOHLCV() requires a since argument')
382
+ unitl = self.safe_integer(params, 'until')
383
+ if unitl is not None:
384
+ params = self.omit(params, 'until')
385
+ request['end'] = self.iso8601(unitl)
386
+ response = self.v1PublicGetInstrumentsInstrumentCandles(self.extend(request, params))
387
+ #
388
+ # {
389
+ # "aggregations": [
390
+ # {
391
+ # "start": "2024-04-23T00:00:00Z",
392
+ # "open": "62884.4",
393
+ # "high": "64710.6",
394
+ # "low": "62884.4",
395
+ # "close": "63508.4",
396
+ # "volume": "3253.9983"
397
+ # }
398
+ # ]
399
+ # }
400
+ #
401
+ candles = self.safe_list(response, 'aggregations', [])
402
+ return self.parse_ohlcvs(candles, market, timeframe, since, limit)
403
+
404
+ def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
405
+ #
406
+ # {
407
+ # "start": "2024-04-23T00:00:00Z",
408
+ # "open": "62884.4",
409
+ # "high": "64710.6",
410
+ # "low": "62884.4",
411
+ # "close": "63508.4",
412
+ # "volume": "3253.9983"
413
+ # }
414
+ #
415
+ return [
416
+ self.parse8601(self.safe_string_2(ohlcv, 'start', 'time')),
417
+ self.safe_number(ohlcv, 'open'),
418
+ self.safe_number(ohlcv, 'high'),
419
+ self.safe_number(ohlcv, 'low'),
420
+ self.safe_number(ohlcv, 'close'),
421
+ self.safe_number(ohlcv, 'volume'),
422
+ ]
423
+
354
424
  def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
355
425
  """
356
426
  fetches historical funding rate prices
@@ -504,6 +574,89 @@ class coinbaseinternational(Exchange, ImplicitAPI):
504
574
  'rate': None,
505
575
  }
506
576
 
577
+ def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[TransferEntry]:
578
+ """
579
+ fetch a history of internal transfers made on an account
580
+ :see: https://docs.cdp.coinbase.com/intx/reference/gettransfers
581
+ :param str code: unified currency code of the currency transferred
582
+ :param int [since]: the earliest time in ms to fetch transfers for
583
+ :param int [limit]: the maximum number of transfers structures to retrieve
584
+ :param dict [params]: extra parameters specific to the exchange API endpoint
585
+ :returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
586
+ """
587
+ self.load_markets()
588
+ request: dict = {
589
+ 'type': 'INTERNAL',
590
+ }
591
+ currency = None
592
+ if code is not None:
593
+ currency = self.currency(code)
594
+ portfolios = None
595
+ portfolios, params = self.handle_option_and_params(params, 'fetchTransfers', 'portfolios')
596
+ if portfolios is not None:
597
+ request['portfolios'] = portfolios
598
+ if since is not None:
599
+ request['time_from'] = self.iso8601(since)
600
+ if limit is not None:
601
+ request['result_limit'] = limit
602
+ else:
603
+ request['result_limit'] = 100
604
+ response = self.v1PrivateGetTransfers(self.extend(request, params))
605
+ transfers = self.safe_list(response, 'results', [])
606
+ return self.parse_transfers(transfers, currency, since, limit)
607
+
608
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
609
+ #
610
+ # {
611
+ # "amount":"0.0008",
612
+ # "asset":"USDC",
613
+ # "created_at":"2024-02-22T16:00:00Z",
614
+ # "from_portfolio":{
615
+ # "id":"13yuk1fs-1-0",
616
+ # "name":"Eng Test Portfolio - 2",
617
+ # "uuid":"018712f2-5ff9-7de3-9010-xxxxxxxxx"
618
+ # },
619
+ # "instrument_id":"149264164756389888",
620
+ # "instrument_symbol":"ETH-PERP",
621
+ # "position_id":"1xy4v51m-1-2",
622
+ # "status":"PROCESSED",
623
+ # "to_portfolio":{
624
+ # "name":"CB_FUND"
625
+ # },
626
+ # "transfer_type":"FUNDING",
627
+ # "transfer_uuid":"a6b708df-2c44-32c5-bb98-xxxxxxxxxx",
628
+ # "updated_at":"2024-02-22T16:00:00Z"
629
+ # }
630
+ #
631
+ datetime = self.safe_integer(transfer, 'created_at')
632
+ timestamp = self.parse8601(datetime)
633
+ currencyId = self.safe_string(transfer, 'asset')
634
+ code = self.safe_currency_code(currencyId)
635
+ fromPorfolio = self.safe_dict(transfer, 'from_portfolio', {})
636
+ fromId = self.safe_string(fromPorfolio, 'id')
637
+ toPorfolio = self.safe_dict(transfer, 'to_portfolio', {})
638
+ toId = self.safe_string(toPorfolio, 'id')
639
+ return {
640
+ 'info': transfer,
641
+ 'id': self.safe_string(transfer, 'transfer_uuid'),
642
+ 'timestamp': timestamp,
643
+ 'datetime': self.iso8601(timestamp),
644
+ 'currency': code,
645
+ 'amount': self.safe_number(transfer, 'amount'),
646
+ 'fromAccount': fromId,
647
+ 'toAccount': toId,
648
+ 'status': self.parse_transfer_status(self.safe_string(transfer, 'status')),
649
+ }
650
+
651
+ def parse_transfer_status(self, status: Str) -> Str:
652
+ statuses: dict = {
653
+ 'FAILED': 'failed',
654
+ 'PROCESSED': 'ok',
655
+ 'NEW': 'pending',
656
+ 'STARTED': 'pending',
657
+ }
658
+ return self.safe_string(statuses, status, status)
659
+
507
660
  def create_deposit_address(self, code: str, params={}):
508
661
  """
509
662
  create a currency deposit address
ccxt/cryptocom.py CHANGED
@@ -17,10 +17,13 @@ from ccxt.base.errors import BadRequest
17
17
  from ccxt.base.errors import BadSymbol
18
18
  from ccxt.base.errors import InsufficientFunds
19
19
  from ccxt.base.errors import InvalidOrder
20
+ from ccxt.base.errors import OrderNotFound
20
21
  from ccxt.base.errors import NotSupported
21
22
  from ccxt.base.errors import DDoSProtection
23
+ from ccxt.base.errors import RateLimitExceeded
22
24
  from ccxt.base.errors import OnMaintenance
23
25
  from ccxt.base.errors import InvalidNonce
26
+ from ccxt.base.errors import RequestTimeout
24
27
  from ccxt.base.decimal_to_precision import TICK_SIZE
25
28
  from ccxt.base.precise import Precise
26
29
 
@@ -401,7 +404,15 @@ class cryptocom(Exchange, ImplicitAPI):
401
404
  '40006': BadRequest,
402
405
  '40007': BadRequest,
403
406
  '40101': AuthenticationError,
404
- '50001': BadRequest,
407
+ '40102': InvalidNonce, # Nonce value differs by more than 60 seconds from server
408
+ '40103': AuthenticationError, # IP address not whitelisted
409
+ '40104': AuthenticationError, # Disallowed based on user tier
410
+ '40107': BadRequest, # Session subscription limit has been exceeded
411
+ '40401': OrderNotFound,
412
+ '40801': RequestTimeout,
413
+ '42901': RateLimitExceeded,
414
+ '43005': InvalidOrder, # Rejected POST_ONLY create-order request(normally happened when exec_inst contains POST_ONLY but time_in_force is NOT GOOD_TILL_CANCEL)
415
+ '50001': ExchangeError,
405
416
  '9010001': OnMaintenance, # {"code":9010001,"message":"SYSTEM_MAINTENANCE","details":"Crypto.com Exchange is currently under maintenance. Please refer to https://status.crypto.com for more details."}
406
417
  },
407
418
  'broad': {},