ccxt-look 1.81.50

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 (264) hide show
  1. package/.cache/eslintcache +1 -0
  2. package/.dockerignore +6 -0
  3. package/.eslintignore +1 -0
  4. package/.gitattributes +5 -0
  5. package/.readthedocs.yaml +16 -0
  6. package/CONTRIBUTING.md +1049 -0
  7. package/LICENSE.txt +21 -0
  8. package/README.md +537 -0
  9. package/SECURITY.md +5 -0
  10. package/build/cleanup-old-tags.js +94 -0
  11. package/build/countries.js +256 -0
  12. package/build/export-exchanges.js +520 -0
  13. package/build/fs.js +51 -0
  14. package/build/transpile.js +1772 -0
  15. package/build/vss.js +78 -0
  16. package/ccxt.browser.js +7 -0
  17. package/ccxt.d.ts +692 -0
  18. package/ccxt.js +171 -0
  19. package/cleanup.sh +2 -0
  20. package/composer-install.sh +20 -0
  21. package/dist/ccxt.browser.js +208383 -0
  22. package/gource.sh +3 -0
  23. package/index.html +7 -0
  24. package/js/.eslintrc +87 -0
  25. package/js/aax.js +2686 -0
  26. package/js/ascendex.js +2584 -0
  27. package/js/base/.eslintrc.js +43 -0
  28. package/js/base/Exchange.js +2371 -0
  29. package/js/base/Precise.js +283 -0
  30. package/js/base/errorHierarchy.js +47 -0
  31. package/js/base/errors.js +55 -0
  32. package/js/base/functions/crypto.js +158 -0
  33. package/js/base/functions/encode.js +118 -0
  34. package/js/base/functions/generic.js +270 -0
  35. package/js/base/functions/misc.js +138 -0
  36. package/js/base/functions/number.js +329 -0
  37. package/js/base/functions/platform.js +38 -0
  38. package/js/base/functions/string.js +21 -0
  39. package/js/base/functions/throttle.js +79 -0
  40. package/js/base/functions/time.js +210 -0
  41. package/js/base/functions/type.js +66 -0
  42. package/js/base/functions.js +28 -0
  43. package/js/bequant.js +32 -0
  44. package/js/bibox.js +1407 -0
  45. package/js/bigone.js +1366 -0
  46. package/js/binance.js +5652 -0
  47. package/js/binancecoinm.js +46 -0
  48. package/js/binanceus.js +46 -0
  49. package/js/binanceusdm.js +49 -0
  50. package/js/bit2c.js +535 -0
  51. package/js/bitbank.js +842 -0
  52. package/js/bitbay.js +16 -0
  53. package/js/bitbns.js +1073 -0
  54. package/js/bitcoincom.js +15 -0
  55. package/js/bitfinex.js +1433 -0
  56. package/js/bitfinex2.js +2025 -0
  57. package/js/bitflyer.js +840 -0
  58. package/js/bitforex.js +614 -0
  59. package/js/bitget.js +2397 -0
  60. package/js/bithumb.js +980 -0
  61. package/js/bitmart.js +2516 -0
  62. package/js/bitmex.js +1809 -0
  63. package/js/bitopro.js +1443 -0
  64. package/js/bitpanda.js +1782 -0
  65. package/js/bitrue.js +1747 -0
  66. package/js/bitso.js +1062 -0
  67. package/js/bitstamp.js +1757 -0
  68. package/js/bitstamp1.js +343 -0
  69. package/js/bittrex.js +1876 -0
  70. package/js/bitvavo.js +1579 -0
  71. package/js/bkex.js +1233 -0
  72. package/js/bl3p.js +346 -0
  73. package/js/blockchaincom.js +969 -0
  74. package/js/btcalpha.js +680 -0
  75. package/js/btcbox.js +477 -0
  76. package/js/btcmarkets.js +1022 -0
  77. package/js/btctradeua.js +466 -0
  78. package/js/btcturk.js +734 -0
  79. package/js/buda.js +946 -0
  80. package/js/bw.js +1265 -0
  81. package/js/bybit.js +3372 -0
  82. package/js/bytetrade.js +1336 -0
  83. package/js/cdax.js +1646 -0
  84. package/js/cex.js +1410 -0
  85. package/js/coinbase.js +1342 -0
  86. package/js/coinbaseprime.js +31 -0
  87. package/js/coinbasepro.js +1466 -0
  88. package/js/coincheck.js +755 -0
  89. package/js/coinex.js +3400 -0
  90. package/js/coinfalcon.js +880 -0
  91. package/js/coinmate.js +794 -0
  92. package/js/coinone.js +816 -0
  93. package/js/coinspot.js +345 -0
  94. package/js/crex24.js +1636 -0
  95. package/js/cryptocom.js +1832 -0
  96. package/js/currencycom.js +1748 -0
  97. package/js/delta.js +1547 -0
  98. package/js/deribit.js +2148 -0
  99. package/js/digifinex.js +1585 -0
  100. package/js/eqonex.js +1660 -0
  101. package/js/exmo.js +1670 -0
  102. package/js/fairdesk.js +1231 -0
  103. package/js/flowbtc.js +35 -0
  104. package/js/fmfwio.js +34 -0
  105. package/js/ftx.js +2751 -0
  106. package/js/ftxus.js +38 -0
  107. package/js/gateio.js +4174 -0
  108. package/js/gemini.js +1397 -0
  109. package/js/hitbtc.js +1343 -0
  110. package/js/hitbtc3.js +2329 -0
  111. package/js/hollaex.js +1486 -0
  112. package/js/huobi.js +5706 -0
  113. package/js/huobijp.js +1710 -0
  114. package/js/huobipro.js +18 -0
  115. package/js/idex.js +1439 -0
  116. package/js/independentreserve.js +649 -0
  117. package/js/indodax.js +742 -0
  118. package/js/itbit.js +722 -0
  119. package/js/kraken.js +2179 -0
  120. package/js/kucoin.js +2571 -0
  121. package/js/kucoinfutures.js +1771 -0
  122. package/js/kuna.js +809 -0
  123. package/js/latoken.js +1445 -0
  124. package/js/lbank.js +760 -0
  125. package/js/liquid.js +1432 -0
  126. package/js/luno.js +873 -0
  127. package/js/lykke.js +1147 -0
  128. package/js/mercado.js +771 -0
  129. package/js/mexc.js +3151 -0
  130. package/js/ndax.js +2233 -0
  131. package/js/novadax.js +1318 -0
  132. package/js/oceanex.js +816 -0
  133. package/js/okcoin.js +3841 -0
  134. package/js/okex.js +16 -0
  135. package/js/okex5.js +16 -0
  136. package/js/okx.js +4795 -0
  137. package/js/paymium.js +498 -0
  138. package/js/phemex.js +2957 -0
  139. package/js/poloniex.js +1674 -0
  140. package/js/probit.js +1346 -0
  141. package/js/qtrade.js +1588 -0
  142. package/js/ripio.js +1061 -0
  143. package/js/static_dependencies/BN/bn.js +3526 -0
  144. package/js/static_dependencies/README.md +1 -0
  145. package/js/static_dependencies/crypto-js/crypto-js.js +5988 -0
  146. package/js/static_dependencies/elliptic/lib/elliptic/curve/base.js +375 -0
  147. package/js/static_dependencies/elliptic/lib/elliptic/curve/edwards.js +433 -0
  148. package/js/static_dependencies/elliptic/lib/elliptic/curve/index.js +8 -0
  149. package/js/static_dependencies/elliptic/lib/elliptic/curve/mont.js +180 -0
  150. package/js/static_dependencies/elliptic/lib/elliptic/curve/short.js +938 -0
  151. package/js/static_dependencies/elliptic/lib/elliptic/curves.js +204 -0
  152. package/js/static_dependencies/elliptic/lib/elliptic/ec/index.js +240 -0
  153. package/js/static_dependencies/elliptic/lib/elliptic/ec/key.js +119 -0
  154. package/js/static_dependencies/elliptic/lib/elliptic/ec/signature.js +24 -0
  155. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/index.js +145 -0
  156. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/key.js +100 -0
  157. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/signature.js +65 -0
  158. package/js/static_dependencies/elliptic/lib/elliptic/precomputed/secp256k1.js +780 -0
  159. package/js/static_dependencies/elliptic/lib/elliptic/utils.js +214 -0
  160. package/js/static_dependencies/elliptic/lib/elliptic.js +22 -0
  161. package/js/static_dependencies/elliptic/lib/hmac-drbg/hmac-drbg.js +114 -0
  162. package/js/static_dependencies/fetch-ponyfill/fetch-node.js +39 -0
  163. package/js/static_dependencies/node-fetch/index.js +1564 -0
  164. package/js/static_dependencies/node-rsa/NodeRSA.js +223 -0
  165. package/js/static_dependencies/node-rsa/asn1/ber/errors.js +13 -0
  166. package/js/static_dependencies/node-rsa/asn1/ber/index.js +21 -0
  167. package/js/static_dependencies/node-rsa/asn1/ber/reader.js +262 -0
  168. package/js/static_dependencies/node-rsa/asn1/ber/types.js +36 -0
  169. package/js/static_dependencies/node-rsa/asn1/index.js +17 -0
  170. package/js/static_dependencies/node-rsa/encryptEngines/js.js +34 -0
  171. package/js/static_dependencies/node-rsa/formats/components.js +71 -0
  172. package/js/static_dependencies/node-rsa/formats/formats.js +31 -0
  173. package/js/static_dependencies/node-rsa/formats/pkcs1.js +148 -0
  174. package/js/static_dependencies/node-rsa/formats/pkcs8.js +187 -0
  175. package/js/static_dependencies/node-rsa/libs/jsbn.js +1252 -0
  176. package/js/static_dependencies/node-rsa/libs/rsa.js +147 -0
  177. package/js/static_dependencies/node-rsa/schemes/pkcs1.js +176 -0
  178. package/js/static_dependencies/node-rsa/schemes/schemes.js +21 -0
  179. package/js/static_dependencies/node-rsa/utils.js +98 -0
  180. package/js/static_dependencies/qs/formats.js +18 -0
  181. package/js/static_dependencies/qs/index.js +11 -0
  182. package/js/static_dependencies/qs/parse.js +242 -0
  183. package/js/static_dependencies/qs/stringify.js +269 -0
  184. package/js/static_dependencies/qs/utils.js +230 -0
  185. package/js/stex.js +1925 -0
  186. package/js/test/.eslintrc.js +42 -0
  187. package/js/test/Exchange/test.balance.js +61 -0
  188. package/js/test/Exchange/test.borrowRate.js +32 -0
  189. package/js/test/Exchange/test.currency.js +52 -0
  190. package/js/test/Exchange/test.fetchBalance.js +23 -0
  191. package/js/test/Exchange/test.fetchBorrowInterest.js +59 -0
  192. package/js/test/Exchange/test.fetchBorrowRate.js +32 -0
  193. package/js/test/Exchange/test.fetchBorrowRates.js +28 -0
  194. package/js/test/Exchange/test.fetchClosedOrders.js +32 -0
  195. package/js/test/Exchange/test.fetchCurrencies.js +35 -0
  196. package/js/test/Exchange/test.fetchDeposits.js +31 -0
  197. package/js/test/Exchange/test.fetchFundingFees.js +19 -0
  198. package/js/test/Exchange/test.fetchFundingRateHistory.js +40 -0
  199. package/js/test/Exchange/test.fetchL2OrderBook.js +23 -0
  200. package/js/test/Exchange/test.fetchLedger.js +42 -0
  201. package/js/test/Exchange/test.fetchLeverageTiers.js +33 -0
  202. package/js/test/Exchange/test.fetchMarketLeverageTiers.js +22 -0
  203. package/js/test/Exchange/test.fetchMarkets.js +33 -0
  204. package/js/test/Exchange/test.fetchMyTrades.js +42 -0
  205. package/js/test/Exchange/test.fetchOHLCV.js +46 -0
  206. package/js/test/Exchange/test.fetchOpenOrders.js +36 -0
  207. package/js/test/Exchange/test.fetchOrderBook.js +25 -0
  208. package/js/test/Exchange/test.fetchOrderBooks.js +35 -0
  209. package/js/test/Exchange/test.fetchOrders.js +41 -0
  210. package/js/test/Exchange/test.fetchPositions.js +47 -0
  211. package/js/test/Exchange/test.fetchStatus.js +35 -0
  212. package/js/test/Exchange/test.fetchTicker.js +38 -0
  213. package/js/test/Exchange/test.fetchTickers.js +49 -0
  214. package/js/test/Exchange/test.fetchTrades.js +39 -0
  215. package/js/test/Exchange/test.fetchTradingFee.js +18 -0
  216. package/js/test/Exchange/test.fetchTradingFees.js +22 -0
  217. package/js/test/Exchange/test.fetchTransactions.js +31 -0
  218. package/js/test/Exchange/test.fetchWithdrawals.js +31 -0
  219. package/js/test/Exchange/test.ledgerItem.js +46 -0
  220. package/js/test/Exchange/test.leverageTier.js +33 -0
  221. package/js/test/Exchange/test.loadMarkets.js +35 -0
  222. package/js/test/Exchange/test.market.js +129 -0
  223. package/js/test/Exchange/test.ohlcv.js +33 -0
  224. package/js/test/Exchange/test.order.js +62 -0
  225. package/js/test/Exchange/test.orderbook.js +61 -0
  226. package/js/test/Exchange/test.position.js +21 -0
  227. package/js/test/Exchange/test.throttle.js +94 -0
  228. package/js/test/Exchange/test.ticker.js +95 -0
  229. package/js/test/Exchange/test.trade.js +68 -0
  230. package/js/test/Exchange/test.tradingFee.js +34 -0
  231. package/js/test/Exchange/test.transaction.js +35 -0
  232. package/js/test/base/.eslintrc +38 -0
  233. package/js/test/base/functions/test.crypto.js +110 -0
  234. package/js/test/base/functions/test.datetime.js +62 -0
  235. package/js/test/base/functions/test.generic.js +152 -0
  236. package/js/test/base/functions/test.number.js +362 -0
  237. package/js/test/base/functions/test.time.js +56 -0
  238. package/js/test/base/functions/test.type.js +53 -0
  239. package/js/test/base/test.base.js +193 -0
  240. package/js/test/errors/test.InsufficientFunds.js +86 -0
  241. package/js/test/errors/test.InvalidNonce.js +64 -0
  242. package/js/test/errors/test.InvalidOrder.js +35 -0
  243. package/js/test/errors/test.OrderNotFound.js +39 -0
  244. package/js/test/test.js +426 -0
  245. package/js/test/test.timeout_hang.js +12 -0
  246. package/js/therock.js +1431 -0
  247. package/js/tidebit.js +632 -0
  248. package/js/tidex.js +939 -0
  249. package/js/timex.js +1283 -0
  250. package/js/upbit.js +1622 -0
  251. package/js/vcc.js +1353 -0
  252. package/js/wavesexchange.js +2185 -0
  253. package/js/wazirx.js +732 -0
  254. package/js/whitebit.js +1352 -0
  255. package/js/woo.js +1577 -0
  256. package/js/xena.js +1948 -0
  257. package/js/yobit.js +1129 -0
  258. package/js/zaif.js +647 -0
  259. package/js/zb.js +4088 -0
  260. package/js/zipmex.js +40 -0
  261. package/js/zonda.js +1497 -0
  262. package/multilang.sh +159 -0
  263. package/package.json +591 -0
  264. package/postinstall.js +103 -0
