ccxt 4.4.49__py2.py3-none-any.whl → 4.4.50__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.
@@ -113,6 +113,48 @@ class paymium(Exchange, ImplicitAPI):
113
113
  },
114
114
  },
115
115
  'precisionMode': TICK_SIZE,
116
+ 'features': {
117
+ 'spot': {
118
+ 'sandbox': False,
119
+ 'createOrder': {
120
+ 'marginMode': False,
121
+ 'triggerPrice': False,
122
+ 'triggerDirection': False,
123
+ 'triggerPriceType': None,
124
+ 'stopLossPrice': False,
125
+ 'takeProfitPrice': False,
126
+ 'attachedStopLossTakeProfit': None,
127
+ 'timeInForce': {
128
+ 'IOC': False,
129
+ 'FOK': False,
130
+ 'PO': False,
131
+ 'GTD': False,
132
+ },
133
+ 'hedged': False,
134
+ 'trailing': False,
135
+ 'leverage': False,
136
+ 'marketBuyByCost': True, # todo
137
+ 'marketBuyRequiresPrice': False,
138
+ 'selfTradePrevention': False,
139
+ 'iceberg': False,
140
+ },
141
+ 'createOrders': None,
142
+ 'fetchMyTrades': None,
143
+ 'fetchOrder': None, # todo
144
+ 'fetchOpenOrders': None, # todo
145
+ 'fetchOrders': None, # todo
146
+ 'fetchClosedOrders': None, # todo
147
+ 'fetchOHLCV': None, # todo
148
+ },
149
+ 'swap': {
150
+ 'linear': None,
151
+ 'inverse': None,
152
+ },
153
+ 'future': {
154
+ 'linear': None,
155
+ 'inverse': None,
156
+ },
157
+ },
116
158
  })
117
159
 
118
160
  def parse_balance(self, response) -> Balances:
@@ -103,7 +103,7 @@ class probit(Exchange, ImplicitAPI):
103
103
  'fetchWithdrawal': False,
104
104
  'fetchWithdrawals': True,
105
105
  'reduceMargin': False,
106
- 'sandbox': True,
106
+ 'sandbox': False,
107
107
  'setLeverage': False,
108
108
  'setMarginMode': False,
109
109
  'setPositionMode': False,
@@ -185,6 +185,73 @@ class probit(Exchange, ImplicitAPI):
185
185
  'taker': self.parse_number('0.002'),
186
186
  },
187
187
  },
