ccxt 4.1.54__py2.py3-none-any.whl → 4.1.56__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.
Potentially problematic release.
This version of ccxt might be problematic. Click here for more details.
- ccxt/__init__.py +2 -2
- ccxt/abstract/binance.py +1 -0
- ccxt/abstract/binancecoinm.py +1 -0
- ccxt/abstract/binanceus.py +1 -0
- ccxt/abstract/binanceusdm.py +1 -0
- ccxt/abstract/bitbank.py +1 -0
- ccxt/abstract/coinbase.py +2 -0
- ccxt/abstract/htx.py +3 -0
- ccxt/abstract/huobi.py +3 -0
- ccxt/abstract/huobipro.py +3 -0
- ccxt/abstract/okex.py +3 -1
- ccxt/abstract/okex5.py +3 -1
- ccxt/abstract/okx.py +3 -1
- ccxt/ace.py +23 -23
- ccxt/alpaca.py +8 -8
- ccxt/ascendex.py +26 -26
- ccxt/async_support/__init__.py +2 -2
- ccxt/async_support/ace.py +23 -23
- ccxt/async_support/alpaca.py +8 -8
- ccxt/async_support/ascendex.py +26 -26
- ccxt/async_support/base/exchange.py +4 -2216
- ccxt/async_support/bigone.py +21 -24
- ccxt/async_support/binance.py +61 -54
- ccxt/async_support/bingx.py +28 -28
- ccxt/async_support/bit2c.py +9 -9
- ccxt/async_support/bitbank.py +11 -10
- ccxt/async_support/bitbns.py +11 -11
- ccxt/async_support/bitfinex.py +15 -15
- ccxt/async_support/bitfinex2.py +22 -22
- ccxt/async_support/bitflyer.py +13 -13
- ccxt/async_support/bitforex.py +10 -10
- ccxt/async_support/bitget.py +44 -44
- ccxt/async_support/bithumb.py +9 -9
- ccxt/async_support/bitmart.py +85 -104
- ccxt/async_support/bitmex.py +27 -27
- ccxt/async_support/bitopro.py +18 -18
- ccxt/async_support/bitpanda.py +18 -18
- ccxt/async_support/bitrue.py +14 -14
- ccxt/async_support/bitso.py +17 -17
- ccxt/async_support/bitstamp.py +17 -17
- ccxt/async_support/bittrex.py +22 -24
- ccxt/async_support/bitvavo.py +15 -15
- ccxt/async_support/bl3p.py +4 -4
- ccxt/async_support/blockchaincom.py +17 -17
- ccxt/async_support/btcalpha.py +14 -14
- ccxt/async_support/btcbox.py +9 -9
- ccxt/async_support/btcmarkets.py +17 -17
- ccxt/async_support/btcturk.py +9 -9
- ccxt/async_support/bybit.py +46 -46
- ccxt/async_support/cex.py +10 -10
- ccxt/async_support/coinbase.py +69 -25
- ccxt/async_support/coinbasepro.py +19 -19
- ccxt/async_support/coincheck.py +10 -10
- ccxt/async_support/coinex.py +57 -66
- ccxt/async_support/coinlist.py +22 -22
- ccxt/async_support/coinmate.py +10 -10
- ccxt/async_support/coinone.py +10 -10
- ccxt/async_support/coinsph.py +17 -17
- ccxt/async_support/coinspot.py +5 -5
- ccxt/async_support/cryptocom.py +27 -27
- ccxt/async_support/currencycom.py +18 -18
- ccxt/async_support/delta.py +21 -21
- ccxt/async_support/deribit.py +24 -24
- ccxt/async_support/digifinex.py +35 -35
- ccxt/async_support/exmo.py +19 -19
- ccxt/async_support/gate.py +38 -38
- ccxt/async_support/gemini.py +11 -11
- ccxt/async_support/hitbtc.py +27 -27
- ccxt/async_support/hollaex.py +19 -19
- ccxt/async_support/htx.py +47 -44
- ccxt/async_support/huobijp.py +22 -22
- ccxt/async_support/idex.py +20 -20
- ccxt/async_support/independentreserve.py +9 -9
- ccxt/async_support/indodax.py +10 -10
- ccxt/async_support/kraken.py +25 -25
- ccxt/async_support/krakenfutures.py +17 -17
- ccxt/async_support/kucoin.py +27 -27
- ccxt/async_support/kucoinfutures.py +20 -20
- ccxt/async_support/kuna.py +19 -19
- ccxt/async_support/latoken.py +14 -14
- ccxt/async_support/lbank.py +18 -18
- ccxt/async_support/luno.py +14 -14
- ccxt/async_support/lykke.py +12 -12
- ccxt/async_support/mercado.py +11 -11
- ccxt/async_support/mexc.py +36 -36
- ccxt/async_support/ndax.py +18 -18
- ccxt/async_support/novadax.py +17 -17
- ccxt/async_support/oceanex.py +12 -12
- ccxt/async_support/okcoin.py +19 -19
- ccxt/async_support/okx.py +48 -45
- ccxt/async_support/p2b.py +6 -6
- ccxt/async_support/paymium.py +6 -6
- ccxt/async_support/phemex.py +57 -57
- ccxt/async_support/poloniex.py +31 -30
- ccxt/async_support/poloniexfutures.py +16 -16
- ccxt/async_support/probit.py +22 -22
- ccxt/async_support/tidex.py +15 -15
- ccxt/async_support/timex.py +20 -20
- ccxt/async_support/tokocrypto.py +16 -16
- ccxt/async_support/upbit.py +15 -15
- ccxt/async_support/wavesexchange.py +12 -12
- ccxt/async_support/wazirx.py +13 -13
- ccxt/async_support/whitebit.py +26 -26
- ccxt/async_support/woo.py +47 -47
- ccxt/async_support/yobit.py +8 -8
- ccxt/async_support/zaif.py +10 -10
- ccxt/async_support/zonda.py +16 -16
- ccxt/base/errors.py +17 -16
- ccxt/base/exchange.py +57 -97
- ccxt/base/types.py +138 -139
- ccxt/bigone.py +21 -24
- ccxt/binance.py +61 -54
- ccxt/bingx.py +28 -28
- ccxt/bit2c.py +9 -9
- ccxt/bitbank.py +11 -10
- ccxt/bitbns.py +11 -11
- ccxt/bitfinex.py +15 -15
- ccxt/bitfinex2.py +22 -22
- ccxt/bitflyer.py +13 -13
- ccxt/bitforex.py +10 -10
- ccxt/bitget.py +44 -44
- ccxt/bithumb.py +9 -9
- ccxt/bitmart.py +85 -104
- ccxt/bitmex.py +27 -27
- ccxt/bitopro.py +18 -18
- ccxt/bitpanda.py +18 -18
- ccxt/bitrue.py +14 -14
- ccxt/bitso.py +17 -17
- ccxt/bitstamp.py +17 -17
- ccxt/bittrex.py +22 -24
- ccxt/bitvavo.py +15 -15
- ccxt/bl3p.py +4 -4
- ccxt/blockchaincom.py +17 -17
- ccxt/btcalpha.py +14 -14
- ccxt/btcbox.py +9 -9
- ccxt/btcmarkets.py +17 -17
- ccxt/btcturk.py +9 -9
- ccxt/bybit.py +46 -46
- ccxt/cex.py +10 -10
- ccxt/coinbase.py +69 -25
- ccxt/coinbasepro.py +19 -19
- ccxt/coincheck.py +10 -10
- ccxt/coinex.py +57 -66
- ccxt/coinlist.py +22 -22
- ccxt/coinmate.py +10 -10
- ccxt/coinone.py +10 -10
- ccxt/coinsph.py +17 -17
- ccxt/coinspot.py +5 -5
- ccxt/cryptocom.py +27 -27
- ccxt/currencycom.py +18 -18
- ccxt/delta.py +21 -21
- ccxt/deribit.py +24 -24
- ccxt/digifinex.py +35 -35
- ccxt/exmo.py +19 -19
- ccxt/gate.py +38 -38
- ccxt/gemini.py +11 -11
- ccxt/hitbtc.py +27 -27
- ccxt/hollaex.py +19 -19
- ccxt/htx.py +47 -44
- ccxt/huobijp.py +22 -22
- ccxt/idex.py +20 -20
- ccxt/independentreserve.py +9 -9
- ccxt/indodax.py +10 -10
- ccxt/kraken.py +25 -25
- ccxt/krakenfutures.py +17 -17
- ccxt/kucoin.py +27 -27
- ccxt/kucoinfutures.py +20 -20
- ccxt/kuna.py +19 -19
- ccxt/latoken.py +14 -14
- ccxt/lbank.py +18 -18
- ccxt/luno.py +14 -14
- ccxt/lykke.py +12 -12
- ccxt/mercado.py +11 -11
- ccxt/mexc.py +36 -36
- ccxt/ndax.py +18 -18
- ccxt/novadax.py +17 -17
- ccxt/oceanex.py +12 -12
- ccxt/okcoin.py +19 -19
- ccxt/okx.py +48 -45
- ccxt/p2b.py +6 -6
- ccxt/paymium.py +6 -6
- ccxt/phemex.py +57 -57
- ccxt/poloniex.py +31 -30
- ccxt/poloniexfutures.py +16 -16
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/alpaca.py +3 -3
- ccxt/pro/ascendex.py +2 -2
- ccxt/pro/binance.py +9 -9
- ccxt/pro/bingx.py +3 -3
- ccxt/pro/bitfinex.py +3 -3
- ccxt/pro/bitfinex2.py +3 -3
- ccxt/pro/bitget.py +3 -3
- ccxt/pro/bitmart.py +2 -2
- ccxt/pro/bitmex.py +3 -3
- ccxt/pro/bitpanda.py +3 -3
- ccxt/pro/bitrue.py +2 -2
- ccxt/pro/bitstamp.py +2 -2
- ccxt/pro/bittrex.py +3 -3
- ccxt/pro/bitvavo.py +3 -3
- ccxt/pro/blockchaincom.py +2 -2
- ccxt/pro/bybit.py +4 -4
- ccxt/pro/cex.py +3 -3
- ccxt/pro/coinbasepro.py +3 -3
- ccxt/pro/coinex.py +2 -2
- ccxt/pro/cryptocom.py +5 -5
- ccxt/pro/deribit.py +3 -3
- ccxt/pro/exmo.py +2 -2
- ccxt/pro/gate.py +3 -3
- ccxt/pro/gemini.py +2 -2
- ccxt/pro/hitbtc.py +4 -4
- ccxt/pro/hollaex.py +3 -3
- ccxt/pro/htx.py +3 -3
- ccxt/pro/idex.py +3 -3
- ccxt/pro/kraken.py +7 -7
- ccxt/pro/krakenfutures.py +4 -4
- ccxt/pro/kucoin.py +3 -3
- ccxt/pro/kucoinfutures.py +3 -3
- ccxt/pro/mexc.py +3 -3
- ccxt/pro/okcoin.py +2 -2
- ccxt/pro/okx.py +6 -6
- ccxt/pro/phemex.py +3 -3
- ccxt/pro/poloniex.py +3 -3
- ccxt/pro/poloniexfutures.py +3 -3
- ccxt/pro/probit.py +3 -3
- ccxt/pro/wazirx.py +3 -3
- ccxt/pro/whitebit.py +3 -3
- ccxt/pro/woo.py +2 -2
- ccxt/probit.py +22 -22
- ccxt/test/base/test_shared_methods.py +3 -3
- ccxt/test/test_async.py +543 -535
- ccxt/test/test_sync.py +542 -534
- ccxt/tidex.py +15 -15
- ccxt/timex.py +20 -20
- ccxt/tokocrypto.py +16 -16
- ccxt/upbit.py +15 -15
- ccxt/wavesexchange.py +12 -12
- ccxt/wazirx.py +13 -13
- ccxt/whitebit.py +26 -26
- ccxt/woo.py +47 -47
- ccxt/yobit.py +8 -8
- ccxt/zaif.py +10 -10
- ccxt/zonda.py +16 -16
- {ccxt-4.1.54.dist-info → ccxt-4.1.56.dist-info}/METADATA +10 -8
- ccxt-4.1.56.dist-info/RECORD +449 -0
- ccxt/async_support/bitstamp1.py +0 -402
- ccxt/async_support/lbank2.py +0 -2620
- ccxt/bitstamp1.py +0 -402
- ccxt/lbank2.py +0 -2619
- ccxt-4.1.54.dist-info/RECORD +0 -453
- {ccxt-4.1.54.dist-info → ccxt-4.1.56.dist-info}/WHEEL +0 -0
- {ccxt-4.1.54.dist-info → ccxt-4.1.56.dist-info}/top_level.txt +0 -0
ccxt/async_support/lbank2.py
DELETED
@@ -1,2620 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
|
3
|
-
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
4
|
-
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
5
|
-
|
6
|
-
from ccxt.async_support.base.exchange import Exchange
|
7
|
-
from ccxt.abstract.lbank2 import ImplicitAPI
|
8
|
-
import asyncio
|
9
|
-
import hashlib
|
10
|
-
from ccxt.base.types import Balances, Int, Order, OrderBook, OrderSide, OrderType, String, Ticker, Tickers, Trade, Transaction
|
11
|
-
from typing import List
|
12
|
-
from ccxt.base.errors import ExchangeError
|
13
|
-
from ccxt.base.errors import PermissionDenied
|
14
|
-
from ccxt.base.errors import BadRequest
|
15
|
-
from ccxt.base.errors import BadSymbol
|
16
|
-
from ccxt.base.errors import InsufficientFunds
|
17
|
-
from ccxt.base.errors import InvalidAddress
|
18
|
-
from ccxt.base.errors import InvalidOrder
|
19
|
-
from ccxt.base.errors import DuplicateOrderId
|
20
|
-
from ccxt.base.errors import RateLimitExceeded
|
21
|
-
from ccxt.base.errors import InvalidNonce
|
22
|
-
from ccxt.base.errors import AuthenticationError
|
23
|
-
from ccxt.base.decimal_to_precision import TICK_SIZE
|
24
|
-
from ccxt.base.precise import Precise
|
25
|
-
|
26
|
-
|
27
|
-
class lbank2(Exchange, ImplicitAPI):
|
28
|
-
|
29
|
-
def describe(self):
|
30
|
-
return self.deep_extend(super(lbank2, self).describe(), {
|
31
|
-
'id': 'lbank2',
|
32
|
-
'name': 'LBank',
|
33
|
-
'countries': ['CN'],
|
34
|
-
'version': 'v2',
|
35
|
-
# 50 per second for making and cancelling orders 1000ms / 50 = 20
|
36
|
-
# 20 per second for all other requests, cost = 50 / 20 = 2.5
|
37
|
-
'rateLimit': 20,
|
38
|
-
'has': {
|
39
|
-
'CORS': False,
|
40
|
-
'spot': True,
|
41
|
-
'margin': False,
|
42
|
-
'swap': None,
|
43
|
-
'future': False,
|
44
|
-
'option': False,
|
45
|
-
'addMargin': False,
|
46
|
-
'cancelAllOrders': True,
|
47
|
-
'cancelOrder': True,
|
48
|
-
'createOrder': True,
|
49
|
-
'createReduceOnlyOrder': False,
|
50
|
-
'createStopLimitOrder': False,
|
51
|
-
'createStopMarketOrder': False,
|
52
|
-
'createStopOrder': False,
|
53
|
-
'fetchBalance': True,
|
54
|
-
'fetchBorrowRate': False,
|
55
|
-
'fetchBorrowRateHistories': False,
|
56
|
-
'fetchBorrowRateHistory': False,
|
57
|
-
'fetchBorrowRates': False,
|
58
|
-
'fetchBorrowRatesPerSymbol': False,
|
59
|
-
'fetchClosedOrders': False,
|
60
|
-
'fetchDepositWithdrawFee': 'emulated',
|
61
|
-
'fetchDepositWithdrawFees': True,
|
62
|
-
'fetchFundingHistory': False,
|
63
|
-
'fetchFundingRate': False,
|
64
|
-
'fetchFundingRateHistory': False,
|
65
|
-
'fetchFundingRates': False,
|
66
|
-
'fetchIndexOHLCV': False,
|
67
|
-
'fetchIsolatedPositions': False,
|
68
|
-
'fetchLeverage': False,
|
69
|
-
'fetchLeverageTiers': False,
|
70
|
-
'fetchMarginMode': False,
|
71
|
-
'fetchMarkets': True,
|
72
|
-
'fetchMarkOHLCV': False,
|
73
|
-
'fetchMyTrades': True,
|
74
|
-
'fetchOHLCV': True,
|
75
|
-
'fetchOpenOrders': True,
|
76
|
-
'fetchOrder': True,
|
77
|
-
'fetchOrderBook': True,
|
78
|
-
'fetchOrders': True,
|
79
|
-
'fetchPosition': False,
|
80
|
-
'fetchPositionMode': False,
|
81
|
-
'fetchPositions': False,
|
82
|
-
'fetchPositionsRisk': False,
|
83
|
-
'fetchPremiumIndexOHLCV': False,
|
84
|
-
'fetchTicker': True,
|
85
|
-
'fetchTickers': True,
|
86
|
-
'fetchTime': True,
|
87
|
-
'fetchTrades': True,
|
88
|
-
'fetchTradingFees': True,
|
89
|
-
'fetchTransactionFees': True,
|
90
|
-
'reduceMargin': False,
|
91
|
-
'setLeverage': False,
|
92
|
-
'setMarginMode': False,
|
93
|
-
'setPositionMode': False,
|
94
|
-
'withdraw': True,
|
95
|
-
},
|
96
|
-
'timeframes': {
|
97
|
-
'1m': 'minute1',
|
98
|
-
'5m': 'minute5',
|
99
|
-
'15m': 'minute15',
|
100
|
-
'30m': 'minute30',
|
101
|
-
'1h': 'hour1',
|
102
|
-
'2h': 'hour2',
|
103
|
-
'4h': 'hour4',
|
104
|
-
'6h': 'hour6',
|
105
|
-
'8h': 'hour8',
|
106
|
-
'12h': 'hour12',
|
107
|
-
'1d': 'day1',
|
108
|
-
'1w': 'week1',
|
109
|
-
},
|
110
|
-
'urls': {
|
111
|
-
'logo': 'https://user-images.githubusercontent.com/1294454/38063602-9605e28a-3302-11e8-81be-64b1e53c4cfb.jpg',
|
112
|
-
'api': {
|
113
|
-
'rest': 'https://api.lbank.info',
|
114
|
-
'contract': 'https://lbkperp.lbank.com',
|
115
|
-
},
|
116
|
-
'api2': 'https://api.lbkex.com',
|
117
|
-
'www': 'https://www.lbank.info',
|
118
|
-
'doc': 'https://www.lbank.info/en-US/docs/index.html',
|
119
|
-
'fees': 'https://lbankinfo.zendesk.com/hc/en-gb/articles/360012072873-Trading-Fees',
|
120
|
-
'referral': 'https://www.lbank.info/invitevip?icode=7QCY',
|
121
|
-
},
|
122
|
-
'api': {
|
123
|
-
'spot': {
|
124
|
-
'public': {
|
125
|
-
'get': {
|
126
|
-
'currencyPairs': 2.5,
|
127
|
-
'accuracy': 2.5,
|
128
|
-
'usdToCny': 2.5,
|
129
|
-
'withdrawConfigs': 2.5,
|
130
|
-
'timestamp': 2.5,
|
131
|
-
'ticker/24hr': 2.5,
|
132
|
-
'ticker': 2.5,
|
133
|
-
'depth': 2.5,
|
134
|
-
'incrDepth': 2.5,
|
135
|
-
'trades': 2.5,
|
136
|
-
'kline': 2.5,
|
137
|
-
# new quote endpoints
|
138
|
-
'supplement/system_ping': 2.5,
|
139
|
-
'supplement/incrDepth': 2.5,
|
140
|
-
'supplement/trades': 2.5,
|
141
|
-
'supplement/ticker/price': 2.5,
|
142
|
-
'supplement/ticker/bookTicker': 2.5,
|
143
|
-
},
|
144
|
-
'post': {
|
145
|
-
'supplement/system_status': 2.5,
|
146
|
-
},
|
147
|
-
},
|
148
|
-
'private': {
|
149
|
-
'post': {
|
150
|
-
# account
|
151
|
-
'user_info': 2.5,
|
152
|
-
'subscribe/get_key': 2.5,
|
153
|
-
'subscribe/refresh_key': 2.5,
|
154
|
-
'subscribe/destroy_key': 2.5,
|
155
|
-
'get_deposit_address': 2.5,
|
156
|
-
'deposit_history': 2.5,
|
157
|
-
# order
|
158
|
-
'create_order': 1,
|
159
|
-
'batch_create_order': 1,
|
160
|
-
'cancel_order': 1,
|
161
|
-
'cancel_clientOrders': 1,
|
162
|
-
'orders_info': 2.5,
|
163
|
-
'orders_info_history': 2.5,
|
164
|
-
'order_transaction_detail': 2.5,
|
165
|
-
'transaction_history': 2.5,
|
166
|
-
'orders_info_no_deal': 2.5,
|
167
|
-
# withdraw
|
168
|
-
'withdraw': 2.5,
|
169
|
-
'withdrawCancel': 2.5,
|
170
|
-
'withdraws': 2.5,
|
171
|
-
'supplement/user_info': 2.5,
|
172
|
-
'supplement/withdraw': 2.5,
|
173
|
-
'supplement/deposit_history': 2.5,
|
174
|
-
'supplement/withdraws': 2.5,
|
175
|
-
'supplement/get_deposit_address': 2.5,
|
176
|
-
'supplement/asset_detail': 2.5,
|
177
|
-
'supplement/customer_trade_fee': 2.5,
|
178
|
-
'supplement/api_Restrictions': 2.5,
|
179
|
-
# new quote endpoints
|
180
|
-
'supplement/system_ping': 2.5,
|
181
|
-
# new order endpoints
|
182
|
-
'supplement/create_order_test': 1,
|
183
|
-
'supplement/create_order': 1,
|
184
|
-
'supplement/cancel_order': 1,
|
185
|
-
'supplement/cancel_order_by_symbol': 1,
|
186
|
-
'supplement/orders_info': 2.5,
|
187
|
-
'supplement/orders_info_no_deal': 2.5,
|
188
|
-
'supplement/orders_info_history': 2.5,
|
189
|
-
'supplement/user_info_account': 2.5,
|
190
|
-
'supplement/transaction_history': 2.5,
|
191
|
-
},
|
192
|
-
},
|
193
|
-
},
|
194
|
-
'contract': {
|
195
|
-
'public': {
|
196
|
-
'get': {
|
197
|
-
'cfd/openApi/v1/pub/getTime': 2.5,
|
198
|
-
'cfd/openApi/v1/pub/instrument': 2.5,
|
199
|
-
'cfd/openApi/v1/pub/marketData': 2.5,
|
200
|
-
'cfd/openApi/v1/pub/marketOrder': 2.5,
|
201
|
-
},
|
202
|
-
},
|
203
|
-
},
|
204
|
-
},
|
205
|
-
'fees': {
|
206
|
-
'trading': {
|
207
|
-
'maker': self.parse_number('0.001'),
|
208
|
-
'taker': self.parse_number('0.001'),
|
209
|
-
},
|
210
|
-
'funding': {
|
211
|
-
'withdraw': {},
|
212
|
-
},
|
213
|
-
},
|
214
|
-
'commonCurrencies': {
|
215
|
-
'VET_ERC20': 'VEN',
|
216
|
-
'PNT': 'Penta',
|
217
|
-
},
|
218
|
-
'precisionMode': TICK_SIZE,
|
219
|
-
'options': {
|
220
|
-
'cacheSecretAsPem': True,
|
221
|
-
'createMarketBuyOrderRequiresPrice': True,
|
222
|
-
'fetchTrades': {
|
223
|
-
'method': 'spotPublicGetTrades', # or 'spotPublicGetTradesSupplement'
|
224
|
-
},
|
225
|
-
'fetchTransactionFees': { # DEPRECATED, please use fetchDepositWithdrawFees
|
226
|
-
'method': 'fetchPrivateTransactionFees', # or 'fetchPublicTransactionFees'
|
227
|
-
},
|
228
|
-
'fetchDepositWithdrawFees': {
|
229
|
-
'method': 'fetchPrivateDepositWithdrawFees', # or 'fetchPublicDepositWithdrawFees'
|
230
|
-
},
|
231
|
-
'fetchDepositAddress': {
|
232
|
-
'method': 'fetchDepositAddressDefault', # or fetchDepositAddressSupplement
|
233
|
-
},
|
234
|
-
'createOrder': {
|
235
|
-
'method': 'spotPrivatePostSupplementCreateOrder', # or spotPrivatePostCreateOrder
|
236
|
-
},
|
237
|
-
'fetchOrder': {
|
238
|
-
'method': 'fetchOrderSupplement', # or fetchOrderDefault
|
239
|
-
},
|
240
|
-
'fetchBalance': {
|
241
|
-
'method': 'spotPrivatePostSupplementUserInfo', # or spotPrivatePostSupplementUserInfoAccount or spotPrivatePostUserInfo
|
242
|
-
},
|
243
|
-
'networks': {
|
244
|
-
'ERC20': 'erc20',
|
245
|
-
'ETH': 'erc20',
|
246
|
-
'TRC20': 'trc20',
|
247
|
-
'TRX': 'trc20',
|
248
|
-
'OMNI': 'omni',
|
249
|
-
'ASA': 'asa',
|
250
|
-
'BEP20': 'bep20(bsc)',
|
251
|
-
'BSC': 'bep20(bsc)',
|
252
|
-
'HT': 'heco',
|
253
|
-
'BNB': 'bep2',
|
254
|
-
'BTC': 'btc',
|
255
|
-
'DOGE': 'dogecoin',
|
256
|
-
'MATIC': 'matic',
|
257
|
-
'POLYGON': 'matic',
|
258
|
-
'OEC': 'oec',
|
259
|
-
'BTCTRON': 'btctron',
|
260
|
-
'XRP': 'xrp',
|
261
|
-
# other unusual chains with number of listed currencies supported
|
262
|
-
# 'avax c-chain': 1,
|
263
|
-
# klay: 12,
|
264
|
-
# bta: 1,
|
265
|
-
# fantom: 1,
|
266
|
-
# celo: 1,
|
267
|
-
# sol: 2,
|
268
|
-
# zenith: 1,
|
269
|
-
# ftm: 5,
|
270
|
-
# bep20: 1,(single token with mis-named chain) SSS
|
271
|
-
# bitci: 1,
|
272
|
-
# sgb: 1,
|
273
|
-
# moonbeam: 1,
|
274
|
-
# ekta: 1,
|
275
|
-
# etl: 1,
|
276
|
-
# arbitrum: 1,
|
277
|
-
# tpc: 1,
|
278
|
-
# ptx: 1
|
279
|
-
# }
|
280
|
-
},
|
281
|
-
'inverse-networks': {
|
282
|
-
'erc20': 'ERC20',
|
283
|
-
'trc20': 'TRC20',
|
284
|
-
'omni': 'OMNI',
|
285
|
-
'asa': 'ASA',
|
286
|
-
'bep20(bsc)': 'BSC',
|
287
|
-
'bep20': 'BSC',
|
288
|
-
'heco': 'HT',
|
289
|
-
'bep2': 'BNB',
|
290
|
-
'btc': 'BTC',
|
291
|
-
'dogecoin': 'DOGE',
|
292
|
-
'matic': 'MATIC',
|
293
|
-
'oec': 'OEC',
|
294
|
-
'btctron': 'BTCTRON',
|
295
|
-
'xrp': 'XRP',
|
296
|
-
},
|
297
|
-
'defaultNetworks': {
|
298
|
-
'USDT': 'TRC20',
|
299
|
-
},
|
300
|
-
},
|
301
|
-
})
|
302
|
-
|
303
|
-
async def fetch_time(self, params={}):
|
304
|
-
"""
|
305
|
-
fetches the current integer timestamp in milliseconds from the exchange server
|
306
|
-
:see: https://www.lbank.info/en-US/docs/index.html#get-timestamp
|
307
|
-
:see: https://www.lbank.com/en-US/docs/contract.html#get-the-current-time
|
308
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
309
|
-
:returns int: the current integer timestamp in milliseconds from the exchange server
|
310
|
-
"""
|
311
|
-
type = None
|
312
|
-
type, params = self.handle_market_type_and_params('fetchTime', None, params)
|
313
|
-
response = None
|
314
|
-
if type == 'swap':
|
315
|
-
response = await self.contractPublicGetCfdOpenApiV1PubGetTime(params)
|
316
|
-
else:
|
317
|
-
response = await self.spotPublicGetTimestamp(params)
|
318
|
-
#
|
319
|
-
# spot
|
320
|
-
#
|
321
|
-
# {
|
322
|
-
# "result": "true",
|
323
|
-
# "data": 1691789627950,
|
324
|
-
# "error_code": 0,
|
325
|
-
# "ts": 1691789627950
|
326
|
-
# }
|
327
|
-
#
|
328
|
-
# swap
|
329
|
-
#
|
330
|
-
# {
|
331
|
-
# "data": 1691789627950,
|
332
|
-
# "error_code": 0,
|
333
|
-
# "msg": "Success",
|
334
|
-
# "result": "true",
|
335
|
-
# "success": True
|
336
|
-
# }
|
337
|
-
#
|
338
|
-
return self.safe_integer(response, 'data')
|
339
|
-
|
340
|
-
async def fetch_markets(self, params={}):
|
341
|
-
"""
|
342
|
-
retrieves data on all markets for lbank2
|
343
|
-
:see: https://www.lbank.com/en-US/docs/index.html#trading-pairs
|
344
|
-
:see: https://www.lbank.com/en-US/docs/contract.html#query-contract-information-list
|
345
|
-
:param dict [params]: extra parameters specific to the exchange api endpoint
|
346
|
-
:returns dict[]: an array of objects representing market data
|
347
|
-
"""
|
348
|
-
marketsPromises = [
|
349
|
-
self.fetch_spot_markets(params),
|
350
|
-
self.fetch_swap_markets(params),
|
351
|
-
]
|
352
|
-
resolvedMarkets = await asyncio.gather(*marketsPromises)
|
353
|
-
return self.array_concat(resolvedMarkets[0], resolvedMarkets[1])
|
354
|
-
|
355
|
-
async def fetch_spot_markets(self, params={}):
|
356
|
-
response = await self.spotPublicGetAccuracy(params)
|
357
|
-
#
|
358
|
-
# {
|
359
|
-
# "result": "true",
|
360
|
-
# "data": [
|
361
|
-
# {
|
362
|
-
# "symbol": "btc_usdt",
|
363
|
-
# "quantityAccuracy": "4",
|
364
|
-
# "minTranQua": "0.0001",
|
365
|
-
# "priceAccuracy": "2"
|
366
|
-
# },
|
367
|
-
# ],
|
368
|
-
# "error_code": 0,
|
369
|
-
# "ts": 1691560288484
|
370
|
-
# }
|
371
|
-
#
|
372
|
-
data = self.safe_value(response, 'data', [])
|
373
|
-
result = []
|
374
|
-
for i in range(0, len(data)):
|
375
|
-
market = data[i]
|
376
|
-
marketId = self.safe_string(market, 'symbol')
|
377
|
-
parts = marketId.split('_')
|
378
|
-
baseId = parts[0]
|
379
|
-
quoteId = parts[1]
|
380
|
-
base = self.safe_currency_code(baseId)
|
381
|
-
quote = self.safe_currency_code(quoteId)
|
382
|
-
symbol = base + '/' + quote
|
383
|
-
result.append({
|
384
|
-
'id': marketId,
|
385
|
-
'symbol': symbol,
|
386
|
-
'base': base,
|
387
|
-
'quote': quote,
|
388
|
-
'settle': None,
|
389
|
-
'baseId': baseId,
|
390
|
-
'quoteId': quoteId,
|
391
|
-
'settleId': None,
|
392
|
-
'type': 'spot',
|
393
|
-
'spot': True,
|
394
|
-
'margin': False,
|
395
|
-
'swap': False,
|
396
|
-
'future': False,
|
397
|
-
'option': False,
|
398
|
-
'active': True,
|
399
|
-
'contract': None,
|
400
|
-
'linear': None,
|
401
|
-
'inverse': None,
|
402
|
-
'contractSize': None,
|
403
|
-
'expiry': None,
|
404
|
-
'expiryDatetime': None,
|
405
|
-
'strike': None,
|
406
|
-
'optionType': None,
|
407
|
-
'precision': {
|
408
|
-
'amount': self.parse_number(self.parse_precision(self.safe_string(market, 'quantityAccuracy'))),
|
409
|
-
'price': self.parse_number(self.parse_precision(self.safe_string(market, 'priceAccuracy'))),
|
410
|
-
},
|
411
|
-
'limits': {
|
412
|
-
'leverage': {
|
413
|
-
'min': None,
|
414
|
-
'max': None,
|
415
|
-
},
|
416
|
-
'amount': {
|
417
|
-
'min': self.safe_number(market, 'minTranQua'),
|
418
|
-
'max': None,
|
419
|
-
},
|
420
|
-
'price': {
|
421
|
-
'min': None,
|
422
|
-
'max': None,
|
423
|
-
},
|
424
|
-
'cost': {
|
425
|
-
'min': None,
|
426
|
-
'max': None,
|
427
|
-
},
|
428
|
-
},
|
429
|
-
'created': None,
|
430
|
-
'info': market,
|
431
|
-
})
|
432
|
-
return result
|
433
|
-
|
434
|
-
async def fetch_swap_markets(self, params={}):
|
435
|
-
request = {
|
436
|
-
'productGroup': 'SwapU',
|
437
|
-
}
|
438
|
-
response = await self.contractPublicGetCfdOpenApiV1PubInstrument(self.extend(request, params))
|
439
|
-
#
|
440
|
-
# {
|
441
|
-
# "data": [
|
442
|
-
# {
|
443
|
-
# "priceLimitUpperValue": 0.2,
|
444
|
-
# "symbol": "BTCUSDT",
|
445
|
-
# "volumeTick": 0.0001,
|
446
|
-
# "indexPrice": "29707.70200000",
|
447
|
-
# "minOrderVolume": "0.0001",
|
448
|
-
# "priceTick": 0.1,
|
449
|
-
# "maxOrderVolume": "30.0",
|
450
|
-
# "baseCurrency": "BTC",
|
451
|
-
# "volumeMultiple": 1.0,
|
452
|
-
# "exchangeID": "Exchange",
|
453
|
-
# "priceCurrency": "USDT",
|
454
|
-
# "priceLimitLowerValue": 0.2,
|
455
|
-
# "clearCurrency": "USDT",
|
456
|
-
# "symbolName": "BTCUSDT",
|
457
|
-
# "defaultLeverage": 20.0,
|
458
|
-
# "minOrderCost": "5.0"
|
459
|
-
# },
|
460
|
-
# ],
|
461
|
-
# "error_code": 0,
|
462
|
-
# "msg": "Success",
|
463
|
-
# "result": "true",
|
464
|
-
# "success": True
|
465
|
-
# }
|
466
|
-
#
|
467
|
-
data = self.safe_value(response, 'data', [])
|
468
|
-
result = []
|
469
|
-
for i in range(0, len(data)):
|
470
|
-
market = data[i]
|
471
|
-
marketId = self.safe_string(market, 'symbol')
|
472
|
-
baseId = self.safe_string(market, 'baseCurrency')
|
473
|
-
settleId = self.safe_string(market, 'clearCurrency')
|
474
|
-
quoteId = settleId
|
475
|
-
base = self.safe_currency_code(baseId)
|
476
|
-
quote = self.safe_currency_code(quoteId)
|
477
|
-
settle = self.safe_currency_code(settleId)
|
478
|
-
symbol = base + '/' + quote + ':' + settle
|
479
|
-
result.append({
|
480
|
-
'id': marketId,
|
481
|
-
'symbol': symbol,
|
482
|
-
'base': base,
|
483
|
-
'quote': quote,
|
484
|
-
'settle': settle,
|
485
|
-
'baseId': baseId,
|
486
|
-
'quoteId': quoteId,
|
487
|
-
'settleId': settleId,
|
488
|
-
'type': 'swap',
|
489
|
-
'spot': False,
|
490
|
-
'margin': False,
|
491
|
-
'swap': True,
|
492
|
-
'future': False,
|
493
|
-
'option': False,
|
494
|
-
'active': True,
|
495
|
-
'contract': True,
|
496
|
-
'linear': True,
|
497
|
-
'inverse': None,
|
498
|
-
'contractSize': self.safe_number(market, 'volumeMultiple'),
|
499
|
-
'expiry': None,
|
500
|
-
'expiryDatetime': None,
|
501
|
-
'strike': None,
|
502
|
-
'optionType': None,
|
503
|
-
'precision': {
|
504
|
-
'amount': self.safe_number(market, 'volumeTick'),
|
505
|
-
'price': self.safe_number(market, 'priceTick'),
|
506
|
-
},
|
507
|
-
'limits': {
|
508
|
-
'leverage': {
|
509
|
-
'min': None,
|
510
|
-
'max': None,
|
511
|
-
},
|
512
|
-
'amount': {
|
513
|
-
'min': self.safe_number(market, 'minOrderVolume'),
|
514
|
-
'max': self.safe_number(market, 'maxOrderVolume'),
|
515
|
-
},
|
516
|
-
'price': {
|
517
|
-
'min': self.safe_number(market, 'priceLimitLowerValue'),
|
518
|
-
'max': self.safe_number(market, 'priceLimitUpperValue'),
|
519
|
-
},
|
520
|
-
'cost': {
|
521
|
-
'min': self.safe_number(market, 'minOrderCost'),
|
522
|
-
'max': None,
|
523
|
-
},
|
524
|
-
},
|
525
|
-
'created': None,
|
526
|
-
'info': market,
|
527
|
-
})
|
528
|
-
return result
|
529
|
-
|
530
|
-
def parse_ticker(self, ticker, market=None) -> Ticker:
|
531
|
-
#
|
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
|
-
# }
|
560
|
-
#
|
561
|
-
timestamp = self.safe_integer(ticker, 'timestamp')
|
562
|
-
marketId = self.safe_string(ticker, 'symbol')
|
563
|
-
symbol = self.safe_symbol(marketId, market)
|
564
|
-
tickerData = self.safe_value(ticker, 'ticker', {})
|
565
|
-
market = self.safe_market(marketId, market)
|
566
|
-
data = ticker if (market['contract']) else tickerData
|
567
|
-
return self.safe_ticker({
|
568
|
-
'symbol': symbol,
|
569
|
-
'timestamp': timestamp,
|
570
|
-
'datetime': self.iso8601(timestamp),
|
571
|
-
'high': self.safe_string_2(data, 'high', 'highestPrice'),
|
572
|
-
'low': self.safe_string_2(data, 'low', 'lowestPrice'),
|
573
|
-
'bid': None,
|
574
|
-
'bidVolume': None,
|
575
|
-
'ask': None,
|
576
|
-
'askVolume': None,
|
577
|
-
'vwap': None,
|
578
|
-
'open': self.safe_string(data, 'openPrice'),
|
579
|
-
'close': None,
|
580
|
-
'last': self.safe_string_2(data, 'latest', 'lastPrice'),
|
581
|
-
'previousClose': None,
|
582
|
-
'change': None,
|
583
|
-
'percentage': self.safe_string(data, 'change'),
|
584
|
-
'average': None,
|
585
|
-
'baseVolume': self.safe_string_2(data, 'vol', 'volume'),
|
586
|
-
'quoteVolume': self.safe_string(data, 'turnover'),
|
587
|
-
'info': ticker,
|
588
|
-
}, market)
|
589
|
-
|
590
|
-
async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
591
|
-
"""
|
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
|
594
|
-
:param str symbol: unified symbol of the market to fetch the ticker for
|
595
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
596
|
-
:returns dict: a `ticker structure <https://github.com/ccxt/ccxt/wiki/Manual#ticker-structure>`
|
597
|
-
"""
|
598
|
-
await self.load_markets()
|
599
|
-
market = self.market(symbol)
|
600
|
-
if market['swap']:
|
601
|
-
responseForSwap = await self.fetch_tickers([market['symbol']], params)
|
602
|
-
return self.safe_value(responseForSwap, market['symbol'])
|
603
|
-
request = {
|
604
|
-
'symbol': market['id'],
|
605
|
-
}
|
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
|
-
# }
|
627
|
-
#
|
628
|
-
data = self.safe_value(response, 'data', [])
|
629
|
-
first = self.safe_value(data, 0, {})
|
630
|
-
return self.parse_ticker(first, market)
|
631
|
-
|
632
|
-
async def fetch_tickers(self, symbols: List[str] = None, params={}) -> Tickers:
|
633
|
-
"""
|
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
|
637
|
-
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
638
|
-
:param dict [params]: extra parameters specific to the lbank api endpoint
|
639
|
-
:returns dict: a dictionary of `ticker structures <https://github.com/ccxt/ccxt/wiki/Manual#ticker-structure>`
|
640
|
-
"""
|
641
|
-
await self.load_markets()
|
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
|
-
#
|
703
|
-
data = self.safe_value(response, 'data', [])
|
704
|
-
return self.parse_tickers(data, symbols)
|
705
|
-
|
706
|
-
async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
707
|
-
"""
|
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
|
711
|
-
:param str symbol: unified symbol of the market to fetch the order book for
|
712
|
-
:param int [limit]: the maximum amount of order book entries to return
|
713
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
714
|
-
:returns dict: A dictionary of `order book structures <https://github.com/ccxt/ccxt/wiki/Manual#order-book-structure>` indexed by market symbols
|
715
|
-
"""
|
716
|
-
await self.load_markets()
|
717
|
-
market = self.market(symbol)
|
718
|
-
if limit is None:
|
719
|
-
limit = 60
|
720
|
-
request = {
|
721
|
-
'symbol': market['id'],
|
722
|
-
}
|
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', {})
|
781
|
-
timestamp = self.milliseconds()
|
782
|
-
if market['swap']:
|
783
|
-
return self.parse_order_book(orderbook, market['symbol'], timestamp, 'bids', 'asks', 'price', 'volume')
|
784
|
-
return self.parse_order_book(orderbook, market['symbol'], timestamp)
|
785
|
-
|
786
|
-
def parse_trade(self, trade, market=None) -> Trade:
|
787
|
-
#
|
788
|
-
# fetchTrades(old) spotPublicGetTrades
|
789
|
-
#
|
790
|
-
# {
|
791
|
-
# "date_ms":1647021989789,
|
792
|
-
# "amount":0.0028,
|
793
|
-
# "price":38804.2,
|
794
|
-
# "type":"buy",
|
795
|
-
# "tid":"52d5616ee35c43019edddebe59b3e094"
|
796
|
-
# }
|
797
|
-
#
|
798
|
-
#
|
799
|
-
# fetchTrades(new) spotPublicGetTradesSupplement
|
800
|
-
#
|
801
|
-
# {
|
802
|
-
# "quoteQty":1675.048485,
|
803
|
-
# "price":0.127545,
|
804
|
-
# "qty":13133,
|
805
|
-
# "id":"3589541dc22e4357b227283650f714e2",
|
806
|
-
# "time":1648058297110,
|
807
|
-
# "isBuyerMaker":false
|
808
|
-
# }
|
809
|
-
#
|
810
|
-
# fetchMyTrades(private)
|
811
|
-
#
|
812
|
-
# {
|
813
|
-
# "orderUuid":"38b4e7a4-14f6-45fd-aba1-1a37024124a0",
|
814
|
-
# "tradeFeeRate":0.0010000000,
|
815
|
-
# "dealTime":1648500944496,
|
816
|
-
# "dealQuantity":30.00000000000000000000,
|
817
|
-
# "tradeFee":0.00453300000000000000,
|
818
|
-
# "txUuid":"11f3850cc6214ea3b495adad3a032794",
|
819
|
-
# "dealPrice":0.15111300000000000000,
|
820
|
-
# "dealVolumePrice":4.53339000000000000000,
|
821
|
-
# "tradeType":"sell_market"
|
822
|
-
# }
|
823
|
-
#
|
824
|
-
timestamp = self.safe_integer_2(trade, 'date_ms', 'time')
|
825
|
-
if timestamp is None:
|
826
|
-
timestamp = self.safe_integer(trade, 'dealTime')
|
827
|
-
amountString = self.safe_string_2(trade, 'amount', 'qty')
|
828
|
-
if amountString is None:
|
829
|
-
amountString = self.safe_string(trade, 'dealQuantity')
|
830
|
-
priceString = self.safe_string(trade, 'price')
|
831
|
-
if priceString is None:
|
832
|
-
priceString = self.safe_string(trade, 'dealPrice')
|
833
|
-
costString = self.safe_string(trade, 'quoteQty')
|
834
|
-
if costString is None:
|
835
|
-
costString = self.safe_string(trade, 'dealVolumePrice')
|
836
|
-
side = self.safe_string_2(trade, 'tradeType', 'type')
|
837
|
-
type = None
|
838
|
-
takerOrMaker = None
|
839
|
-
if side is not None:
|
840
|
-
parts = side.split('_')
|
841
|
-
side = self.safe_string(parts, 0)
|
842
|
-
typePart = self.safe_string(parts, 1)
|
843
|
-
type = 'limit'
|
844
|
-
takerOrMaker = 'taker'
|
845
|
-
if typePart is not None:
|
846
|
-
if typePart == 'market':
|
847
|
-
type = 'market'
|
848
|
-
elif typePart == 'maker':
|
849
|
-
takerOrMaker = 'maker'
|
850
|
-
id = self.safe_string_2(trade, 'tid', 'id')
|
851
|
-
if id is None:
|
852
|
-
id = self.safe_string(trade, 'txUuid')
|
853
|
-
order = self.safe_string(trade, 'orderUuid')
|
854
|
-
symbol = self.safe_symbol(None, market)
|
855
|
-
fee = None
|
856
|
-
feeCost = self.safe_string(trade, 'tradeFee')
|
857
|
-
if feeCost is not None:
|
858
|
-
fee = {
|
859
|
-
'cost': feeCost,
|
860
|
-
'currency': market['base'] if (side == 'buy') else market['quote'],
|
861
|
-
'rate': self.safe_string(trade, 'tradeFeeRate'),
|
862
|
-
}
|
863
|
-
return self.safe_trade({
|
864
|
-
'timestamp': timestamp,
|
865
|
-
'datetime': self.iso8601(timestamp),
|
866
|
-
'symbol': symbol,
|
867
|
-
'id': id,
|
868
|
-
'order': order,
|
869
|
-
'type': type,
|
870
|
-
'takerOrMaker': takerOrMaker,
|
871
|
-
'side': side,
|
872
|
-
'price': priceString,
|
873
|
-
'amount': amountString,
|
874
|
-
'cost': costString,
|
875
|
-
'fee': fee,
|
876
|
-
'info': trade,
|
877
|
-
}, market)
|
878
|
-
|
879
|
-
async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
880
|
-
"""
|
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
|
884
|
-
:param str symbol: unified symbol of the market to fetch trades for
|
885
|
-
:param int [since]: timestamp in ms of the earliest trade to fetch
|
886
|
-
:param int [limit]: the maximum amount of trades to fetch
|
887
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
888
|
-
:returns Trade[]: a list of `trade structures <https://github.com/ccxt/ccxt/wiki/Manual#public-trades>`
|
889
|
-
"""
|
890
|
-
await self.load_markets()
|
891
|
-
market = self.market(symbol)
|
892
|
-
request = {
|
893
|
-
'symbol': market['id'],
|
894
|
-
}
|
895
|
-
if since is not None:
|
896
|
-
request['time'] = since
|
897
|
-
if limit is not None:
|
898
|
-
request['size'] = min(limit, 600)
|
899
|
-
else:
|
900
|
-
request['size'] = 600 # max
|
901
|
-
method = self.safe_string(params, 'method')
|
902
|
-
params = self.omit(params, 'method')
|
903
|
-
if method is None:
|
904
|
-
options = self.safe_value(self.options, 'fetchTrades', {})
|
905
|
-
method = self.safe_string(options, 'method', 'spotPublicGetTrades')
|
906
|
-
response = await getattr(self, method)(self.extend(request, params))
|
907
|
-
#
|
908
|
-
# {
|
909
|
-
# "result":"true",
|
910
|
-
# "data": [
|
911
|
-
# {
|
912
|
-
# "date_ms":1647021989789,
|
913
|
-
# "amount":0.0028,
|
914
|
-
# "price":38804.2,
|
915
|
-
# "type":"buy",
|
916
|
-
# "tid":"52d5616ee35c43019edddebe59b3e094"
|
917
|
-
# }
|
918
|
-
# ],
|
919
|
-
# "error_code":0,
|
920
|
-
# "ts":1647021999308
|
921
|
-
# }
|
922
|
-
#
|
923
|
-
trades = self.safe_value(response, 'data', [])
|
924
|
-
return self.parse_trades(trades, market, since, limit)
|
925
|
-
|
926
|
-
def parse_ohlcv(self, ohlcv, market=None) -> list:
|
927
|
-
#
|
928
|
-
# [
|
929
|
-
# 1482311500, # timestamp
|
930
|
-
# 5423.23, # open
|
931
|
-
# 5472.80, # high
|
932
|
-
# 5516.09, # low
|
933
|
-
# 5462, # close
|
934
|
-
# 234.3250 # volume
|
935
|
-
# ],
|
936
|
-
#
|
937
|
-
return [
|
938
|
-
self.safe_timestamp(ohlcv, 0), # timestamp
|
939
|
-
self.safe_number(ohlcv, 1), # open
|
940
|
-
self.safe_number(ohlcv, 2), # high
|
941
|
-
self.safe_number(ohlcv, 3), # low
|
942
|
-
self.safe_number(ohlcv, 4), # close
|
943
|
-
self.safe_number(ohlcv, 5), # volume
|
944
|
-
]
|
945
|
-
|
946
|
-
async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
947
|
-
"""
|
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
|
950
|
-
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
951
|
-
:param str timeframe: the length of time each candle represents
|
952
|
-
:param int [since]: timestamp in ms of the earliest candle to fetch
|
953
|
-
:param int [limit]: the maximum amount of candles to fetch
|
954
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
955
|
-
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
956
|
-
"""
|
957
|
-
# endpoint doesnt work
|
958
|
-
await self.load_markets()
|
959
|
-
market = self.market(symbol)
|
960
|
-
if limit is None:
|
961
|
-
limit = 100
|
962
|
-
if since is None:
|
963
|
-
duration = self.parse_timeframe(timeframe)
|
964
|
-
since = self.milliseconds() - duration * 1000 * limit
|
965
|
-
request = {
|
966
|
-
'symbol': market['id'],
|
967
|
-
'type': self.safe_string(self.timeframes, timeframe, timeframe),
|
968
|
-
'time': self.parse_to_int(since / 1000),
|
969
|
-
'size': limit, # max 2000
|
970
|
-
}
|
971
|
-
response = await self.spotPublicGetKline(self.extend(request, params))
|
972
|
-
ohlcvs = self.safe_value(response, 'data', [])
|
973
|
-
#
|
974
|
-
#
|
975
|
-
# [
|
976
|
-
# [
|
977
|
-
# 1482311500,
|
978
|
-
# 5423.23,
|
979
|
-
# 5472.80,
|
980
|
-
# 5516.09,
|
981
|
-
# 5462,
|
982
|
-
# 234.3250
|
983
|
-
# ],
|
984
|
-
# [
|
985
|
-
# 1482311400,
|
986
|
-
# 5432.52,
|
987
|
-
# 5459.87,
|
988
|
-
# 5414.30,
|
989
|
-
# 5428.23,
|
990
|
-
# 213.7329
|
991
|
-
# ]
|
992
|
-
# ]
|
993
|
-
#
|
994
|
-
return self.parse_ohlcvs(ohlcvs, market, timeframe, since, limit)
|
995
|
-
|
996
|
-
def parse_balance(self, response) -> Balances:
|
997
|
-
#
|
998
|
-
# spotPrivatePostUserInfo
|
999
|
-
#
|
1000
|
-
# {
|
1001
|
-
# "toBtc": {
|
1002
|
-
# "egc:": "0",
|
1003
|
-
# "iog": "0",
|
1004
|
-
# "ksm": "0",
|
1005
|
-
# },
|
1006
|
-
# "freeze": {
|
1007
|
-
# "egc": "0",
|
1008
|
-
# "iog": "0",
|
1009
|
-
# "ksm": "0" ,
|
1010
|
-
# },
|
1011
|
-
# "asset": {
|
1012
|
-
# "egc": "0",
|
1013
|
-
# "iog": "0",
|
1014
|
-
# "ksm": "0",
|
1015
|
-
# },
|
1016
|
-
# "free": {
|
1017
|
-
# "egc": "0",
|
1018
|
-
# "iog": "0",
|
1019
|
-
# "ksm": "0",
|
1020
|
-
# }
|
1021
|
-
# }
|
1022
|
-
#
|
1023
|
-
# spotPrivatePostSupplementUserInfoAccount
|
1024
|
-
#
|
1025
|
-
# {
|
1026
|
-
# "balances":[
|
1027
|
-
# {
|
1028
|
-
# "asset":"lbk",
|
1029
|
-
# "free":"0",
|
1030
|
-
# "locked":"0"
|
1031
|
-
# }, ...
|
1032
|
-
# ]
|
1033
|
-
# }
|
1034
|
-
#
|
1035
|
-
# spotPrivatePostSupplementUserInfo
|
1036
|
-
#
|
1037
|
-
# [
|
1038
|
-
# {
|
1039
|
-
# "usableAmt":"31.45130723",
|
1040
|
-
# "assetAmt":"31.45130723",
|
1041
|
-
# "networkList":[
|
1042
|
-
# {
|
1043
|
-
# "isDefault":true,
|
1044
|
-
# "withdrawFeeRate":"",
|
1045
|
-
# "name":"bep20(bsc)",
|
1046
|
-
# "withdrawMin":30,
|
1047
|
-
# "minLimit":0.0001,
|
1048
|
-
# "minDeposit":0.0001,
|
1049
|
-
# "feeAssetCode":"doge",
|
1050
|
-
# "withdrawFee":"30",
|
1051
|
-
# "type":1,
|
1052
|
-
# "coin":"doge",
|
1053
|
-
# "network":"bsc"
|
1054
|
-
# },
|
1055
|
-
# {
|
1056
|
-
# "isDefault":false,
|
1057
|
-
# "withdrawFeeRate":"",
|
1058
|
-
# "name":"dogecoin",
|
1059
|
-
# "withdrawMin":10,
|
1060
|
-
# "minLimit":0.0001,
|
1061
|
-
# "minDeposit":10,
|
1062
|
-
# "feeAssetCode":"doge",
|
1063
|
-
# "withdrawFee":"10",
|
1064
|
-
# "type":1,
|
1065
|
-
# "coin":"doge",
|
1066
|
-
# "network":"dogecoin"
|
1067
|
-
# }
|
1068
|
-
# ],
|
1069
|
-
# "freezeAmt":"0",
|
1070
|
-
# "coin":"doge"
|
1071
|
-
# }, ...
|
1072
|
-
# ]
|
1073
|
-
#
|
1074
|
-
timestamp = self.safe_integer(response, 'ts')
|
1075
|
-
result = {
|
1076
|
-
'info': response,
|
1077
|
-
'timestamp': timestamp,
|
1078
|
-
'datetime': self.iso8601(timestamp),
|
1079
|
-
}
|
1080
|
-
data = self.safe_value(response, 'data')
|
1081
|
-
# from spotPrivatePostUserInfo
|
1082
|
-
toBtc = self.safe_value(data, 'toBtc')
|
1083
|
-
if toBtc is not None:
|
1084
|
-
used = self.safe_value(data, 'freeze', {})
|
1085
|
-
free = self.safe_value(data, 'free', {})
|
1086
|
-
currencies = list(free.keys())
|
1087
|
-
for i in range(0, len(currencies)):
|
1088
|
-
currencyId = currencies[i]
|
1089
|
-
code = self.safe_currency_code(currencyId)
|
1090
|
-
account = self.account()
|
1091
|
-
account['used'] = self.safe_string(used, currencyId)
|
1092
|
-
account['free'] = self.safe_string(free, currencyId)
|
1093
|
-
result[code] = account
|
1094
|
-
return self.safe_balance(result)
|
1095
|
-
# from spotPrivatePostSupplementUserInfoAccount
|
1096
|
-
balances = self.safe_value(data, 'balances')
|
1097
|
-
if balances is not None:
|
1098
|
-
for i in range(0, len(balances)):
|
1099
|
-
item = balances[i]
|
1100
|
-
currencyId = self.safe_string(item, 'asset')
|
1101
|
-
codeInner = self.safe_currency_code(currencyId)
|
1102
|
-
account = self.account()
|
1103
|
-
account['free'] = self.safe_string(item, 'free')
|
1104
|
-
account['used'] = self.safe_string(item, 'locked')
|
1105
|
-
result[codeInner] = account
|
1106
|
-
return self.safe_balance(result)
|
1107
|
-
# from spotPrivatePostSupplementUserInfo
|
1108
|
-
isArray = isinstance(data, list)
|
1109
|
-
if isArray is True:
|
1110
|
-
for i in range(0, len(data)):
|
1111
|
-
item = data[i]
|
1112
|
-
currencyId = self.safe_string(item, 'coin')
|
1113
|
-
codeInner = self.safe_currency_code(currencyId)
|
1114
|
-
account = self.account()
|
1115
|
-
account['free'] = self.safe_string(item, 'usableAmt')
|
1116
|
-
account['used'] = self.safe_string(item, 'freezeAmt')
|
1117
|
-
result[codeInner] = account
|
1118
|
-
return self.safe_balance(result)
|
1119
|
-
return None
|
1120
|
-
|
1121
|
-
async def fetch_balance(self, params={}) -> Balances:
|
1122
|
-
"""
|
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
|
1127
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1128
|
-
:returns dict: a `balance structure <https://github.com/ccxt/ccxt/wiki/Manual#balance-structure>`
|
1129
|
-
"""
|
1130
|
-
await self.load_markets()
|
1131
|
-
method = self.safe_string(params, 'method')
|
1132
|
-
if method is None:
|
1133
|
-
options = self.safe_value(self.options, 'fetchBalance', {})
|
1134
|
-
method = self.safe_string(options, 'method', 'spotPrivatePostSupplementUserInfo')
|
1135
|
-
response = await getattr(self, method)()
|
1136
|
-
#
|
1137
|
-
# {
|
1138
|
-
# "result": "true",
|
1139
|
-
# "data": [
|
1140
|
-
# {
|
1141
|
-
# "usableAmt": "14.36",
|
1142
|
-
# "assetAmt": "14.36",
|
1143
|
-
# "networkList": [
|
1144
|
-
# {
|
1145
|
-
# "isDefault": False,
|
1146
|
-
# "withdrawFeeRate": "",
|
1147
|
-
# "name": "erc20",
|
1148
|
-
# "withdrawMin": 30,
|
1149
|
-
# "minLimit": 0.0001,
|
1150
|
-
# "minDeposit": 20,
|
1151
|
-
# "feeAssetCode": "usdt",
|
1152
|
-
# "withdrawFee": "30",
|
1153
|
-
# "type": 1,
|
1154
|
-
# "coin": "usdt",
|
1155
|
-
# "network": "eth"
|
1156
|
-
# },
|
1157
|
-
# ...
|
1158
|
-
# ],
|
1159
|
-
# "freezeAmt": "0",
|
1160
|
-
# "coin": "ada"
|
1161
|
-
# }
|
1162
|
-
# ],
|
1163
|
-
# "code": 0
|
1164
|
-
# }
|
1165
|
-
#
|
1166
|
-
return self.parse_balance(response)
|
1167
|
-
|
1168
|
-
def parse_trading_fee(self, fee, market=None):
|
1169
|
-
#
|
1170
|
-
# {
|
1171
|
-
# "symbol":"skt_usdt",
|
1172
|
-
# "makerCommission":"0.10",
|
1173
|
-
# "takerCommission":"0.10"
|
1174
|
-
# }
|
1175
|
-
#
|
1176
|
-
marketId = self.safe_string(fee, 'symbol')
|
1177
|
-
symbol = self.safe_symbol(marketId)
|
1178
|
-
return {
|
1179
|
-
'info': fee,
|
1180
|
-
'symbol': symbol,
|
1181
|
-
'maker': self.safe_number(fee, 'makerCommission'),
|
1182
|
-
'taker': self.safe_number(fee, 'takerCommission'),
|
1183
|
-
}
|
1184
|
-
|
1185
|
-
async def fetch_trading_fee(self, symbol: str, params={}):
|
1186
|
-
"""
|
1187
|
-
fetch the trading fees for a market
|
1188
|
-
:see: https://www.lbank.info/en-US/docs/index.html#transaction-fee-rate-query
|
1189
|
-
:param str symbol: unified market symbol
|
1190
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1191
|
-
:returns dict: a `fee structure <https://github.com/ccxt/ccxt/wiki/Manual#fee-structure>`
|
1192
|
-
"""
|
1193
|
-
market = self.market(symbol)
|
1194
|
-
result = await self.fetch_trading_fees(self.extend(params, {'category': market['id']}))
|
1195
|
-
return result
|
1196
|
-
|
1197
|
-
async def fetch_trading_fees(self, params={}):
|
1198
|
-
"""
|
1199
|
-
fetch the trading fees for multiple markets
|
1200
|
-
:see: https://www.lbank.info/en-US/docs/index.html#transaction-fee-rate-query
|
1201
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1202
|
-
:returns dict: a dictionary of `fee structures <https://github.com/ccxt/ccxt/wiki/Manual#fee-structure>` indexed by market symbols
|
1203
|
-
"""
|
1204
|
-
await self.load_markets()
|
1205
|
-
request = {}
|
1206
|
-
response = await self.spotPrivatePostSupplementCustomerTradeFee(self.extend(request, params))
|
1207
|
-
fees = self.safe_value(response, 'data', [])
|
1208
|
-
result = {}
|
1209
|
-
for i in range(0, len(fees)):
|
1210
|
-
fee = self.parse_trading_fee(fees[i])
|
1211
|
-
symbol = fee['symbol']
|
1212
|
-
result[symbol] = fee
|
1213
|
-
return result
|
1214
|
-
|
1215
|
-
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount, price=None, params={}):
|
1216
|
-
"""
|
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
|
1220
|
-
:param str symbol: unified symbol of the market to create an order in
|
1221
|
-
:param str type: 'market' or 'limit'
|
1222
|
-
:param str side: 'buy' or 'sell'
|
1223
|
-
:param float amount: how much of currency you want to trade in units of base currency
|
1224
|
-
:param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
1225
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1226
|
-
:returns dict: an `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
|
1227
|
-
"""
|
1228
|
-
await self.load_markets()
|
1229
|
-
market = self.market(symbol)
|
1230
|
-
clientOrderId = self.safe_string_2(params, 'custom_id', 'clientOrderId')
|
1231
|
-
postOnly = self.safe_value(params, 'postOnly', False)
|
1232
|
-
timeInForce = self.safe_string_upper(params, 'timeInForce')
|
1233
|
-
params = self.omit(params, ['custom_id', 'clientOrderId', 'timeInForce', 'postOnly'])
|
1234
|
-
request = {
|
1235
|
-
'symbol': market['id'],
|
1236
|
-
}
|
1237
|
-
ioc = (timeInForce == 'IOC')
|
1238
|
-
fok = (timeInForce == 'FOK')
|
1239
|
-
maker = (postOnly or (timeInForce == 'PO'))
|
1240
|
-
if (type == 'market') and (ioc or fok or maker):
|
1241
|
-
raise InvalidOrder(self.id + ' createOrder() does not allow market FOK, IOC, or postOnly orders. Only limit IOC, FOK, and postOnly orders are allowed')
|
1242
|
-
if type == 'limit':
|
1243
|
-
request['type'] = side
|
1244
|
-
request['price'] = self.price_to_precision(symbol, price)
|
1245
|
-
request['amount'] = self.amount_to_precision(symbol, amount)
|
1246
|
-
if ioc:
|
1247
|
-
request['type'] = side + '_' + 'ioc'
|
1248
|
-
elif fok:
|
1249
|
-
request['type'] = side + '_' + 'fok'
|
1250
|
-
elif maker:
|
1251
|
-
request['type'] = side + '_' + 'maker'
|
1252
|
-
elif type == 'market':
|
1253
|
-
if side == 'sell':
|
1254
|
-
request['type'] = side + '_' + 'market'
|
1255
|
-
request['amount'] = self.amount_to_precision(symbol, amount)
|
1256
|
-
elif side == 'buy':
|
1257
|
-
request['type'] = side + '_' + 'market'
|
1258
|
-
if self.options['createMarketBuyOrderRequiresPrice']:
|
1259
|
-
if price is None:
|
1260
|
-
raise InvalidOrder(self.id + " createOrder() requires the price argument with market buy orders to calculate total order cost(amount to spend), where cost = amount * price. Supply the price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = False to supply the cost in the amount argument(the exchange-specific behaviour)")
|
1261
|
-
else:
|
1262
|
-
amountString = self.number_to_string(amount)
|
1263
|
-
priceString = self.number_to_string(price)
|
1264
|
-
quoteAmount = Precise.string_mul(amountString, priceString)
|
1265
|
-
cost = self.parse_number(quoteAmount)
|
1266
|
-
request['price'] = self.price_to_precision(symbol, cost)
|
1267
|
-
else:
|
1268
|
-
request['price'] = amount
|
1269
|
-
if clientOrderId is not None:
|
1270
|
-
request['custom_id'] = clientOrderId
|
1271
|
-
method = None
|
1272
|
-
method = self.safe_string(params, 'method')
|
1273
|
-
params = self.omit(params, 'method')
|
1274
|
-
if method is None:
|
1275
|
-
options = self.safe_value(self.options, 'createOrder', {})
|
1276
|
-
method = self.safe_string(options, 'method', 'spotPrivatePostSupplementCreateOrder')
|
1277
|
-
response = await getattr(self, method)(self.extend(request, params))
|
1278
|
-
#
|
1279
|
-
# {
|
1280
|
-
# "result":true,
|
1281
|
-
# "data":{
|
1282
|
-
# "symbol":"doge_usdt",
|
1283
|
-
# "order_id":"0cf8a3de-4597-4296-af45-be7abaa06b07"
|
1284
|
-
# },
|
1285
|
-
# "error_code":0,
|
1286
|
-
# "ts":1648162321043
|
1287
|
-
# }
|
1288
|
-
#
|
1289
|
-
result = self.safe_value(response, 'data', {})
|
1290
|
-
return self.safe_order({
|
1291
|
-
'id': self.safe_string(result, 'order_id'),
|
1292
|
-
'info': result,
|
1293
|
-
}, market)
|
1294
|
-
|
1295
|
-
def parse_order_status(self, status):
|
1296
|
-
statuses = {
|
1297
|
-
'-1': 'canceled', # canceled
|
1298
|
-
'0': 'open', # not traded
|
1299
|
-
'1': 'open', # partial deal
|
1300
|
-
'2': 'closed', # complete deal
|
1301
|
-
'3': 'canceled', # filled partially and cancelled
|
1302
|
-
'4': 'closed', # disposal processing
|
1303
|
-
}
|
1304
|
-
return self.safe_string(statuses, status, status)
|
1305
|
-
|
1306
|
-
def parse_order(self, order, market=None) -> Order:
|
1307
|
-
#
|
1308
|
-
# fetchOrderSupplement(private)
|
1309
|
-
#
|
1310
|
-
# {
|
1311
|
-
# "cummulativeQuoteQty":0,
|
1312
|
-
# "symbol":"doge_usdt",
|
1313
|
-
# "executedQty":0,
|
1314
|
-
# "orderId":"53d2d53e-70fb-4398-b722-f48571a5f61e",
|
1315
|
-
# "origQty":1E+2,
|
1316
|
-
# "price":0.05,
|
1317
|
-
# "clientOrderId":null,
|
1318
|
-
# "origQuoteOrderQty":5,
|
1319
|
-
# "updateTime":1648163406000,
|
1320
|
-
# "time":1648163139387,
|
1321
|
-
# "type":"buy_maker",
|
1322
|
-
# "status":-1
|
1323
|
-
# }
|
1324
|
-
#
|
1325
|
-
#
|
1326
|
-
# fetchOrderDefault(private)
|
1327
|
-
#
|
1328
|
-
# {
|
1329
|
-
# "symbol":"shib_usdt",
|
1330
|
-
# "amount":1,
|
1331
|
-
# "create_time":1649367863356,
|
1332
|
-
# "price":0.0000246103,
|
1333
|
-
# "avg_price":0.00002466180000000104,
|
1334
|
-
# "type":"buy_market",
|
1335
|
-
# "order_id":"abe8b92d-86d9-4d6d-b71e-d14f5fb53ddf",
|
1336
|
-
# "custom_id": "007", # field only present if user creates it at order time
|
1337
|
-
# "deal_amount":40548.54065802,
|
1338
|
-
# "status":2
|
1339
|
-
# }
|
1340
|
-
#
|
1341
|
-
# fetchOpenOrders(private)
|
1342
|
-
#
|
1343
|
-
# {
|
1344
|
-
# "cummulativeQuoteQty":0,
|
1345
|
-
# "symbol":"doge_usdt",
|
1346
|
-
# "executedQty":0,
|
1347
|
-
# "orderId":"73878edf-008d-4e4c-8041-df1f1b2cd8bb",
|
1348
|
-
# "origQty":100,
|
1349
|
-
# "price":0.05,
|
1350
|
-
# "origQuoteOrderQty":5,
|
1351
|
-
# "updateTime":1648501762000,
|
1352
|
-
# "time":1648501762353,
|
1353
|
-
# "type":"buy",
|
1354
|
-
# "status":0
|
1355
|
-
# }
|
1356
|
-
#
|
1357
|
-
# fetchOrders(private)
|
1358
|
-
#
|
1359
|
-
# {
|
1360
|
-
# "cummulativeQuoteQty":0,
|
1361
|
-
# "symbol":"doge_usdt",
|
1362
|
-
# "executedQty":0,
|
1363
|
-
# "orderId":"2cadc7cc-b5f6-486b-a5b4-d6ac49a9c186",
|
1364
|
-
# "origQty":100,
|
1365
|
-
# "price":0.05,
|
1366
|
-
# "origQuoteOrderQty":5,
|
1367
|
-
# "updateTime":1648501384000,
|
1368
|
-
# "time":1648501363889,
|
1369
|
-
# "type":"buy",
|
1370
|
-
# "status":-1
|
1371
|
-
# }
|
1372
|
-
#
|
1373
|
-
id = self.safe_string_2(order, 'orderId', 'order_id')
|
1374
|
-
clientOrderId = self.safe_string_2(order, 'clientOrderId', 'custom_id')
|
1375
|
-
timestamp = self.safe_integer_2(order, 'time', 'create_time')
|
1376
|
-
rawStatus = self.safe_string(order, 'status')
|
1377
|
-
marketId = self.safe_string(order, 'symbol')
|
1378
|
-
market = self.safe_market(marketId, market)
|
1379
|
-
timeInForce = None
|
1380
|
-
postOnly = False
|
1381
|
-
type = 'limit'
|
1382
|
-
rawType = self.safe_string(order, 'type') # buy, sell, buy_market, sell_market, buy_maker,sell_maker,buy_ioc,sell_ioc, buy_fok, sell_fok
|
1383
|
-
parts = rawType.split('_')
|
1384
|
-
side = self.safe_string(parts, 0)
|
1385
|
-
typePart = self.safe_string(parts, 1) # market, maker, ioc, fok or None(limit)
|
1386
|
-
if typePart == 'market':
|
1387
|
-
type = 'market'
|
1388
|
-
if typePart == 'maker':
|
1389
|
-
postOnly = True
|
1390
|
-
timeInForce = 'PO'
|
1391
|
-
if typePart == 'ioc':
|
1392
|
-
timeInForce = 'IOC'
|
1393
|
-
if typePart == 'fok':
|
1394
|
-
timeInForce = 'FOK'
|
1395
|
-
price = self.safe_string(order, 'price')
|
1396
|
-
costString = self.safe_string(order, 'cummulativeQuoteQty')
|
1397
|
-
amountString = None
|
1398
|
-
if rawType != 'buy_market':
|
1399
|
-
amountString = self.safe_string_2(order, 'origQty', 'amount')
|
1400
|
-
filledString = self.safe_string_2(order, 'executedQty', 'deal_amount')
|
1401
|
-
return self.safe_order({
|
1402
|
-
'id': id,
|
1403
|
-
'clientOrderId': clientOrderId,
|
1404
|
-
'datetime': self.iso8601(timestamp),
|
1405
|
-
'timestamp': timestamp,
|
1406
|
-
'lastTradeTimestamp': None,
|
1407
|
-
'status': self.parse_order_status(rawStatus),
|
1408
|
-
'symbol': market['symbol'],
|
1409
|
-
'type': type,
|
1410
|
-
'timeInForce': timeInForce,
|
1411
|
-
'postOnly': postOnly,
|
1412
|
-
'side': side,
|
1413
|
-
'price': price,
|
1414
|
-
'stopPrice': None,
|
1415
|
-
'triggerPrice': None,
|
1416
|
-
'cost': costString,
|
1417
|
-
'amount': amountString,
|
1418
|
-
'filled': filledString,
|
1419
|
-
'remaining': None,
|
1420
|
-
'trades': None,
|
1421
|
-
'fee': None,
|
1422
|
-
'info': order,
|
1423
|
-
'average': None,
|
1424
|
-
}, market)
|
1425
|
-
|
1426
|
-
async def fetch_order(self, id: str, symbol: String = None, params={}):
|
1427
|
-
"""
|
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
|
1431
|
-
:param str symbol: unified symbol of the market the order was made in
|
1432
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1433
|
-
:returns dict: An `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
|
1434
|
-
"""
|
1435
|
-
await self.load_markets()
|
1436
|
-
method = self.safe_string(params, 'method')
|
1437
|
-
if method is None:
|
1438
|
-
options = self.safe_value(self.options, 'fetchOrder', {})
|
1439
|
-
method = self.safe_string(options, 'method', 'fetchOrderSupplement')
|
1440
|
-
if method == 'fetchOrderSupplement':
|
1441
|
-
return await self.fetch_order_supplement(id, symbol, params)
|
1442
|
-
return await self.fetch_order_default(id, symbol, params)
|
1443
|
-
|
1444
|
-
async def fetch_order_supplement(self, id: str, symbol: String = None, params={}):
|
1445
|
-
self.check_required_symbol('fetchOrder', symbol)
|
1446
|
-
await self.load_markets()
|
1447
|
-
market = self.market(symbol)
|
1448
|
-
request = {
|
1449
|
-
'symbol': market['id'],
|
1450
|
-
'orderId': id,
|
1451
|
-
}
|
1452
|
-
response = await self.spotPrivatePostSupplementOrdersInfo(self.extend(request, params))
|
1453
|
-
#
|
1454
|
-
# {
|
1455
|
-
# "result":true,
|
1456
|
-
# "data":{
|
1457
|
-
# "cummulativeQuoteQty":0,
|
1458
|
-
# "symbol":"doge_usdt",
|
1459
|
-
# "executedQty":0,
|
1460
|
-
# "orderId":"53d2d53e-70fb-4398-b722-f48571a5f61e",
|
1461
|
-
# "origQty":1E+2,
|
1462
|
-
# "price":0.05,
|
1463
|
-
# "clientOrderId":null,
|
1464
|
-
# "origQuoteOrderQty":5,
|
1465
|
-
# "updateTime":1648163406000,
|
1466
|
-
# "time":1648163139387,
|
1467
|
-
# "type":"buy_maker",
|
1468
|
-
# "status":-1
|
1469
|
-
# },
|
1470
|
-
# "error_code":0,
|
1471
|
-
# "ts":1648164471827
|
1472
|
-
# }
|
1473
|
-
#
|
1474
|
-
result = self.safe_value(response, 'data', {})
|
1475
|
-
return self.parse_order(result)
|
1476
|
-
|
1477
|
-
async def fetch_order_default(self, id: str, symbol: String = None, params={}):
|
1478
|
-
# Id can be a list of ids delimited by a comma
|
1479
|
-
self.check_required_symbol('fetchOrder', symbol)
|
1480
|
-
await self.load_markets()
|
1481
|
-
market = self.market(symbol)
|
1482
|
-
request = {
|
1483
|
-
'symbol': market['id'],
|
1484
|
-
'order_id': id,
|
1485
|
-
}
|
1486
|
-
response = await self.spotPrivatePostOrdersInfo(self.extend(request, params))
|
1487
|
-
#
|
1488
|
-
# {
|
1489
|
-
# "result":true,
|
1490
|
-
# "data":[
|
1491
|
-
# {
|
1492
|
-
# "symbol":"doge_usdt",
|
1493
|
-
# "amount":18,
|
1494
|
-
# "create_time":1647455223186,
|
1495
|
-
# "price":0,
|
1496
|
-
# "avg_price":0.113344,
|
1497
|
-
# "type":"sell_market",
|
1498
|
-
# "order_id":"d4ca1ddd-40d9-42c1-9717-5de435865bec",
|
1499
|
-
# "deal_amount":18,
|
1500
|
-
# "status":2
|
1501
|
-
# }
|
1502
|
-
# ],
|
1503
|
-
# "error_code":0,
|
1504
|
-
# "ts":1647455270776
|
1505
|
-
# }
|
1506
|
-
#
|
1507
|
-
result = self.safe_value(response, 'data', [])
|
1508
|
-
numOrders = len(result)
|
1509
|
-
if numOrders == 1:
|
1510
|
-
return self.parse_order(result[0])
|
1511
|
-
else:
|
1512
|
-
# parsedOrders = []
|
1513
|
-
# for i in range(0, numOrders):
|
1514
|
-
# parsedOrder = self.parse_order(result[i])
|
1515
|
-
# parsedOrders.append(parsedOrder)
|
1516
|
-
# }
|
1517
|
-
# return parsedOrders
|
1518
|
-
raise BadRequest(self.id + ' fetchOrder() can only fetch one order at a time')
|
1519
|
-
|
1520
|
-
async def fetch_my_trades(self, symbol: String = None, since: Int = None, limit: Int = None, params={}):
|
1521
|
-
"""
|
1522
|
-
fetch all trades made by the user
|
1523
|
-
:see: https://www.lbank.info/en-US/docs/index.html#past-transaction-details
|
1524
|
-
:param str symbol: unified market symbol
|
1525
|
-
:param int [since]: the earliest time in ms to fetch trades for
|
1526
|
-
:param int [limit]: the maximum number of trade structures to retrieve
|
1527
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1528
|
-
:returns Trade[]: a list of `trade structures <https://github.com/ccxt/ccxt/wiki/Manual#trade-structure>`
|
1529
|
-
"""
|
1530
|
-
self.check_required_symbol('fetchMyTrades', symbol)
|
1531
|
-
await self.load_markets()
|
1532
|
-
market = self.market(symbol)
|
1533
|
-
since = self.safe_value(params, 'start_date', since)
|
1534
|
-
params = self.omit(params, 'start_date')
|
1535
|
-
request = {
|
1536
|
-
'symbol': market['id'],
|
1537
|
-
# 'start_date' Start time yyyy-mm-dd, the maximum is today, the default is yesterday
|
1538
|
-
# 'end_date' Finish time yyyy-mm-dd, the maximum is today, the default is today
|
1539
|
-
# 'The start': and end date of the query window is up to 2 days
|
1540
|
-
# 'from' Initial transaction number inquiring
|
1541
|
-
# 'direct' inquire direction,The default is the 'next' which is the positive sequence of dealing time,the 'prev' is inverted order of dealing time
|
1542
|
-
# 'size' Query the number of defaults to 100
|
1543
|
-
}
|
1544
|
-
if limit is not None:
|
1545
|
-
request['size'] = limit
|
1546
|
-
if since is not None:
|
1547
|
-
request['start_date'] = self.ymd(since, '-') # max query 2 days ago
|
1548
|
-
request['end_date'] = self.ymd(since + 86400000, '-') # will cover 2 days
|
1549
|
-
response = await self.spotPrivatePostTransactionHistory(self.extend(request, params))
|
1550
|
-
#
|
1551
|
-
# {
|
1552
|
-
# "result":true,
|
1553
|
-
# "data":[
|
1554
|
-
# {
|
1555
|
-
# "orderUuid":"38b4e7a4-14f6-45fd-aba1-1a37024124a0",
|
1556
|
-
# "tradeFeeRate":0.0010000000,
|
1557
|
-
# "dealTime":1648500944496,
|
1558
|
-
# "dealQuantity":30.00000000000000000000,
|
1559
|
-
# "tradeFee":0.00453300000000000000,
|
1560
|
-
# "txUuid":"11f3850cc6214ea3b495adad3a032794",
|
1561
|
-
# "dealPrice":0.15111300000000000000,
|
1562
|
-
# "dealVolumePrice":4.53339000000000000000,
|
1563
|
-
# "tradeType":"sell_market"
|
1564
|
-
# }
|
1565
|
-
# ],
|
1566
|
-
# "error_code":0,
|
1567
|
-
# "ts":1648509742164
|
1568
|
-
# }
|
1569
|
-
#
|
1570
|
-
trades = self.safe_value(response, 'data', [])
|
1571
|
-
return self.parse_trades(trades, market, since, limit)
|
1572
|
-
|
1573
|
-
async def fetch_orders(self, symbol: String = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1574
|
-
"""
|
1575
|
-
fetches information on multiple orders made by the user
|
1576
|
-
:see: https://www.lbank.info/en-US/docs/index.html#query-all-orders
|
1577
|
-
:param str symbol: unified market symbol of the market orders were made in
|
1578
|
-
:param int [since]: the earliest time in ms to fetch orders for
|
1579
|
-
:param int [limit]: the maximum number of order structures to retrieve
|
1580
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1581
|
-
:returns Order[]: a list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
|
1582
|
-
"""
|
1583
|
-
# default query is for canceled and completely filled orders
|
1584
|
-
# does not return open orders unless specified explicitly
|
1585
|
-
self.check_required_symbol('fetchOrders', symbol)
|
1586
|
-
await self.load_markets()
|
1587
|
-
market = self.market(symbol)
|
1588
|
-
if limit is None:
|
1589
|
-
limit = 100
|
1590
|
-
request = {
|
1591
|
-
'symbol': market['id'],
|
1592
|
-
'current_page': 1,
|
1593
|
-
'page_length': limit,
|
1594
|
-
# 'status' -1: Cancelled, 0: Unfilled, 1: Partially filled, 2: Completely filled, 3: Partially filled and cancelled, 4: Cancellation is being processed
|
1595
|
-
}
|
1596
|
-
response = await self.spotPrivatePostSupplementOrdersInfoHistory(self.extend(request, params))
|
1597
|
-
#
|
1598
|
-
# {
|
1599
|
-
# "result":true,
|
1600
|
-
# "data":{
|
1601
|
-
# "total":1,
|
1602
|
-
# "page_length":100,
|
1603
|
-
# "orders":[
|
1604
|
-
# {
|
1605
|
-
# "cummulativeQuoteQty":0,
|
1606
|
-
# "symbol":"doge_usdt",
|
1607
|
-
# "executedQty":0,
|
1608
|
-
# "orderId":"2cadc7cc-b5f6-486b-a5b4-d6ac49a9c186",
|
1609
|
-
# "origQty":100,
|
1610
|
-
# "price":0.05,
|
1611
|
-
# "origQuoteOrderQty":5,
|
1612
|
-
# "updateTime":1648501384000,
|
1613
|
-
# "time":1648501363889,
|
1614
|
-
# "type":"buy",
|
1615
|
-
# "status":-1
|
1616
|
-
# }, ...
|
1617
|
-
# ],
|
1618
|
-
# "current_page":1
|
1619
|
-
# },
|
1620
|
-
# "error_code":0,
|
1621
|
-
# "ts":1648505706348
|
1622
|
-
# }
|
1623
|
-
#
|
1624
|
-
result = self.safe_value(response, 'data', {})
|
1625
|
-
orders = self.safe_value(result, 'orders', [])
|
1626
|
-
return self.parse_orders(orders, market, since, limit)
|
1627
|
-
|
1628
|
-
async def fetch_open_orders(self, symbol: String = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
1629
|
-
"""
|
1630
|
-
fetch all unfilled currently open orders
|
1631
|
-
:see: https://www.lbank.info/en-US/docs/index.html#current-pending-order
|
1632
|
-
:param str symbol: unified market symbol
|
1633
|
-
:param int [since]: the earliest time in ms to fetch open orders for
|
1634
|
-
:param int [limit]: the maximum number of open order structures to retrieve
|
1635
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1636
|
-
:returns Order[]: a list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
|
1637
|
-
"""
|
1638
|
-
self.check_required_symbol('fetchOpenOrders', symbol)
|
1639
|
-
await self.load_markets()
|
1640
|
-
market = self.market(symbol)
|
1641
|
-
if limit is None:
|
1642
|
-
limit = 100
|
1643
|
-
request = {
|
1644
|
-
'symbol': market['id'],
|
1645
|
-
'current_page': 1,
|
1646
|
-
'page_length': limit,
|
1647
|
-
}
|
1648
|
-
response = await self.spotPrivatePostSupplementOrdersInfoNoDeal(self.extend(request, params))
|
1649
|
-
#
|
1650
|
-
# {
|
1651
|
-
# "result":true,
|
1652
|
-
# "data":{
|
1653
|
-
# "total":1,
|
1654
|
-
# "page_length":100,
|
1655
|
-
# "orders":[
|
1656
|
-
# {
|
1657
|
-
# "cummulativeQuoteQty":0,
|
1658
|
-
# "symbol":"doge_usdt",
|
1659
|
-
# "executedQty":0,
|
1660
|
-
# "orderId":"73878edf-008d-4e4c-8041-df1f1b2cd8bb",
|
1661
|
-
# "origQty":100,
|
1662
|
-
# "price":0.05,
|
1663
|
-
# "origQuoteOrderQty":5,
|
1664
|
-
# "updateTime":1648501762000,
|
1665
|
-
# "time":1648501762353,
|
1666
|
-
# "type":"buy",
|
1667
|
-
# "status":0
|
1668
|
-
# }, ...
|
1669
|
-
# ],
|
1670
|
-
# "current_page":1
|
1671
|
-
# },
|
1672
|
-
# "error_code":0,
|
1673
|
-
# "ts":1648506110196
|
1674
|
-
# }
|
1675
|
-
#
|
1676
|
-
result = self.safe_value(response, 'data', {})
|
1677
|
-
orders = self.safe_value(result, 'orders', [])
|
1678
|
-
return self.parse_orders(orders, market, since, limit)
|
1679
|
-
|
1680
|
-
async def cancel_order(self, id: str, symbol: String = None, params={}):
|
1681
|
-
"""
|
1682
|
-
cancels an open order
|
1683
|
-
:see: https://www.lbank.info/en-US/docs/index.html#cancel-order-new
|
1684
|
-
:param str id: order id
|
1685
|
-
:param str symbol: unified symbol of the market the order was made in
|
1686
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1687
|
-
:returns dict: An `order structure <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
|
1688
|
-
"""
|
1689
|
-
self.check_required_symbol('cancelOrder', symbol)
|
1690
|
-
await self.load_markets()
|
1691
|
-
clientOrderId = self.safe_string_2(params, 'origClientOrderId', 'clientOrderId')
|
1692
|
-
params = self.omit(params, ['origClientOrderId', 'clientOrderId'])
|
1693
|
-
market = self.market(symbol)
|
1694
|
-
request = {
|
1695
|
-
'symbol': market['id'],
|
1696
|
-
'orderId': id,
|
1697
|
-
}
|
1698
|
-
if clientOrderId is not None:
|
1699
|
-
request['origClientOrderId'] = clientOrderId
|
1700
|
-
response = await self.spotPrivatePostSupplementCancelOrder(self.extend(request, params))
|
1701
|
-
#
|
1702
|
-
# {
|
1703
|
-
# "result":true,
|
1704
|
-
# "data":{
|
1705
|
-
# "executedQty":0.0,
|
1706
|
-
# "price":0.05,
|
1707
|
-
# "origQty":100.0,
|
1708
|
-
# "tradeType":"buy",
|
1709
|
-
# "status":0
|
1710
|
-
# },
|
1711
|
-
# "error_code":0,
|
1712
|
-
# "ts":1648501286196
|
1713
|
-
# }
|
1714
|
-
result = self.safe_value(response, 'data', {})
|
1715
|
-
return result
|
1716
|
-
|
1717
|
-
async def cancel_all_orders(self, symbol: String = None, params={}):
|
1718
|
-
"""
|
1719
|
-
cancel all open orders in a market
|
1720
|
-
:see: https://www.lbank.info/en-US/docs/index.html#cancel-all-pending-orders-for-a-single-trading-pair
|
1721
|
-
:param str symbol: unified market symbol of the market to cancel orders in
|
1722
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1723
|
-
:returns dict[]: a list of `order structures <https://github.com/ccxt/ccxt/wiki/Manual#order-structure>`
|
1724
|
-
"""
|
1725
|
-
self.check_required_symbol('cancelAllOrders', symbol)
|
1726
|
-
await self.load_markets()
|
1727
|
-
market = self.market(symbol)
|
1728
|
-
request = {
|
1729
|
-
'symbol': market['id'],
|
1730
|
-
}
|
1731
|
-
response = await self.spotPrivatePostSupplementCancelOrderBySymbol(self.extend(request, params))
|
1732
|
-
#
|
1733
|
-
# {
|
1734
|
-
# "result":"true",
|
1735
|
-
# "data":[
|
1736
|
-
# {
|
1737
|
-
# "executedQty":0.00000000000000000000,
|
1738
|
-
# "orderId":"293ef71b-3e67-4962-af93-aa06990a045f",
|
1739
|
-
# "price":0.05000000000000000000,
|
1740
|
-
# "origQty":100.00000000000000000000,
|
1741
|
-
# "tradeType":"buy",
|
1742
|
-
# "status":0
|
1743
|
-
# },
|
1744
|
-
# ],
|
1745
|
-
# "error_code":0,
|
1746
|
-
# "ts":1648506641469
|
1747
|
-
# }
|
1748
|
-
#
|
1749
|
-
result = self.safe_value(response, 'data', [])
|
1750
|
-
return result
|
1751
|
-
|
1752
|
-
def get_network_code_for_currency(self, currencyCode, params):
|
1753
|
-
defaultNetworks = self.safe_value(self.options, 'defaultNetworks')
|
1754
|
-
defaultNetwork = self.safe_string_upper(defaultNetworks, currencyCode)
|
1755
|
-
networks = self.safe_value(self.options, 'networks', {})
|
1756
|
-
network = self.safe_string_upper(params, 'network', defaultNetwork) # self line allows the user to specify either ERC20 or ETH
|
1757
|
-
network = self.safe_string(networks, network, network) # handle ERC20>ETH alias
|
1758
|
-
return network
|
1759
|
-
|
1760
|
-
async def fetch_deposit_address(self, code: str, params={}):
|
1761
|
-
"""
|
1762
|
-
fetch the deposit address for a currency associated with self account
|
1763
|
-
:see: https://www.lbank.info/en-US/docs/index.html#get-deposit-address
|
1764
|
-
:see: https://www.lbank.info/en-US/docs/index.html#the-user-obtains-the-deposit-address
|
1765
|
-
:param str code: unified currency code
|
1766
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1767
|
-
:returns dict: an `address structure <https://github.com/ccxt/ccxt/wiki/Manual#address-structure>`
|
1768
|
-
"""
|
1769
|
-
await self.load_markets()
|
1770
|
-
method = self.safe_string(params, 'method')
|
1771
|
-
params = self.omit(params, 'method')
|
1772
|
-
if method is None:
|
1773
|
-
options = self.safe_value(self.options, 'fetchDepositAddress', {})
|
1774
|
-
method = self.safe_string(options, 'method', 'fetchDepositAddressDefault')
|
1775
|
-
return await getattr(self, method)(code, params)
|
1776
|
-
|
1777
|
-
async def fetch_deposit_address_default(self, code: str, params={}):
|
1778
|
-
await self.load_markets()
|
1779
|
-
currency = self.currency(code)
|
1780
|
-
request = {
|
1781
|
-
'assetCode': currency['id'],
|
1782
|
-
}
|
1783
|
-
network = self.get_network_code_for_currency(code, params)
|
1784
|
-
if network is not None:
|
1785
|
-
request['netWork'] = network # ... yes, really lol
|
1786
|
-
params = self.omit(params, 'network')
|
1787
|
-
response = await self.spotPrivatePostGetDepositAddress(self.extend(request, params))
|
1788
|
-
#
|
1789
|
-
# {
|
1790
|
-
# "result":true,
|
1791
|
-
# "data":{
|
1792
|
-
# "assetCode":"usdt",
|
1793
|
-
# "address":"0xc85689d37ca650bf2f2161364cdedee21eb6ca53",
|
1794
|
-
# "memo":null,
|
1795
|
-
# "netWork":"bep20(bsc)"
|
1796
|
-
# },
|
1797
|
-
# "error_code":0,
|
1798
|
-
# "ts":1648075865103
|
1799
|
-
# }
|
1800
|
-
#
|
1801
|
-
result = self.safe_value(response, 'data')
|
1802
|
-
address = self.safe_string(result, 'address')
|
1803
|
-
tag = self.safe_string(result, 'memo')
|
1804
|
-
networkId = self.safe_string(result, 'netWork')
|
1805
|
-
inverseNetworks = self.safe_value(self.options, 'inverse-networks', {})
|
1806
|
-
networkCode = self.safe_string_upper(inverseNetworks, networkId, networkId)
|
1807
|
-
return {
|
1808
|
-
'currency': code,
|
1809
|
-
'address': address,
|
1810
|
-
'tag': tag,
|
1811
|
-
'network': networkCode,
|
1812
|
-
'info': response,
|
1813
|
-
}
|
1814
|
-
|
1815
|
-
async def fetch_deposit_address_supplement(self, code: str, params={}):
|
1816
|
-
# returns the address for whatever the default network is...
|
1817
|
-
await self.load_markets()
|
1818
|
-
currency = self.currency(code)
|
1819
|
-
request = {
|
1820
|
-
'coin': currency['id'],
|
1821
|
-
}
|
1822
|
-
networks = self.safe_value(self.options, 'networks')
|
1823
|
-
network = self.safe_string_upper(params, 'network')
|
1824
|
-
network = self.safe_string(networks, network, network)
|
1825
|
-
if network is not None:
|
1826
|
-
request['networkName'] = network
|
1827
|
-
params = self.omit(params, 'network')
|
1828
|
-
response = await self.spotPrivatePostSupplementGetDepositAddress(self.extend(request, params))
|
1829
|
-
#
|
1830
|
-
# {
|
1831
|
-
# "result":true,
|
1832
|
-
# "data":{
|
1833
|
-
# "address":"TDxtabCC8iQwaxUUrPcE4WL2jArGAfvQ5A",
|
1834
|
-
# "memo":null,
|
1835
|
-
# "coin":"usdt"
|
1836
|
-
# },
|
1837
|
-
# "error_code":0,
|
1838
|
-
# "ts":1648073818880
|
1839
|
-
# }
|
1840
|
-
#
|
1841
|
-
result = self.safe_value(response, 'data')
|
1842
|
-
address = self.safe_string(result, 'address')
|
1843
|
-
tag = self.safe_string(result, 'memo')
|
1844
|
-
inverseNetworks = self.safe_value(self.options, 'inverse-networks', {})
|
1845
|
-
networkCode = self.safe_string_upper(inverseNetworks, network, network)
|
1846
|
-
return {
|
1847
|
-
'currency': code,
|
1848
|
-
'address': address,
|
1849
|
-
'tag': tag,
|
1850
|
-
'network': networkCode, # will be None if not specified in request
|
1851
|
-
'info': response,
|
1852
|
-
}
|
1853
|
-
|
1854
|
-
async def withdraw(self, code: str, amount, address, tag=None, params={}):
|
1855
|
-
"""
|
1856
|
-
make a withdrawal
|
1857
|
-
:see: https://www.lbank.info/en-US/docs/index.html#withdrawal
|
1858
|
-
:param str code: unified currency code
|
1859
|
-
:param float amount: the amount to withdraw
|
1860
|
-
:param str address: the address to withdraw to
|
1861
|
-
:param str tag:
|
1862
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
1863
|
-
:returns dict: a `transaction structure <https://github.com/ccxt/ccxt/wiki/Manual#transaction-structure>`
|
1864
|
-
"""
|
1865
|
-
tag, params = self.handle_withdraw_tag_and_params(tag, params)
|
1866
|
-
self.check_address(address)
|
1867
|
-
await self.load_markets()
|
1868
|
-
fee = self.safe_string(params, 'fee')
|
1869
|
-
params = self.omit(params, 'fee')
|
1870
|
-
# 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().
|
1871
|
-
self.check_required_argument('withdraw', fee, 'fee')
|
1872
|
-
currency = self.currency(code)
|
1873
|
-
request = {
|
1874
|
-
'address': address,
|
1875
|
-
'coin': currency['id'],
|
1876
|
-
'amount': amount,
|
1877
|
-
'fee': fee, # the correct coin-network fee must be supplied, which can be found by calling fetchDepositWithdrawFees(private)
|
1878
|
-
# 'networkName': defaults to the defaultNetwork of the coin which can be found in the /supplement/user_info endpoint
|
1879
|
-
# 'memo': memo: memo word of bts and dct
|
1880
|
-
# 'mark': Withdrawal Notes
|
1881
|
-
# 'name': Remarks of the address. After hasattr(self, filling) parameter, it will be added to the withdrawal address book of the currency.
|
1882
|
-
# 'withdrawOrderId': withdrawOrderId
|
1883
|
-
# 'type': type=1 is for intra-site transfer
|
1884
|
-
}
|
1885
|
-
if tag is not None:
|
1886
|
-
request['memo'] = tag
|
1887
|
-
network = self.safe_string_upper_2(params, 'network', 'networkName')
|
1888
|
-
params = self.omit(params, ['network', 'networkName'])
|
1889
|
-
networks = self.safe_value(self.options, 'networks')
|
1890
|
-
networkId = self.safe_string(networks, network, network)
|
1891
|
-
if networkId is not None:
|
1892
|
-
request['networkName'] = networkId
|
1893
|
-
response = await self.spotPrivatePostSupplementWithdraw(self.extend(request, params))
|
1894
|
-
#
|
1895
|
-
# {
|
1896
|
-
# "result":true,
|
1897
|
-
# "data": {
|
1898
|
-
# "fee":10.00000000000000000000,
|
1899
|
-
# "withdrawId":1900376
|
1900
|
-
# },
|
1901
|
-
# "error_code":0,
|
1902
|
-
# "ts":1648992501414
|
1903
|
-
# }
|
1904
|
-
#
|
1905
|
-
result = self.safe_value(response, 'data', {})
|
1906
|
-
return {
|
1907
|
-
'info': result,
|
1908
|
-
'id': self.safe_string(result, 'withdrawId'),
|
1909
|
-
}
|
1910
|
-
|
1911
|
-
def parse_transaction_status(self, status, type):
|
1912
|
-
statuses = {
|
1913
|
-
'deposit': {
|
1914
|
-
'1': 'pending',
|
1915
|
-
'2': 'ok',
|
1916
|
-
'3': 'failed',
|
1917
|
-
'4': 'canceled',
|
1918
|
-
'5': 'transfer',
|
1919
|
-
},
|
1920
|
-
'withdrawal': {
|
1921
|
-
'1': 'pending',
|
1922
|
-
'2': 'canceled',
|
1923
|
-
'3': 'failed',
|
1924
|
-
'4': 'ok',
|
1925
|
-
},
|
1926
|
-
}
|
1927
|
-
return self.safe_string(self.safe_value(statuses, type, {}), status, status)
|
1928
|
-
|
1929
|
-
def parse_transaction(self, transaction, currency=None) -> Transaction:
|
1930
|
-
#
|
1931
|
-
# fetchDeposits(private)
|
1932
|
-
#
|
1933
|
-
# {
|
1934
|
-
# "insertTime":1649012310000,
|
1935
|
-
# "amount":9.00000000000000000000,
|
1936
|
-
# "address":"TYASr5UV6HEcXatwdFQfmLVUqQQQMUxHLS",
|
1937
|
-
# "networkName":"trc20",
|
1938
|
-
# "txId":"081e4e9351dd0274922168da5f2d14ea6c495b1c3b440244f4a6dd9fe196bf2b",
|
1939
|
-
# "coin":"usdt",
|
1940
|
-
# "status":"2"
|
1941
|
-
# }
|
1942
|
-
#
|
1943
|
-
#
|
1944
|
-
# fetchWithdrawals(private)
|
1945
|
-
#
|
1946
|
-
# {
|
1947
|
-
# "amount":2.00000000000000000000,
|
1948
|
-
# "address":"TBjrW5JHDyPZjFc5nrRMhRWUDaJmhGhmD6",
|
1949
|
-
# "fee":1.00000000000000000000,
|
1950
|
-
# "networkName":"trc20",
|
1951
|
-
# "coid":"usdt",
|
1952
|
-
# "transferType":"数字资产提现",
|
1953
|
-
# "txId":"47eeee2763ad49b8817524dacfa7d092fb58f8b0ab7e5d25473314df1a793c3d",
|
1954
|
-
# "id":1902194,
|
1955
|
-
# "applyTime":1649014002000,
|
1956
|
-
# "status":"4"
|
1957
|
-
# }
|
1958
|
-
#
|
1959
|
-
id = self.safe_string(transaction, 'id')
|
1960
|
-
type = None
|
1961
|
-
if id is None:
|
1962
|
-
type = 'deposit'
|
1963
|
-
else:
|
1964
|
-
type = 'withdrawal'
|
1965
|
-
txid = self.safe_string(transaction, 'txId')
|
1966
|
-
timestamp = self.safe_integer_2(transaction, 'insertTime', 'applyTime')
|
1967
|
-
networks = self.safe_value(self.options, 'inverse-networks', {})
|
1968
|
-
networkId = self.safe_string(transaction, 'networkName')
|
1969
|
-
network = self.safe_string(networks, networkId, networkId)
|
1970
|
-
address = self.safe_string(transaction, 'address')
|
1971
|
-
addressFrom = None
|
1972
|
-
addressTo = None
|
1973
|
-
if type == 'deposit':
|
1974
|
-
addressFrom = address
|
1975
|
-
else:
|
1976
|
-
addressTo = address
|
1977
|
-
amount = self.safe_number(transaction, 'amount')
|
1978
|
-
currencyId = self.safe_string_2(transaction, 'coin', 'coid')
|
1979
|
-
code = self.safe_currency_code(currencyId, currency)
|
1980
|
-
status = self.parse_transaction_status(self.safe_string(transaction, 'status'), type)
|
1981
|
-
fee = None
|
1982
|
-
feeCost = self.safe_number(transaction, 'fee')
|
1983
|
-
if feeCost is not None:
|
1984
|
-
fee = {
|
1985
|
-
'cost': feeCost,
|
1986
|
-
'currency': code,
|
1987
|
-
}
|
1988
|
-
return {
|
1989
|
-
'info': transaction,
|
1990
|
-
'id': id,
|
1991
|
-
'txid': txid,
|
1992
|
-
'timestamp': timestamp,
|
1993
|
-
'datetime': self.iso8601(timestamp),
|
1994
|
-
'network': network,
|
1995
|
-
'address': address,
|
1996
|
-
'addressTo': addressTo,
|
1997
|
-
'addressFrom': addressFrom,
|
1998
|
-
'tag': None,
|
1999
|
-
'tagTo': None,
|
2000
|
-
'tagFrom': None,
|
2001
|
-
'type': type,
|
2002
|
-
'amount': amount,
|
2003
|
-
'currency': code,
|
2004
|
-
'status': status,
|
2005
|
-
'updated': None,
|
2006
|
-
'comment': None,
|
2007
|
-
'internal': (status == 'transfer'),
|
2008
|
-
'fee': fee,
|
2009
|
-
}
|
2010
|
-
|
2011
|
-
async def fetch_deposits(self, code: String = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
2012
|
-
"""
|
2013
|
-
fetch all deposits made to an account
|
2014
|
-
:see: https://www.lbank.info/en-US/docs/index.html#get-recharge-history
|
2015
|
-
:param str code: unified currency code
|
2016
|
-
:param int [since]: the earliest time in ms to fetch deposits for
|
2017
|
-
:param int [limit]: the maximum number of deposits structures to retrieve
|
2018
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
2019
|
-
:returns dict[]: a list of `transaction structures <https://github.com/ccxt/ccxt/wiki/Manual#transaction-structure>`
|
2020
|
-
"""
|
2021
|
-
await self.load_markets()
|
2022
|
-
request = {
|
2023
|
-
# 'status': Recharge status: ("1","Applying"),("2","Recharge successful"),("3","Recharge failed"),("4","Already Cancel"),("5", "Transfer")
|
2024
|
-
# 'endTime': end time, timestamp in milliseconds, default now
|
2025
|
-
}
|
2026
|
-
currency = None
|
2027
|
-
if code is not None:
|
2028
|
-
currency = self.currency(code)
|
2029
|
-
request['coin'] = currency['id']
|
2030
|
-
if since is not None:
|
2031
|
-
request['startTime'] = since
|
2032
|
-
response = await self.spotPrivatePostSupplementDepositHistory(self.extend(request, params))
|
2033
|
-
#
|
2034
|
-
# {
|
2035
|
-
# "result":true,
|
2036
|
-
# "data": {
|
2037
|
-
# "total":1,
|
2038
|
-
# "depositOrders": [
|
2039
|
-
# {
|
2040
|
-
# "insertTime":1649012310000,
|
2041
|
-
# "amount":9.00000000000000000000,
|
2042
|
-
# "address":"TYASr5UV6HEcXatwdFQfmLVUqQQQMUxHLS",
|
2043
|
-
# "networkName":"trc20",
|
2044
|
-
# "txId":"081e4e9351dd0274922168da5f2d14ea6c495b1c3b440244f4a6dd9fe196bf2b",
|
2045
|
-
# "coin":"usdt",
|
2046
|
-
# "status":"2"
|
2047
|
-
# },
|
2048
|
-
# ],
|
2049
|
-
# "page_length":20,
|
2050
|
-
# "current_page":1
|
2051
|
-
# },
|
2052
|
-
# "error_code":0,
|
2053
|
-
# "ts":1649719721758
|
2054
|
-
# }
|
2055
|
-
#
|
2056
|
-
data = self.safe_value(response, 'data', {})
|
2057
|
-
deposits = self.safe_value(data, 'depositOrders', [])
|
2058
|
-
return self.parse_transactions(deposits, currency, since, limit)
|
2059
|
-
|
2060
|
-
async def fetch_withdrawals(self, code: String = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
2061
|
-
"""
|
2062
|
-
fetch all withdrawals made from an account
|
2063
|
-
:see: https://www.lbank.info/en-US/docs/index.html#get-withdrawal-history
|
2064
|
-
:param str code: unified currency code
|
2065
|
-
:param int [since]: the earliest time in ms to fetch withdrawals for
|
2066
|
-
:param int [limit]: the maximum number of withdrawals structures to retrieve
|
2067
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
2068
|
-
:returns dict[]: a list of `transaction structures <https://github.com/ccxt/ccxt/wiki/Manual#transaction-structure>`
|
2069
|
-
"""
|
2070
|
-
await self.load_markets()
|
2071
|
-
request = {
|
2072
|
-
# 'status': Recharge status: ("1","Applying"),("2","Recharge successful"),("3","Recharge failed"),("4","Already Cancel"),("5", "Transfer")
|
2073
|
-
# 'endTime': end time, timestamp in milliseconds, default now
|
2074
|
-
# 'withdrawOrderId': Custom withdrawal id
|
2075
|
-
}
|
2076
|
-
currency = None
|
2077
|
-
if code is not None:
|
2078
|
-
currency = self.currency(code)
|
2079
|
-
request['coin'] = currency['id']
|
2080
|
-
if since is not None:
|
2081
|
-
request['startTime'] = since
|
2082
|
-
response = await self.spotPrivatePostSupplementWithdraws(self.extend(request, params))
|
2083
|
-
#
|
2084
|
-
# {
|
2085
|
-
# "result":true,
|
2086
|
-
# "data": {
|
2087
|
-
# "total":1,
|
2088
|
-
# "withdraws": [
|
2089
|
-
# {
|
2090
|
-
# "amount":2.00000000000000000000,
|
2091
|
-
# "address":"TBjrW5JHDyPZjFc5nrRMhRWUDaJmhGhmD6",
|
2092
|
-
# "fee":1.00000000000000000000,
|
2093
|
-
# "networkName":"trc20",
|
2094
|
-
# "coid":"usdt",
|
2095
|
-
# "transferType":"数字资产提现",
|
2096
|
-
# "txId":"47eeee2763ad49b8817524dacfa7d092fb58f8b0ab7e5d25473314df1a793c3d",
|
2097
|
-
# "id":1902194,
|
2098
|
-
# "applyTime":1649014002000,
|
2099
|
-
# "status":"4"
|
2100
|
-
# },
|
2101
|
-
# ],
|
2102
|
-
# "page_length":20,
|
2103
|
-
# "current_page":1
|
2104
|
-
# },
|
2105
|
-
# "error_code":0,
|
2106
|
-
# "ts":1649720362362
|
2107
|
-
# }
|
2108
|
-
#
|
2109
|
-
data = self.safe_value(response, 'data', {})
|
2110
|
-
withdraws = self.safe_value(data, 'withdraws', [])
|
2111
|
-
return self.parse_transactions(withdraws, currency, since, limit)
|
2112
|
-
|
2113
|
-
async def fetch_transaction_fees(self, codes=None, params={}):
|
2114
|
-
"""
|
2115
|
-
* @deprecated
|
2116
|
-
please use fetchDepositWithdrawFees instead
|
2117
|
-
:param str[]|None codes: not used by lbank2 fetchTransactionFees()
|
2118
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
2119
|
-
:returns dict: a list of `fee structures <https://github.com/ccxt/ccxt/wiki/Manual#fee-structure>`
|
2120
|
-
"""
|
2121
|
-
# private only returns information for currencies with non-zero balance
|
2122
|
-
await self.load_markets()
|
2123
|
-
isAuthorized = self.check_required_credentials(False)
|
2124
|
-
result = None
|
2125
|
-
if isAuthorized is True:
|
2126
|
-
method = self.safe_string(params, 'method')
|
2127
|
-
params = self.omit(params, 'method')
|
2128
|
-
if method is None:
|
2129
|
-
options = self.safe_value(self.options, 'fetchTransactionFees', {})
|
2130
|
-
method = self.safe_string(options, 'method', 'fetchPrivateTransactionFees')
|
2131
|
-
result = await getattr(self, method)(params)
|
2132
|
-
else:
|
2133
|
-
result = await self.fetch_public_transaction_fees(params)
|
2134
|
-
return result
|
2135
|
-
|
2136
|
-
async def fetch_private_transaction_fees(self, params={}):
|
2137
|
-
# complete response
|
2138
|
-
# incl. for coins which None in public method
|
2139
|
-
await self.load_markets()
|
2140
|
-
response = await self.spotPrivatePostSupplementUserInfo()
|
2141
|
-
#
|
2142
|
-
# {
|
2143
|
-
# "result": "true",
|
2144
|
-
# "data": [
|
2145
|
-
# {
|
2146
|
-
# "usableAmt": "14.36",
|
2147
|
-
# "assetAmt": "14.36",
|
2148
|
-
# "networkList": [
|
2149
|
-
# {
|
2150
|
-
# "isDefault": False,
|
2151
|
-
# "withdrawFeeRate": "",
|
2152
|
-
# "name": "erc20",
|
2153
|
-
# "withdrawMin": 30,
|
2154
|
-
# "minLimit": 0.0001,
|
2155
|
-
# "minDeposit": 20,
|
2156
|
-
# "feeAssetCode": "usdt",
|
2157
|
-
# "withdrawFee": "30",
|
2158
|
-
# "type": 1,
|
2159
|
-
# "coin": "usdt",
|
2160
|
-
# "network": "eth"
|
2161
|
-
# },
|
2162
|
-
# ...
|
2163
|
-
# ],
|
2164
|
-
# "freezeAmt": "0",
|
2165
|
-
# "coin": "ada"
|
2166
|
-
# }
|
2167
|
-
# ],
|
2168
|
-
# "code": 0
|
2169
|
-
# }
|
2170
|
-
#
|
2171
|
-
result = self.safe_value(response, 'data', [])
|
2172
|
-
withdrawFees = {}
|
2173
|
-
for i in range(0, len(result)):
|
2174
|
-
entry = result[i]
|
2175
|
-
currencyId = self.safe_string(entry, 'coin')
|
2176
|
-
code = self.safe_currency_code(currencyId)
|
2177
|
-
networkList = self.safe_value(entry, 'networkList', [])
|
2178
|
-
withdrawFees[code] = {}
|
2179
|
-
for j in range(0, len(networkList)):
|
2180
|
-
networkEntry = networkList[j]
|
2181
|
-
networkId = self.safe_string(networkEntry, 'name')
|
2182
|
-
networkCode = self.safe_string(self.options['inverse-networks'], networkId, networkId)
|
2183
|
-
fee = self.safe_number(networkEntry, 'withdrawFee')
|
2184
|
-
if fee is not None:
|
2185
|
-
withdrawFees[code][networkCode] = fee
|
2186
|
-
return {
|
2187
|
-
'withdraw': withdrawFees,
|
2188
|
-
'deposit': {},
|
2189
|
-
'info': response,
|
2190
|
-
}
|
2191
|
-
|
2192
|
-
async def fetch_public_transaction_fees(self, params={}):
|
2193
|
-
# extremely incomplete response
|
2194
|
-
# vast majority fees None
|
2195
|
-
await self.load_markets()
|
2196
|
-
code = self.safe_string_2(params, 'coin', 'assetCode')
|
2197
|
-
params = self.omit(params, ['coin', 'assetCode'])
|
2198
|
-
request = {}
|
2199
|
-
if code is not None:
|
2200
|
-
currency = self.currency(code)
|
2201
|
-
request['assetCode'] = currency['id']
|
2202
|
-
response = await self.spotPublicGetWithdrawConfigs(self.extend(request, params))
|
2203
|
-
#
|
2204
|
-
# {
|
2205
|
-
# "result": "true",
|
2206
|
-
# "data": [
|
2207
|
-
# {
|
2208
|
-
# "amountScale": "4",
|
2209
|
-
# "chain": "heco",
|
2210
|
-
# "assetCode": "lbk",
|
2211
|
-
# "min": "200",
|
2212
|
-
# "transferAmtScale": "4",
|
2213
|
-
# "canWithDraw": True,
|
2214
|
-
# "fee": "100",
|
2215
|
-
# "minTransfer": "0.0001",
|
2216
|
-
# "type": "1"
|
2217
|
-
# },
|
2218
|
-
# ...
|
2219
|
-
# ],
|
2220
|
-
# "error_code": "0",
|
2221
|
-
# "ts": "1663364435973"
|
2222
|
-
# }
|
2223
|
-
#
|
2224
|
-
result = self.safe_value(response, 'data', [])
|
2225
|
-
withdrawFees = {}
|
2226
|
-
for i in range(0, len(result)):
|
2227
|
-
item = result[i]
|
2228
|
-
canWithdraw = self.safe_value(item, 'canWithDraw')
|
2229
|
-
if canWithdraw == 'true':
|
2230
|
-
currencyId = self.safe_string(item, 'assetCode')
|
2231
|
-
codeInner = self.safe_currency_code(currencyId)
|
2232
|
-
chain = self.safe_string(item, 'chain')
|
2233
|
-
network = self.safe_string(self.options['inverse-networks'], chain, chain)
|
2234
|
-
if network is None:
|
2235
|
-
network = codeInner
|
2236
|
-
fee = self.safe_string(item, 'fee')
|
2237
|
-
if withdrawFees[codeInner] is None:
|
2238
|
-
withdrawFees[codeInner] = {}
|
2239
|
-
withdrawFees[codeInner][network] = self.parse_number(fee)
|
2240
|
-
return {
|
2241
|
-
'withdraw': withdrawFees,
|
2242
|
-
'deposit': {},
|
2243
|
-
'info': response,
|
2244
|
-
}
|
2245
|
-
|
2246
|
-
async def fetch_deposit_withdraw_fees(self, codes: List[str] = None, params={}):
|
2247
|
-
"""
|
2248
|
-
when using private endpoint, only returns information for currencies with non-zero balance, use public method by specifying self.options['fetchDepositWithdrawFees']['method'] = 'fetchPublicDepositWithdrawFees'
|
2249
|
-
:see: https://www.lbank.info/en-US/docs/index.html#get-all-coins-information
|
2250
|
-
:see: https://www.lbank.info/en-US/docs/index.html#withdrawal-configurations
|
2251
|
-
:param str[]|None codes: array of unified currency codes
|
2252
|
-
:param dict [params]: extra parameters specific to the lbank2 api endpoint
|
2253
|
-
:returns dict: a list of `fee structures <https://github.com/ccxt/ccxt/wiki/Manual#fee-structure>`
|
2254
|
-
"""
|
2255
|
-
await self.load_markets()
|
2256
|
-
isAuthorized = self.check_required_credentials(False)
|
2257
|
-
method = None
|
2258
|
-
if isAuthorized is True:
|
2259
|
-
method = self.safe_string(params, 'method')
|
2260
|
-
params = self.omit(params, 'method')
|
2261
|
-
if method is None:
|
2262
|
-
options = self.safe_value(self.options, 'fetchDepositWithdrawFees', {})
|
2263
|
-
method = self.safe_string(options, 'method', 'fetchPrivateDepositWithdrawFees')
|
2264
|
-
else:
|
2265
|
-
method = 'fetchPublicDepositWithdrawFees'
|
2266
|
-
return await getattr(self, method)(codes, params)
|
2267
|
-
|
2268
|
-
async def fetch_private_deposit_withdraw_fees(self, codes=None, params={}):
|
2269
|
-
# complete response
|
2270
|
-
# incl. for coins which None in public method
|
2271
|
-
await self.load_markets()
|
2272
|
-
response = await self.spotPrivatePostSupplementUserInfo(params)
|
2273
|
-
#
|
2274
|
-
# {
|
2275
|
-
# "result": "true",
|
2276
|
-
# "data": [
|
2277
|
-
# {
|
2278
|
-
# "usableAmt": "14.36",
|
2279
|
-
# "assetAmt": "14.36",
|
2280
|
-
# "networkList": [
|
2281
|
-
# {
|
2282
|
-
# "isDefault": False,
|
2283
|
-
# "withdrawFeeRate": "",
|
2284
|
-
# "name": "erc20",
|
2285
|
-
# "withdrawMin": 30,
|
2286
|
-
# "minLimit": 0.0001,
|
2287
|
-
# "minDeposit": 20,
|
2288
|
-
# "feeAssetCode": "usdt",
|
2289
|
-
# "withdrawFee": "30",
|
2290
|
-
# "type": 1,
|
2291
|
-
# "coin": "usdt",
|
2292
|
-
# "network": "eth"
|
2293
|
-
# },
|
2294
|
-
# ...
|
2295
|
-
# ],
|
2296
|
-
# "freezeAmt": "0",
|
2297
|
-
# "coin": "ada"
|
2298
|
-
# }
|
2299
|
-
# ],
|
2300
|
-
# "code": 0
|
2301
|
-
# }
|
2302
|
-
#
|
2303
|
-
data = self.safe_value(response, 'data', [])
|
2304
|
-
return self.parse_deposit_withdraw_fees(data, codes, 'coin')
|
2305
|
-
|
2306
|
-
async def fetch_public_deposit_withdraw_fees(self, codes=None, params={}):
|
2307
|
-
# extremely incomplete response
|
2308
|
-
# vast majority fees None
|
2309
|
-
await self.load_markets()
|
2310
|
-
request = {}
|
2311
|
-
response = await self.spotPublicGetWithdrawConfigs(self.extend(request, params))
|
2312
|
-
#
|
2313
|
-
# {
|
2314
|
-
# "result": "true",
|
2315
|
-
# "data": [
|
2316
|
-
# {
|
2317
|
-
# "amountScale": "4",
|
2318
|
-
# "chain": "heco",
|
2319
|
-
# "assetCode": "lbk",
|
2320
|
-
# "min": "200",
|
2321
|
-
# "transferAmtScale": "4",
|
2322
|
-
# "canWithDraw": True,
|
2323
|
-
# "fee": "100",
|
2324
|
-
# "minTransfer": "0.0001",
|
2325
|
-
# "type": "1"
|
2326
|
-
# },
|
2327
|
-
# ...
|
2328
|
-
# ],
|
2329
|
-
# "error_code": "0",
|
2330
|
-
# "ts": "1663364435973"
|
2331
|
-
# }
|
2332
|
-
#
|
2333
|
-
data = self.safe_value(response, 'data', [])
|
2334
|
-
return self.parse_public_deposit_withdraw_fees(data, codes)
|
2335
|
-
|
2336
|
-
def parse_public_deposit_withdraw_fees(self, response, codes=None):
|
2337
|
-
#
|
2338
|
-
# [
|
2339
|
-
# {
|
2340
|
-
# "amountScale": "4",
|
2341
|
-
# "chain": "heco",
|
2342
|
-
# "assetCode": "lbk",
|
2343
|
-
# "min": "200",
|
2344
|
-
# "transferAmtScale": "4",
|
2345
|
-
# "canWithDraw": True,
|
2346
|
-
# "fee": "100",
|
2347
|
-
# "minTransfer": "0.0001",
|
2348
|
-
# "type": "1"
|
2349
|
-
# },
|
2350
|
-
# ...
|
2351
|
-
# ]
|
2352
|
-
#
|
2353
|
-
result = {}
|
2354
|
-
for i in range(0, len(response)):
|
2355
|
-
fee = response[i]
|
2356
|
-
canWithdraw = self.safe_value(fee, 'canWithDraw')
|
2357
|
-
if canWithdraw is True:
|
2358
|
-
currencyId = self.safe_string(fee, 'assetCode')
|
2359
|
-
code = self.safe_currency_code(currencyId)
|
2360
|
-
if codes is None or self.in_array(code, codes):
|
2361
|
-
withdrawFee = self.safe_number(fee, 'fee')
|
2362
|
-
if withdrawFee is not None:
|
2363
|
-
resultValue = self.safe_value(result, code)
|
2364
|
-
if resultValue is None:
|
2365
|
-
result[code] = self.deposit_withdraw_fee([fee])
|
2366
|
-
else:
|
2367
|
-
result[code]['info'].append(fee)
|
2368
|
-
chain = self.safe_string(fee, 'chain')
|
2369
|
-
networkCode = self.safe_string(self.options['inverse-networks'], chain, chain)
|
2370
|
-
if networkCode is not None:
|
2371
|
-
result[code]['networks'][networkCode] = {
|
2372
|
-
'withdraw': {
|
2373
|
-
'fee': withdrawFee,
|
2374
|
-
'percentage': None,
|
2375
|
-
},
|
2376
|
-
'deposit': {
|
2377
|
-
'fee': None,
|
2378
|
-
'percentage': None,
|
2379
|
-
},
|
2380
|
-
}
|
2381
|
-
else:
|
2382
|
-
result[code]['withdraw'] = {
|
2383
|
-
'fee': withdrawFee,
|
2384
|
-
'percentage': None,
|
2385
|
-
}
|
2386
|
-
return result
|
2387
|
-
|
2388
|
-
def parse_deposit_withdraw_fee(self, fee, currency=None):
|
2389
|
-
#
|
2390
|
-
# * only used for fetchPrivateDepositWithdrawFees
|
2391
|
-
#
|
2392
|
-
# {
|
2393
|
-
# "usableAmt": "14.36",
|
2394
|
-
# "assetAmt": "14.36",
|
2395
|
-
# "networkList": [
|
2396
|
-
# {
|
2397
|
-
# "isDefault": False,
|
2398
|
-
# "withdrawFeeRate": "",
|
2399
|
-
# "name": "erc20",
|
2400
|
-
# "withdrawMin": 30,
|
2401
|
-
# "minLimit": 0.0001,
|
2402
|
-
# "minDeposit": 20,
|
2403
|
-
# "feeAssetCode": "usdt",
|
2404
|
-
# "withdrawFee": "30",
|
2405
|
-
# "type": 1,
|
2406
|
-
# "coin": "usdt",
|
2407
|
-
# "network": "eth"
|
2408
|
-
# },
|
2409
|
-
# ...
|
2410
|
-
# ],
|
2411
|
-
# "freezeAmt": "0",
|
2412
|
-
# "coin": "ada"
|
2413
|
-
# }
|
2414
|
-
#
|
2415
|
-
result = self.deposit_withdraw_fee(fee)
|
2416
|
-
networkList = self.safe_value(fee, 'networkList', [])
|
2417
|
-
for j in range(0, len(networkList)):
|
2418
|
-
networkEntry = networkList[j]
|
2419
|
-
networkId = self.safe_string(networkEntry, 'name')
|
2420
|
-
networkCode = self.safe_string_upper(self.options['inverse-networks'], networkId, networkId)
|
2421
|
-
withdrawFee = self.safe_number(networkEntry, 'withdrawFee')
|
2422
|
-
isDefault = self.safe_value(networkEntry, 'isDefault')
|
2423
|
-
if withdrawFee is not None:
|
2424
|
-
if isDefault:
|
2425
|
-
result['withdraw'] = {
|
2426
|
-
'fee': withdrawFee,
|
2427
|
-
'percentage': None,
|
2428
|
-
}
|
2429
|
-
result['networks'][networkCode] = {
|
2430
|
-
'withdraw': {
|
2431
|
-
'fee': withdrawFee,
|
2432
|
-
'percentage': None,
|
2433
|
-
},
|
2434
|
-
'deposit': {
|
2435
|
-
'fee': None,
|
2436
|
-
'percentage': None,
|
2437
|
-
},
|
2438
|
-
}
|
2439
|
-
return result
|
2440
|
-
|
2441
|
-
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
2442
|
-
query = self.omit(params, self.extract_params(path))
|
2443
|
-
url = self.urls['api']['rest'] + '/' + self.version + '/' + self.implode_params(path, params)
|
2444
|
-
# Every spot endpoint ends with ".do"
|
2445
|
-
if api[0] == 'spot':
|
2446
|
-
url += '.do'
|
2447
|
-
else:
|
2448
|
-
url = self.urls['api']['contract'] + '/' + self.implode_params(path, params)
|
2449
|
-
if api[1] == 'public':
|
2450
|
-
if query:
|
2451
|
-
url += '?' + self.urlencode(self.keysort(query))
|
2452
|
-
else:
|
2453
|
-
self.check_required_credentials()
|
2454
|
-
timestamp = str(self.milliseconds())
|
2455
|
-
echostr = self.uuid22() + self.uuid16()
|
2456
|
-
query = self.extend({
|
2457
|
-
'api_key': self.apiKey,
|
2458
|
-
}, query)
|
2459
|
-
signatureMethod = None
|
2460
|
-
if len(self.secret) > 32:
|
2461
|
-
signatureMethod = 'RSA'
|
2462
|
-
else:
|
2463
|
-
signatureMethod = 'HmacSHA256'
|
2464
|
-
auth = self.rawencode(self.keysort(self.extend({
|
2465
|
-
'echostr': echostr,
|
2466
|
-
'signature_method': signatureMethod,
|
2467
|
-
'timestamp': timestamp,
|
2468
|
-
}, query)))
|
2469
|
-
encoded = self.encode(auth)
|
2470
|
-
hash = self.hash(encoded, 'md5')
|
2471
|
-
uppercaseHash = hash.upper()
|
2472
|
-
sign = None
|
2473
|
-
if signatureMethod == 'RSA':
|
2474
|
-
cacheSecretAsPem = self.safe_value(self.options, 'cacheSecretAsPem', True)
|
2475
|
-
pem = None
|
2476
|
-
if cacheSecretAsPem:
|
2477
|
-
pem = self.safe_value(self.options, 'pem')
|
2478
|
-
if pem is None:
|
2479
|
-
pem = self.convert_secret_to_pem(self.encode(self.secret))
|
2480
|
-
self.options['pem'] = pem
|
2481
|
-
else:
|
2482
|
-
pem = self.convert_secret_to_pem(self.encode(self.secret))
|
2483
|
-
sign = self.rsa(uppercaseHash, pem, 'sha256')
|
2484
|
-
elif signatureMethod == 'HmacSHA256':
|
2485
|
-
sign = self.hmac(self.encode(uppercaseHash), self.encode(self.secret), hashlib.sha256)
|
2486
|
-
query['sign'] = sign
|
2487
|
-
body = self.urlencode(self.keysort(query))
|
2488
|
-
headers = {
|
2489
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
2490
|
-
'timestamp': timestamp,
|
2491
|
-
'signature_method': signatureMethod,
|
2492
|
-
'echostr': echostr,
|
2493
|
-
}
|
2494
|
-
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
2495
|
-
|
2496
|
-
def convert_secret_to_pem(self, secret):
|
2497
|
-
lineLength = 64
|
2498
|
-
secretLength = len(secret) - 0
|
2499
|
-
numLines = self.parse_to_int(secretLength / lineLength)
|
2500
|
-
numLines = self.sum(numLines, 1)
|
2501
|
-
pem = "-----BEGIN PRIVATE KEY-----\n" # eslint-disable-line
|
2502
|
-
for i in range(0, numLines):
|
2503
|
-
start = i * lineLength
|
2504
|
-
end = self.sum(start, lineLength)
|
2505
|
-
pem += self.secret[start:end] + "\n" # eslint-disable-line
|
2506
|
-
return pem + '-----END PRIVATE KEY-----'
|
2507
|
-
|
2508
|
-
def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
2509
|
-
if response is None:
|
2510
|
-
return None
|
2511
|
-
success = self.safe_value(response, 'result')
|
2512
|
-
if success == 'false' or not success:
|
2513
|
-
errorCode = self.safe_string(response, 'error_code')
|
2514
|
-
message = self.safe_string({
|
2515
|
-
'10000': 'Internal error',
|
2516
|
-
'10001': 'The required parameters can not be empty',
|
2517
|
-
'10002': 'Validation failed',
|
2518
|
-
'10003': 'Invalid parameter',
|
2519
|
-
'10004': 'Request too frequent',
|
2520
|
-
'10005': 'Secret key does not exist',
|
2521
|
-
'10006': 'User does not exist',
|
2522
|
-
'10007': 'Invalid signature',
|
2523
|
-
'10008': 'Invalid Trading Pair',
|
2524
|
-
'10009': 'Price and/or Amount are required for limit order',
|
2525
|
-
'10010': 'Price and/or Amount must be less than minimum requirement',
|
2526
|
-
# '10011': 'Market orders can not be missing the amount of the order',
|
2527
|
-
# '10012': 'market sell orders can not be missing orders',
|
2528
|
-
'10013': 'The amount is too small',
|
2529
|
-
'10014': 'Insufficient amount of money in the account',
|
2530
|
-
'10015': 'Invalid order type',
|
2531
|
-
'10016': 'Insufficient account balance',
|
2532
|
-
'10017': 'Server Error',
|
2533
|
-
'10018': 'Page size should be between 1 and 50',
|
2534
|
-
'10019': 'Cancel NO more than 3 orders in one request',
|
2535
|
-
'10020': 'Volume < 0.001',
|
2536
|
-
'10021': 'Price < 0.01',
|
2537
|
-
'10022': 'Invalid authorization',
|
2538
|
-
'10023': 'Market Order is not supported yet',
|
2539
|
-
'10024': 'User cannot trade on self pair',
|
2540
|
-
'10025': 'Order has been filled',
|
2541
|
-
'10026': 'Order has been cancelld',
|
2542
|
-
'10027': 'Order is cancelling',
|
2543
|
-
'10028': 'Wrong query time',
|
2544
|
-
'10029': 'from is not in the query time',
|
2545
|
-
'10030': 'from do not match the transaction type of inqury',
|
2546
|
-
'10031': 'echostr length must be valid and length must be from 30 to 40',
|
2547
|
-
'10033': 'Failed to create order',
|
2548
|
-
'10036': 'customID duplicated',
|
2549
|
-
'10100': 'Has no privilege to withdraw',
|
2550
|
-
'10101': 'Invalid fee rate to withdraw',
|
2551
|
-
'10102': 'Too little to withdraw',
|
2552
|
-
'10103': 'Exceed daily limitation of withdraw',
|
2553
|
-
'10104': 'Cancel was rejected',
|
2554
|
-
'10105': 'Request has been cancelled',
|
2555
|
-
'10106': 'None trade time',
|
2556
|
-
'10107': 'Start price exception',
|
2557
|
-
'10108': 'can not create order',
|
2558
|
-
'10109': 'wallet address is not mapping',
|
2559
|
-
'10110': 'transfer fee is not mapping',
|
2560
|
-
'10111': 'mount > 0',
|
2561
|
-
'10112': 'fee is too lower',
|
2562
|
-
'10113': 'transfer fee is 0',
|
2563
|
-
'10600': 'intercepted by replay attacks filter, check timestamp',
|
2564
|
-
'10601': 'Interface closed unavailable',
|
2565
|
-
'10701': 'invalid asset code',
|
2566
|
-
'10702': 'not allowed deposit',
|
2567
|
-
}, errorCode, self.json(response))
|
2568
|
-
ErrorClass = self.safe_value({
|
2569
|
-
'10001': BadRequest,
|
2570
|
-
'10002': AuthenticationError,
|
2571
|
-
'10003': BadRequest,
|
2572
|
-
'10004': RateLimitExceeded,
|
2573
|
-
'10005': AuthenticationError,
|
2574
|
-
'10006': AuthenticationError,
|
2575
|
-
'10007': AuthenticationError,
|
2576
|
-
'10008': BadSymbol,
|
2577
|
-
'10009': InvalidOrder,
|
2578
|
-
'10010': InvalidOrder,
|
2579
|
-
'10013': InvalidOrder,
|
2580
|
-
'10014': InsufficientFunds,
|
2581
|
-
'10015': InvalidOrder,
|
2582
|
-
'10016': InsufficientFunds,
|
2583
|
-
'10017': ExchangeError,
|
2584
|
-
'10018': BadRequest,
|
2585
|
-
'10019': BadRequest,
|
2586
|
-
'10020': BadRequest,
|
2587
|
-
'10021': InvalidOrder,
|
2588
|
-
'10022': PermissionDenied, # 'Invalid authorization',
|
2589
|
-
'10023': InvalidOrder, # 'Market Order is not supported yet',
|
2590
|
-
'10024': PermissionDenied, # 'User cannot trade on self pair',
|
2591
|
-
'10025': InvalidOrder, # 'Order has been filled',
|
2592
|
-
'10026': InvalidOrder, # 'Order has been cancelled',
|
2593
|
-
'10027': InvalidOrder, # 'Order is cancelling',
|
2594
|
-
'10028': BadRequest, # 'Wrong query time',
|
2595
|
-
'10029': BadRequest, # 'from is not in the query time',
|
2596
|
-
'10030': BadRequest, # 'from do not match the transaction type of inqury',
|
2597
|
-
'10031': InvalidNonce, # 'echostr length must be valid and length must be from 30 to 40',
|
2598
|
-
'10033': ExchangeError, # 'Failed to create order',
|
2599
|
-
'10036': DuplicateOrderId, # 'customID duplicated',
|
2600
|
-
'10100': PermissionDenied, # 'Has no privilege to withdraw',
|
2601
|
-
'10101': BadRequest, # 'Invalid fee rate to withdraw',
|
2602
|
-
'10102': InsufficientFunds, # 'Too little to withdraw',
|
2603
|
-
'10103': ExchangeError, # 'Exceed daily limitation of withdraw',
|
2604
|
-
'10104': ExchangeError, # 'Cancel was rejected',
|
2605
|
-
'10105': ExchangeError, # 'Request has been cancelled',
|
2606
|
-
'10106': BadRequest, # 'None trade time',
|
2607
|
-
'10107': BadRequest, # 'Start price exception',
|
2608
|
-
'10108': ExchangeError, # 'can not create order',
|
2609
|
-
'10109': InvalidAddress, # 'wallet address is not mapping',
|
2610
|
-
'10110': ExchangeError, # 'transfer fee is not mapping',
|
2611
|
-
'10111': BadRequest, # 'mount > 0',
|
2612
|
-
'10112': BadRequest, # 'fee is too lower',
|
2613
|
-
'10113': BadRequest, # 'transfer fee is 0',
|
2614
|
-
'10600': BadRequest, # 'intercepted by replay attacks filter, check timestamp',
|
2615
|
-
'10601': ExchangeError, # 'Interface closed unavailable',
|
2616
|
-
'10701': BadSymbol, # 'invalid asset code',
|
2617
|
-
'10702': PermissionDenied, # 'not allowed deposit',
|
2618
|
-
}, errorCode, ExchangeError)
|
2619
|
-
raise ErrorClass(message)
|
2620
|
-
return None
|