package/js/delta.js ADDED
@@ -0,0 +1,1547 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { ExchangeError, InsufficientFunds, BadRequest, BadSymbol, InvalidOrder, AuthenticationError, ArgumentsRequired, OrderNotFound, ExchangeNotAvailable } = require ('./base/errors');
7
+ const { TICK_SIZE } = require ('./base/functions/number');
8
+
9
+ // ---------------------------------------------------------------------------
10
+
11
+ module.exports = class delta extends Exchange {
12
+ describe () {
13
+ return this.deepExtend (super.describe (), {
14
+ 'id': 'delta',
15
+ 'name': 'Delta Exchange',
16
+ 'countries': [ 'VC' ], // Saint Vincent and the Grenadines
17
+ 'rateLimit': 300,
18
+ 'version': 'v2',
19
+ // new metainfo interface
20
+ 'has': {
21
+ 'CORS': undefined,
22
+ 'spot': true,
23
+ 'margin': undefined,
24
+ 'swap': undefined,
25
+ 'future': undefined,
26
+ 'option': undefined,
27
+ 'cancelAllOrders': true,
28
+ 'cancelOrder': true,
29
+ 'createOrder': true,
30
+ 'editOrder': true,
31
+ 'fetchBalance': true,
32
+ 'fetchClosedOrders': true,
33
+ 'fetchCurrencies': true,
34
+ 'fetchDepositAddress': true,
35
+ 'fetchLedger': true,
36
+ 'fetchLeverageTiers': false, // An infinite number of tiers, see examples/js/delta-maintenance-margin-rate-max-leverage.js
37
+ 'fetchMarketLeverageTiers': false,
38
+ 'fetchMarkets': true,
39
+ 'fetchMyTrades': true,
40
+ 'fetchOHLCV': true,
41
+ 'fetchOpenOrders': true,
42
+ 'fetchOrderBook': true,
43
+ 'fetchPosition': true,
44
+ 'fetchPositions': true,
45
+ 'fetchStatus': true,
46
+ 'fetchTicker': true,
47
+ 'fetchTickers': true,
48
+ 'fetchTime': true,
49
+ 'fetchTrades': true,
50
+ },
51
+ 'timeframes': {
52
+ '1m': '1m',
53
+ '3m': '3m',
54
+ '5m': '5m',
55
+ '15m': '15m',
56
+ '30m': '30m',
57
+ '1h': '1h',
58
+ '2h': '2h',
59
+ '4h': '4h',
60
+ '6h': '6h',
61
+ '1d': '1d',
62
+ '7d': '7d',
63
+ '1w': '1w',
64
+ '2w': '2w',
65
+ '1M': '30d',
66
+ },
67
+ 'urls': {
68
+ 'logo': 'https://user-images.githubusercontent.com/1294454/99450025-3be60a00-2931-11eb-9302-f4fd8d8589aa.jpg',
69
+ 'test': {
70
+ 'public': 'https://testnet-api.delta.exchange',
71
+ 'private': 'https://testnet-api.delta.exchange',
72
+ },
73
+ 'api': {
74
+ 'public': 'https://api.delta.exchange',
75
+ 'private': 'https://api.delta.exchange',
76
+ },
77
+ 'www': 'https://www.delta.exchange',
78
+ 'doc': [
79
+ 'https://docs.delta.exchange',
80
+ ],
81
+ 'fees': 'https://www.delta.exchange/fees',
82
+ 'referral': 'https://www.delta.exchange/app/signup/?code=IULYNB',
83
+ },
84
+ 'api': {
85
+ 'public': {
86
+ 'get': [
87
+ 'assets',
88
+ 'settings',
89
+ 'indices',
90
+ 'products',
91
+ 'tickers',
92
+ 'tickers/{symbol}',
93
+ 'l2orderbook/{symbol}',
94
+ 'trades/{symbol}',
95
+ 'history/candles',
96
+ 'history/sparklines',
97
+ ],
98
+ },
99
+ 'private': {
100
+ 'get': [
101
+ 'orders',
102
+ 'orders/leverage',
103
+ 'positions',
104
+ 'positions/margined',
105
+ 'orders/history',
106
+ 'fills',
107
+ 'fills/history/download/csv',
108
+ 'wallet/balances',
109
+ 'wallet/transactions',
110
+ 'wallet/transactions/download',
111
+ 'deposits/address',
112
+ ],
113
+ 'post': [
114
+ 'orders',
115
+ 'orders/batch',
116
+ 'orders/leverage',
117
+ 'positions/change_margin',
118
+ ],
119
+ 'put': [
120
+ 'orders',
121
+ 'orders/batch',
122
+ ],
123
+ 'delete': [
124
+ 'orders',
125
+ 'orders/all',
126
+ 'orders/batch',
127
+ ],
128
+ },
129
+ },
130
+ 'fees': {
131
+ 'trading': {
132
+ 'tierBased': true,
133
+ 'percentage': true,
134
+ 'taker': 0.15 / 100,
135
+ 'maker': 0.10 / 100,
136
+ 'tiers': {
137
+ 'taker': [
138
+ [ 0, 0.15 / 100 ],
139
+ [ 100, 0.13 / 100 ],
140
+ [ 250, 0.13 / 100 ],
141
+ [ 1000, 0.1 / 100 ],
142
+ [ 5000, 0.09 / 100 ],
143
+ [ 10000, 0.075 / 100 ],
144
+ [ 20000, 0.065 / 100 ],
145
+ ],
146
+ 'maker': [
147
+ [ 0, 0.1 / 100 ],
148
+ [ 100, 0.1 / 100 ],
149
+ [ 250, 0.09 / 100 ],
150
+ [ 1000, 0.075 / 100 ],
151
+ [ 5000, 0.06 / 100 ],
152
+ [ 10000, 0.05 / 100 ],
153
+ [ 20000, 0.05 / 100 ],
154
+ ],
155
+ },
156
+ },
157
+ },
158
+ 'precisionMode': TICK_SIZE,
159
+ 'requiredCredentials': {
160
+ 'apiKey': true,
161
+ 'secret': false,
162
+ },
163
+ 'exceptions': {
164
+ 'exact': {
165
+ // Margin required to place order with selected leverage and quantity is insufficient.
166
+ 'insufficient_margin': InsufficientFunds, // {"error":{"code":"insufficient_margin","context":{"available_balance":"0.000000000000000000","required_additional_balance":"1.618626000000000000000000000"}},"success":false}
167
+ 'order_size_exceed_available': InvalidOrder, // The order book doesn't have sufficient liquidity, hence the order couldnt be filled, for example, ioc orders
168
+ 'risk_limits_breached': BadRequest, // orders couldn't be placed as it will breach allowed risk limits.
169
+ 'invalid_contract': BadSymbol, // The contract/product is either doesn't exist or has already expired.
170
+ 'immediate_liquidation': InvalidOrder, // Order will cause immediate liquidation.
171
+ 'out_of_bankruptcy': InvalidOrder, // Order prices are out of position bankruptcy limits.
172
+ 'self_matching_disrupted_post_only': InvalidOrder, // Self matching is not allowed during auction.
173
+ 'immediate_execution_post_only': InvalidOrder, // orders couldn't be placed as it includes post only orders which will be immediately executed
174
+ 'bad_schema': BadRequest, // {"error":{"code":"bad_schema","context":{"schema_errors":[{"code":"validation_error","message":"id is required","param":""}]}},"success":false}
175
+ 'invalid_api_key': AuthenticationError, // {"success":false,"error":{"code":"invalid_api_key"}}
176
+ 'invalid_signature': AuthenticationError, // {"success":false,"error":{"code":"invalid_signature"}}
177
+ 'open_order_not_found': OrderNotFound, // {"error":{"code":"open_order_not_found"},"success":false}
178
+ 'unavailable': ExchangeNotAvailable, // {"error":{"code":"unavailable"},"success":false}
179
+ },
180
+ 'broad': {
181
+ },
182
+ },
183
+ });
184
+ }
185
+
186
+ async fetchTime (params = {}) {
187
+ const response = await this.publicGetSettings (params);
188
+ // full response sample under `fetchStatus`
189
+ const result = this.safeValue (response, 'result', {});
190
+ return this.safeIntegerProduct (result, 'server_time', 0.001);
191
+ }
192
+
193
+ async fetchStatus (params = {}) {
194
+ const response = await this.publicGetSettings (params);
195
+ //
196
+ // {
197
+ // "result": {
198
+ // "deto_liquidity_mining_daily_reward": "40775",
199
+ // "deto_msp": "1.0",
200
+ // "deto_staking_daily_reward": "23764.08",
201
+ // "enabled_wallets": [
202
+ // "BTC",
203
+ // ...
204
+ // ],
205
+ // "portfolio_margin_params": {
206
+ // "enabled_portfolios": {
207
+ // ".DEAVAXUSDT": {
208
+ // "asset_id": 5,
209
+ // "futures_contingency_margin_percent": "1",
210
+ // "interest_rate": "0",
211
+ // "maintenance_margin_multiplier": "0.8",
212
+ // "max_price_shock": "20",
213
+ // "max_short_notional_limit": "2000",
214
+ // "options_contingency_margin_percent": "1",
215
+ // "options_discount_range": "10",
216
+ // "options_liq_band_range_percentage": "25",
217
+ // "settling_asset": "USDT",
218
+ // "sort_priority": 5,
219
+ // "underlying_asset": "AVAX",
220
+ // "volatility_down_shock": "30",
221
+ // "volatility_up_shock": "45"
222
+ // },
223
+ // ...
224
+ // },
225
+ // "portfolio_enabled_contracts": [
226
+ // "futures",
227
+ // "perpetual_futures",
228
+ // "call_options",
229
+ // "put_options"
230
+ // ]
231
+ // },
232
+ // "server_time": 1650640673500273,
233
+ // "trade_farming_daily_reward": "100000",
234
+ // "circulating_supply": "140000000",
235
+ // "circulating_supply_update_time": "1636752800",
236
+ // "deto_referral_mining_daily_reward": "0",
237
+ // "deto_total_reward_pool": "100000000",
238
+ // "deto_trade_mining_daily_reward": "0",
239
+ // "kyc_deposit_limit": "20",
240
+ // "kyc_withdrawal_limit": "10000",
241
+ // "maintenance_start_time": "1650387600000000",
242
+ // "msp_deto_commission_percent": "25",
243
+ // "under_maintenance": "false"
244
+ // },
245
+ // "success": true
246
+ // }
247
+ //
248
+ const result = this.safeValue (response, 'result', {});
249
+ const underMaintenance = this.safeString (result, 'under_maintenance');
250
+ const status = (underMaintenance === 'true') ? 'maintenance' : 'ok';
251
+ const updated = this.safeIntegerProduct (result, 'server_time', 0.001, this.milliseconds ());
252
+ return {
253
+ 'status': status,
254
+ 'updated': updated,
255
+ 'eta': undefined,
256
+ 'url': undefined,
257
+ 'info': response,
258
+ };
259
+ }
260
+
261
+ async fetchCurrencies (params = {}) {
262
+ const response = await this.publicGetAssets (params);
263
+ //
264
+ // {
265
+ // "result":[
266
+ // {
267
+ // "base_withdrawal_fee":"0.0005",
268
+ // "deposit_status":"enabled",
269
+ // "id":2,
270
+ // "interest_credit":true,
271
+ // "interest_slabs":[
272
+ // {"limit":"0.1","rate":"0"},
273
+ // {"limit":"1","rate":"0.05"},
274
+ // {"limit":"5","rate":"0.075"},
275
+ // {"limit":"10","rate":"0.1"},
276
+ // {"limit":"9999999999999999","rate":"0"}
277
+ // ],
278
+ // "kyc_deposit_limit":"10",
279
+ // "kyc_withdrawal_limit":"2",
280
+ // "min_withdrawal_amount":"0.001",
281
+ // "minimum_precision":4,
282
+ // "name":"Bitcoin",
283
+ // "precision":8,
284
+ // "sort_priority":1,
285
+ // "symbol":"BTC",
286
+ // "variable_withdrawal_fee":"0",
287
+ // "withdrawal_status":"enabled"
288
+ // },
289
+ // ],
290
+ // "success":true
291
+ // }
292
+ //
293
+ const currencies = this.safeValue (response, 'result', []);
294
+ const result = {};
295
+ for (let i = 0; i < currencies.length; i++) {
296
+ const currency = currencies[i];
297
+ const id = this.safeString (currency, 'symbol');
298
+ const numericId = this.safeInteger (currency, 'id');
299
+ const code = this.safeCurrencyCode (id);
300
+ const depositStatus = this.safeString (currency, 'deposit_status');
301
+ const withdrawalStatus = this.safeString (currency, 'withdrawal_status');
302
+ const depositsEnabled = (depositStatus === 'enabled');
303
+ const withdrawalsEnabled = (withdrawalStatus === 'enabled');
304
+ const active = depositsEnabled && withdrawalsEnabled;
305
+ const precision = this.safeInteger (currency, 'precision');
306
+ result[code] = {
307
+ 'id': id,
308
+ 'numericId': numericId,
309
+ 'code': code,
310
+ 'name': this.safeString (currency, 'name'),
311
+ 'info': currency, // the original payload
312
+ 'active': active,
313
+ 'deposit': depositsEnabled,
314
+ 'withdraw': withdrawalsEnabled,
315
+ 'fee': this.safeNumber (currency, 'base_withdrawal_fee'),
316
+ 'precision': 1 / Math.pow (10, precision),
317
+ 'limits': {
318
+ 'amount': { 'min': undefined, 'max': undefined },
319
+ 'withdraw': {
320
+ 'min': this.safeNumber (currency, 'min_withdrawal_amount'),
321
+ 'max': undefined,
322
+ },
323
+ },
324
+ };
325
+ }
326
+ return result;
327
+ }
328
+
329
+ async loadMarkets (reload = false, params = {}) {
330
+ const markets = await super.loadMarkets (reload, params);
331
+ const currenciesByNumericId = this.safeValue (this.options, 'currenciesByNumericId');
332
+ if ((currenciesByNumericId === undefined) || reload) {
333
+ this.options['currenciesByNumericId'] = this.indexBy (this.currencies, 'numericId');
334
+ }
335
+ const marketsByNumericId = this.safeValue (this.options, 'marketsByNumericId');
336
+ if ((marketsByNumericId === undefined) || reload) {
337
+ this.options['marketsByNumericId'] = this.indexBy (this.markets, 'numericId');
338
+ }
339
+ return markets;
340
+ }
341
+
342
+ async fetchMarkets (params = {}) {
343
+ const response = await this.publicGetProducts (params);
344
+ //
345
+ // {
346
+ // "meta":{
347
+ // "after":null,
348
+ // "before":null,
349
+ // "limit":100,
350
+ // "total_count":81
351
+ // },
352
+ // "result":[
353
+ // {
354
+ // "annualized_funding":"5.475000000000000000",
355
+ // "is_quanto":false,
356
+ // "ui_config":{
357
+ // "default_trading_view_candle":"15",
358
+ // "leverage_slider_values":[1,3,5,10,25,50],
359
+ // "price_clubbing_values":[0.001,0.005,0.05,0.1,0.5,1,5],
360
+ // "show_bracket_orders":false,
361
+ // "sort_priority":29,
362
+ // "tags":[]
363
+ // },
364
+ // "basis_factor_max_limit":"0.15",
365
+ // "symbol":"P-LINK-D-151120",
366
+ // "id":1584,
367
+ // "default_leverage":"5.000000000000000000",
368
+ // "maker_commission_rate":"0.0005",
369
+ // "contract_unit_currency":"LINK",
370
+ // "strike_price":"12.507948",
371
+ // "settling_asset":{
372
+ // // asset structure
373
+ // },
374
+ // "auction_start_time":null,
375
+ // "auction_finish_time":null,
376
+ // "settlement_time":"2020-11-15T12:00:00Z",
377
+ // "launch_time":"2020-11-14T11:55:05Z",
378
+ // "spot_index":{
379
+ // // index structure
380
+ // },
381
+ // "trading_status":"operational",
382
+ // "tick_size":"0.001",
383
+ // "position_size_limit":100000,
384
+ // "notional_type":"vanilla", // vanilla, inverse
385
+ // "price_band":"0.4",
386
+ // "barrier_price":null,
387
+ // "description":"Daily LINK PUT options quoted in USDT and settled in USDT",
388
+ // "insurance_fund_margin_contribution":"1",
389
+ // "quoting_asset":{
390
+ // // asset structure
391
+ // },
392
+ // "liquidation_penalty_factor":"0.2",
393
+ // "product_specs":{"max_volatility":3,"min_volatility":0.3,"spot_price_band":"0.40"},
394
+ // "initial_margin_scaling_factor":"0.0001",
395
+ // "underlying_asset":{
396
+ // // asset structure
397
+ // },
398
+ // "state":"live",
399
+ // "contract_value":"1",
400
+ // "initial_margin":"2",
401
+ // "impact_size":5000,
402
+ // "settlement_price":null,
403
+ // "contract_type":"put_options", // put_options, call_options, move_options, perpetual_futures, interest_rate_swaps, futures, spreads
404
+ // "taker_commission_rate":"0.0005",
405
+ // "maintenance_margin":"1",
406
+ // "short_description":"LINK Daily PUT Options",
407
+ // "maintenance_margin_scaling_factor":"0.00005",
408
+ // "funding_method":"mark_price",
409
+ // "max_leverage_notional":"20000"
410
+ // },
411
+ // ],
412
+ // "success":true
413
+ // }
414
+ //
415
+ const markets = this.safeValue (response, 'result', []);
416
+ const result = [];
417
+ for (let i = 0; i < markets.length; i++) {
418
+ const market = markets[i];
419
+ let type = this.safeString (market, 'contract_type');
420
+ // const settlingAsset = this.safeValue (market, 'settling_asset', {});
421
+ const quotingAsset = this.safeValue (market, 'quoting_asset', {});
422
+ const underlyingAsset = this.safeValue (market, 'underlying_asset', {});
423
+ const settlingAsset = this.safeValue (market, 'settling_asset');
424
+ const baseId = this.safeString (underlyingAsset, 'symbol');
425
+ const quoteId = this.safeString (quotingAsset, 'symbol');
426
+ const settleId = this.safeString (settlingAsset, 'symbol');
427
+ const id = this.safeString (market, 'symbol');
428
+ const numericId = this.safeInteger (market, 'id');
429
+ const base = this.safeCurrencyCode (baseId);
430
+ const quote = this.safeCurrencyCode (quoteId);
431
+ const settle = this.safeCurrencyCode (settleId);
432
+ const callOptions = (type === 'call_options');
433
+ const putOptions = (type === 'put_options');
434
+ const moveOptions = (type === 'move_options');
435
+ const spot = (type === 'spot');
436
+ const swap = (type === 'perpetual_futures');
437
+ const future = (type === 'futures');
438
+ const option = (callOptions || putOptions || moveOptions);
439
+ const strike = this.safeString (market, 'strike_price');
440
+ const expiryDatetime = this.safeString (market, 'settlement_time');
441
+ const expiry = this.parse8601 (expiryDatetime);
442
+ const contractSize = this.safeNumber (market, 'contract_value');
443
+ const linear = (settle === base);
444
+ let optionType = undefined;
445
+ let symbol = base + '/' + quote;
446
+ if (swap || future || option) {
447
+ symbol = symbol + ':' + settle;
448
+ if (future || option) {
449
+ symbol = symbol + '-' + this.yymmdd (expiry);
450
+ if (option) {
451
+ type = 'option';
452
+ let letter = 'C';
453
+ optionType = 'call';
454
+ if (putOptions) {
455
+ letter = 'P';
456
+ optionType = 'put';
457
+ } else if (moveOptions) {
458
+ letter = 'M';
459
+ optionType = 'move';
460
+ }
461
+ symbol = symbol + ':' + strike + ':' + letter;
462
+ } else {
463
+ type = 'future';
464
+ }
465
+ } else {
466
+ type = 'swap';
467
+ }
468
+ } else {
469
+ symbol = id;
470
+ }
471
+ const state = this.safeString (market, 'state');
472
+ result.push ({
473
+ 'id': id,
474
+ 'numericId': numericId,
475
+ 'symbol': symbol,
476
+ 'base': base,
477
+ 'quote': quote,
478
+ 'settle': settle,
479
+ 'baseId': baseId,
480
+ 'quoteId': quoteId,
481
+ 'settleId': settleId,
482
+ 'type': type,
483
+ 'spot': spot,
484
+ 'margin': spot ? undefined : false,
485
+ 'swap': swap,
486
+ 'future': future,
487
+ 'option': option,
488
+ 'active': (state === 'live'),
489
+ 'contract': !spot,
490
+ 'linear': spot ? undefined : linear,
491
+ 'inverse': spot ? undefined : !linear,
492
+ 'taker': this.safeNumber (market, 'taker_commission_rate'),
493
+ 'maker': this.safeNumber (market, 'maker_commission_rate'),
494
+ 'contractSize': contractSize,
495
+ 'expiry': expiry,
496
+ 'expiryDatetime': expiryDatetime,
497
+ 'strike': this.parseNumber (strike),
498
+ 'optionType': optionType,
499
+ 'precision': {
500
+ 'amount': this.parseNumber ('1'), // number of contracts
501
+ 'price': this.safeNumber (market, 'tick_size'),
502
+ },
503
+ 'limits': {
504
+ 'leverage': {
505
+ 'min': undefined,
506
+ 'max': undefined,
507
+ },
508
+ 'amount': {
509
+ 'min': this.parseNumber ('1'),
510
+ 'max': this.safeNumber (market, 'position_size_limit'),
511
+ },
512
+ 'price': {
513
+ 'min': undefined,
514
+ 'max': undefined,
515
+ },
516
+ 'cost': {
517
+ 'min': this.safeNumber (market, 'min_size'),
518
+ 'max': undefined,
519
+ },
520
+ },
521
+ 'info': market,
522
+ });
523
+ }
524
+ return result;
525
+ }
526
+
527
+ parseTicker (ticker, market = undefined) {
528
+ //
529
+ // fetchTicker, fetchTickers
530
+ //
531
+ // {
532
+ // "close":15837.5,
533
+ // "high":16354,
534
+ // "low":15751.5,
535
+ // "mark_price":"15820.100867",
536
+ // "open":16140.5,
537
+ // "product_id":139,
538
+ // "size":640552,
539
+ // "spot_price":"15827.050000000001",
540
+ // "symbol":"BTCUSDT",
541
+ // "timestamp":1605373550208262,
542
+ // "turnover":10298630.3735,
543
+ // "turnover_symbol":"USDT",
544
+ // "turnover_usd":10298630.3735,
545
+ // "volume":640.5520000000001
546
+ // }
547
+ //
548
+ const timestamp = this.safeIntegerProduct (ticker, 'timestamp', 0.001);
549
+ const marketId = this.safeString (ticker, 'symbol');
550
+ const symbol = this.safeSymbol (marketId, market);
551
+ const last = this.safeString (ticker, 'close');
552
+ const open = this.safeString (ticker, 'open');
553
+ const baseVolume = this.safeString (ticker, 'volume');
554
+ const quoteVolume = this.safeString (ticker, 'turnover');
555
+ return this.safeTicker ({
556
+ 'symbol': symbol,
557
+ 'timestamp': timestamp,
558
+ 'datetime': this.iso8601 (timestamp),
559
+ 'high': this.safeString (ticker, 'high'),
560
+ 'low': this.safeString (ticker, 'low'),
561
+ 'bid': undefined,
562
+ 'bidVolume': undefined,
563
+ 'ask': undefined,
564
+ 'askVolume': undefined,
565
+ 'vwap': undefined,
566
+ 'open': open,
567
+ 'close': last,
568
+ 'last': last,
569
+ 'previousClose': undefined,
570
+ 'change': undefined,
571
+ 'percentage': undefined,
572
+ 'average': undefined,
573
+ 'baseVolume': baseVolume,
574
+ 'quoteVolume': quoteVolume,
575
+ 'info': ticker,
576
+ }, market, false);
577
+ }
578
+
579
+ async fetchTicker (symbol, params = {}) {
580
+ await this.loadMarkets ();
581
+ const market = this.market (symbol);
582
+ const request = {
583
+ 'symbol': market['id'],
584
+ };
585
+ const response = await this.publicGetTickersSymbol (this.extend (request, params));
586
+ //
587
+ // {
588
+ // "result":{
589
+ // "close":15837.5,
590
+ // "high":16354,
591
+ // "low":15751.5,
592
+ // "mark_price":"15820.100867",
593
+ // "open":16140.5,
594
+ // "product_id":139,
595
+ // "size":640552,
596
+ // "spot_price":"15827.050000000001",
597
+ // "symbol":"BTCUSDT",
598
+ // "timestamp":1605373550208262,
599
+ // "turnover":10298630.3735,
600
+ // "turnover_symbol":"USDT",
601
+ // "turnover_usd":10298630.3735,
602
+ // "volume":640.5520000000001
603
+ // },
604
+ // "success":true
605
+ // }
606
+ //
607
+ const result = this.safeValue (response, 'result', {});
608
+ return this.parseTicker (result, market);
609
+ }
610
+
611
+ async fetchTickers (symbols = undefined, params = {}) {
612
+ await this.loadMarkets ();
613
+ const response = await this.publicGetTickers (params);
614
+ //
615
+ // {
616
+ // "result":[
617
+ // {
618
+ // "close":0.003966,
619
+ // "high":0.004032,
620
+ // "low":0.003606,
621
+ // "mark_price":"0.00396328",
622
+ // "open":0.003996,
623
+ // "product_id":1327,
624
+ // "size":6242,
625
+ // "spot_price":"0.0039555",
626
+ // "symbol":"AAVEBTC",
627
+ // "timestamp":1605374143864107,
628
+ // "turnover":23.997904999999996,
629
+ // "turnover_symbol":"BTC",
630
+ // "turnover_usd":387957.4544782897,
631
+ // "volume":6242
632
+ // },
633
+ // ],
634
+ // "success":true
635
+ // }
636
+ //
637
+ const tickers = this.safeValue (response, 'result', []);
638
+ const result = {};
639
+ for (let i = 0; i < tickers.length; i++) {
640
+ const ticker = this.parseTicker (tickers[i]);
641
+ const symbol = ticker['symbol'];
642
+ result[symbol] = ticker;
643
+ }
644
+ return this.filterByArray (result, 'symbol', symbols);
645
+ }
646
+
647
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
648
+ await this.loadMarkets ();
649
+ const request = {
650
+ 'symbol': this.marketId (symbol),
651
+ };
652
+ if (limit !== undefined) {
653
+ request['depth'] = limit;
654
+ }
655
+ const response = await this.publicGetL2orderbookSymbol (this.extend (request, params));
656
+ //
657
+ // {
658
+ // "result":{
659
+ // "buy":[
660
+ // {"price":"15814.0","size":912},
661
+ // {"price":"15813.5","size":1279},
662
+ // {"price":"15813.0","size":1634},
663
+ // ],
664
+ // "sell":[
665
+ // {"price":"15814.5","size":625},
666
+ // {"price":"15815.0","size":982},
667
+ // {"price":"15815.5","size":1328},
668
+ // ],
669
+ // "symbol":"BTCUSDT"
670
+ // },
671
+ // "success":true
672
+ // }
673
+ //
674
+ const result = this.safeValue (response, 'result', {});
675
+ return this.parseOrderBook (result, symbol, undefined, 'buy', 'sell', 'price', 'size');
676
+ }
677
+
678
+ parseTrade (trade, market = undefined) {
679
+ //
680
+ // public fetchTrades
681
+ //
682
+ // {
683
+ // "buyer_role":"maker",
684
+ // "price":"15896.5",
685
+ // "seller_role":"taker",
686
+ // "size":241,
687
+ // "symbol":"BTCUSDT",
688
+ // "timestamp":1605376684714595
689
+ // }
690
+ //
691
+ // private fetchMyTrades
692
+ //
693
+ // {
694
+ // "commission":"0.008335000000000000",
695
+ // "created_at":"2020-11-16T19:07:19Z",
696
+ // "fill_type":"normal",
697
+ // "id":"e7ff05c233a74245b72381f8dd91d1ce",
698
+ // "meta_data":{
699
+ // "effective_commission_rate":"0.0005",
700
+ // "order_price":"16249",
701
+ // "order_size":1,
702
+ // "order_type":"market_order",
703
+ // "order_unfilled_size":0,
704
+ // "trading_fee_credits_used":"0"
705
+ // },
706
+ // "order_id":"152999629",
707
+ // "price":"16669",
708
+ // "product":{
709
+ // "contract_type":"perpetual_futures",
710
+ // "contract_unit_currency":"BTC",
711
+ // "contract_value":"0.001",
712
+ // "id":139,
713
+ // "notional_type":"vanilla",
714
+ // "quoting_asset":{"minimum_precision":2,"precision":6,"symbol":"USDT"},
715
+ // "settling_asset":{"minimum_precision":2,"precision":6,"symbol":"USDT"},
716
+ // "symbol":"BTCUSDT",
717
+ // "tick_size":"0.5",
718
+ // "underlying_asset":{"minimum_precision":4,"precision":8,"symbol":"BTC"}
719
+ // },
720
+ // "product_id":139,
721
+ // "role":"taker",
722
+ // "side":"sell",
723
+ // "size":1
724
+ // }
725
+ //
726
+ const id = this.safeString (trade, 'id');
727
+ const orderId = this.safeString (trade, 'order_id');
728
+ let timestamp = this.parse8601 (this.safeString (trade, 'created_at'));
729
+ timestamp = this.safeIntegerProduct (trade, 'timestamp', 0.001, timestamp);
730
+ const priceString = this.safeString (trade, 'price');
731
+ const amountString = this.safeString (trade, 'size');
732
+ const product = this.safeValue (trade, 'product', {});
733
+ const marketId = this.safeString (product, 'symbol');
734
+ const symbol = this.safeSymbol (marketId, market);
735
+ const sellerRole = this.safeString (trade, 'seller_role');
736
+ let side = this.safeString (trade, 'side');
737
+ if (side === undefined) {
738
+ if (sellerRole === 'taker') {
739
+ side = 'sell';
740
+ } else if (sellerRole === 'maker') {
741
+ side = 'buy';
742
+ }
743
+ }
744
+ const takerOrMaker = this.safeString (trade, 'role');
745
+ const metaData = this.safeValue (trade, 'meta_data', {});
746
+ let type = this.safeString (metaData, 'order_type');
747
+ if (type !== undefined) {
748
+ type = type.replace ('_order', '');
749
+ }
750
+ const feeCostString = this.safeString (trade, 'commission');
751
+ let fee = undefined;
752
+ if (feeCostString !== undefined) {
753
+ const settlingAsset = this.safeValue (product, 'settling_asset', {});
754
+ const feeCurrencyId = this.safeString (settlingAsset, 'symbol');
755
+ const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);
756
+ fee = {
757
+ 'cost': feeCostString,
758
+ 'currency': feeCurrencyCode,
759
+ };
760
+ }
761
+ return this.safeTrade ({
762
+ 'id': id,
763
+ 'order': orderId,
764
+ 'timestamp': timestamp,
765
+ 'datetime': this.iso8601 (timestamp),
766
+ 'symbol': symbol,
767
+ 'type': type,
768
+ 'side': side,
769
+ 'price': priceString,
770
+ 'amount': amountString,
771
+ 'cost': undefined,
772
+ 'takerOrMaker': takerOrMaker,
773
+ 'fee': fee,
774
+ 'info': trade,
775
+ }, market);
776
+ }
777
+
778
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
779
+ await this.loadMarkets ();
780
+ const market = this.market (symbol);
781
+ const request = {
782
+ 'symbol': market['id'],
783
+ };
784
+ const response = await this.publicGetTradesSymbol (this.extend (request, params));
785
+ //
786
+ // {
787
+ // "result":[
788
+ // {
789
+ // "buyer_role":"maker",
790
+ // "price":"15896.5",
791
+ // "seller_role":"taker",
792
+ // "size":241,
793
+ // "symbol":"BTCUSDT",
794
+ // "timestamp":1605376684714595
795
+ // }
796
+ // ],
797
+ // "success":true
798
+ // }
799
+ //
800
+ const result = this.safeValue (response, 'result', []);
801
+ return this.parseTrades (result, market, since, limit);
802
+ }
803
+
804
+ parseOHLCV (ohlcv, market = undefined) {
805
+ //
806
+ // {
807
+ // "time":1605393120,
808
+ // "open":15989,
809
+ // "high":15989,
810
+ // "low":15987.5,
811
+ // "close":15987.5,
812
+ // "volume":565
813
+ // }
814
+ //
815
+ return [
816
+ this.safeTimestamp (ohlcv, 'time'),
817
+ this.safeNumber (ohlcv, 'open'),
818
+ this.safeNumber (ohlcv, 'high'),
819
+ this.safeNumber (ohlcv, 'low'),
820
+ this.safeNumber (ohlcv, 'close'),
821
+ this.safeNumber (ohlcv, 'volume'),
822
+ ];
823
+ }
824
+
825
+ async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
826
+ await this.loadMarkets ();
827
+ const market = this.market (symbol);
828
+ const request = {
829
+ 'symbol': market['id'],
830
+ 'resolution': this.timeframes[timeframe],
831
+ };
832
+ const duration = this.parseTimeframe (timeframe);
833
+ limit = limit ? limit : 2000; // max 2000
834
+ if (since === undefined) {
835
+ const end = this.seconds ();
836
+ request['end'] = end;
837
+ request['start'] = end - limit * duration;
838
+ } else {
839
+ const start = parseInt (since / 1000);
840
+ request['start'] = start;
841
+ request['end'] = this.sum (start, limit * duration);
842
+ }
843
+ const response = await this.publicGetHistoryCandles (this.extend (request, params));
844
+ //
845
+ // {
846
+ // "success":true,
847
+ // "result":[
848
+ // {"time":1605393120,"open":15989,"high":15989,"low":15987.5,"close":15987.5,"volume":565},
849
+ // {"time":1605393180,"open":15966,"high":15966,"low":15959,"close":15959,"volume":24},
850
+ // {"time":1605393300,"open":15973,"high":15973,"low":15973,"close":15973,"volume":1288},
851
+ // ]
852
+ // }
853
+ //
854
+ const result = this.safeValue (response, 'result', []);
855
+ return this.parseOHLCVs (result, market, timeframe, since, limit);
856
+ }
857
+
858
+ parseBalance (response) {
859
+ const balances = this.safeValue (response, 'result', []);
860
+ const result = { 'info': response };
861
+ const currenciesByNumericId = this.safeValue (this.options, 'currenciesByNumericId', {});
862
+ for (let i = 0; i < balances.length; i++) {
863
+ const balance = balances[i];
864
+ const currencyId = this.safeString (balance, 'asset_id');
865
+ const currency = this.safeValue (currenciesByNumericId, currencyId);
866
+ const code = (currency === undefined) ? currencyId : currency['code'];
867
+ const account = this.account ();
868
+ account['total'] = this.safeString (balance, 'balance');
869
+ account['free'] = this.safeString (balance, 'available_balance');
870
+ result[code] = account;
871
+ }
872
+ return this.safeBalance (result);
873
+ }
874
+
875
+ async fetchBalance (params = {}) {
876
+ await this.loadMarkets ();
877
+ const response = await this.privateGetWalletBalances (params);
878
+ //
879
+ // {
880
+ // "result":[
881
+ // {
882
+ // "asset_id":1,
883
+ // "available_balance":"0",
884
+ // "balance":"0",
885
+ // "commission":"0",
886
+ // "id":154883,
887
+ // "interest_credit":"0",
888
+ // "order_margin":"0",
889
+ // "pending_referral_bonus":"0",
890
+ // "pending_trading_fee_credit":"0",
891
+ // "position_margin":"0",
892
+ // "trading_fee_credit":"0",
893
+ // "user_id":22142
894
+ // },
895
+ // ],
896
+ // "success":true
897
+ // }
898
+ //
899
+ return this.parseBalance (response);
900
+ }
901
+
902
+ async fetchPosition (symbol, params = {}) {
903
+ await this.loadMarkets ();
904
+ const market = this.market (symbol);
905
+ const request = {
906
+ 'product_id': market['numericId'],
907
+ };
908
+ const response = await this.privateGetPositions (this.extend (request, params));
909
+ //
910
+ // {
911
+ // "result":{
912
+ // "entry_price":null,
913
+ // "size":0,
914
+ // "timestamp":1605454074268079
915
+ // },
916
+ // "success":true
917
+ // }
918
+ //
919
+ const result = this.safeValue (response, 'result', {});
920
+ return result;
921
+ }
922
+
923
+ async fetchPositions (symbols = undefined, params = {}) {
924
+ await this.loadMarkets ();
925
+ const response = await this.privateGetPositionsMargined (params);
926
+ //
927
+ // {
928
+ // "success": true,
929
+ // "result": [
930
+ // {
931
+ // "user_id": 0,
932
+ // "size": 0,
933
+ // "entry_price": "string",
934
+ // "margin": "string",
935
+ // "liquidation_price": "string",
936
+ // "bankruptcy_price": "string",
937
+ // "adl_level": 0,
938
+ // "product_id": 0
939
+ // }
940
+ // ]
941
+ // }
942
+ //
943
+ const result = this.safeValue (response, 'result', []);
944
+ return result;
945
+ }
946
+
947
+ parseOrderStatus (status) {
948
+ const statuses = {
949
+ 'open': 'open',
950
+ 'pending': 'open',
951
+ 'closed': 'closed',
952
+ 'cancelled': 'canceled',
953
+ };
954
+ return this.safeString (statuses, status, status);
955
+ }
956
+
957
+ parseOrder (order, market = undefined) {
958
+ //
959
+ // createOrder, cancelOrder, editOrder, fetchOpenOrders, fetchClosedOrders
960
+ //
961
+ // {
962
+ // "average_fill_price":null,
963
+ // "bracket_order":null,
964
+ // "bracket_stop_loss_limit_price":null,
965
+ // "bracket_stop_loss_price":null,
966
+ // "bracket_take_profit_limit_price":null,
967
+ // "bracket_take_profit_price":null,
968
+ // "bracket_trail_amount":null,
969
+ // "cancellation_reason":null,
970
+ // "client_order_id":null,
971
+ // "close_on_trigger":"false",
972
+ // "commission":"0",
973
+ // "created_at":"2020-11-16T02:38:26Z",
974
+ // "id":152870626,
975
+ // "limit_price":"10000",
976
+ // "meta_data":{"source":"api"},
977
+ // "order_type":"limit_order",
978
+ // "paid_commission":"0",
979
+ // "product_id":139,
980
+ // "reduce_only":false,
981
+ // "side":"buy",
982
+ // "size":0,
983
+ // "state":"open",
984
+ // "stop_order_type":null,
985
+ // "stop_price":null,
986
+ // "stop_trigger_method":"mark_price",
987
+ // "time_in_force":"gtc",
988
+ // "trail_amount":null,
989
+ // "unfilled_size":0,
990
+ // "user_id":22142
991
+ // }
992
+ //
993
+ const id = this.safeString (order, 'id');
994
+ const clientOrderId = this.safeString (order, 'client_order_id');
995
+ const timestamp = this.parse8601 (this.safeString (order, 'created_at'));
996
+ const marketId = this.safeString (order, 'product_id');
997
+ const marketsByNumericId = this.safeValue (this.options, 'marketsByNumericId', {});
998
+ market = this.safeValue (marketsByNumericId, marketId, market);
999
+ const symbol = (market === undefined) ? marketId : market['symbol'];
1000
+ const status = this.parseOrderStatus (this.safeString (order, 'state'));
1001
+ const side = this.safeString (order, 'side');
1002
+ let type = this.safeString (order, 'order_type');
1003
+ type = type.replace ('_order', '');
1004
+ const price = this.safeString (order, 'limit_price');
1005
+ const amount = this.safeString (order, 'size');
1006
+ const remaining = this.safeString (order, 'unfilled_size');
1007
+ const average = this.safeString (order, 'average_fill_price');
1008
+ let fee = undefined;
1009
+ const feeCostString = this.safeString (order, 'paid_commission');
1010
+ if (feeCostString !== undefined) {
1011
+ let feeCurrencyCode = undefined;
1012
+ if (market !== undefined) {
1013
+ const settlingAsset = this.safeValue (market['info'], 'settling_asset', {});
1014
+ const feeCurrencyId = this.safeString (settlingAsset, 'symbol');
1015
+ feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);
1016
+ }
1017
+ fee = {
1018
+ 'cost': feeCostString,
1019
+ 'currency': feeCurrencyCode,
1020
+ };
1021
+ }
1022
+ return this.safeOrder ({
1023
+ 'info': order,
1024
+ 'id': id,
1025
+ 'clientOrderId': clientOrderId,
1026
+ 'timestamp': timestamp,
1027
+ 'datetime': this.iso8601 (timestamp),
1028
+ 'lastTradeTimestamp': undefined,
1029
+ 'symbol': symbol,
1030
+ 'type': type,
1031
+ 'side': side,
1032
+ 'price': price,
1033
+ 'amount': amount,
1034
+ 'cost': undefined,
1035
+ 'average': average,
1036
+ 'filled': undefined,
1037
+ 'remaining': remaining,
1038
+ 'status': status,
1039
+ 'fee': fee,
1040
+ 'trades': undefined,
1041
+ }, market);
1042
+ }
1043
+
1044
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
1045
+ await this.loadMarkets ();
1046
+ const orderType = type + '_order';
1047
+ const market = this.market (symbol);
1048
+ const request = {
1049
+ 'product_id': market['numericId'],
1050
+ // 'limit_price': this.priceToPrecision (symbol, price),
1051
+ 'size': this.amountToPrecision (symbol, amount),
1052
+ 'side': side,
1053
+ 'order_type': orderType,
1054
+ // 'client_order_id': 'string',
1055
+ // 'time_in_force': 'gtc', // gtc, ioc, fok
1056
+ // 'post_only': 'false', // 'true',
1057
+ // 'reduce_only': 'false', // 'true',
1058
+ };
1059
+ if (type === 'limit') {
1060
+ request['limit_price'] = this.priceToPrecision (symbol, price);
1061
+ }
1062
+ const clientOrderId = this.safeString2 (params, 'clientOrderId', 'client_order_id');
1063
+ params = this.omit (params, [ 'clientOrderId', 'client_order_id' ]);
1064
+ if (clientOrderId !== undefined) {
1065
+ request['client_order_id'] = clientOrderId;
1066
+ }
1067
+ const response = await this.privatePostOrders (this.extend (request, params));
1068
+ //
1069
+ // {
1070
+ // "result":{
1071
+ // "average_fill_price":null,
1072
+ // "bracket_order":null,
1073
+ // "bracket_stop_loss_limit_price":null,
1074
+ // "bracket_stop_loss_price":null,
1075
+ // "bracket_take_profit_limit_price":null,
1076
+ // "bracket_take_profit_price":null,
1077
+ // "bracket_trail_amount":null,
1078
+ // "cancellation_reason":null,
1079
+ // "client_order_id":null,
1080
+ // "close_on_trigger":"false",
1081
+ // "commission":"0",
1082
+ // "created_at":"2020-11-16T02:38:26Z",
1083
+ // "id":152870626,
1084
+ // "limit_price":"10000",
1085
+ // "meta_data":{"source":"api"},
1086
+ // "order_type":"limit_order",
1087
+ // "paid_commission":"0",
1088
+ // "product_id":139,
1089
+ // "reduce_only":false,
1090
+ // "side":"buy",
1091
+ // "size":0,
1092
+ // "state":"open",
1093
+ // "stop_order_type":null,
1094
+ // "stop_price":null,
1095
+ // "stop_trigger_method":"mark_price",
1096
+ // "time_in_force":"gtc",
1097
+ // "trail_amount":null,
1098
+ // "unfilled_size":0,
1099
+ // "user_id":22142
1100
+ // },
1101
+ // "success":true
1102
+ // }
1103
+ //
1104
+ const result = this.safeValue (response, 'result', {});
1105
+ return this.parseOrder (result, market);
1106
+ }
1107
+
1108
+ async editOrder (id, symbol, type, side, amount, price = undefined, params = {}) {
1109
+ await this.loadMarkets ();
1110
+ const market = this.market (symbol);
1111
+ const request = {
1112
+ 'id': parseInt (id),
1113
+ 'product_id': market['numericId'],
1114
+ // 'limit_price': this.priceToPrecision (symbol, price),
1115
+ // 'size': this.amountToPrecision (symbol, amount),
1116
+ };
1117
+ if (amount !== undefined) {
1118
+ request['size'] = parseInt (this.amountToPrecision (symbol, amount));
1119
+ }
1120
+ if (price !== undefined) {
1121
+ request['limit_price'] = this.priceToPrecision (symbol, price);
1122
+ }
1123
+ const response = await this.privatePutOrders (this.extend (request, params));
1124
+ //
1125
+ // {
1126
+ // "success": true,
1127
+ // "result": {
1128
+ // "id": "ashb1212",
1129
+ // "product_id": 27,
1130
+ // "limit_price": "9200",
1131
+ // "side": "buy",
1132
+ // "size": 100,
1133
+ // "unfilled_size": 50,
1134
+ // "user_id": 1,
1135
+ // "order_type": "limit_order",
1136
+ // "state": "open",
1137
+ // "created_at": "..."
1138
+ // }
1139
+ // }
1140
+ //
1141
+ const result = this.safeValue (response, 'result');
1142
+ return this.parseOrder (result, market);
1143
+ }
1144
+
1145
+ async cancelOrder (id, symbol = undefined, params = {}) {
1146
+ if (symbol === undefined) {
1147
+ throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
1148
+ }
1149
+ await this.loadMarkets ();
1150
+ const market = this.market (symbol);
1151
+ const request = {
1152
+ 'id': parseInt (id),
1153
+ 'product_id': market['numericId'],
1154
+ };
1155
+ const response = await this.privateDeleteOrders (this.extend (request, params));
1156
+ //
1157
+ // {
1158
+ // "result":{
1159
+ // "average_fill_price":null,
1160
+ // "bracket_order":null,
1161
+ // "bracket_stop_loss_limit_price":null,
1162
+ // "bracket_stop_loss_price":null,
1163
+ // "bracket_take_profit_limit_price":null,
1164
+ // "bracket_take_profit_price":null,
1165
+ // "bracket_trail_amount":null,
1166
+ // "cancellation_reason":"cancelled_by_user",
1167
+ // "client_order_id":null,
1168
+ // "close_on_trigger":"false",
1169
+ // "commission":"0",
1170
+ // "created_at":"2020-11-16T02:38:26Z",
1171
+ // "id":152870626,
1172
+ // "limit_price":"10000",
1173
+ // "meta_data":{"source":"api"},
1174
+ // "order_type":"limit_order",
1175
+ // "paid_commission":"0",
1176
+ // "product_id":139,
1177
+ // "reduce_only":false,
1178
+ // "side":"buy",
1179
+ // "size":0,
1180
+ // "state":"cancelled",
1181
+ // "stop_order_type":null,
1182
+ // "stop_price":null,
1183
+ // "stop_trigger_method":"mark_price",
1184
+ // "time_in_force":"gtc",
1185
+ // "trail_amount":null,
1186
+ // "unfilled_size":0,
1187
+ // "user_id":22142
1188
+ // },
1189
+ // "success":true
1190
+ // }
1191
+ //
1192
+ const result = this.safeValue (response, 'result');
1193
+ return this.parseOrder (result, market);
1194
+ }
1195
+
1196
+ async cancelAllOrders (symbol = undefined, params = {}) {
1197
+ if (symbol === undefined) {
1198
+ throw new ArgumentsRequired (this.id + ' cancelAllOrders() requires a symbol argument');
1199
+ }
1200
+ await this.loadMarkets ();
1201
+ const market = this.market (symbol);
1202
+ const request = {
1203
+ 'product_id': market['numericId'],
1204
+ // 'cancel_limit_orders': 'true',
1205
+ // 'cancel_stop_orders': 'true',
1206
+ };
1207
+ const response = this.privateDeleteOrdersAll (this.extend (request, params));
1208
+ //
1209
+ // {
1210
+ // "result":{},
1211
+ // "success":true
1212
+ // }
1213
+ //
1214
+ return response;
1215
+ }
1216
+
1217
+ async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1218
+ return await this.fetchOrdersWithMethod ('privateGetOrders', symbol, since, limit, params);
1219
+ }
1220
+
1221
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1222
+ return await this.fetchOrdersWithMethod ('privateGetOrdersHistory', symbol, since, limit, params);
1223
+ }
1224
+
1225
+ async fetchOrdersWithMethod (method, symbol = undefined, since = undefined, limit = undefined, params = {}) {
1226
+ await this.loadMarkets ();
1227
+ const request = {
1228
+ // 'product_ids': market['id'], // comma-separated
1229
+ // 'contract_types': types, // comma-separated, futures, perpetual_futures, call_options, put_options, interest_rate_swaps, move_options, spreads
1230
+ // 'order_types': types, // comma-separated, market, limit, stop_market, stop_limit, all_stop
1231
+ // 'start_time': since * 1000,
1232
+ // 'end_time': this.microseconds (),
1233
+ // 'after': string, // after cursor for pagination
1234
+ // 'before': string, // before cursor for pagination
1235
+ // 'page_size': limit, // number of records per page
1236
+ };
1237
+ let market = undefined;
1238
+ if (symbol !== undefined) {
1239
+ market = this.market (symbol);
1240
+ request['product_ids'] = market['numericId']; // accepts a comma-separated list of ids
1241
+ }
1242
+ if (since !== undefined) {
1243
+ request['start_time'] = since.toString () + '000';
1244
+ }
1245
+ if (limit !== undefined) {
1246
+ request['page_size'] = limit;
1247
+ }
1248
+ const response = await this[method] (this.extend (request, params));
1249
+ //
1250
+ // {
1251
+ // "success": true,
1252
+ // "result": [
1253
+ // {
1254
+ // "id": "ashb1212",
1255
+ // "product_id": 27,
1256
+ // "limit_price": "9200",
1257
+ // "side": "buy",
1258
+ // "size": 100,
1259
+ // "unfilled_size": 50,
1260
+ // "user_id": 1,
1261
+ // "order_type": "limit_order",
1262
+ // "state": "open",
1263
+ // "created_at": "..."
1264
+ // }
1265
+ // ],
1266
+ // "meta": {
1267
+ // "after": "string",
1268
+ // "before": "string"
1269
+ // }
1270
+ // }
1271
+ //
1272
+ const result = this.safeValue (response, 'result', []);
1273
+ return this.parseOrders (result, market, since, limit);
1274
+ }
1275
+
1276
+ async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1277
+ await this.loadMarkets ();
1278
+ const request = {
1279
+ // 'product_ids': market['id'], // comma-separated
1280
+ // 'contract_types': types, // comma-separated, futures, perpetual_futures, call_options, put_options, interest_rate_swaps, move_options, spreads
1281
+ // 'start_time': since * 1000,
1282
+ // 'end_time': this.microseconds (),
1283
+ // 'after': string, // after cursor for pagination
1284
+ // 'before': string, // before cursor for pagination
1285
+ // 'page_size': limit, // number of records per page
1286
+ };
1287
+ let market = undefined;
1288
+ if (symbol !== undefined) {
1289
+ market = this.market (symbol);
1290
+ request['product_ids'] = market['numericId']; // accepts a comma-separated list of ids
1291
+ }
1292
+ if (since !== undefined) {
1293
+ request['start_time'] = since.toString () + '000';
1294
+ }
1295
+ if (limit !== undefined) {
1296
+ request['page_size'] = limit;
1297
+ }
1298
+ const response = await this.privateGetFills (this.extend (request, params));
1299
+ //
1300
+ // {
1301
+ // "meta":{
1302
+ // "after":null,
1303
+ // "before":null,
1304
+ // "limit":10,
1305
+ // "total_count":2
1306
+ // },
1307
+ // "result":[
1308
+ // {
1309
+ // "commission":"0.008335000000000000",
1310
+ // "created_at":"2020-11-16T19:07:19Z",
1311
+ // "fill_type":"normal",
1312
+ // "id":"e7ff05c233a74245b72381f8dd91d1ce",
1313
+ // "meta_data":{
1314
+ // "effective_commission_rate":"0.0005",
1315
+ // "order_price":"16249",
1316
+ // "order_size":1,
1317
+ // "order_type":"market_order",
1318
+ // "order_unfilled_size":0,
1319
+ // "trading_fee_credits_used":"0"
1320
+ // },
1321
+ // "order_id":"152999629",
1322
+ // "price":"16669",
1323
+ // "product":{
1324
+ // "contract_type":"perpetual_futures",
1325
+ // "contract_unit_currency":"BTC",
1326
+ // "contract_value":"0.001",
1327
+ // "id":139,
1328
+ // "notional_type":"vanilla",
1329
+ // "quoting_asset":{"minimum_precision":2,"precision":6,"symbol":"USDT"},
1330
+ // "settling_asset":{"minimum_precision":2,"precision":6,"symbol":"USDT"},
1331
+ // "symbol":"BTCUSDT",
1332
+ // "tick_size":"0.5",
1333
+ // "underlying_asset":{"minimum_precision":4,"precision":8,"symbol":"BTC"}
1334
+ // },
1335
+ // "product_id":139,
1336
+ // "role":"taker",
1337
+ // "side":"sell",
1338
+ // "size":1
1339
+ // }
1340
+ // ],
1341
+ // "success":true
1342
+ // }
1343
+ //
1344
+ const result = this.safeValue (response, 'result', []);
1345
+ return this.parseTrades (result, market, since, limit);
1346
+ }
1347
+
1348
+ async fetchLedger (code = undefined, since = undefined, limit = undefined, params = {}) {
1349
+ await this.loadMarkets ();
1350
+ const request = {
1351
+ // 'asset_id': currency['numericId'],
1352
+ // 'end_time': this.seconds (),
1353
+ // 'after': 'string', // after cursor for pagination
1354
+ // 'before': 'string', // before cursor for pagination
1355
+ // 'page_size': limit,
1356
+ };
1357
+ let currency = undefined;
1358
+ if (code !== undefined) {
1359
+ currency = this.currency (code);
1360
+ request['asset_id'] = currency['numericId'];
1361
+ }
1362
+ if (limit !== undefined) {
1363
+ request['page_size'] = limit;
1364
+ }
1365
+ const response = await this.privateGetWalletTransactions (this.extend (request, params));
1366
+ //
1367
+ // {
1368
+ // "meta":{"after":null,"before":null,"limit":10,"total_count":1},
1369
+ // "result":[
1370
+ // {
1371
+ // "amount":"29.889184",
1372
+ // "asset_id":5,
1373
+ // "balance":"29.889184",
1374
+ // "created_at":"2020-11-15T21:25:01Z",
1375
+ // "meta_data":{
1376
+ // "deposit_id":3884,
1377
+ // "transaction_id":"0x41a60174849828530abb5008e98fc63c9b598288743ec4ba9620bcce900a3b8d"
1378
+ // },
1379
+ // "transaction_type":"deposit",
1380
+ // "user_id":22142,
1381
+ // "uuid":"70bb5679da3c4637884e2dc63efaa846"
1382
+ // }
1383
+ // ],
1384
+ // "success":true
1385
+ // }
1386
+ //
1387
+ const result = this.safeValue (response, 'result', []);
1388
+ return this.parseLedger (result, currency, since, limit);
1389
+ }
1390
+
1391
+ parseLedgerEntryType (type) {
1392
+ const types = {
1393
+ 'pnl': 'pnl',
1394
+ 'deposit': 'transaction',
1395
+ 'withdrawal': 'transaction',
1396
+ 'commission': 'fee',
1397
+ 'conversion': 'trade',
1398
+ // 'perpetual_futures_funding': 'perpetual_futures_funding',
1399
+ // 'withdrawal_cancellation': 'withdrawal_cancellation',
1400
+ 'referral_bonus': 'referral',
1401
+ 'commission_rebate': 'rebate',
1402
+ // 'promo_credit': 'promo_credit',
1403
+ };
1404
+ return this.safeString (types, type, type);
1405
+ }
1406
+
1407
+ parseLedgerEntry (item, currency = undefined) {
1408
+ //
1409
+ // {
1410
+ // "amount":"29.889184",
1411
+ // "asset_id":5,
1412
+ // "balance":"29.889184",
1413
+ // "created_at":"2020-11-15T21:25:01Z",
1414
+ // "meta_data":{
1415
+ // "deposit_id":3884,
1416
+ // "transaction_id":"0x41a60174849828530abb5008e98fc63c9b598288743ec4ba9620bcce900a3b8d"
1417
+ // },
1418
+ // "transaction_type":"deposit",
1419
+ // "user_id":22142,
1420
+ // "uuid":"70bb5679da3c4637884e2dc63efaa846"
1421
+ // }
1422
+ //
1423
+ const id = this.safeString (item, 'uuid');
1424
+ let direction = undefined;
1425
+ const account = undefined;
1426
+ const metaData = this.safeValue (item, 'meta_data', {});
1427
+ const referenceId = this.safeString (metaData, 'transaction_id');
1428
+ const referenceAccount = undefined;
1429
+ let type = this.safeString (item, 'transaction_type');
1430
+ if ((type === 'deposit') || (type === 'commission_rebate') || (type === 'referral_bonus') || (type === 'pnl') || (type === 'withdrawal_cancellation') || (type === 'promo_credit')) {
1431
+ direction = 'in';
1432
+ } else if ((type === 'withdrawal') || (type === 'commission') || (type === 'conversion') || (type === 'perpetual_futures_funding')) {
1433
+ direction = 'out';
1434
+ }
1435
+ type = this.parseLedgerEntryType (type);
1436
+ const currencyId = this.safeInteger (item, 'asset_id');
1437
+ const currenciesByNumericId = this.safeValue (this.options, 'currenciesByNumericId');
1438
+ currency = this.safeValue (currenciesByNumericId, currencyId, currency);
1439
+ const code = (currency === undefined) ? undefined : currency['code'];
1440
+ const amount = this.safeNumber (item, 'amount');
1441
+ const timestamp = this.parse8601 (this.safeString (item, 'created_at'));
1442
+ const after = this.safeNumber (item, 'balance');
1443
+ const before = Math.max (0, after - amount);
1444
+ const status = 'ok';
1445
+ return {
1446
+ 'info': item,
1447
+ 'id': id,
1448
+ 'direction': direction,
1449
+ 'account': account,
1450
+ 'referenceId': referenceId,
1451
+ 'referenceAccount': referenceAccount,
1452
+ 'type': type,
1453
+ 'currency': code,
1454
+ 'amount': amount,
1455
+ 'before': before,
1456
+ 'after': after,
1457
+ 'status': status,
1458
+ 'timestamp': timestamp,
1459
+ 'datetime': this.iso8601 (timestamp),
1460
+ 'fee': undefined,
1461
+ };
1462
+ }
1463
+
1464
+ async fetchDepositAddress (code, params = {}) {
1465
+ await this.loadMarkets ();
1466
+ const currency = this.currency (code);
1467
+ const request = {
1468
+ 'asset_symbol': currency['id'],
1469
+ };
1470
+ const response = await this.privateGetDepositsAddress (this.extend (request, params));
1471
+ //
1472
+ // {
1473
+ // "success":true,
1474
+ // "result":{
1475
+ // "id":19628,
1476
+ // "user_id":22142,
1477
+ // "address":"0x0eda26523397534f814d553a065d8e46b4188e9a",
1478
+ // "status":"active",
1479
+ // "updated_at":"2020-11-15T20:25:53.000Z",
1480
+ // "created_at":"2020-11-15T20:25:53.000Z",
1481
+ // "asset_symbol":"USDT",
1482
+ // "custodian":"onc"
1483
+ // }
1484
+ // }
1485
+ //
1486
+ const result = this.safeValue (response, 'result', {});
1487
+ const address = this.safeString (result, 'address');
1488
+ this.checkAddress (address);
1489
+ return {
1490
+ 'currency': code,
1491
+ 'address': address,
1492
+ 'tag': undefined,
1493
+ 'network': undefined,
1494
+ 'info': response,
1495
+ };
1496
+ }
1497
+
1498
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1499
+ const requestPath = '/' + this.version + '/' + this.implodeParams (path, params);
1500
+ let url = this.urls['api'][api] + requestPath;
1501
+ const query = this.omit (params, this.extractParams (path));
1502
+ if (api === 'public') {
1503
+ if (Object.keys (query).length) {
1504
+ url += '?' + this.urlencode (query);
1505
+ }
1506
+ } else if (api === 'private') {
1507
+ this.checkRequiredCredentials ();
1508
+ const timestamp = this.seconds ().toString ();
1509
+ headers = {
1510
+ 'api-key': this.apiKey,
1511
+ 'timestamp': timestamp,
1512
+ };
1513
+ let auth = method + timestamp + requestPath;
1514
+ if ((method === 'GET') || (method === 'DELETE')) {
1515
+ if (Object.keys (query).length) {
1516
+ const queryString = '?' + this.urlencode (query);
1517
+ auth += queryString;
1518
+ url += queryString;
1519
+ }
1520
+ } else {
1521
+ body = this.json (query);
1522
+ auth += body;
1523
+ headers['Content-Type'] = 'application/json';
1524
+ }
1525
+ const signature = this.hmac (this.encode (auth), this.encode (this.secret));
1526
+ headers['signature'] = signature;
1527
+ }
1528
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
1529
+ }
1530
+
1531
+ handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
1532
+ if (response === undefined) {
1533
+ return;
1534
+ }
1535
+ //
1536
+ // {"error":{"code":"insufficient_margin","context":{"available_balance":"0.000000000000000000","required_additional_balance":"1.618626000000000000000000000"}},"success":false}
1537
+ //
1538
+ const error = this.safeValue (response, 'error', {});
1539
+ const errorCode = this.safeString (error, 'code');
1540
+ if (errorCode !== undefined) {
1541
+ const feedback = this.id + ' ' + body;
1542
+ this.throwExactlyMatchedException (this.exceptions['exact'], errorCode, feedback);
1543
+ this.throwBroadlyMatchedException (this.exceptions['broad'], errorCode, feedback);
1544
+ throw new ExchangeError (feedback); // unknown message
1545
+ }
1546
+ }
1547
+ };