188
+ 'features': {
189
+ 'spot': {
190
+ 'sandbox': False,
191
+ 'createOrder': {
192
+ 'marginMode': False,
193
+ 'triggerPrice': False,
194
+ 'triggerDirection': False,
195
+ 'triggerPriceType': None,
196
+ 'stopLossPrice': False,
197
+ 'takeProfitPrice': False,
198
+ 'attachedStopLossTakeProfit': None,
199
+ # todo
200
+ 'timeInForce': {
201
+ 'IOC': True,
202
+ 'FOK': True,
203
+ 'PO': False,
204
+ 'GTD': False,
205
+ },
206
+ 'hedged': False,
207
+ 'trailing': False,
208
+ 'leverage': False,
209
+ 'marketBuyByCost': True,
210
+ 'marketBuyRequiresPrice': False,
211
+ 'selfTradePrevention': False,
212
+ 'iceberg': False,
213
+ },
214
+ 'createOrders': None,
215
+ 'fetchMyTrades': {
216
+ 'marginMode': False,
217
+ 'limit': 1000,
218
+ 'daysBack': 100000, # todo
219
+ 'untilDays': 100000, # todo
220
+ },
221
+ 'fetchOrder': {
222
+ 'marginMode': False,
223
+ 'trigger': False,
224
+ 'trailing': False,
225
+ },
226
+ 'fetchOpenOrders': {
227
+ 'marginMode': False,
228
+ 'limit': None,
229
+ 'trigger': False,
230
+ 'trailing': False,
231
+ },
232
+ 'fetchOrders': None,
233
+ 'fetchClosedOrders': {
234
+ 'marginMode': False,
235
+ 'limit': 1000,
236
+ 'daysBack': 100000, # todo
237
+ 'daysBackCanceled': 1, # todo
238
+ 'untilDays': 90,
239
+ 'trigger': False,
240
+ 'trailing': False,
241
+ },
242
+ 'fetchOHLCV': {
243
+ 'limit': 4000,
244
+ },
245
+ },
246
+ 'swap': {
247
+ 'linear': None,
248
+ 'inverse': None,
249
+ },
250
+ 'future': {
251
+ 'linear': None,
252
+ 'inverse': None,
253
+ },
254
+ },
188
255
  'exceptions': {
189
256
  'exact': {
190
257
  'UNAUTHORIZED': AuthenticationError,
@@ -281,6 +281,73 @@ class timex(Exchange, ImplicitAPI):
281
281
  'defaultSort': 'timestamp,asc',
282
282
  'defaultSortOrders': 'createdAt,asc',
283
283
  },
284
+ 'features': {
285
+ 'spot': {
286
+ 'sandbox': False,
287
+ 'createOrder': {
288
+ 'marginMode': False,
289
+ 'triggerPrice': False,
290
+ 'triggerDirection': False,
291
+ 'triggerPriceType': None,
292
+ 'stopLossPrice': False,
293
+ 'takeProfitPrice': False,
294
+ 'attachedStopLossTakeProfit': None,
295
+ # todo
296
+ 'timeInForce': {
297
+ 'IOC': True,
298
+ 'FOK': True,
299
+ 'PO': False,
300
+ 'GTD': True,
301
+ },
302
+ 'hedged': False,
303
+ 'trailing': False,
304
+ 'leverage': False,
305
+ 'marketBuyByCost': False,
306
+ 'marketBuyRequiresPrice': False,
307
+ 'selfTradePrevention': False,
308
+ 'iceberg': False,
309
+ },
310
+ 'createOrders': None,
311
+ 'fetchMyTrades': {
312
+ 'marginMode': False,
313
+ 'limit': 100, # todo
314
+ 'daysBack': 100000, # todo
315
+ 'untilDays': 100000, # todo
316
+ },
317
+ 'fetchOrder': {
318
+ 'marginMode': False,
319
+ 'trigger': False,
320
+ 'trailing': False,
321
+ },
322
+ 'fetchOpenOrders': {
323
+ 'marginMode': False,
324
+ 'limit': 100, # todo
325
+ 'trigger': False,
326
+ 'trailing': False,
327
+ },
328
+ 'fetchOrders': None, # todo
329
+ 'fetchClosedOrders': {
330
+ 'marginMode': False,
331
+ 'limit': 100, # todo
332
+ 'daysBack': 100000, # todo
333
+ 'daysBackCanceled': 1, # todo
334
+ 'untilDays': 100000, # todo
335
+ 'trigger': False,
336
+ 'trailing': False,
337
+ },
338
+ 'fetchOHLCV': {
339
+ 'limit': None,
340
+ },
341
+ },
342
+ 'swap': {
343
+ 'linear': None,
344
+ 'inverse': None,
345
+ },
346
+ 'future': {
347
+ 'linear': None,
348
+ 'inverse': None,
349
+ },
350
+ },
284
351
  })
285
352
 
286
353
  async def fetch_time(self, params={}):
@@ -619,6 +619,79 @@ class tokocrypto(Exchange, ImplicitAPI):
619
619
  'MAX_POSITION': InvalidOrder, # {"code":-2010,"msg":"Filter failure: MAX_POSITION"}
620
620
  },
621
621
  },
622
+ 'features': {
623
+ 'spot': {
624
+ 'sandbox': False,
625
+ 'createOrder': {
626
+ 'marginMode': False,
627
+ 'triggerPrice': True,
628
+ 'triggerDirection': False,
629
+ 'triggerPriceType': None,
630
+ 'stopLossPrice': False, # todo
631
+ 'takeProfitPrice': False, # todo
632
+ 'attachedStopLossTakeProfit': None,
633
+ 'timeInForce': {
634
+ 'IOC': True,
635
+ 'FOK': True,
636
+ 'PO': True,
637
+ 'GTD': False,
638
+ },
639
+ 'hedged': False,
640
+ 'trailing': False,
641
+ 'leverage': False,
642
+ 'marketBuyByCost': True,
643
+ 'marketBuyRequiresPrice': True,
644
+ 'selfTradePrevention': True, # todo
645
+ 'iceberg': True, # todo
646
+ },
647
+ 'createOrders': None,
648
+ 'fetchMyTrades': {
649
+ 'marginMode': False,
650
+ 'limit': 1000,
651
+ 'daysBack': 100000, # todo
652
+ 'untilDays': 100000, # todo
653
+ },
654
+ 'fetchOrder': {
655
+ 'marginMode': False,
656
+ 'trigger': False,
657
+ 'trailing': False,
658
+ },
659
+ 'fetchOpenOrders': {
660
+ 'marginMode': False,
661
+ 'limit': 1000,
662
+ 'trigger': False,
663
+ 'trailing': False,
664
+ },
665
+ 'fetchOrders': {
666
+ 'marginMode': False,
667
+ 'limit': 1000,
668
+ 'daysBack': 100000,
669
+ 'untilDays': 100000,
670
+ 'trigger': False,
671
+ 'trailing': False,
672
+ },
673
+ 'fetchClosedOrders': {
674
+ 'marginMode': False,
675
+ 'limit': 1000,
676
+ 'daysBack': 100000, # todo
677
+ 'daysBackCanceled': 1, # todo
678
+ 'untilDays': 100000, # todo
679
+ 'trigger': False,
680
+ 'trailing': False,
681
+ },
682
+ 'fetchOHLCV': {
683
+ 'limit': 1000,
684
+ },
685
+ },
686
+ 'swap': {
687
+ 'linear': None,
688
+ 'inverse': None,
689
+ },
690
+ 'future': {
691
+ 'linear': None,
692
+ 'inverse': None,
693
+ },
694
+ },
622
695
  })
623
696
 
624
697
  def nonce(self):
@@ -635,9 +708,14 @@ class tokocrypto(Exchange, ImplicitAPI):
635
708
  """
636
709
  response = await self.publicGetOpenV1CommonTime(params)
637
710
  #
711
+ # {
712
+ # "code": 0,
713
+ # "msg": "Success",
714
+ # "data": null,
715
+ # "timestamp": 1737378074159
716
+ # }
638
717
  #
639
- #
640
- return self.safe_integer(response, 'serverTime')
718
+ return self.safe_integer(response, 'timestamp')
641
719
 
642
720
  async def fetch_markets(self, params={}) -> List[Market]:
643
721
  """
@@ -1575,7 +1653,6 @@ class tokocrypto(Exchange, ImplicitAPI):
1575
1653
  create a trade order
1576
1654
 
1577
1655
  https://www.tokocrypto.com/apidocs/#new-order--signed
1578
- https://www.tokocrypto.com/apidocs/#account-trade-list-signed
1579
1656
 
1580
1657
  :param str symbol: unified symbol of the market to create an order in
1581
1658
  :param str type: 'market' or 'limit'
