ccxt 4.4.82__py2.py3-none-any.whl → 4.4.86__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. ccxt/__init__.py +3 -9
  2. ccxt/abstract/blofin.py +8 -0
  3. ccxt/abstract/btcbox.py +1 -0
  4. ccxt/abstract/myokx.py +2 -0
  5. ccxt/abstract/okx.py +2 -0
  6. ccxt/apex.py +2 -1
  7. ccxt/ascendex.py +187 -151
  8. ccxt/async_support/__init__.py +3 -9
  9. ccxt/async_support/apex.py +2 -1
  10. ccxt/async_support/ascendex.py +187 -151
  11. ccxt/async_support/base/exchange.py +51 -24
  12. ccxt/async_support/base/ws/cache.py +6 -1
  13. ccxt/async_support/bequant.py +1 -1
  14. ccxt/async_support/bitget.py +5 -6
  15. ccxt/async_support/bitmart.py +1 -1
  16. ccxt/async_support/bitrue.py +14 -32
  17. ccxt/async_support/bitso.py +33 -0
  18. ccxt/async_support/bitstamp.py +33 -0
  19. ccxt/async_support/{huobijp.py → bittrade.py} +11 -11
  20. ccxt/async_support/blofin.py +145 -14
  21. ccxt/async_support/btcbox.py +25 -5
  22. ccxt/async_support/bybit.py +16 -37
  23. ccxt/async_support/cex.py +2 -4
  24. ccxt/async_support/coinbase.py +58 -47
  25. ccxt/async_support/coinbaseexchange.py +141 -32
  26. ccxt/async_support/coincatch.py +14 -67
  27. ccxt/async_support/coinex.py +28 -29
  28. ccxt/async_support/coinlist.py +17 -16
  29. ccxt/async_support/coinmetro.py +20 -11
  30. ccxt/async_support/coinone.py +8 -10
  31. ccxt/async_support/coinsph.py +124 -2
  32. ccxt/async_support/cryptocom.py +109 -2
  33. ccxt/async_support/cryptomus.py +42 -80
  34. ccxt/async_support/delta.py +75 -36
  35. ccxt/async_support/deribit.py +4 -5
  36. ccxt/async_support/derive.py +46 -10
  37. ccxt/async_support/ellipx.py +175 -77
  38. ccxt/async_support/gate.py +1 -1
  39. ccxt/async_support/gemini.py +3 -4
  40. ccxt/async_support/hitbtc.py +56 -65
  41. ccxt/async_support/hollaex.py +106 -49
  42. ccxt/async_support/htx.py +20 -43
  43. ccxt/async_support/hyperliquid.py +6 -6
  44. ccxt/async_support/kraken.py +27 -23
  45. ccxt/async_support/kucoinfutures.py +5 -0
  46. ccxt/async_support/lbank.py +1 -1
  47. ccxt/async_support/mexc.py +2 -2
  48. ccxt/async_support/ndax.py +25 -24
  49. ccxt/async_support/okcoin.py +12 -29
  50. ccxt/async_support/okx.py +9 -0
  51. ccxt/async_support/onetrading.py +10 -7
  52. ccxt/async_support/oxfun.py +40 -110
  53. ccxt/async_support/paradex.py +123 -4
  54. ccxt/base/exchange.py +21 -2
  55. ccxt/base/types.py +3 -0
  56. ccxt/bequant.py +1 -1
  57. ccxt/bitget.py +5 -6
  58. ccxt/bitmart.py +1 -1
  59. ccxt/bitrue.py +14 -32
  60. ccxt/bitso.py +33 -0
  61. ccxt/bitstamp.py +33 -0
  62. ccxt/{huobijp.py → bittrade.py} +11 -11
  63. ccxt/blofin.py +145 -14
  64. ccxt/btcbox.py +24 -5
  65. ccxt/bybit.py +16 -37
  66. ccxt/cex.py +2 -4
  67. ccxt/coinbase.py +58 -47
  68. ccxt/coinbaseexchange.py +141 -32
  69. ccxt/coincatch.py +14 -67
  70. ccxt/coinex.py +28 -29
  71. ccxt/coinlist.py +17 -16
  72. ccxt/coinmetro.py +20 -11
  73. ccxt/coinone.py +8 -10
  74. ccxt/coinsph.py +124 -2
  75. ccxt/cryptocom.py +109 -2
  76. ccxt/cryptomus.py +42 -80
  77. ccxt/delta.py +75 -36
  78. ccxt/deribit.py +4 -5
  79. ccxt/derive.py +46 -10
  80. ccxt/ellipx.py +175 -77
  81. ccxt/gate.py +1 -1
  82. ccxt/gemini.py +3 -4
  83. ccxt/hitbtc.py +56 -65
  84. ccxt/hollaex.py +106 -49
  85. ccxt/htx.py +20 -43
  86. ccxt/hyperliquid.py +6 -6
  87. ccxt/kraken.py +27 -23
  88. ccxt/kucoinfutures.py +5 -0
  89. ccxt/lbank.py +1 -1
  90. ccxt/mexc.py +2 -2
  91. ccxt/ndax.py +25 -24
  92. ccxt/okcoin.py +12 -29
  93. ccxt/okx.py +9 -0
  94. ccxt/onetrading.py +10 -7
  95. ccxt/oxfun.py +40 -110
  96. ccxt/paradex.py +123 -4
  97. ccxt/pro/__init__.py +109 -5
  98. ccxt/pro/binance.py +32 -33
  99. ccxt/pro/bithumb.py +5 -3
  100. ccxt/pro/{huobijp.py → bittrade.py} +3 -3
  101. ccxt/pro/kraken.py +249 -79
  102. ccxt/pro/luno.py +6 -5
  103. ccxt/pro/mexc.py +254 -7
  104. ccxt/pro/poloniex.py +6 -2
  105. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/METADATA +8 -11
  106. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/RECORD +110 -121
  107. ccxt/abstract/bl3p.py +0 -19
  108. ccxt/abstract/idex.py +0 -26
  109. ccxt/abstract/kuna.py +0 -182
  110. ccxt/async_support/base/ws/fast_client.py +0 -97
  111. ccxt/async_support/bl3p.py +0 -543
  112. ccxt/async_support/idex.py +0 -1889
  113. ccxt/async_support/kuna.py +0 -1935
  114. ccxt/bl3p.py +0 -543
  115. ccxt/idex.py +0 -1889
  116. ccxt/kuna.py +0 -1935
  117. ccxt/pro/idex.py +0 -687
  118. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  119. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/LICENSE.txt +0 -0
  120. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/WHEEL +0 -0
  121. {ccxt-4.4.82.dist-info → ccxt-4.4.86.dist-info}/top_level.txt +0 -0
