ccxt 4.0.71__py2.py3-none-any.whl → 4.0.73__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.
@@ -5,6 +5,7 @@
5
5
 
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.lbank2 import ImplicitAPI
8
+ import asyncio
8
9
  import hashlib
9
10
  from ccxt.base.types import OrderSide
10
11
  from ccxt.base.types import OrderType
@@ -12,7 +13,6 @@ from typing import Optional
12
13
  from typing import List
13
14
  from ccxt.base.errors import ExchangeError
14
15
  from ccxt.base.errors import PermissionDenied
15
- from ccxt.base.errors import ArgumentsRequired
16
16
  from ccxt.base.errors import BadRequest
17
17
  from ccxt.base.errors import BadSymbol
18
18
  from ccxt.base.errors import InsufficientFunds
@@ -41,7 +41,7 @@ class lbank2(Exchange, ImplicitAPI):
41
41
  'CORS': False,
42
42
  'spot': True,
43
43
  'margin': False,
44
- 'swap': False,
44
+ 'swap': None,
45
45
  'future': False,
46
46
  'option': False,
47
47
  'addMargin': False,
@@ -85,6 +85,7 @@ class lbank2(Exchange, ImplicitAPI):
85
85
  'fetchPremiumIndexOHLCV': False,
86
86
  'fetchTicker': True,
87
87
  'fetchTickers': True,
88
+ 'fetchTime': True,
88
89
  'fetchTrades': True,
89
90
  'fetchTradingFees': True,
90
91
  'fetchTransactionFees': True,
@@ -112,6 +113,7 @@ class lbank2(Exchange, ImplicitAPI):
112
113
  'logo': 'https://user-images.githubusercontent.com/1294454/38063602-9605e28a-3302-11e8-81be-64b1e53c4cfb.jpg',
113
114
  'api': {
114
115
  'rest': 'https://api.lbank.info',
116
+ 'contract': 'https://lbkperp.lbank.com',
115
117
  },
116
118
  'api2': 'https://api.lbkex.com',
117
119
  'www': 'https://www.lbank.info',
@@ -120,73 +122,85 @@ class lbank2(Exchange, ImplicitAPI):
120
122
  'referral': 'https://www.lbank.info/invitevip?icode=7QCY',
121
123
  },