@@ -1733,7 +1810,7 @@ class tokocrypto(Exchange, ImplicitAPI):
1733
1810
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
1734
1811
  """
1735
1812
 
1736
- https://www.tokocrypto.com/apidocs/#all-orders-signed
1813
+ https://www.tokocrypto.com/apidocs/#query-order-signed
1737
1814
 
1738
1815
  fetches information on an order made by the user
1739
1816
  :param str id: order id
@@ -164,6 +164,57 @@ class tradeogre(Exchange, ImplicitAPI):
164
164
  },
165
165
  'options': {
166
166
  },
167
+ 'features': {
168
+ 'spot': {
169
+ 'sandbox': False,
170
+ 'createOrder': {
171
+ 'marginMode': False,
172
+ 'triggerPrice': False,
173
+ 'triggerDirection': False,
174
+ 'triggerPriceType': None,
175
+ 'stopLossPrice': False,
176
+ 'takeProfitPrice': False,
177
+ 'attachedStopLossTakeProfit': None,
178
+ 'timeInForce': {
179
+ 'IOC': False,
180
+ 'FOK': False,
181
+ 'PO': False,
182
+ 'GTD': False,
183
+ },
184
+ 'hedged': False,
185
+ 'trailing': False,
186
+ 'leverage': False,
187
+ 'marketBuyByCost': False,
188
+ 'marketBuyRequiresPrice': False,
189
+ 'selfTradePrevention': False,
190
+ 'iceberg': False,
191
+ },
192
+ 'createOrders': None,
193
+ 'fetchMyTrades': None,
194
+ 'fetchOrder': {
195
+ 'marginMode': False,
196
+ 'trigger': False,
197
+ 'trailing': False,
198
+ },
199
+ 'fetchOpenOrders': {
200
+ 'marginMode': False,
201
+ 'limit': None,
202
+ 'trigger': False,
203
+ 'trailing': False,
204
+ },
205
+ 'fetchOrders': None,
206
+ 'fetchClosedOrders': None,
207
+ 'fetchOHLCV': None, # todo
208
+ },
209
+ 'swap': {
210
+ 'linear': None,
211
+ 'inverse': None,
212
+ },
213
+ 'future': {
214
+ 'linear': None,
215
+ 'inverse': None,
216
+ },
217
+ },
167
218
  })
168
219
 
169
220
  async def fetch_markets(self, params={}) -> List[Market]:
@@ -442,6 +493,9 @@ class tradeogre(Exchange, ImplicitAPI):
442
493
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
443
494
  """
444
495
  create a trade order
496
+
497
+ https://tradeogre.com/help/api#:~:text=u%20%27%7Bpublic%7D%3A%7Bprivate%7D%27-,Submit%20Buy%20Order
498
+
445
499
  :param str symbol: unified symbol of the market to create an order in
446
500
  :param str type: must be 'limit'
447
501
  :param str side: 'buy' or 'sell'
@@ -499,6 +553,9 @@ class tradeogre(Exchange, ImplicitAPI):
499
553
  async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
500
554
  """
501
555
  fetch all unfilled currently open orders
556
+
557
+ https://tradeogre.com/help/api#:~:text=%7B%22success%22%3Atrue%7D-,Get%20Orders,-Method%20(POST)
558
+
502
559
  :param str symbol: unified market symbol of the market orders were made in
503
560
  :param int [since]: the earliest time in ms to fetch orders for
504
561
  :param int [limit]: the maximum number of order structures to retrieve
@@ -519,7 +576,7 @@ class tradeogre(Exchange, ImplicitAPI):
519
576
  """
520
577
  fetches information on an order made by the user
521
578
 
522
- https://github.com/ace-exchange/ace-official-api-docs/blob/master/api_v2.md#open-api---order-status
579
+ https://tradeogre.com/help/api#:~:text=market%22%3A%22XMR%2DBTC%22%7D%5D-,Get%20Order,-Method%20(GET)
523
580
 
524
581
  :param str id: order id
525
582
  :param str symbol: unified symbol of the market the order was made in
@@ -272,6 +272,8 @@ class whitebit(Exchange, ImplicitAPI):
272
272
  },
273
273
  },
274
274
  'options': {
275
+ 'timeDifference': 0, # the difference between system clock and exchange clock
276
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
275
277
  'fiatCurrencies': ['EUR', 'USD', 'RUB', 'UAH'],
276
278
  'fetchBalance': {
277
279
  'account': 'spot',
@@ -328,6 +330,8 @@ class whitebit(Exchange, ImplicitAPI):
328
330
  :param dict [params]: extra parameters specific to the exchange API endpoint
329
331
  :returns dict[]: an array of objects representing market data
330
332
  """
333
+ if self.options['adjustForTimeDifference']:
334
+ await self.load_time_difference()
331
335
  markets = await self.v4PublicGetMarkets()
332
336
  #
333
337
  # [
@@ -1227,7 +1231,7 @@ class whitebit(Exchange, ImplicitAPI):
1227
1231
  response = await self.v4PublicGetTime(params)
1228
1232
  #
1229
1233
  # {
1230
- # "time":1635467280514
1234
+ # "time":1737380046
1231
1235
  # }
1232
1236
  #
1233
1237
  return self.safe_integer(response, 'time')
@@ -2514,7 +2518,7 @@ class whitebit(Exchange, ImplicitAPI):
2514
2518
  return self.in_array(currency, fiatCurrencies)
2515
2519
 
2516
2520
  def nonce(self):
2517
- return self.milliseconds()
2521
+ return self.milliseconds() - self.options['timeDifference']
2518
2522
 
2519
2523
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2520
2524
  query = self.omit(params, self.extract_params(path))
@@ -2527,10 +2531,12 @@ class whitebit(Exchange, ImplicitAPI):
2527
2531
  url += '?' + self.urlencode(query)
2528
2532
  if accessibility == 'private':
2529
2533
  self.check_required_credentials()
2530
- nonce = str(self.nonce())
2534
+ nonce = self.nonce()
2535
+ timestamp = self.parse_to_int(nonce / 1000)
2536
+ timestampString = str(timestamp)
2531
2537
  secret = self.encode(self.secret)
2532
2538
  request = '/' + 'api' + '/' + version + pathWithParams
2533
- body = self.json(self.extend({'request': request, 'nonce': nonce}, params))
2539
+ body = self.json(self.extend({'request': request, 'nonce': timestampString}, params))
2534
2540
  payload = self.string_to_base64(body)
2535
2541
  signature = self.hmac(self.encode(payload), secret, hashlib.sha512)
2536
2542
  headers = {
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.4.49'
7
+ __version__ = '4.4.50'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
@@ -2876,6 +2876,67 @@ class Exchange(object):
2876
2876
  }
2877
2877
 
2878
2878
  def safe_currency_structure(self, currency: object):
2879
+ # derive data from networks: deposit, withdraw, active, fee, limits, precision
2880
+ networks = self.safe_dict(currency, 'networks', {})
2881
+ keys = list(networks.keys())
2882
+ length = len(keys)
2883
+ if length != 0:
2884
+ for i in range(0, length):
2885
+ network = networks[keys[i]]
2886
+ deposit = self.safe_bool(network, 'deposit')
2887
+ if currency['deposit'] is None or deposit:
2888
+ currency['deposit'] = deposit
2889
+ withdraw = self.safe_bool(network, 'withdraw')
2890
+ if currency['withdraw'] is None or withdraw:
2891
+ currency['withdraw'] = withdraw
2892
+ active = self.safe_bool(network, 'active')
2893
+ if currency['active'] is None or active:
2894
+ currency['active'] = active
2895
+ # find lowest fee(which is more desired)
2896
+ fee = self.safe_string(network, 'fee')
2897
+ feeMain = self.safe_string(currency, 'fee')
2898
+ if feeMain is None or Precise.string_lt(fee, feeMain):
2899
+ currency['fee'] = self.parse_number(fee)
2900
+ # find lowest precision(which is more desired)
2901
+ precision = self.safe_string(network, 'precision')
2902
+ precisionMain = self.safe_string(currency, 'precision')
2903
+ if precisionMain is None or Precise.string_lt(precision, precisionMain):
2904
+ currency['precision'] = self.parse_number(precision)
2905
+ # limits
2906
+ limits = self.safe_dict(network, 'limits')
2907
+ limitsMain = self.safe_dict(currency, 'limits')
2908
+ if limitsMain is None:
2909
+ currency['limits'] = {}
2910
+ # deposits
2911
+ limitsDeposit = self.safe_dict(limits, 'deposit')
2912
+ limitsDepositMain = self.safe_dict(limitsMain, 'deposit')
2913
+ if limitsDepositMain is None:
2914
+ currency['limits']['deposit'] = {}
2915
+ limitsDepositMin = self.safe_string(limitsDeposit, 'min')
2916
+ limitsDepositMax = self.safe_string(limitsDeposit, 'max')
2917
+ limitsDepositMinMain = self.safe_string(limitsDepositMain, 'min')
2918
+ limitsDepositMaxMain = self.safe_string(limitsDepositMain, 'max')
2919
+ # find min
2920
+ if limitsDepositMinMain is None or Precise.string_lt(limitsDepositMin, limitsDepositMinMain):
2921
+ currency['limits']['deposit']['min'] = self.parse_number(limitsDepositMin)
2922
+ # find max
2923
+ if limitsDepositMaxMain is None or Precise.string_gt(limitsDepositMax, limitsDepositMaxMain):
2924
+ currency['limits']['deposit']['max'] = self.parse_number(limitsDepositMax)
2925
+ # withdrawals
2926
+ limitsWithdraw = self.safe_dict(limits, 'withdraw')
2927
+ limitsWithdrawMain = self.safe_dict(limitsMain, 'withdraw')
2928
+ if limitsWithdrawMain is None:
2929
+ currency['limits']['withdraw'] = {}
2930
+ limitsWithdrawMin = self.safe_string(limitsWithdraw, 'min')
2931
+ limitsWithdrawMax = self.safe_string(limitsWithdraw, 'max')
2932
+ limitsWithdrawMinMain = self.safe_string(limitsWithdrawMain, 'min')
2933
+ limitsWithdrawMaxMain = self.safe_string(limitsWithdrawMain, 'max')
2934
+ # find min
2935
+ if limitsWithdrawMinMain is None or Precise.string_lt(limitsWithdrawMin, limitsWithdrawMinMain):
2936
+ currency['limits']['withdraw']['min'] = self.parse_number(limitsWithdrawMin)
2937
+ # find max
2938
+ if limitsWithdrawMaxMain is None or Precise.string_gt(limitsWithdrawMax, limitsWithdrawMaxMain):
2939
+ currency['limits']['withdraw']['max'] = self.parse_number(limitsWithdrawMax)
2879
2940
  return self.extend({
2880
2941
  'info': None,
2881
2942
  'id': None,
ccxt/binance.py CHANGED
@@ -502,6 +502,7 @@ class binance(Exchange, ImplicitAPI):
502
502
  'portfolio/repay-futures-switch': 3, # Weight(IP): 30 => cost = 0.1 * 30 = 3
503
503
  'portfolio/margin-asset-leverage': 5, # Weight(IP): 50 => cost = 0.1 * 50 = 5
504
504
  'portfolio/balance': 2,
505
+ 'portfolio/negative-balance-exchange-record': 2,
505
506
  # staking
506
507
  'staking/productList': 0.1,
507
508
  'staking/position': 0.1,
@@ -5000,11 +5001,13 @@ class binance(Exchange, ImplicitAPI):
5000
5001
  until = self.safe_integer(params, 'until')
5001
5002
  if until is not None:
5002
5003
  request['endTime'] = until
5003
- if limit is not None:
5004
- isFutureOrSwap = (market['swap'] or market['future'])
5005
- request['limit'] = min(limit, 1000) if isFutureOrSwap else limit # default = 500, maximum = 1000
5006
5004
  method = self.safe_string(self.options, 'fetchTradesMethod')
5007
5005
  method = self.safe_string_2(params, 'fetchTradesMethod', 'method', method)
5006
+ if limit is not None:
5007
+ isFutureOrSwap = (market['swap'] or market['future'])
5008
+ isHistoricalEndpoint = (method is not None) and (method.find('GetHistoricalTrades') >= 0)
5009
+ maxLimitForContractHistorical = 500 if isHistoricalEndpoint else 1000
5010
+ request['limit'] = min(limit, maxLimitForContractHistorical) if isFutureOrSwap else limit # default = 500, maximum = 1000
5008
5011
  params = self.omit(params, ['until', 'fetchTradesMethod'])
5009
5012
  response = None
5010
5013
  if market['option'] or method == 'eapiPublicGetTrades':
@@ -6836,6 +6839,7 @@ class binance(Exchange, ImplicitAPI):
6836
6839
  :param str symbol: unified market symbol
6837
6840
  :param dict [params]: extra parameters specific to the exchange API endpoint
6838
6841
  :param str [params.trigger]: set to True if you would like to fetch portfolio margin account stop or conditional orders
6842
+ :param boolean [params.portfolioMargin]: set to True if you would like to fetch for a portfolio margin account
6839
6843
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
6840
6844
  """
6841
6845
  if symbol is None:
@@ -10158,7 +10162,7 @@ class binance(Exchange, ImplicitAPI):
10158
10162
  # }
10159
10163
  #
10160
10164
  marketId = self.safe_string(position, 'symbol')
10161
- market = self.safe_market(marketId, market)
10165
+ market = self.safe_market(marketId, market, None, 'swap')
10162
10166
  symbol = market['symbol']
10163
10167
  side = self.safe_string_lower(position, 'side')
10164
10168
  quantity = self.safe_string(position, 'quantity')
ccxt/blofin.py CHANGED
@@ -295,7 +295,7 @@ class blofin(Exchange, ImplicitAPI):
295
295
  'trailing': False,
296
296
  },
297
297
  'fetchOHLCV': {
298
- 'max': 1440,
298
+ 'limit': 1440,
299
299
  },
300
300
  },
301
301
  'spot': {
ccxt/coinex.py CHANGED
@@ -480,7 +480,7 @@ class coinex(Exchange, ImplicitAPI):
480
480
  'ERC20': 'ERC20',
481
481
  'BRC20': 'BRC20',
482
482
  'SOL': 'SOL',
483
- 'TON': 'SOL',
483
+ 'TON': 'TON',
484
484
  'BSV': 'BSV',
485
485
  'AVAXC': 'AVA_C',
486
486
  'AVAXX': 'AVA',
@@ -4608,13 +4608,13 @@ class coinex(Exchange, ImplicitAPI):
4608
4608
  self.check_address(address)
4609
4609
  self.load_markets()
4610
4610
  currency = self.currency(code)
4611
- if tag:
4612
- address = address + ':' + tag
4613
4611
  request: dict = {
4614
4612
  'ccy': currency['id'],
4615
4613
  'to_address': address, # must be authorized, inter-user transfer by a registered mobile phone number or an email address is supported
4616
4614
  'amount': self.number_to_string(amount), # the actual amount without fees, https://www.coinex.com/fees
4617
4615
  }
4616
+ if tag is not None:
4617
+ request['memo'] = tag
4618
4618
  networkCode = None
4619
4619
  networkCode, params = self.handle_network_code_and_params(params)
4620
4620
  if networkCode is not None:
ccxt/hollaex.py CHANGED
@@ -829,7 +829,7 @@ class hollaex(Exchange, ImplicitAPI):
829
829
 
830
830
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
831
831
  """
832
- fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
832
+ hollaex has large gaps between candles, so it's recommended to specify since
833
833
 
834
834
  https://apidocs.hollaex.com/#chart
835
835
 
@@ -838,6 +838,7 @@ class hollaex(Exchange, ImplicitAPI):
838
838
  :param int [since]: timestamp in ms of the earliest candle to fetch
839
839
  :param int [limit]: the maximum amount of candles to fetch
840
840
  :param dict [params]: extra parameters specific to the exchange API endpoint
841
+ :param int [params.until]: timestamp in ms of the latest candle to fetch
841
842
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
842
843
  """
843
844
  self.load_markets()
@@ -846,22 +847,17 @@ class hollaex(Exchange, ImplicitAPI):
846
847
  'symbol': market['id'],
847
848
  'resolution': self.safe_string(self.timeframes, timeframe, timeframe),
848
849
  }
849
- duration = self.parse_timeframe(timeframe)
850
- if since is None:
851
- if limit is None:
852
- limit = 1000 # they have no defaults and can actually provide tens of thousands of bars in one request, but we should cap "default" at generous amount
853
- end = self.seconds()
854
- start = end - duration * limit
855
- request['to'] = end
856
- request['from'] = start
850
+ until = self.safe_integer(params, 'until')
851
+ end = self.seconds()
852
+ if until is not None:
853
+ end = self.parse_to_int(until / 1000)
854
+ defaultSpan = 2592000 # 30 days
855
+ if since is not None:
856
+ request['from'] = self.parse_to_int(since / 1000)
857
857
  else:
858
- if limit is None:
859
- request['from'] = self.parse_to_int(since / 1000)
860
- request['to'] = self.seconds()
861
- else:
862
- start = self.parse_to_int(since / 1000)
863
- request['from'] = start
864
- request['to'] = self.sum(start, duration * limit)
858
+ request['from'] = end - defaultSpan
859
+ request['to'] = end
860
+ params = self.omit(params, 'until')
865
861
  response = self.publicGetChart(self.extend(request, params))
866
862
  #
867
863
  # [