ccxt/kuna.py DELETED
@@ -1,1935 +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.base.exchange import Exchange
7
- from ccxt.abstract.kuna import ImplicitAPI
8
- import hashlib
9
- import json
10
- from ccxt.base.types import Any, Balances, Currencies, Currency, DepositAddress, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction
11
- from typing import List
12
- from ccxt.base.errors import ExchangeError
13
- from ccxt.base.errors import ArgumentsRequired
14
- from ccxt.base.errors import BadRequest
15
- from ccxt.base.errors import InsufficientFunds
16
- from ccxt.base.errors import InvalidOrder
17
- from ccxt.base.errors import OrderNotFound
18
- from ccxt.base.errors import NotSupported
19
- from ccxt.base.decimal_to_precision import TICK_SIZE
20
- from ccxt.base.precise import Precise
21
-
22
-
23
- class kuna(Exchange, ImplicitAPI):
24
-
25
- def describe(self) -> Any:
26
- return self.deep_extend(super(kuna, self).describe(), {
27
- 'id': 'kuna',
28
- 'name': 'Kuna',
29
- 'countries': ['UA'],
30
- 'rateLimit': 1000, # on private endpoints rateLimit = 200 for authenticated users, 50 for pro/vip users
31
- 'version': 'v4',
32
- 'has': {
33
- 'CORS': None,
34
- 'spot': True,
35
- 'margin': False,
36
- 'swap': False,
37
- 'future': False,
38
- 'option': False,
39
- 'addMargin': False,
40
- 'cancelOrder': True,
41
- 'cancelOrders': True,
42
- 'closeAllPositions': False,
43
- 'closePosition': False,
44
- 'createDepositAddress': True,
45
- 'createOrder': True,
46
- 'createPostOnlyOrder': False,
47
- 'createReduceOnlyOrder': False,
48
- 'createStopLimitOrder': True,
49
- 'createStopMarketOrder': False,
50
- 'createStopOrder': True,
51
- 'fetchBalance': True,
52
- 'fetchBorrowInterest': False,
53
- 'fetchBorrowRateHistories': False,
54
- 'fetchBorrowRateHistory': False,
55
- 'fetchClosedOrders': True,
56
- 'fetchCrossBorrowRate': False,
57
- 'fetchCrossBorrowRates': False,
58
- 'fetchCurrencies': True,
59
- 'fetchDeposit': True,
60
- 'fetchDepositAddress': True,
61
- 'fetchDepositAddresses': False,
62
- 'fetchDepositAddressesByNetwork': False,
63
- 'fetchDeposits': True,
64
- 'fetchDepositsWithdrawals': False,
65
- 'fetchFundingHistory': False,
66
- 'fetchFundingRate': False,
67
- 'fetchFundingRateHistory': False,
68
- 'fetchFundingRates': False,
69
- 'fetchIndexOHLCV': False,
70
- 'fetchIsolatedBorrowRate': False,
71
- 'fetchIsolatedBorrowRates': False,
72
- 'fetchIsolatedPositions': False,
73
- 'fetchL3OrderBook': True,
74
- 'fetchLeverage': False,
75
- 'fetchLeverageTiers': False,
76
- 'fetchMarginMode': False,
77
- 'fetchMarketLeverageTiers': False,
78
- 'fetchMarkets': True,
79
- 'fetchMarkOHLCV': False,
80
- 'fetchMyTrades': True,
81
- 'fetchOHLCV': False,
82
- 'fetchOpenInterest': False,
83
- 'fetchOpenInterestHistory': False,
84
- 'fetchOpenOrders': True,
85
- 'fetchOrder': True,
86
- 'fetchOrderBook': True,
87
- 'fetchOrdersByStatus': True,
88
- 'fetchPosition': False,
89
- 'fetchPositionMode': False,
90
- 'fetchPositions': False,
91
- 'fetchPositionsForSymbol': False,
92
- 'fetchPositionsRisk': False,
93
- 'fetchPremiumIndexOHLCV': False,
94
- 'fetchTicker': True,
95
- 'fetchTickers': True,
96
- 'fetchTime': True,
97
- 'fetchTrades': True,
98
- 'fetchTradingFee': False,
99
- 'fetchTradingFees': False,
100
- 'fetchTransactions': False,
101
- 'fetchTransfers': False,
102
- 'fetchWithdrawAddresses': False,
103
- 'fetchWithdrawal': True,
104
- 'fetchWithdrawals': True,
105
- 'reduceMargin': False,
106
- 'repayCrossMargin': False,
107
- 'repayIsolatedMargin': False,
108
- 'setLeverage': False,
109
- 'setMargin': False,
110
- 'setMarginMode': False,
111
- 'setPositionMode': False,
112
- 'signIn': False,
113
- 'transfer': False,
114
- 'withdraw': True,
115
- },
116
- 'timeframes': None,
117
- 'urls': {
118
- 'extension': '.json',
119
- 'referral': 'https://kuna.io?r=kunaid-gvfihe8az7o4',
120
- 'logo': 'https://user-images.githubusercontent.com/51840849/87153927-f0578b80-c2c0-11ea-84b6-74612568e9e1.jpg',
121
- 'api': {
122
- 'xreserve': 'https://api.xreserve.fund',
123
- 'v3': 'https://api.kuna.io',
124
- 'v4': 'https://api.kuna.io',
125
- 'public': 'https://kuna.io', # v2
126
- 'private': 'https://kuna.io', # v2
127
- },
128
- 'www': 'https://kuna.io',
129
- 'doc': 'https://kuna.io/documents/api',
130
- 'fees': 'https://kuna.io/documents/api',
131
- },
132
- 'api': {
133
- 'xreserve': {
134
- 'get': {
135
- 'nonce': 1,
136
- 'fee': 1,
137
- 'delegated-transactions': 1,
138
- },
139
- 'post': {
140
- 'delegate-transfer': 1,
141
- },
142
- },
143
- 'v4': {
144
- 'private': {
145
- 'get': {
146
- 'private/me': 1,
147
- 'private/getBalance': 1,
148
- 'order/private/active': 1,
149
- 'order/private/history': 1,
150
- 'order/private/{id}/trades': 1,
151
- 'order/private/details/{id}': 1,
152
- 'trade/private/history': 1,
153
- 'transaction/private/{hash}': 1,
154
- 'deposit/private/preRequest': 1,
155
- 'deposit/private/crypto/address': 1,
156
- 'deposit/private/crypto/getMerchantAddress': 1,
157
- 'deposit/private/history': 1,
158
- 'deposit/private/details/{depositId}': 1,
159
- 'withdraw/private/preRequest': 1,
160
- 'withdraw/private/history': 1,
161
- 'withdraw/private/details/{withdrawId}': 1,
162
- 'kuna-code/{id}': 1,
163
- 'kuna-code/{code}/check': 1,
164
- 'kuna-code/issued-by-me': 1,
165
- 'kuna-code/redeemed-by-me': 1,
166
- },
167
- 'post': {
168
- 'order/private/create': 1,
169
- 'order/private/cancel': 1,
170
- 'order/private/cancel/multi': 1,
171
- 'deposit/private/crypto/generateAddress': 1,
172
- 'deposit/private/crypto/generateMerchantAddress': 1,
173
- 'withdraw/private/create': 1,
174
- 'kuna-code': 1,
175
- },
176
- 'put': {
177
- 'kuna-code/redeem': 1,
178
- },
179
- },
180
- 'public': {
181
- 'get': {
182
- 'public/timestamp': 1,
183
- 'public/fees': 1,
184
- 'public/currencies?type={type}': 1,
185
- 'public/currencies': 1,
186
- 'markets/public/getAll': 1,
187
- 'markets/public/tickers?pairs={pairs}': 1,
188
- 'order/public/book/{pairs}': 1,
189
- 'trade/public/book/{pairs}': 1,
190
- },
191
- },
192
- },
193
- 'v3': {
194
- 'public': {
195
- 'get': {
196
- 'timestamp': 1,
197
- 'currencies': 1,
198
- 'markets': 1,
199
- 'tickers': 1,
200
- 'k': 1,
201
- 'trades_history': 1,
202
- 'fees': 1,
203
- 'exchange-rates': 1,
204
- 'exchange-rates/currency': 1,
205
- 'book/market': 1,
206
- 'kuna_codes/code/check': 1,
207
- 'landing_page_statistic': 1,
208
- 'translations/locale': 1,
209
- 'trades/market/hist': 1,
210
- },
211
- 'post': {
212
- 'http_test': 1,
213
- 'deposit_channels': 1,
214
- 'withdraw_channels': 1,
215
- 'subscription_plans': 1,
216
- 'send_to': 1,
217
- 'confirm_token': 1,
218
- 'kunaid': 1,
219
- 'withdraw/prerequest': 1,
220
- 'deposit/prerequest': 1,
221
- 'deposit/exchange-rates': 1,
222
- },
223
- },
224
- 'sign': {
225
- 'get': {
226
- 'reset_password/token': 1,
227
- },
228
- 'post': {
229
- 'signup/google': 1,
230
- 'signup/resend_confirmation': 1,
231
- 'signup': 1,
232
- 'signin': 1,
233
- 'signin/two_factor': 1,
234
- 'signin/resend_confirm_device': 1,
235
- 'signin/confirm_device': 1,
236
- 'reset_password': 1,
237
- 'cool-signin': 1,
238
- },
239
- 'put': {
240
- 'reset_password/token': 1,
241
- 'signup/code/confirm': 1,
242
- },
243
- },
244
- 'private': {
245
- 'post': {
246
- 'auth/w/order/submit': 1,
247
- 'auth/r/orders': 1,
248
- 'auth/r/orders/market': 1,
249
- 'auth/r/orders/markets': 1,
250
- 'auth/api_tokens/delete': 1,
251
- 'auth/api_tokens/create': 1,
252
- 'auth/api_tokens': 1,
253
- 'auth/signin_history/uniq': 1,
254
- 'auth/signin_history': 1,
255
- 'auth/disable_withdraw_confirmation': 1,
256
- 'auth/change_password': 1,
257
- 'auth/deposit_address': 1,
258
- 'auth/announcements/accept': 1,
259
- 'auth/announcements/unaccepted': 1,
260
- 'auth/otp/deactivate': 1,
261
- 'auth/otp/activate': 1,
262
- 'auth/otp/secret': 1,
263
- 'auth/r/order/market/:order_id/trades': 1,
264
- 'auth/r/orders/market/hist': 1,
265
- 'auth/r/orders/hist': 1,
266
- 'auth/r/orders/hist/markets': 1,
267
- 'auth/r/orders/details': 1,
268
- 'auth/assets-history': 1,
269
- 'auth/assets-history/withdraws': 1,
270
- 'auth/assets-history/deposits': 1,
271
- 'auth/r/wallets': 1,
272
- 'auth/markets/favorites': 1,
273
- 'auth/markets/favorites/list': 1,
274
- 'auth/me/update': 1,
275
- 'auth/me': 1,
276
- 'auth/fund_sources': 1,
277
- 'auth/fund_sources/list': 1,
278
- 'auth/withdraw/resend_confirmation': 1,
279
- 'auth/withdraw': 1,
280
- 'auth/withdraw/details': 1,
281
- 'auth/withdraw/info': 1,
282
- 'auth/payment_addresses': 1,
283
- 'auth/deposit/prerequest': 1,
284
- 'auth/deposit/exchange-rates': 1,
285
- 'auth/deposit': 1,
286
- 'auth/deposit/details': 1,
287
- 'auth/deposit/info': 1,
288
- 'auth/kuna_codes/count': 1,
289
- 'auth/kuna_codes/details': 1,
290
- 'auth/kuna_codes/edit': 1,
291
- 'auth/kuna_codes/send-pdf': 1,
292
- 'auth/kuna_codes': 1,
293
- 'auth/kuna_codes/redeemed-by-me': 1,
294
- 'auth/kuna_codes/issued-by-me': 1,
295
- 'auth/payment_requests/invoice': 1,
296
- 'auth/payment_requests/type': 1,
297
- 'auth/referral_program/weekly_earnings': 1,
298
- 'auth/referral_program/stats': 1,
299
- 'auth/merchant/payout_services': 1,
300
- 'auth/merchant/withdraw': 1,
301
- 'auth/merchant/payment_services': 1,
302
- 'auth/merchant/deposit': 1,
303
- 'auth/verification/auth_token': 1,
304
- 'auth/kunaid_purchase/create': 1,
305
- 'auth/devices/list': 1,
306
- 'auth/sessions/list': 1,
307
- 'auth/subscriptions/reactivate': 1,
308
- 'auth/subscriptions/cancel': 1,
309
- 'auth/subscriptions/prolong': 1,
310
- 'auth/subscriptions/create': 1,
311
- 'auth/subscriptions/list': 1,
312
- 'auth/kuna_ids/list': 1,
313
- 'order/cancel/multi': 1,
314
- 'order/cancel': 1,
315
- },
316
- 'put': {
317
- 'auth/fund_sources/id': 1,
318
- 'auth/kuna_codes/redeem': 1,
319
- },
320
- 'delete': {
321
- 'auth/markets/favorites': 1,
322
- 'auth/fund_sources': 1,
323
- 'auth/devices': 1,
324
- 'auth/devices/list': 1,
325
- 'auth/sessions/list': 1,
326
- 'auth/sessions': 1,
327
- },
328
- },
329
- },
330
- 'public': {
331
- 'get': [
332
- 'depth', # Get depth or specified market Both asks and bids are sorted from highest price to lowest.
333
- 'k_with_pending_trades', # Get K data with pending trades, which are the trades not included in K data yet, because there's delay between trade generated and processed by K data generator
334
- 'k', # Get OHLC(k line) of specific market
335
- 'markets', # Get all available markets
336
- 'order_book', # Get the order book of specified market
337
- 'order_book/{market}',
338
- 'tickers', # Get ticker of all markets
339
- 'tickers/{market}', # Get ticker of specific market
340
- 'timestamp', # Get server current time, in seconds since Unix epoch
341
- 'trades', # Get recent trades on market, each trade is included only once Trades are sorted in reverse creation order.
342
- 'trades/{market}',
343
- ],
344
- },
345
- 'private': {
346
- 'get': [
347
- 'members/me', # Get your profile and accounts info
348
- 'deposits', # Get your deposits history
349
- 'deposit', # Get details of specific deposit
350
- 'deposit_address', # Where to deposit The address field could be empty when a new address is generating(e.g. for bitcoin), you should try again later in that case.
351
- 'orders', # Get your orders, results is paginated
352
- 'order', # Get information of specified order
353
- 'trades/my', # Get your executed trades Trades are sorted in reverse creation order.
354
- 'withdraws', # Get your cryptocurrency withdraws
355
- 'withdraw', # Get your cryptocurrency withdraw
356
- ],
357
- 'post': [
358
- 'orders', # Create a Sell/Buy order
359
- 'orders/multi', # Create multiple sell/buy orders
360
- 'orders/clear', # Cancel all my orders
361
- 'order/delete', # Cancel an order
362
- 'withdraw', # Create a withdraw
363
- ],
364
- },
365
- },
366
- 'features': {
367
- 'spot': {
368
- 'sandbox': False,
369
- 'createOrder': {
370
- 'marginMode': False,
371
- 'triggerPrice': True,
372
- 'triggerPriceType': None,
373
- 'triggerDirection': False,
374
- 'stopLossPrice': False, # todo
375
- 'takeProfitPrice': False, # todo
376
- 'attachedStopLossTakeProfit': None,
377
- 'timeInForce': {
378
- 'IOC': False,
379
- 'FOK': False,
380
- 'PO': False,
381
- 'GTD': False,
382
- },
383
- 'hedged': False,
384
- 'selfTradePrevention': False,
385
- 'trailing': False,
386
- 'leverage': False,
387
- 'marketBuyByCost': True,
388
- 'marketBuyRequiresPrice': False,
389
- 'iceberg': False,
390
- },
391
- 'createOrders': None,
392
- 'fetchMyTrades': None, # todo implement
393
- 'fetchOrder': {
394
- 'marginMode': False,
395
- 'trigger': False,
396
- 'trailing': False,
397
- 'symbolRequired': False,
398
- },
399
- 'fetchOpenOrders': {
400
- 'marginMode': False,
401
- 'limit': 100,
402
- 'trigger': False,
403
- 'trailing': False,
404
- 'symbolRequired': False,
405
- },
406
- 'fetchOrders': None,
407
- 'fetchClosedOrders': {
408
- 'marginMode': False,
409
- 'limit': 100,
410
- 'daysBack': 100000, # todo
411
- 'daysBackCanceled': 1,
412
- 'untilDays': 14,
413
- 'trigger': False,
414
- 'trailing': False,
415
- 'symbolRequired': False,
416
- },
417
- 'fetchOHLCV': None,
418
- },
419
- 'swap': {
420
- 'linear': None,
421
- 'inverse': None,
422
- },
423
- 'future': {
424
- 'linear': None,
425
- 'inverse': None,
426
- },
427
- },
428
- 'fees': {
429
- 'trading': {
430
- 'tierBased': False,
431
- 'percentage': True,
432
- 'taker': self.parse_number('0.0025'),
433
- 'maker': self.parse_number('0.0025'),
434
- },
435
- 'funding': {
436
- 'withdraw': {
437
- 'UAH': '1%',
438
- 'BTC': 0.001,
439
- 'BCH': 0.001,
440
- 'ETH': 0.01,
441
- 'WAVES': 0.01,
442
- 'GOL': 0.0,
443
- 'GBG': 0.0,
444
- # 'RMC': 0.001 BTC
445
- # 'ARN': 0.01 ETH
446
- # 'R': 0.01 ETH
447
- # 'EVR': 0.01 ETH
448
- },
449
- 'deposit': {
450
- # 'UAH': (amount) => amount * 0.001 + 5
451
- },
452
- },
453
- },
454
- 'commonCurrencies': {
455
- 'PLA': 'Plair',
456
- },
457
- 'precisionMode': TICK_SIZE,
458
- 'exceptions': {
459
- 'ARGUMENT_VALIDATION_ERROR': BadRequest,
460
- 'PAYMENT_METHOD_NOT_SUPPORTED': BadRequest,
461
- 'NOT_FOUND': OrderNotFound,
462
- 'INVALID:ORDER_SIZE': InvalidOrder,
463
- 'WrongRequestException': BadRequest,
464
- 'INSUFFICIENT_FUNDS': InsufficientFunds,
465
- '2002': InsufficientFunds,
466
- '2003': OrderNotFound,
467
- },
468
- 'options': {
469
- # 'account': 'pro' # Only for pro accounts
470
- },
471
- })
472
-
473
- def fetch_time(self, params={}) -> Int:
474
- """
475
- fetches the current integer timestamp in milliseconds from the exchange server
476
-
477
- https://docs.kuna.io/docs/get-time-on-the-server
478
-
479
- :param dict [params]: extra parameters specific to the exchange API endpoint
480
- :returns int: the current integer timestamp in milliseconds from the exchange server
481
- """
482
- response = self.v4PublicGetPublicTimestamp(params)
483
- #
484
- # {
485
- # "data": {
486
- # "timestamp": 1686740531,
487
- # "timestamp_miliseconds": 1686740531725,
488
- # }
489
- # }
490
- #
491
- data = self.safe_value(response, 'data', {})
492
- return self.safe_integer(data, 'timestamp_miliseconds')
493
-
494
- def fetch_currencies(self, params={}) -> Currencies:
495
- """
496
- fetches all available currencies on an exchange
497
-
498
- https://docs.kuna.io/docs/get-information-about-available-currencies
499
-
500
- :param dict [params]: extra parameters specific to the exchange API endpoint
501
- :returns dict: an associative dictionary of currencies
502
- """
503
- response = self.v4PublicGetPublicCurrencies(params)
504
- #
505
- # {
506
- # "data": [
507
- # {
508
- # "code": "BTC",
509
- # "name": "Bitcoin",
510
- # "payload": {
511
- # "chart": "https://kuna-pro.kuna.io/bitcoin-chart",
512
- # "icons": {
513
- # "svg": "https://kuna-pro.kuna.io/icon-btc-svg",
514
- # "png2x": "https://kuna-pro.kuna.io/icon-btc-png2x",
515
- # "png3x": "https://kuna-pro.kuna.io/icon-btc-png3x",
516
- # "svgXL": "https://kuna-pro.kuna.io/icon-btc-svg"
517
- # },
518
- # "pngChart": "https://kuna-pro.kuna.io/png-bitcoin-chart"
519
- # },
520
- # "position": 1,
521
- # "precision": 8,
522
- # "tradePrecision": 6,
523
- # "type": "Crypto"
524
- # }
525
- # ]
526
- # }
527
- #
528
- data = self.safe_value(response, 'data', [])
529
- return self.parse_currencies(data)
530
-
531
- def parse_currency(self, currency: dict) -> Currency:
532
- #
533
- # {
534
- # "code": "BTC",
535
- # "name": "Bitcoin",
536
- # "payload": {
537
- # "chart": "https://kuna-pro.kuna.io/bitcoin-chart",
538
- # "icons": {
539
- # "svg": "https://kuna-pro.kuna.io/icon-btc-svg",
540
- # "png2x": "https://kuna-pro.kuna.io/icon-btc-png2x",
541
- # "png3x": "https://kuna-pro.kuna.io/icon-btc-png3x",
542
- # "svgXL": "https://kuna-pro.kuna.io/icon-btc-svg"
543
- # },
544
- # "pngChart": "https://kuna-pro.kuna.io/png-bitcoin-chart"
545
- # },
546
- # "position": 1,
547
- # "precision": 8,
548
- # "tradePrecision": 6,
549
- # "type": "Crypto"
550
- # }
551
- #
552
- currencyId = self.safe_string(currency, 'code')
553
- precision = self.safe_string(currency, 'precision')
554
- tradePrecision = self.safe_string(currency, 'tradePrecision')
555
- return self.safe_currency_structure({
556
- 'info': currency,
557
- 'id': currencyId,
558
- 'code': self.safe_currency_code(currencyId),
559
- 'type': None,
560
- 'margin': None,
561
- 'name': self.safe_string(currency, 'name'),
562
- 'active': None,
563
- 'deposit': None,
564
- 'withdraw': None,
565
- 'fee': None,
566
- 'precision': self.parse_number(Precise.string_min(precision, tradePrecision)),
567
- 'limits': {
568
- 'amount': {
569
- 'min': None,
570
- 'max': None,
571
- },
572
- 'withdraw': {
573
- 'min': None,
574
- 'max': None,
575
- },
576
- },
577
- 'networks': {},
578
- })
579
-
580
- def fetch_markets(self, params={}) -> List[Market]:
581
- """
582
- retrieves data on all markets for kuna
583
-
584
- https://docs.kuna.io/docs/get-all-traded-markets
585
-
586
- :param dict [params]: extra parameters specific to the exchange API endpoint
587
- :returns dict[]: an array of objects representing market data
588
- """
589
- response = self.v4PublicGetMarketsPublicGetAll(params)
590
- #
591
- # {
592
- # "data": [
593
- # {
594
- # "pair": "BTC_USDT", # Traded pair of assets
595
- # "baseAsset": { # The base asset of the traded pair, the one to sell or buy result of the trade
596
- # "code": "BTC",
597
- # "precision": 6 # Maximum amount of digits for the decimal part of a number
598
- # },
599
- # "quoteAsset": { # The quoted asset of the traded pair, the one to use to sell or buy the base asset
600
- # "code": "USDT",
601
- # "precision": 2 # Maximum amount of digits for the decimal part of a number
602
- # },
603
- # "tickerPriceChange": "-0.07" # Relative change compared with the last tick
604
- # }
605
- # ]
606
- # }
607
- #
608
- data = self.safe_value(response, 'data', [])
609
- markets = []
610
- for i in range(0, len(data)):
611
- item = data[i]
612
- marketId = self.safe_string(item, 'pair')
613
- baseAsset = self.safe_value(item, 'baseAsset')
614
- quoteAsset = self.safe_value(item, 'quoteAsset')
615
- baseId = self.safe_string(baseAsset, 'code')
616
- quoteId = self.safe_string(quoteAsset, 'code')
617
- base = self.safe_currency_code(baseId)
618
- quote = self.safe_currency_code(quoteId)
619
- basePrecision = self.safe_string(baseAsset, 'precision')
620
- quotePrecision = self.safe_string(quoteAsset, 'precision')
621
- markets.append({
622
- 'id': marketId,
623
- 'symbol': base + '/' + quote,
624
- 'base': base,
625
- 'quote': quote,
626
- 'settle': None,
627
- 'baseId': baseId,
628
- 'quoteId': quoteId,
629
- 'settleId': None,
630
- 'type': 'spot',
631
- 'spot': True,
632
- 'margin': False,
633
- 'swap': False,
634
- 'future': False,
635
- 'option': False,
636
- 'active': None,
637
- 'contract': False,
638
- 'linear': None,
639
- 'inverse': None,
640
- 'contractSize': None,
641
- 'expiry': None,
642
- 'expiryDatetime': None,
643
- 'strike': None,
644
- 'optionType': None,
645
- 'precision': {
646
- 'amount': self.parse_number(self.parse_precision(basePrecision)),
647
- 'price': self.parse_number(self.parse_precision(quotePrecision)),
648
- },
649
- 'limits': {
650
- 'leverage': {
651
- 'min': None,
652
- 'max': None,
653
- },
654
- 'amount': {
655
- 'min': None,
656
- 'max': None,
657
- },
658
- 'price': {
659
- 'min': None,
660
- 'max': None,
661
- },
662
- 'cost': {
663
- 'min': None,
664
- 'max': None,
665
- },
666
- },
667
- 'created': None,
668
- 'info': item,
669
- })
670
- return markets
671
-
672
- def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
673
- """
674
- fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
675
-
676
- https://docs.kuna.io/docs/get-public-orders-book
677
-
678
- :param str symbol: unified symbol of the market to fetch the order book for
679
- :param int [limit]: 5, 10, 20, 50, 100, 500, or 1000(default)
680
- :param dict [params]: extra parameters specific to the exchange API endpoint
681
- :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
682
- """
683
- self.load_markets()
684
- market = self.market(symbol)
685
- request: dict = {
686
- 'pairs': market['id'],
687
- }
688
- if limit is not None:
689
- request['level'] = limit
690
- response = self.v4PublicGetOrderPublicBookPairs(self.extend(request, params))
691
- #
692
- # {
693
- # "data": {
694
- # "asks": [ # An array of sell orders
695
- # [
696
- # "16950", # Sell price, level 1
697
- # "0.001" # Sell quantity, level 1
698
- # ],
699
- # [
700
- # "17000", # Sell price, level 2
701
- # "0.01" # Sell quantity, level 2
702
- # ]
703
- # ],
704
- # "bids": [ # An array of buy orders
705
- # [
706
- # "16700", # Sell price, level 1
707
- # "0.01" # Sell quantity, level 1
708
- # ],
709
- # [
710
- # "16000", # Sell price, level 2
711
- # "0.001" # Sell quantity, level 2
712
- # ]
713
- # ]
714
- # }
715
- # }
716
- #
717
- data = self.safe_dict(response, 'data', {})
718
- return self.parse_order_book(data, market['symbol'], None, 'bids', 'asks', 0, 1)
719
-
720
- def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
721
- #
722
- # {
723
- # "pair": "BTC_USDT", # Traded pair
724
- # "percentagePriceChange": "-0.03490931899641581", # Relative price change, in percent
725
- # "price": "27900", # Current median price
726
- # "equivalentPrice": "", # TBD
727
- # "high": "29059.69", # Highest price
728
- # "low": "27900", # Lowest price
729
- # "baseVolume": "2.9008499999999993", # Traded volume
730
- # "quoteVolume": "82251.41477976", # Traded volume
731
- # "bestBidPrice": "27926.91", # The best bid price now
732
- # "bestAskPrice": "27970.02", # The best ask price now
733
- # "priceChange": "-973.9700000000012" # Absolute price change
734
- # }
735
- #
736
- marketId = self.safe_string(ticker, 'pair')
737
- return self.safe_ticker({
738
- 'info': ticker,
739
- 'symbol': self.safe_symbol(marketId, market),
740
- 'timestamp': None,
741
- 'datetime': None,
742
- 'high': self.safe_string(ticker, 'high'),
743
- 'low': self.safe_string(ticker, 'low'),
744
- 'bid': self.safe_string(ticker, 'bestBidPrice'),
745
- 'ask': self.safe_string(ticker, 'bestAskPrice'),
746
- 'vwap': None,
747
- 'open': self.safe_string(ticker, 'open'),
748
- 'close': None,
749
- 'last': None,
750
- 'previousClose': None,
751
- 'change': self.safe_string(ticker, 'priceChange'),
752
- 'percentage': self.safe_string(ticker, 'percentagePriceChange'),
753
- 'average': None,
754
- 'baseVolume': self.safe_string(ticker, 'baseVolume'),
755
- 'quoteVolume': self.safe_string(ticker, 'quoteVolume'),
756
- }, market)
757
-
758
- def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
759
- """
760
- fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market. The average is not returned in the response, but the median can be accessed via response['info']['price']
761
-
762
- https://docs.kuna.io/docs/get-market-info-by-tickers
763
-
764
- :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
765
- :param dict [params]: extra parameters specific to the exchange API endpoint
766
- :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
767
- """
768
- self.load_markets()
769
- if symbols is None:
770
- raise ArgumentsRequired(self.id + ' fetchTickers() requires a symbols argument')
771
- symbols = self.market_symbols(symbols)
772
- marketIds = self.market_ids(symbols)
773
- request: dict = {
774
- 'pairs': ','.join(marketIds),
775
- }
776
- response = self.v4PublicGetMarketsPublicTickersPairsPairs(self.extend(request, params))
777
- #
778
- # {
779
- # "data": [
780
- # {
781
- # "pair": "BTC_USDT", # Traded pair
782
- # "percentagePriceChange": "-0.03490931899641581", # Relative price change, in percent
783
- # "price": "27900", # Current median price
784
- # "equivalentPrice": "", # TBD
785
- # "high": "29059.69", # Highest price
786
- # "low": "27900", # Lowest price
787
- # "baseVolume": "2.9008499999999993", # Traded volume
788
- # "quoteVolume": "82251.41477976", # Traded volume
789
- # "bestBidPrice": "27926.91", # The best bid price now
790
- # "bestAskPrice": "27970.02", # The best ask price now
791
- # "priceChange": "-973.9700000000012" # Absolute price change
792
- # }
793
- # ...
794
- # ]
795
- # }
796
- #
797
- data = self.safe_list(response, 'data', [])
798
- return self.parse_tickers(data, symbols, params)
799
-
800
- def fetch_ticker(self, symbol: str, params={}) -> Ticker:
801
- """
802
- fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
803
-
804
- https://docs.kuna.io/docs/get-market-info-by-tickers
805
-
806
- :param str symbol: unified symbol of the market to fetch the ticker for
807
- :param dict [params]: extra parameters specific to the exchange API endpoint
808
- :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
809
- """
810
- self.load_markets()
811
- market = self.market(symbol)
812
- request: dict = {
813
- 'pairs': market['id'],
814
- }
815
- response = self.v4PublicGetMarketsPublicTickersPairsPairs(self.extend(request, params))
816
- #
817
- # {
818
- # "data": [
819
- # {
820
- # "pair": "BTC_USDT", # Traded pair
821
- # "percentagePriceChange": "-0.03490931899641581", # Relative price change, in percent
822
- # "price": "27900", # Current median price
823
- # "equivalentPrice": "", # TBD
824
- # "high": "29059.69", # Highest price
825
- # "low": "27900", # Lowest price
826
- # "baseVolume": "2.9008499999999993", # Traded volume
827
- # "quoteVolume": "82251.41477976", # Traded volume
828
- # "bestBidPrice": "27926.91", # The best bid price now
829
- # "bestAskPrice": "27970.02", # The best ask price now
830
- # "priceChange": "-973.9700000000012" # Absolute price change
831
- # }
832
- # ...
833
- # ]
834
- # }
835
- #
836
- data = self.safe_value(response, 'data', [])
837
- ticker = self.safe_dict(data, 0)
838
- return self.parse_ticker(ticker, market)
839
-
840
- def fetch_l3_order_book(self, symbol: str, limit: Int = None, params={}):
841
- """
842
- TODO: double check
843
- fetches level 3 information on open orders with bid(buy) and ask(sell) prices, volumes and other data
844
- :param str symbol: unified market symbol
845
- :param int [limit]: max number of orders to return, default is None
846
- :param dict [params]: extra parameters specific to the exchange API endpoint
847
- :returns dict: an `order book structure <https://docs.ccxt.com/#/?id=order-book-structure>`
848
- """
849
- return self.fetch_order_book(symbol, limit, params)
850
-
851
- def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
852
- """
853
- get the list of most recent trades for a particular symbol
854
-
855
- https://docs.kuna.io/docs/get-public-trades-book
856
-
857
- :param str symbol: unified symbol of the market to fetch trades for
858
- :param int [since]: timestamp in ms of the earliest trade to fetch
859
- :param int [limit]: between 1 and 100, 25 by default
860
- :param dict [params]: extra parameters specific to the exchange API endpoint
861
- :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
862
- """
863
- self.load_markets()
864
- market = self.market(symbol)
865
- request: dict = {
866
- 'pairs': market['id'],
867
- }
868
- if limit is not None:
869
- request['limit'] = limit
870
- response = self.v4PublicGetTradePublicBookPairs(self.extend(request, params))
871
- #
872
- # {
873
- # 'data': [
874
- # {
875
- # 'createdAt': '2024-03-02T00:10:49.385Z',
876
- # 'id': '3b42878a-3688-4bc1-891e-5cc2fc902142',
877
- # 'matchPrice': '62181.31',
878
- # 'matchQuantity': '0.00568',
879
- # 'pair': 'BTC_USDT',
880
- # 'quoteQuantity': '353.1898408',
881
- # 'side': 'Bid'
882
- # },
883
- # ...
884
- # ]
885
- # }
886
- #
887
- data = self.safe_list(response, 'data', [])
888
- return self.parse_trades(data, market, since, limit)
889
-
890
- def parse_trade(self, trade: dict, market: Market = None) -> Trade:
891
- #
892
- # fetchTrades(public)
893
- #
894
- # {
895
- # "id": "3e5591ba-2778-4d85-8851-54284045ea44", # Unique identifier of a trade
896
- # "pair": "BTC_USDT", # Market pair that is being traded
897
- # "quoteQuantity": "11528.8118", # Qty of the quote asset, hasattr(self, USDT) example
898
- # "matchPrice": "18649", # Exchange price at the moment of execution
899
- # "matchQuantity": "0.6182", # Qty of the base asset, hasattr(self, BTC) example
900
- # "createdAt": "2022-09-23T14:30:41.486Z", # Date-time of trade execution, UTC
901
- # "side": "Ask" # Trade type: `Ask` or `Bid`. Bid for buying base asset, Ask for selling base asset(e.g. for BTC_USDT trading pair, BTC is the base asset).
902
- # }
903
- #
904
- # fetchMyTrades, fetchOrder(private)
905
- #
906
- # {
907
- # "id": "edb17459-c9bf-4148-9ae6-7367d7f55d71", # Unique identifier of a trade
908
- # "orderId": "a80bec3f-4ffa-45c1-9d78-f6301e9748fe", # Unique identifier of an order associated with the trade
909
- # "pair": "BTC_USDT", # Traded pair, base asset first, followed by quoted asset
910
- # "quantity": "1.5862", # Traded quantity of base asset
911
- # "price": "19087", # Price of the trade
912
- # "isTaker": True, # Various fees for Makers and Takers; "Market" orders are always `true`
913
- # "fee": "0.0039655", # Exchange commission fee
914
- # "feeCurrency": "BTC", # Currency of the commission
915
- # "isBuyer": True, # Buy or sell the base asset
916
- # "quoteQuantity": "30275.7994", # Quote asset quantity spent to fulfill the base amount
917
- # "createdAt": "2022-09-29T13:43:53.824Z", # Date-time of trade execution, UTC
918
- # }
919
- #
920
- datetime = self.safe_string(trade, 'createdAt')
921
- marketId = self.safe_string(trade, 'pair')
922
- isTaker = self.safe_value(trade, 'isMaker')
923
- side = self.safe_string_lower(trade, 'side')
924
- if side is None:
925
- isBuyer = self.safe_value(trade, 'isBuyer')
926
- side = 'buy' if isBuyer else 'sell'
927
- return self.safe_trade({
928
- 'info': trade,
929
- 'id': self.safe_string(trade, 'id'),
930
- 'symbol': self.safe_symbol(marketId, market),
931
- 'timestamp': self.parse8601(datetime),
932
- 'datetime': datetime,
933
- 'type': None,
934
- 'side': side,
935
- 'order': self.safe_string(trade, 'orderId'),
936
- 'takerOrMaker': 'taker' if isTaker else 'maker',
937
- 'price': self.safe_string_2(trade, 'matchPrice', 'price'),
938
- 'amount': self.safe_string_2(trade, 'matchQuantity', 'quantity'),
939
- 'cost': self.safe_string(trade, 'quoteQuantity'),
940
- 'fee': {
941
- 'cost': self.safe_string(trade, 'fee'),
942
- 'currency': self.safe_currency_code(self.safe_string(trade, 'feeCurrency')),
943
- },
944
- }, market)
945
-
946
- def parse_balance(self, response) -> Balances:
947
- #
948
- # [
949
- # {
950
- # "currency": "UAH",
951
- # "balance": "7134.6",
952
- # "lockBalance": "100"
953
- # }
954
- # ...
955
- # ]
956
- #
957
- result: dict = {'info': response}
958
- for i in range(0, len(response)):
959
- balance = response[i]
960
- currencyId = self.safe_string(balance, 'currency')
961
- code = self.safe_currency_code(currencyId)
962
- account = self.account()
963
- account['free'] = self.safe_string(balance, 'balance')
964
- account['used'] = self.safe_string(balance, 'lockBalance')
965
- result[code] = account
966
- return self.safe_balance(result)
967
-
968
- def fetch_balance(self, params={}) -> Balances:
969
- """
970
- query for balance and get the amount of funds available for trading or funds locked in orders
971
- :param dict [params]: extra parameters specific to the exchange API endpoint
972
- :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
973
- """
974
- self.load_markets()
975
- response = self.v4PrivateGetPrivateGetBalance(params)
976
- #
977
- # {
978
- # "data": [{
979
- # "currency": "UAH", # Wallet currency
980
- # "balance": "7134.6", # Available balance, precision depends on the currency
981
- # "lockBalance": "100" # Minimum amount locked on the balance
982
- # }]
983
- # }
984
- #
985
- data = self.safe_value(response, 'data', [])
986
- return self.parse_balance(data)
987
-
988
- def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
989
- """
990
- create a trade order
991
-
992
- https://docs.kuna.io/docs/create-a-new-order-private
993
-
994
- :param str symbol: unified symbol of the market to create an order in
995
- :param str type: 'market' or 'limit'
996
- :param str side: 'buy' or 'sell'
997
- :param float amount: how much of currency you want to trade in units of base currency
998
- :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
999
- :param dict [params]: extra parameters specific to the exchange API endpoint
1000
- :param float [params.triggerPrice]: the price at which a trigger order is triggered at
1001
-
1002
- EXCHANGE SPECIFIC PARAMETERS
1003
- :param str [params.id]: id must be a UUID format, if you do not specify id, it will be generated automatically.
1004
- :param float [params.quoteQuantity]: the max quantity of the quote asset to use for selling/buying
1005
- :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1006
- """
1007
- self.load_markets()
1008
- market = self.market(symbol)
1009
- triggerPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
1010
- params = self.omit(params, ['triggerPrice', 'stopPrice'])
1011
- capitalizedType = self.capitalize(type)
1012
- request: dict = {
1013
- 'pair': market['id'],
1014
- 'orderSide': 'Bid' if (side == 'buy') else 'Ask',
1015
- 'quantity': self.number_to_string(amount),
1016
- 'type': capitalizedType,
1017
- }
1018
- if capitalizedType == 'Limit':
1019
- request['price'] = self.price_to_precision(market['symbol'], price)
1020
- if triggerPrice is not None:
1021
- if capitalizedType == 'Market':
1022
- raise BadRequest(self.id + ' createOrder() cannot place trigger market orders, or trigger limit')
1023
- request['stopPrice'] = self.price_to_precision(market['symbol'], triggerPrice)
1024
- if capitalizedType != 'TakeProfitLimit':
1025
- request['type'] = 'StopLossLimit'
1026
- response = self.v4PrivatePostOrderPrivateCreate(self.extend(request, params))
1027
- #
1028
- # {
1029
- # "data": {
1030
- # "id": "b0fcb54c-2278-4f16-a300-02765faad8b0", # ID of your newly created order
1031
- # "type": "Limit", # Type of an order
1032
- # "quantity": "0.06", # Original order quantity
1033
- # "executedQuantity": "0", # Traded quantity in stock(>0 if traded)
1034
- # "pair": "BTC_USDT", # Traded pair
1035
- # "price": "26440.46", # Price of the trade
1036
- # "status": "Open", # The status of the order
1037
- # "createdAt": "2023-07-11T08:01:30.550Z", # Date-time of order creation, UTC
1038
- # "updatedAt": "2023-07-11T08:01:30.550Z" # Date-time of the last update of the order, UTC
1039
- # }
1040
- # }
1041
- #
1042
- data = self.safe_dict(response, 'data', {})
1043
- return self.parse_order(data, market)
1044
-
1045
- def cancel_order(self, id: str, symbol: Str = None, params={}):
1046
- """
1047
- cancels an open order
1048
- :param str id: order id
1049
- :param str symbol: unified market symbol
1050
- :param dict [params]: extra parameters specific to the exchange API endpoint
1051
- :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1052
- """
1053
- self.load_markets()
1054
- request: dict = {
1055
- 'orderId': id,
1056
- }
1057
- response = self.v4PrivatePostOrderPrivateCancel(self.extend(request, params))
1058
- #
1059
- # {
1060
- # "data": {
1061
- # "success": True
1062
- # }
1063
- # }
1064
- #
1065
- data = self.safe_value(response, 'data', {})
1066
- market = None
1067
- if symbol is not None:
1068
- market = self.market(symbol)
1069
- order = self.parse_order(data, market)
1070
- order['id'] = id
1071
- return order
1072
-
1073
- def cancel_orders(self, ids: List[str], symbol: Str = None, params={}):
1074
- """
1075
- cancels an open order
1076
- :param str ids: order ids
1077
- :param str symbol: not used by kuna cancelOrder
1078
- :param dict [params]: extra parameters specific to the exchange API endpoint
1079
- :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1080
- """
1081
- self.load_markets()
1082
- request: dict = {
1083
- 'orderIds': ids,
1084
- }
1085
- response = self.v4PrivatePostOrderPrivateCancelMulti(self.extend(request, params))
1086
- #
1087
- # {
1088
- # "data": [
1089
- # {
1090
- # "id": "c7fc5b2b-bd9d-48c1-a458-a83412669fe2", # Unique identifier of a canceled order
1091
- # "success": True # Status for self order
1092
- # },
1093
- # ...
1094
- # ]
1095
- # }
1096
- #
1097
- data = self.safe_list(response, 'data', [])
1098
- return self.parse_orders(data)
1099
-
1100
- def parse_order_status(self, status: Str):
1101
- statuses: dict = {
1102
- 'Canceled': 'canceled',
1103
- 'Closed': 'filled',
1104
- 'Pending': 'open',
1105
- 'Open': 'open',
1106
- 'done': 'closed',
1107
- 'wait': 'open',
1108
- 'cancel': 'canceled',
1109
- }
1110
- return self.safe_string(statuses, status, status)
1111
-
1112
- def parse_order(self, order: dict, market: Market = None) -> Order:
1113
- #
1114
- # createOrder, fetchOrder, fetchOpenOrders, fetchOrdersByStatus
1115
- #
1116
- # {
1117
- # "id": "5992a049-8612-409d-8599-2c3d7298b106", # Unique identifier of an order
1118
- # "type": "Limit", # Type of an order
1119
- # "quantity": "5", # Original order quantity
1120
- # "executedQuantity": "0", # Traded quantity in stock(>0 if traded)
1121
- # "cumulativeQuoteQty": "0", # *absent on createOrder* Traded quantity in money(>0 if traded)
1122
- # "cost": "0.05", # Total amount
1123
- # "side": "Bid", # *absent on createOrder* Bid for buying base asset, Ask for selling base asset. FYI: For BTC_USDT trading pair, BTC is the base asset
1124
- # "pair": "TRX_USDT", # Traded pair
1125
- # "price": "0.01", # Price of the trade
1126
- # "status": "Open", # The status of the order
1127
- # "createdAt": "2023-07-11T07:04:20.131Z", # Date-time of order creation, UTC
1128
- # "updatedAt": "2023-07-11T07:04:20.131Z" # Date-time of the last update of the order, UTC
1129
- # "closedAt": "2023-05-08T08:53:58.333Z" # *absent on fetchOpenOrders/createOrder* Date-time of order finish time, UTC
1130
- # "trades": [ # * fetchOrder only *
1131
- # {
1132
- # "id": "15ff497c-8d25-4155-8184-bb1f905cce1e", # Unique identifier of a trade
1133
- # "orderId": "4b9b9705-e85f-4180-bdec-219fbf025fa3", # Unique identifier of an associated order
1134
- # "pair": "BTC_USDT", # Traded pair
1135
- # "quantity": "0.00054", # Traded quantity
1136
- # "price": "27770", # Traded price
1137
- # "isTaker": False, # Various fees for Makers and Takers; "Market" orders are always `true`
1138
- # "fee": "0.000001350", # Exchange commission fee
1139
- # "feeCurrency": "BTC", # Currency of the commission
1140
- # "isBuyer": True, # Buy or sell the base asset
1141
- # "quoteQuantity": "14.9958", # Quote asset quantity
1142
- # "createdAt": "2023-05-08T08:53:58.332Z" # Date-time of trade execution, UTC
1143
- # }
1144
- # ]
1145
- # }
1146
- #
1147
- # cancelOrder, cancelOrders
1148
- #
1149
- # {
1150
- # "id": "c7fc5b2b-bd9d-48c1-a458-a83412669fe2", # Unique identifier of a canceled order *absent on cancelOrder*
1151
- # "success": True # Status for self order
1152
- # }
1153
- #
1154
- marketId = self.safe_string(order, 'pair')
1155
- datetime = self.safe_string(order, 'createdAt')
1156
- side = self.safe_string(order, 'side')
1157
- if side == 'Bid':
1158
- side = 'buy'
1159
- elif side == 'Ask':
1160
- side = 'sell'
1161
- trades = self.safe_value(order, 'trades', [])
1162
- return self.safe_order({
1163
- 'info': order,
1164
- 'id': self.safe_string_2(order, 'id', 'orderId'),
1165
- 'clientOrderId': None,
1166
- 'symbol': self.safe_symbol(marketId, market),
1167
- 'timestamp': self.parse8601(datetime),
1168
- 'datetime': datetime,
1169
- 'lastTradeTimestamp': self.parse8601(self.safe_string(order, 'updatedAt')),
1170
- 'status': self.parse_order_status(self.safe_string(order, 'status')),
1171
- 'type': self.safe_string_lower(order, 'type'),
1172
- 'timeInForce': None,
1173
- 'postOnly': None,
1174
- 'side': side,
1175
- 'price': self.safe_string(order, 'price'),
1176
- 'triggerPrice': self.safe_string(order, 'stopPrice'),
1177
- 'amount': self.safe_string(order, 'quantity'),
1178
- 'filled': self.safe_string(order, 'executedQuantity'),
1179
- 'remaining': None,
1180
- 'trades': self.parse_trades(trades),
1181
- 'cost': self.safe_string(order, 'cost'),
1182
- 'average': None,
1183
- 'fee': None,
1184
- }, market)
1185
-
1186
- def fetch_order(self, id: str, symbol: Str = None, params={}):
1187
- """
1188
- fetches information on an order made by the user
1189
-
1190
- https://docs.kuna.io/docs/get-order-details-by-id
1191
-
1192
- :param str id: order id
1193
- :param str symbol: not used by kuna fetchOrder
1194
- :param dict [params]: extra parameters specific to the exchange API endpoint
1195
-
1196
- EXCHANGE SPECIFIC PARAMETERS
1197
- :param boolean [params.withTrades]: default is True, specify if the response should include trades associated with the order
1198
- :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1199
- """
1200
- self.load_markets()
1201
- request: dict = {
1202
- 'id': id,
1203
- 'withTrades': True,
1204
- }
1205
- response = self.v4PrivateGetOrderPrivateDetailsId(self.extend(request, params))
1206
- #
1207
- # {
1208
- # "data": {
1209
- # "id": "4b9b9705-e85f-4180-bdec-219fbf025fa3",
1210
- # "type": "Limit",
1211
- # "quantity": "0.00054",
1212
- # "executedQuantity": "0.00054",
1213
- # "cumulativeQuoteQty": "14.99580",
1214
- # "cost": "14.9958",
1215
- # "side": "Bid",
1216
- # "pair": "BTC_USDT",
1217
- # "price": "27770",
1218
- # "status": "Closed",
1219
- # "createdAt": "2023-05-08T08:39:46.708Z",
1220
- # "updatedAt": "2023-05-08T08:53:58.332Z",
1221
- # "closedAt": "2023-05-08T08:53:58.333Z",
1222
- # "trades": [
1223
- # {
1224
- # "id": "15ff497c-8d25-4155-8184-bb1f905cce1e", # Unique identifier of a trade
1225
- # "orderId": "4b9b9705-e85f-4180-bdec-219fbf025fa3", # Unique identifier of an associated order
1226
- # "pair": "BTC_USDT", # Traded pair
1227
- # "quantity": "0.00054", # Traded quantity
1228
- # "price": "27770", # Traded price
1229
- # "isTaker": False, # Various fees for Makers and Takers; "Market" orders are always `true`
1230
- # "fee": "0.000001350", # Exchange commission fee
1231
- # "feeCurrency": "BTC", # Currency of the commission
1232
- # "isBuyer": True, # Buy or sell the base asset
1233
- # "quoteQuantity": "14.9958", # Quote asset quantity
1234
- # "createdAt": "2023-05-08T08:53:58.332Z" # Date-time of trade execution, UTC
1235
- # }
1236
- # ]
1237
- # }
1238
- # }
1239
- #
1240
- data = self.safe_dict(response, 'data', {})
1241
- return self.parse_order(data)
1242
-
1243
- def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1244
- """
1245
- fetch all unfilled currently open orders
1246
-
1247
- https://docs.kuna.io/docs/get-active-client-orders-private
1248
-
1249
- :param str symbol: unified market symbol
1250
- :param int [since]: the earliest time in ms to fetch open orders for
1251
- :param int [limit]: 1-100, the maximum number of open orders structures to retrieve
1252
- :param dict [params]: extra parameters specific to the exchange API endpoint
1253
- :param int [params.until]: the latest timestamp(ms) to fetch orders for
1254
-
1255
- EXCHANGE SPECIFIC PARAMETERS
1256
- :param str [params.sort]: asc(oldest-on-top) or desc(newest-on-top)
1257
- :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1258
- """
1259
- self.load_markets()
1260
- until = self.safe_integer(params, 'until')
1261
- params = self.omit(params, ['until'])
1262
- market = None
1263
- request: dict = {
1264
- }
1265
- if symbol is not None:
1266
- market = self.market(symbol)
1267
- request['pairs'] = market['id']
1268
- if since is not None:
1269
- request['start'] = self.iso8601(since)
1270
- if limit is not None:
1271
- request['limit'] = limit
1272
- if until is not None:
1273
- request['end'] = self.iso8601(until)
1274
- response = self.v4PrivateGetOrderPrivateActive(self.extend(request, params))
1275
- #
1276
- # {
1277
- # "data": [
1278
- # {
1279
- # "id": "5992a049-8612-409d-8599-2c3d7298b106", # Unique identifier of an order
1280
- # "type": "Limit", # Type of an order
1281
- # "quantity": "5", # Original order quantity
1282
- # "executedQuantity": "0", # Traded quantity in stock(>0 if traded)
1283
- # "cumulativeQuoteQty": "0", # Traded quantity in money(>0 if traded)
1284
- # "cost": "0.05", # Total amount
1285
- # "side": "Bid", # Bid for buying base asset, Ask for selling base asset. FYI: For BTC_USDT trading pair, BTC is the base asset
1286
- # "pair": "TRX_USDT", # Traded pair
1287
- # "price": "0.01", # Price of the trade
1288
- # "status": "Open", # The status of the order
1289
- # "createdAt": "2023-07-11T07:04:20.131Z", # Date-time of order creation, UTC
1290
- # "updatedAt": "2023-07-11T07:04:20.131Z" # Date-time of the last update of the order, UTC
1291
- # }
1292
- # ...
1293
- # ]
1294
- # }
1295
- #
1296
- data = self.safe_list(response, 'data', [])
1297
- return self.parse_orders(data, market, since, limit)
1298
-
1299
- def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1300
- """
1301
- fetches information on multiple closed orders made by the user
1302
-
1303
- https://docs.kuna.io/docs/get-private-orders-history
1304
-
1305
- :param str symbol: unified market symbol of the market orders were made in
1306
- :param int [since]: the earliest time in ms to fetch orders for
1307
- :param int [limit]: the maximum number of order structures to retrieve
1308
- :param dict [params]: extra parameters specific to the exchange API endpoint
1309
- :param int [params.until]: the latest time in ms to fetch orders for
1310
-
1311
- EXCHANGE SPECIFIC PARAMETERS
1312
- :param str [params.sort]: asc(oldest-on-top) or desc(newest-on-top)
1313
- :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1314
- """
1315
- return self.fetch_orders_by_status('closed', symbol, since, limit, params)
1316
-
1317
- def fetch_orders_by_status(self, status, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1318
- """
1319
- fetch a list of orders
1320
-
1321
- https://docs.kuna.io/docs/get-private-orders-history
1322
-
1323
- :param str status: canceled, closed, expired, open, pending, rejected, or waitStop
1324
- :param str symbol: unified market symbol of the market orders were made in
1325
- :param int [since]: the earliest time in ms to fetch orders for
1326
- :param int [limit]: 1-100, the maximum number of open orders structures to retrieve
1327
- :param dict [params]: extra parameters specific to the exchange API endpoint
1328
- :param int [params.until]: the latest timestamp(ms) to fetch orders for
1329
-
1330
- EXCHANGE SPECIFIC PARAMETERS
1331
- :param str [params.sort]: asc(oldest-on-top) or desc(newest-on-top)
1332
- :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1333
- """
1334
- self.load_markets()
1335
- if status == 'open':
1336
- return self.fetch_open_orders(symbol, since, limit, params)
1337
- until = self.safe_integer(params, 'until')
1338
- params = self.omit(params, ['until'])
1339
- market = None
1340
- request: dict = {
1341
- 'status': self.capitalize(status),
1342
- }
1343
- if symbol is not None:
1344
- market = self.market(symbol)
1345
- request['pairs'] = market['id']
1346
- if since is not None:
1347
- request['start'] = self.iso8601(since)
1348
- if limit is not None:
1349
- request['limit'] = limit
1350
- if until is not None:
1351
- request['end'] = self.iso8601(until)
1352
- response = self.v4PrivateGetOrderPrivateHistory(request)
1353
- #
1354
- # {
1355
- # "data": [
1356
- # {
1357
- # "id": "4b9b9705-e85f-4180-bdec-219fbf025fa3", # Unique identifier of an order
1358
- # "type": "Limit", # Type of an order
1359
- # "quantity": "0.00054", # Original order quantity
1360
- # "executedQuantity": "0.00054", # Traded quantity in stock(>0 if traded)
1361
- # "cumulativeQuoteQty": "14.99580", # Traded quantity in money(>0 if traded)
1362
- # "cost": "14.9958", # Total amount
1363
- # "side": "Bid", # Bid for buying base asset, Ask for selling base asset. FYI: For BTC_USDT trading pair, BTC is the base asset
1364
- # "pair": "BTC_USDT", # Traded pair
1365
- # "price": "27770", # Price of the trade
1366
- # "status": "Closed", # The status of the order
1367
- # "createdAt": "2023-05-08T08:39:46.708Z", # Date-time of order creation, UTC
1368
- # "updatedAt": "2023-05-08T08:53:58.332Z", # Date-time of the last update of the order, UTC
1369
- # "closedAt": "2023-05-08T08:53:58.333Z" # Date-time of order finish time, UTC
1370
- # },
1371
- # ...
1372
- # ]
1373
- # }
1374
- #
1375
- data = self.safe_list(response, 'data', [])
1376
- return self.parse_orders(data, market, since, limit)
1377
-
1378
- def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1379
- """
1380
- fetch all trades made by the user
1381
-
1382
- https://docs.kuna.io/docs/get-private-trades-history
1383
-
1384
- :param str symbol: unified market symbol
1385
- :param int [since]: not used by kuna fetchMyTrades
1386
- :param int [limit]: not used by kuna fetchMyTrades
1387
- :param dict [params]: extra parameters specific to the exchange API endpoint
1388
-
1389
- EXCHANGE SPECIFIC PARAMETERS
1390
- :param str [params.orderId]: UUID of an order, to receive trades for self order only
1391
- :param str [params.sort]: asc(oldest-on-top) or desc(newest-on-top)
1392
- :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1393
- """
1394
- self.load_markets()
1395
- market = None
1396
- request: dict = {}
1397
- if symbol is not None:
1398
- market = self.market(symbol)
1399
- request['pair'] = market['id']
1400
- response = self.v4PrivateGetTradePrivateHistory(self.extend(request, params))
1401
- #
1402
- # {
1403
- # "data": [
1404
- # {
1405
- # "id": "edb17459-c9bf-4148-9ae6-7367d7f55d71", # Unique identifier of a trade
1406
- # "orderId": "a80bec3f-4ffa-45c1-9d78-f6301e9748fe", # Unique identifier of an order associated with the trade
1407
- # "pair": "BTC_USDT", # Traded pair, base asset first, followed by quoted asset
1408
- # "quantity": "1.5862", # Traded quantity of base asset
1409
- # "price": "19087", # Price of the trade
1410
- # "isTaker": True, # Various fees for Makers and Takers; "Market" orders are always `true`
1411
- # "fee": "0.0039655", # Exchange commission fee
1412
- # "feeCurrency": "BTC", # Currency of the commission
1413
- # "isBuyer": True, # Buy or sell the base asset
1414
- # "quoteQuantity": "30275.7994", # Quote asset quantity spent to fulfill the base amount
1415
- # "createdAt": "2022-09-29T13:43:53.824Z", # Date-time of trade execution, UTC
1416
- # },
1417
- # ]
1418
- # }
1419
- #
1420
- data = self.safe_list(response, 'data')
1421
- return self.parse_trades(data, market, since, limit)
1422
-
1423
- def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
1424
- """
1425
- make a withdrawal
1426
-
1427
- https://docs.kuna.io/docs/create-a-withdraw
1428
-
1429
- :param str code: unified currency code
1430
- :param float amount: the amount to withdraw
1431
- :param str address: the address to withdraw to
1432
- :param str tag:
1433
- :param dict [params]: extra parameters specific to the exchange API endpoint
1434
- :param str [params.chain]: the chain to withdraw to
1435
-
1436
- EXCHANGE SPECIFIC PARAMETERS
1437
- :param str [params.id]: id must be a uuid format, if you do not specify id, it will be generated automatically
1438
- :param boolean [params.withdrawAll]: self field says that the amount should also include a fee
1439
- :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1440
- """
1441
- self.check_address(address)
1442
- chain = self.safe_string_2(params, 'chain', 'network')
1443
- params = self.omit(params, ['chain', 'network'])
1444
- self.load_markets()
1445
- currency = self.currency(code)
1446
- if chain is None:
1447
- if currency['code'].find('USD') > 0:
1448
- raise ArgumentsRequired(self.id + ' withdraw() requires an extra parameter params["network"] to withdraw ' + currency['code'])
1449
- else:
1450
- chain = currency['id'].upper()
1451
- networkId = self.network_code_to_id(chain)
1452
- request: dict = {
1453
- 'currency': networkId,
1454
- 'amount': amount,
1455
- 'address': address,
1456
- 'paymentMethod': chain, # TODO: double check, Withdraw method for currency, should be taken from "Get info about withdrawal methods by currency name" endpoint(key field).
1457
- }
1458
- if tag is not None:
1459
- request['paymentId'] = tag
1460
- response = self.v4PrivatePostWithdrawPrivateCreate(self.extend(request, params))
1461
- #
1462
- # {
1463
- # "data": {
1464
- # "id": "edb17459-c9bf-4148-9ae6-7367d7f55d71", # unique identifier of a withdraw
1465
- # "status": "waitingForConfirmation" # status of a withdraw, if you turn off withdrawal confirmation by email, it will return "processing" status, which means that the transaction is already being processed on our side
1466
- # }
1467
- # }
1468
- #
1469
- data = self.safe_dict(response, 'data', {})
1470
- return self.parse_transaction(data, currency)
1471
-
1472
- def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1473
- """
1474
- fetch all withdrawals made to an account
1475
-
1476
- https://docs.kuna.io/docs/get-withdraw-history
1477
-
1478
- :param str code: unified currency code
1479
- :param int [since]: the earliest time in ms to fetch withdrawals for
1480
- :param int [limit]: the maximum number of withdrawals structures to retrieve
1481
- :param dict [params]: extra parameters specific to the exchange API endpoint
1482
- :param int [params.until]: the latest time in ms to fetch deposits for
1483
-
1484
- EXCHANGE SPECIFIC PARAMETERS
1485
- :param str [params.status]: Created, Canceled, PartiallyProcessed, Processing, Processed, WaitForConfirmation, Pending, AmlChecking
1486
- :param str [params.sortField]: amount(sorting by time), createdAt(sorting by date)
1487
- :param str [params.sortOrder]: asc(oldest-on-top), or desc(newest-on-top, default)
1488
- :param int [params.skip]: 0 - ... Select the number of transactions to skip
1489
- :param str [params.address]:
1490
- :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1491
- """
1492
- self.load_markets()
1493
- until = self.safe_integer(params, 'until')
1494
- params = self.omit(params, 'until')
1495
- currency = None
1496
- if code is not None:
1497
- currency = self.currency(code)
1498
- request: dict = {}
1499
- if code is not None:
1500
- request['currency'] = code
1501
- if since is not None:
1502
- request['dateFrom'] = self.iso8601(since)
1503
- if limit is not None:
1504
- request['take'] = limit
1505
- if until is not None:
1506
- request['dateTo'] = self.iso8601(until)
1507
- response = self.v4PrivateGetWithdrawPrivateHistory(self.extend(request, params))
1508
- #
1509
- # {
1510
- # "data": [
1511
- # {
1512
- # "id": "e9aa15b8-9c19-42eb-800a-026a7a153990", # Unique identifier of withdrawal
1513
- # "amount": "10.75", # Amount deducted from your account
1514
- # "asset": "USDT", # Withdrawal currency
1515
- # "merchantId": "16214228-5c0c-5abc-be6a-c90259b21d4e", # Internal ID(not for use)
1516
- # "paymentCode": "TRX", # Blockchain name
1517
- # "status": "Processed", # Withdrawal status
1518
- # "type": "Withdraw", # Transaction type
1519
- # "reason": [], # Reason for manual transaction processing
1520
- # "address": "TL3CWAwviQQYSnzHT4RotCWYnarnunQM46", # Withdrawal address
1521
- # "memo": "", # Withdrawal memo
1522
- # "txId": "5ecc4e559b528c57be6723ac960a38211fbd3101ef4b59008452b3bd88c84621", # Withdrawal transaction hash
1523
- # "fee": "0.75", # Withdrawal fee
1524
- # "processedAmount": "10", # Withdrawal amount
1525
- # "createdAt": "2023-06-09T11:33:02.383Z", # Withdrawal creation date
1526
- # "updatedAt": "2023-06-09T11:34:25.317Z" # Date of final withdrawal status
1527
- # },
1528
- # ...
1529
- # ]
1530
- # }
1531
- #
1532
- data = self.safe_list(response, 'data', [])
1533
- return self.parse_transactions(data, currency)
1534
-
1535
- def fetch_withdrawal(self, id: str, code: Str = None, params={}):
1536
- """
1537
- fetch data on a currency withdrawal via the withdrawal id
1538
-
1539
- https://docs.kuna.io/docs/get-withdraw-details-by-id
1540
-
1541
- :param str id: withdrawal id
1542
- :param str code: not used by kuna.fetchWithdrawal
1543
- :param dict [params]: extra parameters specific to the exchange API endpoint
1544
- :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1545
- """
1546
- self.load_markets()
1547
- request: dict = {
1548
- 'withdrawId': id,
1549
- }
1550
- response = self.v4PrivateGetWithdrawPrivateDetailsWithdrawId(self.extend(request, params))
1551
- #
1552
- # {
1553
- # "data": {
1554
- # "id": "e9aa15b8-9c19-42eb-800a-026a7a153990", # Unique identifier of withdrawal
1555
- # "amount": "10.75", # Amount deducted from your account
1556
- # "asset": "USDT", # Withdrawal currency
1557
- # "merchantId": "16214228-5c0c-5abc-be6a-c90259b21d4e", # Internal ID(not for use)
1558
- # "paymentCode": "TRX", # Blockchain name
1559
- # "status": "Processed", # Withdrawal status
1560
- # "type": "Withdraw", # Transaction type
1561
- # "reason": [], # Reason for manual transaction processing
1562
- # "address": "TL3CWAwviQQYSnzHT4RotCWYnarnunQM46", # Withdrawal address
1563
- # "memo": "", # Withdrawal memo
1564
- # "txId": "5ecc4e559b528c57be6723ac960a38211fbd3101ef4b59008452b3bd88c84621", # Withdrawal transaction hash
1565
- # "fee": "0.75", # Withdrawal fee
1566
- # "processedAmount": "10", # Withdrawal amount
1567
- # "createdAt": "2023-06-09T11:33:02.383Z", # Withdrawal creation date
1568
- # "updatedAt": "2023-06-09T11:34:25.317Z" # Date of final withdrawal status
1569
- # }
1570
- # }
1571
- #
1572
- data = self.safe_dict(response, 'data', {})
1573
- return self.parse_transaction(data)
1574
-
1575
- def create_deposit_address(self, code: str, params={}) -> DepositAddress:
1576
- """
1577
- create a currency deposit address
1578
-
1579
- https://docs.kuna.io/docs/generate-a-constant-crypto-address-for-deposit
1580
-
1581
- :param str code: unified currency code of the currency for the deposit address
1582
- :param dict [params]: extra parameters specific to the exchange API endpoint
1583
- :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1584
- """
1585
- self.load_markets()
1586
- currency = self.currency(code)
1587
- request: dict = {
1588
- 'source': currency['id'],
1589
- }
1590
- response = self.v4PrivatePostDepositPrivateCryptoGenerateAddress(self.extend(request, params))
1591
- #
1592
- # {
1593
- # "data": {
1594
- # "id": "1300c2b6-ree4-4f1e-2a9d-e0f7ed0991a7", # ID of your address
1595
- # "source": "BTC", # Blockchain name for which you want to get the address to deposit into the account
1596
- # "address": "bc1qm6xfv0qsaaanx0egn6hca5vgsd4r7ak9ttha2a" # Your deposit address
1597
- # }
1598
- # }
1599
- #
1600
- data = self.safe_dict(response, 'data', {})
1601
- return self.parse_deposit_address(data, currency)
1602
-
1603
- def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
1604
- """
1605
- fetch the deposit address for a currency associated with self account
1606
-
1607
- https://docs.kuna.io/docs/find-crypto-address-for-deposit
1608
-
1609
- :param str code: unified currency code
1610
- :param dict [params]: extra parameters specific to the exchange API endpoint
1611
- :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
1612
- """
1613
- self.load_markets()
1614
- currency = self.currency(code)
1615
- request: dict = {
1616
- 'source': currency['id'].upper(),
1617
- }
1618
- response = self.v4PrivateGetDepositPrivateCryptoAddress(self.extend(request, params))
1619
- #
1620
- # {
1621
- # "data": {
1622
- # "id": "c52b6646-fb91-4760-b147-a4f952e8652c", # ID of the address.
1623
- # "source": "BTC", # Blockchain name for which you want to get the address to deposit into the account.
1624
- # "address": "bc1qm6xfv0qsaaanx0egn6hca5vgsd4r7ak9ttha2a" # Your deposit address
1625
- # }
1626
- # }
1627
- #
1628
- data = self.safe_dict(response, 'data', {})
1629
- return self.parse_deposit_address(data, currency)
1630
-
1631
- def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
1632
- #
1633
- # {
1634
- # "id": "c52b6646-fb91-4760-b147-a4f952e8652c", # ID of the address.
1635
- # "source": "BTC", # Blockchain name for which you want to get the address to deposit into the account.
1636
- # "address": "bc1qm6xfv0qsaaanx0egn6hca5vgsd4r7ak9ttha2a" # Your deposit address
1637
- # }
1638
- #
1639
- currencyId = self.safe_string(depositAddress, 'source')
1640
- return {
1641
- 'info': self.safe_string(depositAddress, ''),
1642
- 'currency': self.safe_currency_code(currencyId, currency),
1643
- 'network': None,
1644
- 'address': self.safe_string(depositAddress, 'address'),
1645
- 'tag': None,
1646
- }
1647
-
1648
- def parse_transaction_status(self, status: Str):
1649
- statuses: dict = {
1650
- 'Created': 'pending',
1651
- 'Canceled': 'canceled',
1652
- 'PartiallyProcessed': 'pending',
1653
- 'Processing': 'pending',
1654
- 'Processed': 'ok',
1655
- 'WaitForConfirmation': 'pending',
1656
- 'Pending': 'pending',
1657
- 'AmlChecking': 'pending',
1658
- }
1659
- return self.safe_string(statuses, status, status)
1660
-
1661
- def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1662
- """
1663
- fetch all deposits made to an account
1664
-
1665
- https://docs.kuna.io/docs/get-deposit-history
1666
-
1667
- :param str code: unified currency code
1668
- :param int [since]: the earliest time in ms to fetch deposits for
1669
- :param int [limit]: the maximum number of deposits structures to retrieve
1670
- :param dict [params]: extra parameters specific to the exchange API endpoint
1671
- :param int [params.until]: the latest time in ms to fetch deposits for
1672
-
1673
- EXCHANGE SPECIFIC PARAMETERS
1674
- :param str [params.status]: Created, Canceled, PartiallyProcessed, Processing, Processed, WaitForConfirmation, Pending, AmlChecking
1675
- :param str [params.sortField]: amount(sorting by time), createdAt(sorting by date)
1676
- :param str [params.sortOrder]: asc(oldest-on-top), or desc(newest-on-top, default)
1677
- :param int [params.skip]: 0 - ... Select the number of transactions to skip
1678
- :param str [params.address]:
1679
- :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1680
- """
1681
- self.load_markets()
1682
- until = self.safe_integer(params, 'until')
1683
- params = self.omit(params, 'until')
1684
- currency = None
1685
- if code is not None:
1686
- currency = self.currency(code)
1687
- request: dict = {}
1688
- if code is not None:
1689
- request['currency'] = code
1690
- if since is not None:
1691
- request['dateFrom'] = self.iso8601(since)
1692
- if limit is not None:
1693
- request['take'] = limit
1694
- if until is not None:
1695
- request['dateTo'] = self.iso8601(until)
1696
- response = self.v4PrivateGetDepositPrivateHistory(self.extend(request, params))
1697
- #
1698
- # {
1699
- # "data": [
1700
- # {
1701
- # "id": "a201cb3c-5830-57ac-ad2c-f6a588dd55eb", # Unique ID of deposit
1702
- # "amount": "9.9", # Amount credited to your account
1703
- # "asset": "USDT", # Deposit currency
1704
- # "merchantId": "16214228-5c0c-5abc-be6a-c90259b21d4e", # Internal ID(not for use)
1705
- # "paymentCode": "TRX", # Blockchain name
1706
- # "status": "Processed", # Transactions status
1707
- # "type": "Deposit", # Transaction type
1708
- # "reason": [], # Reason for manual transaction processing
1709
- # "address": "TNeBQz8RyGGiAYAR7r8G6QGxtTWDkpH4dV", # Deposit address
1710
- # "memo": "", # Deposit memo
1711
- # "txId": "8a0b0c5a2ac5679879b71b2fa63b0a5c39f90bc8ff6c41e708906b398ac3d4ef", # Deposit transaction hash
1712
- # "fee": "0.1", # Deposit fee
1713
- # "processedAmount": "10", # Amount of deposit
1714
- # "createdAt": "2023-06-13T12:55:01.256Z", # Deposit receipt date
1715
- # "updatedAt": "2023-06-13T12:55:01.696Z" # Deposit credit date
1716
- # },
1717
- # ...
1718
- # ]
1719
- # }
1720
- #
1721
- data = self.safe_list(response, 'data', [])
1722
- return self.parse_transactions(data, currency)
1723
-
1724
- def fetch_deposit(self, id: str, code: Str = None, params={}):
1725
- """
1726
- fetch data on a currency deposit via the deposit id
1727
-
1728
- https://docs.kuna.io/docs/get-deposit-details-by-id
1729
-
1730
- :param str id: deposit id
1731
- :param str code: filter by currency code
1732
- :param dict [params]: extra parameters specific to the exchange API endpoint
1733
- :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1734
- """
1735
- self.load_markets()
1736
- currency = None
1737
- if code is not None:
1738
- currency = self.currency(code)
1739
- request: dict = {
1740
- 'depositId': id,
1741
- }
1742
- response = self.v4PrivateGetDepositPrivateDetailsDepositId(self.extend(request, params))
1743
- #
1744
- # {
1745
- # "data": {
1746
- # "id": "a201cb3c-5830-57ac-ad2c-f6a588dd55eb", # Unique ID of deposit
1747
- # "amount": "9.9", # Amount credited to your account
1748
- # "asset": "USDT", # Deposit currency
1749
- # "merchantId": "16214228-5c0c-5abc-be6a-c90259b21d4e", # Internal ID(not for use)
1750
- # "paymentCode": "TRX", # Blockchain name
1751
- # "status": "Processed", # Transactions status
1752
- # "type": "Deposit", # Transaction type
1753
- # "reason": [], # Reason for manual transaction processing
1754
- # "address": "TNeBQz8RyGGiAYAR7r8G6QGxtTWDkpH4dV", # Deposit address
1755
- # "memo": "", # Deposit memo
1756
- # "txId": "8a0b0c5a2ac5679879b71b2fa63b0a5c39f90bc8ff6c41e708906b398ac3d4ef", # Deposit transaction hash
1757
- # "fee": "0.1", # Deposit fee
1758
- # "processedAmount": "10", # Amount of deposit
1759
- # "createdAt": "2023-06-13T12:55:01.256Z", # Deposit receipt date
1760
- # "updatedAt": "2023-06-13T12:55:01.696Z" # Deposit credit date
1761
- # }
1762
- # }
1763
- #
1764
- data = self.safe_dict(response, 'data', {})
1765
- return self.parse_transaction(data, currency)
1766
-
1767
- def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
1768
- #
1769
- # {
1770
- # "id": "a201cb3c-5830-57ac-ad2c-f6a588dd55eb", # Unique ID of deposit
1771
- # "amount": "9.9", # Amount credited to your account
1772
- # "asset": "USDT", # Deposit currency
1773
- # "merchantId": "16214228-5c0c-5abc-be6a-c90259b21d4e", # Internal ID(not for use)
1774
- # "paymentCode": "TRX", # Blockchain name
1775
- # "status": "Processed", # Transactions status
1776
- # "type": "Deposit", # Transaction type
1777
- # "reason": [], # Reason for manual transaction processing
1778
- # "address": "TNeBQz8RyGGiAYAR7r8G6QGxtTWDkpH4dV", # Deposit address
1779
- # "memo": "", # Deposit memo
1780
- # "txId": "8a0b0c5a2ac5679879b71b2fa63b0a5c39f90bc8ff6c41e708906b398ac3d4ef", # Deposit transaction hash
1781
- # "fee": "0.1", # Deposit fee
1782
- # "processedAmount": "10", # Amount of deposit
1783
- # "createdAt": "2023-06-13T12:55:01.256Z", # Deposit receipt date
1784
- # "updatedAt": "2023-06-13T12:55:01.696Z" # Deposit credit date
1785
- # }
1786
- #
1787
- datetime = self.safe_string(transaction, 'createdAt')
1788
- currencyId = self.safe_string(transaction, 'asset')
1789
- code = self.safe_currency_code(currencyId, currency)
1790
- networkId = self.safe_string(transaction, 'paymentCode')
1791
- type = self.safe_string_lower(transaction, 'type')
1792
- address = self.safe_string(transaction, 'address')
1793
- isDeposit = (type == 'deposit')
1794
- parsedType = type if isDeposit else 'withdrawal'
1795
- return {
1796
- 'info': transaction,
1797
- 'id': self.safe_string(transaction, 'id'),
1798
- 'txid': self.safe_string(transaction, 'txId'),
1799
- 'currency': code,
1800
- 'timestamp': self.parse8601(datetime),
1801
- 'datetime': datetime,
1802
- 'network': self.network_id_to_code(networkId),
1803
- 'addressFrom': None,
1804
- 'address': address,
1805
- 'addressTo': address,
1806
- 'amount': self.safe_number(transaction, 'amount'),
1807
- 'type': parsedType,
1808
- 'status': self.parse_transaction_status(self.safe_string(transaction, 'status')),
1809
- 'updated': self.parse8601(self.safe_string(transaction, 'updatedAt')),
1810
- 'tagFrom': None,
1811
- 'tag': None,
1812
- 'tagTo': None,
1813
- 'comment': self.safe_string(transaction, 'memo'),
1814
- 'internal': None,
1815
- 'fee': {
1816
- 'cost': self.safe_number(transaction, 'fee'),
1817
- 'currency': code,
1818
- },
1819
- }
1820
-
1821
- def nonce(self):
1822
- return self.milliseconds()
1823
-
1824
- def encode_params(self, params):
1825
- if 'orders' in params:
1826
- orders = params['orders']
1827
- query = self.urlencode(self.keysort(self.omit(params, 'orders')))
1828
- for i in range(0, len(orders)):
1829
- order = orders[i]
1830
- keys = list(order.keys())
1831
- for k in range(0, len(keys)):
1832
- key = keys[k]
1833
- value = order[key]
1834
- query += '&orders%5B%5D%5B' + key + '%5D=' + str(value)
1835
- return query
1836
- return self.urlencode(self.keysort(params))
1837
-
1838
- def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
1839
- url = None
1840
- if isinstance(api, list):
1841
- isGet = method == 'GET'
1842
- version = self.safe_string(api, 0)
1843
- access = self.safe_string(api, 1)
1844
- if version == 'v3':
1845
- url = self.urls['api'][version] + '/' + version + '/' + self.implode_params(path, params)
1846
- if access == 'public':
1847
- if isGet:
1848
- if params:
1849
- url += '?' + self.urlencode(params)
1850
- elif (method == 'POST') or (method == 'PUT'):
1851
- headers = {'Content-Type': 'application/json'}
1852
- body = self.json(params)
1853
- elif access == 'private':
1854
- raise NotSupported(self.id + ' private v3 API is not supported yet')
1855
- elif version == 'v4':
1856
- extractedParams = self.extract_params(path)
1857
- urlPath = '/' + version + '/' + self.implode_params(path, params)
1858
- params = self.omit(params, extractedParams)
1859
- if isGet:
1860
- paramsList = list(params.keys())
1861
- numParams = len(paramsList)
1862
- if numParams > 0:
1863
- urlPath += '?' + self.urlencode(params)
1864
- if access == 'private':
1865
- nonce = str(self.nonce())
1866
- auth = urlPath + nonce
1867
- if isGet:
1868
- auth = auth + self.json({})
1869
- else:
1870
- auth = auth + self.json(params)
1871
- body = params
1872
- headers = {
1873
- 'Content-Type': 'application/json',
1874
- 'accept': 'application/json',
1875
- 'nonce': nonce,
1876
- 'public-key': self.apiKey,
1877
- 'signature': self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha384, 'hex'),
1878
- }
1879
- account = self.safe_string(self.options, 'account')
1880
- if account == 'pro':
1881
- headers['account'] = 'pro'
1882
- url = self.urls['api'][version] + urlPath
1883
- else:
1884
- request = '/api/' + self.version + '/' + self.implode_params(path, params)
1885
- if 'extension' in self.urls:
1886
- request += self.urls['extension']
1887
- query = self.omit(params, self.extract_params(path))
1888
- url = self.urls['api'][api] + request
1889
- if api == 'public':
1890
- if query:
1891
- url += '?' + self.urlencode(query)
1892
- else:
1893
- self.check_required_credentials()
1894
- nonce = str(self.nonce())
1895
- queryInner = self.encode_params(self.extend({
1896
- 'access_key': self.apiKey,
1897
- 'tonce': nonce,
1898
- }, params))
1899
- auth = method + '|' + request + '|' + queryInner
1900
- signed = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
1901
- suffix = query + '&signature=' + signed
1902
- if method == 'GET':
1903
- url += '?' + suffix
1904
- else:
1905
- body = suffix
1906
- headers = {'Content-Type': 'application/x-www-form-urlencoded'}
1907
- if body is not None:
1908
- body = json.dumps(body)
1909
- return {'url': url, 'method': method, 'body': body, 'headers': headers}
1910
-
1911
- def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
1912
- #
1913
- # {
1914
- # "errors": [
1915
- # {
1916
- # "extensions": {
1917
- # "code": "IP_NOT_IN_WHITE_LIST"
1918
- # },
1919
- # "code": "IP_NOT_IN_WHITE_LIST"
1920
- # }
1921
- # ]
1922
- # }
1923
- #
1924
- errors = self.safe_value(response, 'errors')
1925
- if (response is None) and (errors is None):
1926
- return None
1927
- if (errors is not None) or (code == 400):
1928
- error = self.safe_value(errors, 0)
1929
- if error is None:
1930
- error = self.safe_value(response, 'error')
1931
- errorCode = self.safe_string(error, 'code')
1932
- feedback = self.id + ' ' + self.json(response)
1933
- self.throw_exactly_matched_exception(self.exceptions, errorCode, feedback)
1934
- raise ExchangeError(feedback)
1935
- return None