122
124
  'api': {
123
- 'public': {
124
- 'get': {
125
- 'currencyPairs': 2.5,
126
- 'accuracy': 2.5,
127
- 'usdToCny': 2.5,
128
- 'withdrawConfigs': 2.5,
129
- 'timestamp': 2.5,
130
- 'ticker/24hr': 2.5,
131
- 'ticker': 2.5,
132
- 'depth': 2.5,
133
- 'incrDepth': 2.5,
134
- 'trades': 2.5,
135
- 'kline': 2.5,
136
- # new quote endpoints
137
- 'supplement/system_ping': 2.5,
138
- 'supplement/incrDepth': 2.5,
139
- 'supplement/trades': 2.5,
140
- 'supplement/ticker/price': 2.5,
141
- 'supplement/ticker/bookTicker': 2.5,
125
+ 'spot': {
126
+ 'public': {
127
+ 'get': {
128
+ 'currencyPairs': 2.5,
129
+ 'accuracy': 2.5,
130
+ 'usdToCny': 2.5,
131
+ 'withdrawConfigs': 2.5,
132
+ 'timestamp': 2.5,
133
+ 'ticker/24hr': 2.5,
134
+ 'ticker': 2.5,
135
+ 'depth': 2.5,
136
+ 'incrDepth': 2.5,
137
+ 'trades': 2.5,
138
+ 'kline': 2.5,
139
+ # new quote endpoints
140
+ 'supplement/system_ping': 2.5,
141
+ 'supplement/incrDepth': 2.5,
142
+ 'supplement/trades': 2.5,
143
+ 'supplement/ticker/price': 2.5,
144
+ 'supplement/ticker/bookTicker': 2.5,
145
+ },
146
+ 'post': {
147
+ 'supplement/system_status': 2.5,
148
+ },
142
149
  },
143
- 'post': {
144
- 'supplement/system_status': 2.5,
150
+ 'private': {
151
+ 'post': {
152
+ # account
153
+ 'user_info': 2.5,
154
+ 'subscribe/get_key': 2.5,
155
+ 'subscribe/refresh_key': 2.5,
156
+ 'subscribe/destroy_key': 2.5,
157
+ 'get_deposit_address': 2.5,
158
+ 'deposit_history': 2.5,
159
+ # order
160
+ 'create_order': 1,
161
+ 'batch_create_order': 1,
162
+ 'cancel_order': 1,
163
+ 'cancel_clientOrders': 1,
164
+ 'orders_info': 2.5,
165
+ 'orders_info_history': 2.5,
166
+ 'order_transaction_detail': 2.5,
167
+ 'transaction_history': 2.5,
168
+ 'orders_info_no_deal': 2.5,
169
+ # withdraw
170
+ 'withdraw': 2.5,
171
+ 'withdrawCancel': 2.5,
172
+ 'withdraws': 2.5,
173
+ 'supplement/user_info': 2.5,
174
+ 'supplement/withdraw': 2.5,
175
+ 'supplement/deposit_history': 2.5,
176
+ 'supplement/withdraws': 2.5,
177
+ 'supplement/get_deposit_address': 2.5,
178
+ 'supplement/asset_detail': 2.5,
179
+ 'supplement/customer_trade_fee': 2.5,
180
+ 'supplement/api_Restrictions': 2.5,
181
+ # new quote endpoints
182
+ 'supplement/system_ping': 2.5,
183
+ # new order endpoints
184
+ 'supplement/create_order_test': 1,
185
+ 'supplement/create_order': 1,
186
+ 'supplement/cancel_order': 1,
187
+ 'supplement/cancel_order_by_symbol': 1,
188
+ 'supplement/orders_info': 2.5,
189
+ 'supplement/orders_info_no_deal': 2.5,
190
+ 'supplement/orders_info_history': 2.5,
191
+ 'supplement/user_info_account': 2.5,
192
+ 'supplement/transaction_history': 2.5,
193
+ },
145
194
  },
146
195
  },
147
- 'private': {
148
- 'post': {
149
- # account
150
- 'user_info': 2.5,
151
- 'subscribe/get_key': 2.5,
152
- 'subscribe/refresh_key': 2.5,
153
- 'subscribe/destroy_key': 2.5,
154
- 'get_deposit_address': 2.5,
155
- 'deposit_history': 2.5,
156
- # order
157
- 'create_order': 1,
158
- 'batch_create_order': 1,
159
- 'cancel_order': 1,
160
- 'cancel_clientOrders': 1,
161
- 'orders_info': 2.5,
162
- 'orders_info_history': 2.5,
163
- 'order_transaction_detail': 2.5,
164
- 'transaction_history': 2.5,
165
- 'orders_info_no_deal': 2.5,
166
- # withdraw
167
- 'withdraw': 2.5,
168
- 'withdrawCancel': 2.5,
169
- 'withdraws': 2.5,
170
- 'supplement/user_info': 2.5,
171
- 'supplement/withdraw': 2.5,
172
- 'supplement/deposit_history': 2.5,
173
- 'supplement/withdraws': 2.5,
174
- 'supplement/get_deposit_address': 2.5,
175
- 'supplement/asset_detail': 2.5,
176
- 'supplement/customer_trade_fee': 2.5,
177
- 'supplement/api_Restrictions': 2.5,
178
- # new quote endpoints
179
- 'supplement/system_ping': 2.5,
180
- # new order endpoints
181
- 'supplement/create_order_test': 1,
182
- 'supplement/create_order': 1,
183
- 'supplement/cancel_order': 1,
184
- 'supplement/cancel_order_by_symbol': 1,
185
- 'supplement/orders_info': 2.5,
186
- 'supplement/orders_info_no_deal': 2.5,
187
- 'supplement/orders_info_history': 2.5,
188
- 'supplement/user_info_account': 2.5,
189
- 'supplement/transaction_history': 2.5,
196
+ 'contract': {
197
+ 'public': {
198
+ 'get': {
199
+ 'cfd/openApi/v1/pub/getTime': 2.5,
200
+ 'cfd/openApi/v1/pub/instrument': 2.5,
201
+ 'cfd/openApi/v1/pub/marketData': 2.5,
202
+ 'cfd/openApi/v1/pub/marketOrder': 2.5,
203
+ },
190
204
  },
191
205
  },
192
206
  },
@@ -208,7 +222,7 @@ class lbank2(Exchange, ImplicitAPI):
208
222
  'cacheSecretAsPem': True,
209
223
  'createMarketBuyOrderRequiresPrice': True,
210
224
  'fetchTrades': {
211
- 'method': 'publicGetTrades', # or 'publicGetTradesSupplement'
225
+ 'method': 'spotPublicGetTrades', # or 'spotPublicGetTradesSupplement'
212
226
  },
213
227
  'fetchTransactionFees': { # DEPRECATED, please use fetchDepositWithdrawFees
214
228
  'method': 'fetchPrivateTransactionFees', # or 'fetchPublicTransactionFees'
@@ -220,13 +234,13 @@ class lbank2(Exchange, ImplicitAPI):
220
234
  'method': 'fetchDepositAddressDefault', # or fetchDepositAddressSupplement
221
235
  },
222
236
  'createOrder': {
223
- 'method': 'privatePostSupplementCreateOrder', # or privatePostCreateOrder
237
+ 'method': 'spotPrivatePostSupplementCreateOrder', # or spotPrivatePostCreateOrder
224
238
  },
225
239
  'fetchOrder': {
226
240
  'method': 'fetchOrderSupplement', # or fetchOrderDefault
227
241
  },
228
242
  'fetchBalance': {
229
- 'method': 'privatePostSupplementUserInfo', # or privatePostSupplementUserInfoAccount or privatePostUserInfo
243
+ 'method': 'spotPrivatePostSupplementUserInfo', # or spotPrivatePostSupplementUserInfoAccount or spotPrivatePostUserInfo
230
244
  },
231
245
  'networks': {
232
246
  'ERC20': 'erc20',
@@ -288,24 +302,76 @@ class lbank2(Exchange, ImplicitAPI):
288
302
  },
289
303
  })
290
304
 
305
+ async def fetch_time(self, params={}):
306
+ """
307
+ fetches the current integer timestamp in milliseconds from the exchange server
308
+ see https://www.lbank.info/en-US/docs/index.html#get-timestamp
309
+ see https://www.lbank.com/en-US/docs/contract.html#get-the-current-time
310
+ :param dict [params]: extra parameters specific to the lbank2 api endpoint
311
+ :returns int: the current integer timestamp in milliseconds from the exchange server
312
+ """
313
+ type = None
314
+ type, params = self.handle_market_type_and_params('fetchTime', None, params)
315
+ response = None
316
+ if type == 'swap':
317
+ response = await self.contractPublicGetCfdOpenApiV1PubGetTime(params)
318
+ else:
319
+ response = await self.spotPublicGetTimestamp(params)
320
+ #
321
+ # spot
322
+ #
323
+ # {
324
+ # "result": "true",
325
+ # "data": 1691789627950,
326
+ # "error_code": 0,
327
+ # "ts": 1691789627950
328
+ # }
329
+ #
330
+ # swap
331
+ #
332
+ # {
333
+ # "data": 1691789627950,
334
+ # "error_code": 0,
335
+ # "msg": "Success",
336
+ # "result": "true",
337
+ # "success": True
338
+ # }
339
+ #
340
+ return self.safe_integer(response, 'data')
341
+
291
342
  async def fetch_markets(self, params={}):
292
343
  """
293
344
  retrieves data on all markets for lbank2
294
345
  see https://www.lbank.com/en-US/docs/index.html#trading-pairs
346
+ see https://www.lbank.com/en-US/docs/contract.html#query-contract-information-list
295
347
  :param dict [params]: extra parameters specific to the exchange api endpoint
296
348
  :returns dict[]: an array of objects representing market data
297
349
  """
298
- # needs to return a list of unified market structures
299
- response = await self.publicGetAccuracy()
300
- data = self.safe_value(response, 'data')
301
- # [
302
- # {
303
- # symbol: 'snx3s_usdt',
304
- # quantityAccuracy: '2',
305
- # minTranQua: '0.01',
306
- # priceAccuracy: '6'
307
- # }
308
- # ]
350
+ marketsPromises = [
351
+ self.fetch_spot_markets(params),
352
+ self.fetch_swap_markets(params),
353
+ ]
354
+ resolvedMarkets = await asyncio.gather(*marketsPromises)
355
+ return self.array_concat(resolvedMarkets[0], resolvedMarkets[1])
356
+
357
+ async def fetch_spot_markets(self, params={}):
358
+ response = await self.spotPublicGetAccuracy(params)
359
+ #
360
+ # {
361
+ # "result": "true",
362
+ # "data": [
363
+ # {
364
+ # "symbol": "btc_usdt",
365
+ # "quantityAccuracy": "4",
366
+ # "minTranQua": "0.0001",
367
+ # "priceAccuracy": "2"
368
+ # },
369
+ # ],
370
+ # "error_code": 0,
371
+ # "ts": 1691560288484
372
+ # }
373
+ #
374
+ data = self.safe_value(response, 'data', [])
309
375
  result = []
310
376
  for i in range(0, len(data)):
311
377
  market = data[i]
@@ -313,10 +379,9 @@ class lbank2(Exchange, ImplicitAPI):
313
379
  parts = marketId.split('_')
314
380
  baseId = parts[0]
315
381
  quoteId = parts[1]
316
- base = baseId.upper()
317
- quote = quoteId.upper()
382
+ base = self.safe_currency_code(baseId)
383
+ quote = self.safe_currency_code(quoteId)
318
384
  symbol = base + '/' + quote
319
- amountPrecision = self.parse_number(self.parse_precision(self.safe_string(market, 'quantityAccuracy')))
320
385
  result.append({
321
386
  'id': marketId,
322
387
  'symbol': symbol,
@@ -342,7 +407,7 @@ class lbank2(Exchange, ImplicitAPI):
342
407
  'strike': None,
343
408
  'optionType': None,
344
409
  'precision': {
345
- 'amount': amountPrecision,
410
+ 'amount': self.parse_number(self.parse_precision(self.safe_string(market, 'quantityAccuracy'))),
346
411
  'price': self.parse_number(self.parse_precision(self.safe_string(market, 'priceAccuracy'))),
347
412
  },
348
413
  'limits': {
@@ -367,80 +432,198 @@ class lbank2(Exchange, ImplicitAPI):
367
432
  })
368
433
  return result
369
434
 
435
+ async def fetch_swap_markets(self, params={}):
436
+ request = {
437
+ 'productGroup': 'SwapU',
438
+ }
439
+ response = await self.contractPublicGetCfdOpenApiV1PubInstrument(self.extend(request, params))
440
+ #
441
+ # {
442
+ # "data": [
443
+ # {
444
+ # "priceLimitUpperValue": 0.2,
445
+ # "symbol": "BTCUSDT",
446
+ # "volumeTick": 0.0001,
447
+ # "indexPrice": "29707.70200000",
448
+ # "minOrderVolume": "0.0001",
449
+ # "priceTick": 0.1,
450
+ # "maxOrderVolume": "30.0",
451
+ # "baseCurrency": "BTC",
452
+ # "volumeMultiple": 1.0,
453
+ # "exchangeID": "Exchange",
454
+ # "priceCurrency": "USDT",
455
+ # "priceLimitLowerValue": 0.2,
456
+ # "clearCurrency": "USDT",
457
+ # "symbolName": "BTCUSDT",
458
+ # "defaultLeverage": 20.0,
459
+ # "minOrderCost": "5.0"
460
+ # },
461
+ # ],
462
+ # "error_code": 0,
463
+ # "msg": "Success",
464
+ # "result": "true",
465
+ # "success": True
466
+ # }
467
+ #
468
+ data = self.safe_value(response, 'data', [])
469
+ result = []
470
+ for i in range(0, len(data)):
471
+ market = data[i]
472
+ marketId = self.safe_string(market, 'symbol')
473
+ baseId = self.safe_string(market, 'baseCurrency')
474
+ settleId = self.safe_string(market, 'clearCurrency')
475
+ quoteId = settleId
476
+ base = self.safe_currency_code(baseId)
477
+ quote = self.safe_currency_code(quoteId)
478
+ settle = self.safe_currency_code(settleId)
479
+ symbol = base + '/' + quote + ':' + settle
480
+ result.append({
481
+ 'id': marketId,
482
+ 'symbol': symbol,
483
+ 'base': base,
484
+ 'quote': quote,
485
+ 'settle': settle,
486
+ 'baseId': baseId,
487
+ 'quoteId': quoteId,
488
+ 'settleId': settleId,
489
+ 'type': 'swap',
490
+ 'spot': False,
491
+ 'margin': False,
492
+ 'swap': True,
493
+ 'future': False,
494
+ 'option': False,
495
+ 'active': True,
496
+ 'contract': True,
497
+ 'linear': True,
498
+ 'inverse': None,
499
+ 'contractSize': self.safe_number(market, 'volumeMultiple'),
500
+ 'expiry': None,
501
+ 'expiryDatetime': None,
502
+ 'strike': None,
503
+ 'optionType': None,
504
+ 'precision': {
505
+ 'amount': self.safe_number(market, 'volumeTick'),
506
+ 'price': self.safe_number(market, 'priceTick'),
507
+ },
508
+ 'limits': {
509
+ 'leverage': {
510
+ 'min': None,
511
+ 'max': None,
512
+ },
513
+ 'amount': {
514
+ 'min': self.safe_number(market, 'minOrderVolume'),
515
+ 'max': self.safe_number(market, 'maxOrderVolume'),
516
+ },
517
+ 'price': {
518
+ 'min': self.safe_number(market, 'priceLimitLowerValue'),
519
+ 'max': self.safe_number(market, 'priceLimitUpperValue'),
520
+ },
521
+ 'cost': {
522
+ 'min': self.safe_number(market, 'minOrderCost'),
523
+ 'max': None,
524
+ },
525
+ },
526
+ 'info': market,
527
+ })
528
+ return result
529
+
370
530
  def parse_ticker(self, ticker, market=None):
371
531
  #
372
- # {
373
- # "symbol":"btc_usdt",
374
- # "ticker": {
375
- # "high":40200.88,
376
- # "vol":7508.3096,
377
- # "low":38239.38,
378
- # "change":0.75,
379
- # "turnover":292962771.34,
380
- # "latest":39577.95
381
- # },
382
- # "timestamp":1647005189792
383
- # }
532
+ # spot: fetchTicker, fetchTickers
533
+ #
534
+ # {
535
+ # "symbol": "btc_usdt",
536
+ # "ticker": {
537
+ # "high": "29695.57",
538
+ # "vol": "6890.2789",
539
+ # "low": "29110",
540
+ # "change": "0.58",
541
+ # "turnover": "202769821.06",
542
+ # "latest": "29405.98"
543
+ # },
544
+ # "timestamp": :1692064274908
545
+ # }
546
+ #
547
+ # swap: fetchTickers
548
+ #
549
+ # {
550
+ # "prePositionFeeRate": "0.000053",
551
+ # "volume": "2435.459",
552
+ # "symbol": "BTCUSDT",
553
+ # "highestPrice": "29446.5",
554
+ # "lowestPrice": "29362.9",
555
+ # "openPrice": "29419.5",
556
+ # "markedPrice": "29385.1",
557
+ # "turnover": "36345526.2438402",
558
+ # "lastPrice": "29387.0"
559
+ # }
384
560
  #
561
+ timestamp = self.safe_integer(ticker, 'timestamp')
385
562
  marketId = self.safe_string(ticker, 'symbol')
386
563
  symbol = self.safe_symbol(marketId, market)
387
- timestamp = self.safe_integer(ticker, 'timestamp')
388
- tickerData = self.safe_value(ticker, 'ticker')
564
+ tickerData = self.safe_value(ticker, 'ticker', {})
565
+ market = self.safe_market(marketId, market)
566
+ data = ticker if (market['contract']) else tickerData
389
567
  return self.safe_ticker({
390
568
  'symbol': symbol,
391
569
  'timestamp': timestamp,
392
570
  'datetime': self.iso8601(timestamp),
393
- 'high': self.safe_string(tickerData, 'high'),
394
- 'low': self.safe_string(tickerData, 'low'),
571
+ 'high': self.safe_string_2(data, 'high', 'highestPrice'),
572
+ 'low': self.safe_string_2(data, 'low', 'lowestPrice'),
395
573
  'bid': None,
396
574
  'bidVolume': None,
397
575
  'ask': None,
398
576
  'askVolume': None,
399
577
  'vwap': None,
400
- 'open': None,
578
+ 'open': self.safe_string(data, 'openPrice'),
401
579
  'close': None,
402
- 'last': self.safe_string(tickerData, 'latest'),
580
+ 'last': self.safe_string_2(data, 'latest', 'lastPrice'),
403
581
  'previousClose': None,
404
582
  'change': None,
405
- 'percentage': self.safe_string(tickerData, 'change'),
583
+ 'percentage': self.safe_string(data, 'change'),
406
584
  'average': None,
407
- 'baseVolume': self.safe_string(tickerData, 'vol'),
408
- 'quoteVolume': self.safe_string(tickerData, 'turnover'),
585
+ 'baseVolume': self.safe_string_2(data, 'vol', 'volume'),
586
+ 'quoteVolume': self.safe_string(data, 'turnover'),
409
587
  'info': ticker,
410
588
  }, market)
411
589
 
412
590
  async def fetch_ticker(self, symbol: str, params={}):
413
591
  """
414
592
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
593
+ see https://www.lbank.info/en-US/docs/index.html#query-current-market-data-new
415
594
  :param str symbol: unified symbol of the market to fetch the ticker for
416
595
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
417
596
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
418
597
  """
419
598
  await self.load_markets()
420
599
  market = self.market(symbol)
600
+ if market['swap']:
601
+ response = await self.fetch_tickers([market['symbol']], params)
602
+ return self.safe_value(response, market['symbol'])
421
603
  request = {
422
604
  'symbol': market['id'],
423
605
  }
424
- response = await self.publicGetTicker24hr(self.extend(request, params))
425
- #
426
- # {
427
- # "result":"true",
428
- # "data": [
429
- # {
430
- # "symbol":"btc_usdt",
431
- # "ticker":{
432
- # "high":40200.88,
433
- # "vol":7508.3096,
434
- # "low":38239.38,
435
- # "change":0.75,
436
- # "turnover":292962771.34,
437
- # "latest":39577.95
438
- # },
439
- # "timestamp":1647005189792
440
- # }
441
- # ],
442
- # "error_code":0,"ts":1647005190755
443
- # }
606
+ response = await self.spotPublicGetTicker24hr(self.extend(request, params))
607
+ #
608
+ # {
609
+ # "result": "true",
610
+ # "data": [
611
+ # {
612
+ # "symbol": "btc_usdt",
613
+ # "ticker": {
614
+ # "high": "29695.57",
615
+ # "vol": "6890.2789",
616
+ # "low": "29110",
617
+ # "change": "0.58",
618
+ # "turnover": "202769821.06",
619
+ # "latest": "29405.98"
620
+ # },
621
+ # "timestamp": :1692064274908
622
+ # }
623
+ # ],
624
+ # "error_code": 0,
625
+ # "ts": :1692064276872
626
+ # }
444
627
  #
445
628
  data = self.safe_value(response, 'data', [])
446
629
  first = self.safe_value(data, 0, {})
@@ -449,21 +632,82 @@ class lbank2(Exchange, ImplicitAPI):
449
632
  async def fetch_tickers(self, symbols: Optional[List[str]] = None, params={}):
450
633
  """
451
634
  fetches price tickers for multiple markets, statistical calculations with the information calculated over the past 24 hours each market
635
+ see https://www.lbank.info/en-US/docs/index.html#query-current-market-data-new
636
+ see https://www.lbank.com/en-US/docs/contract.html#query-contract-market-list
452
637
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
453
638
  :param dict [params]: extra parameters specific to the lbank api endpoint
454
639
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
455
640
  """
456
641
  await self.load_markets()
457
- request = {
458
- 'symbol': 'all',
459
- }
460
- response = await self.publicGetTicker24hr(self.extend(request, params))
642
+ market = None
643
+ if symbols is not None:
644
+ symbols = self.market_symbols(symbols)
645
+ symbolsLength = len(symbols)
646
+ if symbolsLength > 0:
647
+ market = self.market(symbols[0])
648
+ request = {}
649
+ type = None
650
+ type, params = self.handle_market_type_and_params('fetchTickers', market, params)
651
+ response = None
652
+ if type == 'swap':
653
+ request['productGroup'] = 'SwapU'
654
+ response = await self.contractPublicGetCfdOpenApiV1PubMarketData(self.extend(request, params))
655
+ else:
656
+ request['symbol'] = 'all'
657
+ response = await self.spotPublicGetTicker24hr(self.extend(request, params))
658
+ #
659
+ # spot
660
+ #
661
+ # {
662
+ # "result": "true",
663
+ # "data": [
664
+ # {
665
+ # "symbol": "btc_usdt",
666
+ # "ticker": {
667
+ # "high": "29695.57",
668
+ # "vol": "6890.2789",
669
+ # "low": "29110",
670
+ # "change": "0.58",
671
+ # "turnover": "202769821.06",
672
+ # "latest": "29405.98"
673
+ # },
674
+ # "timestamp": :1692064274908
675
+ # }
676
+ # ],
677
+ # "error_code": 0,
678
+ # "ts": :1692064276872
679
+ # }
680
+ #
681
+ # swap
682
+ #
683
+ # {
684
+ # "data": [
685
+ # {
686
+ # "prePositionFeeRate": "0.000053",
687
+ # "volume": "2435.459",
688
+ # "symbol": "BTCUSDT",
689
+ # "highestPrice": "29446.5",
690
+ # "lowestPrice": "29362.9",
691
+ # "openPrice": "29419.5",
692
+ # "markedPrice": "29385.1",
693
+ # "turnover": "36345526.2438402",
694
+ # "lastPrice": "29387.0"
695
+ # },
696
+ # ],
697
+ # "error_code": 0,
698
+ # "msg": "Success",
699
+ # "result": "true",
700
+ # "success": True
701
+ # }
702
+ #
461
703
  data = self.safe_value(response, 'data', [])
462
704
  return self.parse_tickers(data, symbols)
463
705
 
464
706
  async def fetch_order_book(self, symbol: str, limit: Optional[int] = None, params={}):
465
707
  """
466
708
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
709
+ see https://www.lbank.info/en-US/docs/index.html#query-market-depth
710
+ see https://www.lbank.com/en-US/docs/contract.html#get-handicap
467
711
  :param str symbol: unified symbol of the market to fetch the order book for
468
712
  :param int [limit]: the maximum amount of order book entries to return
469
713
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
@@ -475,16 +719,73 @@ class lbank2(Exchange, ImplicitAPI):
475
719
  limit = 60
476
720
  request = {
477
721
  'symbol': market['id'],
478
- 'size': limit,
479
722
  }
480
- response = await self.publicGetDepth(self.extend(request, params))
481
- orderbook = response['data']
723
+ type = None
724
+ type, params = self.handle_market_type_and_params('fetchOrderBook', market, params)
725
+ response = None
726
+ if type == 'swap':
727
+ request['depth'] = limit
728
+ response = await self.contractPublicGetCfdOpenApiV1PubMarketOrder(self.extend(request, params))
729
+ else:
730
+ request['size'] = limit
731
+ response = await self.spotPublicGetDepth(self.extend(request, params))
732
+ #
733
+ # spot
734
+ #
735
+ # {
736
+ # "result": "true",
737
+ # "data": {
738
+ # "asks": [
739
+ # ["29243.37", "2.8783"],
740
+ # ["29243.39", "2.2842"],
741
+ # ["29243.4", "0.0337"]
742
+ # ],
743
+ # "bids": [
744
+ # ["29243.36", "1.5258"],
745
+ # ["29243.34", "0.8218"],
746
+ # ["29243.28", "1.285"]
747
+ # ],
748
+ # "timestamp": :1692157328820
749
+ # },
750
+ # "error_code": 0,
751
+ # "ts": :1692157328820
752
+ # }
753
+ #
754
+ # swap
755
+ #
756
+ # {
757
+ # "data": {
758
+ # "symbol": "BTCUSDT",
759
+ # "asks": [
760
+ # {
761
+ # "volume": "14.6535",
762
+ # "price": "29234.2",
763
+ # "orders": "1"
764
+ # },
765
+ # ],
766
+ # "bids": [
767
+ # {
768
+ # "volume": "13.4899",
769
+ # "price": "29234.1",
770
+ # "orders": "4"
771
+ # },
772
+ # ]
773
+ # },
774
+ # "error_code": 0,
775
+ # "msg": "Success",
776
+ # "result": "true",
777
+ # "success": True
778
+ # }
779
+ #
780
+ orderbook = self.safe_value(response, 'data', {})
482
781
  timestamp = self.milliseconds()
782
+ if market['swap']:
783
+ return self.parse_order_book(orderbook, market['symbol'], timestamp, 'bids', 'asks', 'price', 'volume')
483
784
  return self.parse_order_book(orderbook, market['symbol'], timestamp)
484
785
 
485
786
  def parse_trade(self, trade, market=None):
486
787
  #
487
- # fetchTrades(old) publicGetTrades
788
+ # fetchTrades(old) spotPublicGetTrades
488
789
  #
489
790
  # {
490
791
  # "date_ms":1647021989789,
@@ -495,7 +796,7 @@ class lbank2(Exchange, ImplicitAPI):
495
796
  # }
496
797
  #
497
798
  #
498
- # fetchTrades(new) publicGetTradesSupplement
799
+ # fetchTrades(new) spotPublicGetTradesSupplement
499
800
  #
500
801
  # {
501
802
  # "quoteQty":1675.048485,
@@ -578,6 +879,8 @@ class lbank2(Exchange, ImplicitAPI):
578
879
  async def fetch_trades(self, symbol: str, since: Optional[int] = None, limit: Optional[int] = None, params={}):
579
880
  """
580
881
  get the list of most recent trades for a particular symbol
882
+ see https://www.lbank.info/en-US/docs/index.html#query-historical-transactions
883
+ see https://www.lbank.info/en-US/docs/index.html#recent-transactions-list
581
884
  :param str symbol: unified symbol of the market to fetch trades for
582
885
  :param int [since]: timestamp in ms of the earliest trade to fetch
583
886
  :param int [limit]: the maximum amount of trades to fetch
@@ -599,7 +902,7 @@ class lbank2(Exchange, ImplicitAPI):
599
902
  params = self.omit(params, 'method')
600
903
  if method is None:
601
904
  options = self.safe_value(self.options, 'fetchTrades', {})
602
- method = self.safe_string(options, 'method', 'publicGetTrades')
905
+ method = self.safe_string(options, 'method', 'spotPublicGetTrades')
603
906
  response = await getattr(self, method)(self.extend(request, params))
604
907
  #
605
908
  # {
@@ -616,6 +919,7 @@ class lbank2(Exchange, ImplicitAPI):
616
919
  # "error_code":0,
617
920
  # "ts":1647021999308
618
921
  # }
922
+ #
619
923
  trades = self.safe_value(response, 'data', [])
620
924
  return self.parse_trades(trades, market, since, limit)
621
925
 
@@ -642,6 +946,7 @@ class lbank2(Exchange, ImplicitAPI):
642
946
  async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Optional[int] = None, limit: Optional[int] = None, params={}):
643
947
  """
644
948
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
949
+ see https://www.lbank.info/en-US/docs/index.html#query-k-bar-data
645
950
  :param str symbol: unified symbol of the market to fetch OHLCV data for
646
951
  :param str timeframe: the length of time each candle represents
647
952
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -663,7 +968,7 @@ class lbank2(Exchange, ImplicitAPI):
663
968
  'time': self.parse_to_int(since / 1000),
664
969
  'size': limit, # max 2000
665
970
  }
666
- response = await self.publicGetKline(self.extend(request, params))
971
+ response = await self.spotPublicGetKline(self.extend(request, params))
667
972
  ohlcvs = self.safe_value(response, 'data', [])
668
973
  #
669
974
  #
@@ -690,7 +995,7 @@ class lbank2(Exchange, ImplicitAPI):
690
995
 
691
996
  def parse_balance(self, response):
692
997
  #
693
- # privatePostUserInfo
998
+ # spotPrivatePostUserInfo
694
999
  #
695
1000
  # {
696
1001
  # "toBtc": {
@@ -715,7 +1020,7 @@ class lbank2(Exchange, ImplicitAPI):
715
1020
  # }
716
1021
  # }
717
1022
  #
718
- # privatePostSupplementUserInfoAccount
1023
+ # spotPrivatePostSupplementUserInfoAccount
719
1024
  #
720
1025
  # {
721
1026
  # "balances":[
@@ -727,7 +1032,7 @@ class lbank2(Exchange, ImplicitAPI):
727
1032
  # ]
728
1033
  # }
729
1034
  #
730
- # privatePostSupplementUserInfo
1035
+ # spotPrivatePostSupplementUserInfo
731
1036
  #
732
1037
  # [
733
1038
  # {
@@ -773,7 +1078,7 @@ class lbank2(Exchange, ImplicitAPI):
773
1078
  'datetime': self.iso8601(timestamp),
774
1079
  }
775
1080
  data = self.safe_value(response, 'data')
776
- # from privatePostUserInfo
1081
+ # from spotPrivatePostUserInfo
777
1082
  toBtc = self.safe_value(data, 'toBtc')
778
1083
  if toBtc is not None:
779
1084
  used = self.safe_value(data, 'freeze', {})
@@ -787,7 +1092,7 @@ class lbank2(Exchange, ImplicitAPI):
787
1092
  account['free'] = self.safe_string(free, currencyId)
788
1093
  result[code] = account
789
1094
  return self.safe_balance(result)
790
- # from privatePostSupplementUserInfoAccount
1095
+ # from spotPrivatePostSupplementUserInfoAccount
791
1096
  balances = self.safe_value(data, 'balances')
792
1097
  if balances is not None:
793
1098
  for i in range(0, len(balances)):
@@ -799,7 +1104,7 @@ class lbank2(Exchange, ImplicitAPI):
799
1104
  account['used'] = self.safe_string(item, 'locked')
800
1105
  result[codeInner] = account
801
1106
  return self.safe_balance(result)
802
- # from privatePostSupplementUserInfo
1107
+ # from spotPrivatePostSupplementUserInfo
803
1108
  isArray = isinstance(data, list)
804
1109
  if isArray is True:
805
1110
  for i in range(0, len(data)):
@@ -816,6 +1121,9 @@ class lbank2(Exchange, ImplicitAPI):
816
1121
  async def fetch_balance(self, params={}):
817
1122
  """
818
1123
  query for balance and get the amount of funds available for trading or funds locked in orders
1124
+ see https://www.lbank.info/en-US/docs/index.html#asset-information
1125
+ see https://www.lbank.info/en-US/docs/index.html#account-information
1126
+ see https://www.lbank.info/en-US/docs/index.html#get-all-coins-information
819
1127
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
820
1128
  :returns dict: a `balance structure <https://docs.ccxt.com/en/latest/manual.html?#balance-structure>`
821
1129
  """
@@ -823,7 +1131,7 @@ class lbank2(Exchange, ImplicitAPI):
823
1131
  method = self.safe_string(params, 'method')
824
1132
  if method is None:
825
1133
  options = self.safe_value(self.options, 'fetchBalance', {})
826
- method = self.safe_string(options, 'method', 'privatePostSupplementUserInfo')
1134
+ method = self.safe_string(options, 'method', 'spotPrivatePostSupplementUserInfo')
827
1135
  response = await getattr(self, method)()
828
1136
  #
829
1137
  # {
@@ -877,6 +1185,7 @@ class lbank2(Exchange, ImplicitAPI):
877
1185
  async def fetch_trading_fee(self, symbol: str, params={}):
878
1186
  """
879
1187
  fetch the trading fees for a market
1188
+ see https://www.lbank.info/en-US/docs/index.html#transaction-fee-rate-query
880
1189
  :param str symbol: unified market symbol
881
1190
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
882
1191
  :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -888,12 +1197,13 @@ class lbank2(Exchange, ImplicitAPI):
888
1197
  async def fetch_trading_fees(self, params={}):
889
1198
  """
890
1199
  fetch the trading fees for multiple markets
1200
+ see https://www.lbank.info/en-US/docs/index.html#transaction-fee-rate-query
891
1201
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
892
1202
  :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
893
1203
  """
894
1204
  await self.load_markets()
895
1205
  request = {}
896
- response = await self.privatePostSupplementCustomerTradeFee(self.extend(request, params))
1206
+ response = await self.spotPrivatePostSupplementCustomerTradeFee(self.extend(request, params))
897
1207
  fees = self.safe_value(response, 'data', [])
898
1208
  result = {}
899
1209
  for i in range(0, len(fees)):
@@ -905,6 +1215,8 @@ class lbank2(Exchange, ImplicitAPI):
905
1215
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
906
1216
  """
907
1217
  create a trade order
1218
+ see https://www.lbank.info/en-US/docs/index.html#place-order
1219
+ see https://www.lbank.info/en-US/docs/index.html#place-an-order
908
1220
  :param str symbol: unified symbol of the market to create an order in
909
1221
  :param str type: 'market' or 'limit'
910
1222
  :param str side: 'buy' or 'sell'
@@ -961,7 +1273,7 @@ class lbank2(Exchange, ImplicitAPI):
961
1273
  params = self.omit(params, 'method')
962
1274
  if method is None:
963
1275
  options = self.safe_value(self.options, 'createOrder', {})
964
- method = self.safe_string(options, 'method', 'privatePostSupplementCreateOrder')
1276
+ method = self.safe_string(options, 'method', 'spotPrivatePostSupplementCreateOrder')
965
1277
  response = await getattr(self, method)(self.extend(request, params))
966
1278
  #
967
1279
  # {
@@ -1114,6 +1426,8 @@ class lbank2(Exchange, ImplicitAPI):
1114
1426
  async def fetch_order(self, id: str, symbol: Optional[str] = None, params={}):
1115
1427
  """
1116
1428
  fetches information on an order made by the user
1429
+ see https://www.lbank.info/en-US/docs/index.html#query-order
1430
+ see https://www.lbank.info/en-US/docs/index.html#query-order-new
1117
1431
  :param str symbol: unified symbol of the market the order was made in
1118
1432
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
1119
1433
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
@@ -1127,15 +1441,14 @@ class lbank2(Exchange, ImplicitAPI):
1127
1441
  return result
1128
1442
 
1129
1443
  async def fetch_order_supplement(self, id: str, symbol: Optional[str] = None, params={}):
1444
+ self.check_required_symbol('fetchOrder', symbol)
1130
1445
  await self.load_markets()
1131
- if symbol is None:
1132
- raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
1133
1446
  market = self.market(symbol)
1134
1447
  request = {
1135
1448
  'symbol': market['id'],
1136
1449
  'orderId': id,
1137
1450
  }
1138
- response = await self.privatePostSupplementOrdersInfo(self.extend(request, params))
1451
+ response = await self.spotPrivatePostSupplementOrdersInfo(self.extend(request, params))
1139
1452
  #
1140
1453
  # {
1141
1454
  # "result":true,
@@ -1162,15 +1475,14 @@ class lbank2(Exchange, ImplicitAPI):
1162
1475
 
1163
1476
  async def fetch_order_default(self, id: str, symbol: Optional[str] = None, params={}):
1164
1477
  # Id can be a list of ids delimited by a comma
1478
+ self.check_required_symbol('fetchOrder', symbol)
1165
1479
  await self.load_markets()
1166
- if symbol is None:
1167
- raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
1168
1480
  market = self.market(symbol)
1169
1481
  request = {
1170
1482
  'symbol': market['id'],
1171
1483
  'order_id': id,
1172
1484
  }
1173
- response = await self.privatePostOrdersInfo(self.extend(request, params))
1485
+ response = await self.spotPrivatePostOrdersInfo(self.extend(request, params))
1174
1486
  #
1175
1487
  # {
1176
1488
  # "result":true,
@@ -1205,14 +1517,14 @@ class lbank2(Exchange, ImplicitAPI):
1205
1517
  async def fetch_my_trades(self, symbol: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
1206
1518
  """
1207
1519
  fetch all trades made by the user
1520
+ see https://www.lbank.info/en-US/docs/index.html#past-transaction-details
1208
1521
  :param str symbol: unified market symbol
1209
1522
  :param int [since]: the earliest time in ms to fetch trades for
1210
- :param int [limit]: the maximum number of trades structures to retrieve
1523
+ :param int [limit]: the maximum number of trade structures to retrieve
1211
1524
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
1212
1525
  :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1213
1526
  """
1214
- if symbol is None:
1215
- raise ArgumentsRequired(self.id + ' fetchMyTrades() requires a symbol argument')
1527
+ self.check_required_symbol('fetchMyTrades', symbol)
1216
1528
  await self.load_markets()
1217
1529
  market = self.market(symbol)
1218
1530
  since = self.safe_value(params, 'start_date', since)
@@ -1231,7 +1543,7 @@ class lbank2(Exchange, ImplicitAPI):
1231
1543
  if since is not None:
1232
1544
  request['start_date'] = self.ymd(since, '-') # max query 2 days ago
1233
1545
  request['end_date'] = self.ymd(since + 86400000, '-') # will cover 2 days
1234
- response = await self.privatePostTransactionHistory(self.extend(request, params))
1546
+ response = await self.spotPrivatePostTransactionHistory(self.extend(request, params))
1235
1547
  #
1236
1548
  # {
1237
1549
  # "result":true,
@@ -1258,16 +1570,16 @@ class lbank2(Exchange, ImplicitAPI):
1258
1570
  async def fetch_orders(self, symbol: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
1259
1571
  """
1260
1572
  fetches information on multiple orders made by the user
1573
+ see https://www.lbank.info/en-US/docs/index.html#query-all-orders
1261
1574
  :param str symbol: unified market symbol of the market orders were made in
1262
1575
  :param int [since]: the earliest time in ms to fetch orders for
1263
- :param int [limit]: the maximum number of orde structures to retrieve
1576
+ :param int [limit]: the maximum number of order structures to retrieve
1264
1577
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
1265
1578
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1266
1579
  """
1267
1580
  # default query is for canceled and completely filled orders
1268
1581
  # does not return open orders unless specified explicitly
1269
- if symbol is None:
1270
- raise ArgumentsRequired(self.id + ' fetchOrders() requires a symbol argument')
1582
+ self.check_required_symbol('fetchOrders', symbol)
1271
1583
  await self.load_markets()
1272
1584
  market = self.market(symbol)
1273
1585
  if limit is None:
@@ -1278,7 +1590,7 @@ class lbank2(Exchange, ImplicitAPI):
1278
1590
  'page_length': limit,
1279
1591
  # 'status' -1: Cancelled, 0: Unfilled, 1: Partially filled, 2: Completely filled, 3: Partially filled and cancelled, 4: Cancellation is being processed
1280
1592
  }
1281
- response = await self.privatePostSupplementOrdersInfoHistory(self.extend(request, params))
1593
+ response = await self.spotPrivatePostSupplementOrdersInfoHistory(self.extend(request, params))
1282
1594
  #
1283
1595
  # {
1284
1596
  # "result":true,
@@ -1313,14 +1625,14 @@ class lbank2(Exchange, ImplicitAPI):
1313
1625
  async def fetch_open_orders(self, symbol: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
1314
1626
  """
1315
1627
  fetch all unfilled currently open orders
1628
+ see https://www.lbank.info/en-US/docs/index.html#current-pending-order
1316
1629
  :param str symbol: unified market symbol
1317
1630
  :param int [since]: the earliest time in ms to fetch open orders for
1318
- :param int [limit]: the maximum number of open orders structures to retrieve
1631
+ :param int [limit]: the maximum number of open order structures to retrieve
1319
1632
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
1320
1633
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1321
1634
  """
1322
- if symbol is None:
1323
- raise ArgumentsRequired(self.id + ' fetchOpenOrders() requires a symbol argument')
1635
+ self.check_required_symbol('fetchOpenOrders', symbol)
1324
1636
  await self.load_markets()
1325
1637
  market = self.market(symbol)
1326
1638
  if limit is None:
@@ -1330,7 +1642,7 @@ class lbank2(Exchange, ImplicitAPI):
1330
1642
  'current_page': 1,
1331
1643
  'page_length': limit,
1332
1644
  }
1333
- response = await self.privatePostSupplementOrdersInfoNoDeal(self.extend(request, params))
1645
+ response = await self.spotPrivatePostSupplementOrdersInfoNoDeal(self.extend(request, params))
1334
1646
  #
1335
1647
  # {
1336
1648
  # "result":true,
@@ -1365,24 +1677,24 @@ class lbank2(Exchange, ImplicitAPI):
1365
1677
  async def cancel_order(self, id: str, symbol: Optional[str] = None, params={}):
1366
1678
  """
1367
1679
  cancels an open order
1680
+ see https://www.lbank.info/en-US/docs/index.html#cancel-order-new
1368
1681
  :param str id: order id
1369
1682
  :param str symbol: unified symbol of the market the order was made in
1370
1683
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
1371
1684
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1372
1685
  """
1373
- if symbol is None:
1374
- raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
1686
+ self.check_required_symbol('cancelOrder', symbol)
1375
1687
  await self.load_markets()
1376
1688
  clientOrderId = self.safe_string_2(params, 'origClientOrderId', 'clientOrderId')
1377
1689
  params = self.omit(params, ['origClientOrderId', 'clientOrderId'])
1378
1690
  market = self.market(symbol)
1379
1691
  request = {
1380
1692
  'symbol': market['id'],
1693
+ 'orderId': id,
1381
1694
  }
1382
1695
  if clientOrderId is not None:
1383
1696
  request['origClientOrderId'] = clientOrderId
1384
- request['orderId'] = id
1385
- response = await self.privatePostSupplementCancelOrder(self.extend(request, params))
1697
+ response = await self.spotPrivatePostSupplementCancelOrder(self.extend(request, params))
1386
1698
  #
1387
1699
  # {
1388
1700
  # "result":true,
@@ -1402,18 +1714,18 @@ class lbank2(Exchange, ImplicitAPI):
1402
1714
  async def cancel_all_orders(self, symbol: Optional[str] = None, params={}):
1403
1715
  """
1404
1716
  cancel all open orders in a market
1717
+ see https://www.lbank.info/en-US/docs/index.html#cancel-all-pending-orders-for-a-single-trading-pair
1405
1718
  :param str symbol: unified market symbol of the market to cancel orders in
1406
1719
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
1407
1720
  :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1408
1721
  """
1409
- if symbol is None:
1410
- raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol argument')
1722
+ self.check_required_symbol('cancelAllOrders', symbol)
1411
1723
  await self.load_markets()
1412
1724
  market = self.market(symbol)
1413
1725
  request = {
1414
1726
  'symbol': market['id'],
1415
1727
  }
1416
- response = await self.privatePostSupplementCancelOrderBySymbol(self.extend(request, params))
1728
+ response = await self.spotPrivatePostSupplementCancelOrderBySymbol(self.extend(request, params))
1417
1729
  #
1418
1730
  # {
1419
1731
  # "result":"true",
@@ -1445,6 +1757,8 @@ class lbank2(Exchange, ImplicitAPI):
1445
1757
  async def fetch_deposit_address(self, code: str, params={}):
1446
1758
  """
1447
1759
  fetch the deposit address for a currency associated with self account
1760
+ see https://www.lbank.info/en-US/docs/index.html#get-deposit-address
1761
+ see https://www.lbank.info/en-US/docs/index.html#the-user-obtains-the-deposit-address
1448
1762
  :param str code: unified currency code
1449
1763
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
1450
1764
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
@@ -1454,7 +1768,7 @@ class lbank2(Exchange, ImplicitAPI):
1454
1768
  params = self.omit(params, 'method')
1455
1769
  if method is None:
1456
1770
  options = self.safe_value(self.options, 'fetchDepositAddress', {})
1457
- method = self.safe_string(options, 'method', 'fetchPrivateTradingFees')
1771
+ method = self.safe_string(options, 'method', 'fetchDepositAddressDefault')
1458
1772
  return await getattr(self, method)(code, params)
1459
1773
 
1460
1774
  async def fetch_deposit_address_default(self, code: str, params={}):
@@ -1467,7 +1781,7 @@ class lbank2(Exchange, ImplicitAPI):
1467
1781
  if network is not None:
1468
1782
  request['netWork'] = network # ... yes, really lol
1469
1783
  params = self.omit(params, 'network')
1470
- response = await self.privatePostGetDepositAddress(self.extend(request, params))
1784
+ response = await self.spotPrivatePostGetDepositAddress(self.extend(request, params))
1471
1785
  #
1472
1786
  # {
1473
1787
  # "result":true,
@@ -1508,7 +1822,7 @@ class lbank2(Exchange, ImplicitAPI):
1508
1822
  if network is not None:
1509
1823
  request['networkName'] = network
1510
1824
  params = self.omit(params, 'network')
1511
- response = await self.privatePostSupplementGetDepositAddress(self.extend(request, params))
1825
+ response = await self.spotPrivatePostSupplementGetDepositAddress(self.extend(request, params))
1512
1826
  #
1513
1827
  # {
1514
1828
  # "result":true,
@@ -1537,6 +1851,7 @@ class lbank2(Exchange, ImplicitAPI):
1537
1851
  async def withdraw(self, code: str, amount, address, tag=None, params={}):
1538
1852
  """
1539
1853
  make a withdrawal
1854
+ see https://www.lbank.info/en-US/docs/index.html#withdrawal
1540
1855
  :param str code: unified currency code
1541
1856
  :param float amount: the amount to withdraw
1542
1857
  :param str address: the address to withdraw to
@@ -1549,8 +1864,8 @@ class lbank2(Exchange, ImplicitAPI):
1549
1864
  await self.load_markets()
1550
1865
  fee = self.safe_string(params, 'fee')
1551
1866
  params = self.omit(params, 'fee')
1552
- if fee is None:
1553
- raise ArgumentsRequired(self.id + ' withdraw() requires a fee argument to be supplied in params, the relevant coin network fee can be found by calling fetchDepositWithdrawFees(), note: if no network param is supplied then the default network will be used, self can also be found in fetchDepositWithdrawFees()')
1867
+ # The relevant coin network fee can be found by calling fetchDepositWithdrawFees(), note: if no network param is supplied then the default network will be used, self can also be found in fetchDepositWithdrawFees().
1868
+ self.check_required_argument('withdraw', fee, 'fee')
1554
1869
  currency = self.currency(code)
1555
1870
  request = {
1556
1871
  'address': address,
@@ -1572,7 +1887,7 @@ class lbank2(Exchange, ImplicitAPI):
1572
1887
  networkId = self.safe_string(networks, network, network)
1573
1888
  if networkId is not None:
1574
1889
  request['networkName'] = networkId
1575
- response = await self.privatePostSupplementWithdraw(self.extend(request, params))
1890
+ response = await self.spotPrivatePostSupplementWithdraw(self.extend(request, params))
1576
1891
  #
1577
1892
  # {
1578
1893
  # "result":true,
@@ -1693,6 +2008,7 @@ class lbank2(Exchange, ImplicitAPI):
1693
2008
  async def fetch_deposits(self, code: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
1694
2009
  """
1695
2010
  fetch all deposits made to an account
2011
+ see https://www.lbank.info/en-US/docs/index.html#get-recharge-history
1696
2012
  :param str code: unified currency code
1697
2013
  :param int [since]: the earliest time in ms to fetch deposits for
1698
2014
  :param int [limit]: the maximum number of deposits structures to retrieve
@@ -1710,7 +2026,7 @@ class lbank2(Exchange, ImplicitAPI):
1710
2026
  request['coin'] = currency['id']
1711
2027
  if since is not None:
1712
2028
  request['startTime'] = since
1713
- response = await self.privatePostSupplementDepositHistory(self.extend(request, params))
2029
+ response = await self.spotPrivatePostSupplementDepositHistory(self.extend(request, params))
1714
2030
  #
1715
2031
  # {
1716
2032
  # "result":true,
@@ -1741,6 +2057,7 @@ class lbank2(Exchange, ImplicitAPI):
1741
2057
  async def fetch_withdrawals(self, code: Optional[str] = None, since: Optional[int] = None, limit: Optional[int] = None, params={}):
1742
2058
  """
1743
2059
  fetch all withdrawals made from an account
2060
+ see https://www.lbank.info/en-US/docs/index.html#get-withdrawal-history
1744
2061
  :param str code: unified currency code
1745
2062
  :param int [since]: the earliest time in ms to fetch withdrawals for
1746
2063
  :param int [limit]: the maximum number of withdrawals structures to retrieve
@@ -1759,7 +2076,7 @@ class lbank2(Exchange, ImplicitAPI):
1759
2076
  request['coin'] = currency['id']
1760
2077
  if since is not None:
1761
2078
  request['startTime'] = since
1762
- response = await self.privatePostSupplementWithdraws(self.extend(request, params))
2079
+ response = await self.spotPrivatePostSupplementWithdraws(self.extend(request, params))
1763
2080
  #
1764
2081
  # {
1765
2082
  # "result":true,
@@ -1817,7 +2134,7 @@ class lbank2(Exchange, ImplicitAPI):
1817
2134
  # complete response
1818
2135
  # incl. for coins which None in public method
1819
2136
  await self.load_markets()
1820
- response = await self.privatePostSupplementUserInfo()
2137
+ response = await self.spotPrivatePostSupplementUserInfo()
1821
2138
  #
1822
2139
  # {
1823
2140
  # "result": "true",
@@ -1879,7 +2196,7 @@ class lbank2(Exchange, ImplicitAPI):
1879
2196
  if code is not None:
1880
2197
  currency = self.currency(code)
1881
2198
  request['assetCode'] = currency['id']
1882
- response = await self.publicGetWithdrawConfigs(self.extend(request, params))
2199
+ response = await self.spotPublicGetWithdrawConfigs(self.extend(request, params))
1883
2200
  #
1884
2201
  # {
1885
2202
  # result: 'true',
@@ -1926,6 +2243,8 @@ class lbank2(Exchange, ImplicitAPI):
1926
2243
  async def fetch_deposit_withdraw_fees(self, codes: Optional[List[str]] = None, params={}):
1927
2244
  """
1928
2245
  when using private endpoint, only returns information for currencies with non-zero balance, use public method by specifying self.options['fetchDepositWithdrawFees']['method'] = 'fetchPublicDepositWithdrawFees'
2246
+ see https://www.lbank.info/en-US/docs/index.html#get-all-coins-information
2247
+ see https://www.lbank.info/en-US/docs/index.html#withdrawal-configurations
1929
2248
  :param str[]|None codes: array of unified currency codes
1930
2249
  :param dict [params]: extra parameters specific to the lbank2 api endpoint
1931
2250
  :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -1947,7 +2266,7 @@ class lbank2(Exchange, ImplicitAPI):
1947
2266
  # complete response
1948
2267
  # incl. for coins which None in public method
1949
2268
  await self.load_markets()
1950
- response = await self.privatePostSupplementUserInfo(params)
2269
+ response = await self.spotPrivatePostSupplementUserInfo(params)
1951
2270
  #
1952
2271
  # {
1953
2272
  # "result": "true",
@@ -1986,7 +2305,7 @@ class lbank2(Exchange, ImplicitAPI):
1986
2305
  # vast majority fees None
1987
2306
  await self.load_markets()
1988
2307
  request = {}
1989
- response = await self.publicGetWithdrawConfigs(self.extend(request, params))
2308
+ response = await self.spotPublicGetWithdrawConfigs(self.extend(request, params))
1990
2309
  #
1991
2310
  # {
1992
2311
  # result: 'true',
@@ -2119,9 +2438,12 @@ class lbank2(Exchange, ImplicitAPI):
2119
2438
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2120
2439
  query = self.omit(params, self.extract_params(path))
2121
2440
  url = self.urls['api']['rest'] + '/' + self.version + '/' + self.implode_params(path, params)
2122
- # Every endpoint ends with ".do"
2123
- url += '.do'
2124
- if api == 'public':
2441
+ # Every spot endpoint ends with ".do"
2442
+ if api[0] == 'spot':
2443
+ url += '.do'
2444
+ else:
2445
+ url = self.urls['api']['contract'] + '/' + self.implode_params(path, params)
2446
+ if api[1] == 'public':
2125
2447
  if query:
2126
2448
  url += '?' + self.urlencode(self.keysort(query))
2127
2449
  else: