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/bybit.js ADDED
@@ -0,0 +1,3372 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { TICK_SIZE } = require ('./base/functions/number');
7
+ const { AuthenticationError, ExchangeError, ArgumentsRequired, PermissionDenied, InvalidOrder, OrderNotFound, InsufficientFunds, BadRequest, RateLimitExceeded, InvalidNonce } = require ('./base/errors');
8
+ const Precise = require ('./base/Precise');
9
+
10
+ // ---------------------------------------------------------------------------
11
+
12
+ module.exports = class bybit extends Exchange {
13
+ describe () {
14
+ return this.deepExtend (super.describe (), {
15
+ 'id': 'bybit',
16
+ 'name': 'Bybit',
17
+ 'countries': [ 'VG' ], // British Virgin Islands
18
+ 'version': 'v2',
19
+ 'userAgent': undefined,
20
+ // 50 requests per second for GET requests, 1000ms / 50 = 20ms between requests
21
+ // 20 requests per second for POST requests, cost = 50 / 20 = 2.5
22
+ 'rateLimit': 20,
23
+ 'hostname': 'bybit.com', // bybit.com, bytick.com
24
+ 'has': {
25
+ 'CORS': true,
26
+ 'spot': true,
27
+ 'margin': false,
28
+ 'swap': true,
29
+ 'future': true,
30
+ 'option': undefined,
31
+ 'cancelAllOrders': true,
32
+ 'cancelOrder': true,
33
+ 'createOrder': true,
34
+ 'createStopLimitOrder': true,
35
+ 'createStopMarketOrder': true,
36
+ 'createStopOrder': true,
37
+ 'editOrder': true,
38
+ 'fetchBalance': true,
39
+ 'fetchBorrowRate': false,
40
+ 'fetchBorrowRates': false,
41
+ 'fetchClosedOrders': true,
42
+ 'fetchDeposits': true,
43
+ 'fetchFundingRate': true,
44
+ 'fetchFundingRateHistory': false,
45
+ 'fetchIndexOHLCV': true,
46
+ 'fetchLedger': true,
47
+ 'fetchMarketLeverageTiers': true,
48
+ 'fetchMarkets': true,
49
+ 'fetchMarkOHLCV': true,
50
+ 'fetchMyTrades': true,
51
+ 'fetchOHLCV': true,
52
+ 'fetchOpenOrders': true,
53
+ 'fetchOrder': true,
54
+ 'fetchOrderBook': true,
55
+ 'fetchOrders': true,
56
+ 'fetchOrderTrades': true,
57
+ 'fetchPositions': true,
58
+ 'fetchPremiumIndexOHLCV': true,
59
+ 'fetchTicker': true,
60
+ 'fetchTickers': true,
61
+ 'fetchTime': true,
62
+ 'fetchTrades': true,
63
+ 'fetchTradingFee': false,
64
+ 'fetchTradingFees': false,
65
+ 'fetchTransactions': undefined,
66
+ 'fetchWithdrawals': true,
67
+ 'setLeverage': true,
68
+ 'setMarginMode': true,
69
+ },
70
+ 'timeframes': {
71
+ '1m': '1',
72
+ '3m': '3',
73
+ '5m': '5',
74
+ '15m': '15',
75
+ '30m': '30',
76
+ '1h': '60',
77
+ '2h': '120',
78
+ '4h': '240',
79
+ '6h': '360',
80
+ '12h': '720',
81
+ '1d': 'D',
82
+ '1w': 'W',
83
+ '1M': 'M',
84
+ '1y': 'Y',
85
+ },
86
+ 'urls': {
87
+ 'test': {
88
+ 'spot': 'https://api-testnet.{hostname}',
89
+ 'futures': 'https://api-testnet.{hostname}',
90
+ 'v2': 'https://api-testnet.{hostname}',
91
+ 'public': 'https://api-testnet.{hostname}',
92
+ 'private': 'https://api-testnet.{hostname}',
93
+ },
94
+ 'logo': 'https://user-images.githubusercontent.com/51840849/76547799-daff5b80-649e-11ea-87fb-3be9bac08954.jpg',
95
+ 'api': {
96
+ 'spot': 'https://api.{hostname}',
97
+ 'futures': 'https://api.{hostname}',
98
+ 'v2': 'https://api.{hostname}',
99
+ 'public': 'https://api.{hostname}',
100
+ 'private': 'https://api.{hostname}',
101
+ },
102
+ 'www': 'https://www.bybit.com',
103
+ 'doc': [
104
+ 'https://bybit-exchange.github.io/docs/inverse/',
105
+ 'https://bybit-exchange.github.io/docs/linear/',
106
+ 'https://github.com/bybit-exchange',
107
+ ],
108
+ 'fees': 'https://help.bybit.com/hc/en-us/articles/360039261154',
109
+ 'referral': 'https://www.bybit.com/app/register?ref=X7Prm',
110
+ },
111
+ 'api': {
112
+ // outdated endpoints -----------------------------------------
113
+ 'spot': {
114
+ 'public': {
115
+ 'get': [
116
+ 'symbols',
117
+ ],
118
+ },
119
+ 'quote': {
120
+ 'get': [
121
+ 'depth',
122
+ 'depth/merged',
123
+ 'trades',
124
+ 'kline',
125
+ 'ticker/24hr',
126
+ 'ticker/price',
127
+ 'ticker/book_ticker',
128
+ ],
129
+ },
130
+ 'private': {
131
+ 'get': [
132
+ 'order',
133
+ 'open-orders',
134
+ 'history-orders',
135
+ 'myTrades',
136
+ 'account',
137
+ 'time',
138
+ ],
139
+ 'post': [
140
+ 'order',
141
+ ],
142
+ 'delete': [
143
+ 'order',
144
+ 'order/fast',
145
+ ],
146
+ },
147
+ 'order': {
148
+ 'delete': [
149
+ 'batch-cancel',
150
+ 'batch-fast-cancel',
151
+ 'batch-cancel-by-ids',
152
+ ],
153
+ },
154
+ },
155
+ 'futures': {
156
+ 'private': {
157
+ 'get': [
158
+ 'order/list',
159
+ 'order',
160
+ 'stop-order/list',
161
+ 'stop-order',
162
+ 'position/list',
163
+ 'execution/list',
164
+ 'trade/closed-pnl/list',
165
+ ],
166
+ 'post': [
167
+ 'order/create',
168
+ 'order/cancel',
169
+ 'order/cancelAll',
170
+ 'order/replace',
171
+ 'stop-order/create',
172
+ 'stop-order/cancel',
173
+ 'stop-order/cancelAll',
174
+ 'stop-order/replace',
175
+ 'position/change-position-margin',
176
+ 'position/trading-stop',
177
+ 'position/leverage/save',
178
+ 'position/switch-mode',
179
+ 'position/switch-isolated',
180
+ 'position/risk-limit',
181
+ ],
182
+ },
183
+ },
184
+ 'v2': {
185
+ 'public': {
186
+ 'get': [
187
+ 'orderBook/L2',
188
+ 'kline/list',
189
+ 'tickers',
190
+ 'trading-records',
191
+ 'symbols',
192
+ 'liq-records',
193
+ 'mark-price-kline',
194
+ 'index-price-kline',
195
+ 'premium-index-kline',
196
+ 'open-interest',
197
+ 'big-deal',
198
+ 'account-ratio',
199
+ 'time',
200
+ 'announcement',
201
+ 'funding/prev-funding-rate',
202
+ 'risk-limit/list',
203
+ ],
204
+ },
205
+ 'private': {
206
+ 'get': [
207
+ 'order/list',
208
+ 'order',
209
+ 'stop-order/list',
210
+ 'stop-order',
211
+ 'position/list',
212
+ 'position/fee-rate',
213
+ 'execution/list',
214
+ 'trade/closed-pnl/list',
215
+ 'funding/prev-funding-rate',
216
+ 'funding/prev-funding',
217
+ 'funding/predicted-funding',
218
+ 'account/api-key',
219
+ 'account/lcp',
220
+ 'wallet/balance',
221
+ 'wallet/fund/records',
222
+ 'wallet/withdraw/list',
223
+ 'exchange-order/list',
224
+ ],
225
+ 'post': [
226
+ 'order/create',
227
+ 'order/cancel',
228
+ 'order/cancelAll',
229
+ 'order/replace',
230
+ 'stop-order/create',
231
+ 'stop-order/cancel',
232
+ 'stop-order/cancelAll',
233
+ 'stop-order/replace',
234
+ 'position/change-position-margin',
235
+ 'position/trading-stop',
236
+ 'position/leverage/save',
237
+ 'position/switch-mode',
238
+ 'position/switch-isolated',
239
+ 'position/risk-limit',
240
+ ],
241
+ },
242
+ },
243
+ // new endpoints ------------------------------------------
244
+ 'public': {
245
+ 'get': {
246
+ // inverse swap
247
+ 'v2/public/orderBook/L2': 1,
248
+ 'v2/public/kline/list': 3,
249
+ 'v2/public/tickers': 1,
250
+ 'v2/public/trading-records': 1,
251
+ 'v2/public/symbols': 1,
252
+ 'v2/public/mark-price-kline': 3,
253
+ 'v2/public/index-price-kline': 3,
254
+ 'v2/public/premium-index-kline': 2,
255
+ 'v2/public/open-interest': 1,
256
+ 'v2/public/big-deal': 1,
257
+ 'v2/public/account-ratio': 1,
258
+ 'v2/public/funding-rate': 1,
259
+ 'v2/public/elite-ratio': 1,
260
+ // linear swap USDT
261
+ 'public/linear/kline': 3,
262
+ 'public/linear/recent-trading-records': 1,
263
+ 'public/linear/funding/prev-funding-rate': 1,
264
+ 'public/linear/mark-price-kline': 1,
265
+ 'public/linear/index-price-kline': 1,
266
+ 'public/linear/premium-index-kline': 1,
267
+ // spot
268
+ 'spot/v1/time': 1,
269
+ 'spot/v1/symbols': 1,
270
+ 'spot/quote/v1/depth': 1,
271
+ 'spot/quote/v1/depth/merged': 1,
272
+ 'spot/quote/v1/trades': 1,
273
+ 'spot/quote/v1/kline': 1,
274
+ 'spot/quote/v1/ticker/24hr': 1,
275
+ 'spot/quote/v1/ticker/price': 1,
276
+ 'spot/quote/v1/ticker/book_ticker': 1,
277
+ // data
278
+ 'v2/public/time': 1,
279
+ 'v2/public/announcement': 1,
280
+ // USDC endpoints are testnet only as of 2022 Jan 11 ----------
281
+ // option USDC (testnet only)
282
+ 'option/usdc/openapi/public/v1/order-book': 1,
283
+ 'option/usdc/openapi/public/v1/symbols': 1,
284
+ 'option/usdc/openapi/public/v1/tick': 1,
285
+ 'option/usdc/openapi/public/v1/delivery-price': 1,
286
+ 'option/usdc/openapi/public/v1/query-trade-latest': 1,
287
+ // perpetual swap USDC (testnet only)
288
+ 'perpetual/usdc/openapi/public/v1/order-book': 1,
289
+ 'perpetual/usdc/openapi/public/v1/symbols': 1,
290
+ 'perpetual/usdc/openapi/public/v1/tick': 1,
291
+ 'perpetual/usdc/openapi/public/v1/kline/list': 1,
292
+ 'perpetual/usdc/openapi/public/v1/mark-price-kline': 1,
293
+ 'perpetual/usdc/openapi/public/v1/index-price-kline': 1,
294
+ 'perpetual/usdc/openapi/public/v1/premium-index-kline': 1,
295
+ 'perpetual/usdc/openapi/public/v1/open-interest': 1,
296
+ 'perpetual/usdc/openapi/public/v1/big-deal': 1,
297
+ 'perpetual/usdc/openapi/public/v1/account-ratio': 1,
298
+ },
299
+ // outdated endpoints--------------------------------------
300
+ 'linear': {
301
+ 'get': [
302
+ 'kline',
303
+ 'recent-trading-records',
304
+ 'funding/prev-funding-rate',
305
+ 'mark-price-kline',
306
+ 'index-price-kline',
307
+ 'premium-index-kline',
308
+ 'risk-limit',
309
+ ],
310
+ },
311
+ },
312
+ // new endpoints ------------------------------------------
313
+ 'private': {
314
+ 'get': {
315
+ // inverse swap
316
+ 'v2/private/order/list': 5,
317
+ 'v2/private/order': 5,
318
+ 'v2/private/stop-order/list': 5,
319
+ 'v2/private/stop-order': 1,
320
+ 'v2/private/position/list': 25,
321
+ 'v2/private/position/fee-rate': 40,
322
+ 'v2/private/execution/list': 25,
323
+ 'v2/private/trade/closed-pnl/list': 1,
324
+ 'v2/public/risk-limit/list': 1, // TODO check
325
+ 'v2/public/funding/prev-funding-rate': 25, // TODO check
326
+ 'v2/private/funding/prev-funding': 25,
327
+ 'v2/private/funding/predicted-funding': 25,
328
+ 'v2/private/account/api-key': 5,
329
+ 'v2/private/account/lcp': 1,
330
+ 'v2/private/wallet/balance': 25, // 120 per minute = 2 per second => cost = 50 / 2 = 25
331
+ 'v2/private/wallet/fund/records': 25,
332
+ 'v2/private/wallet/withdraw/list': 25,
333
+ 'v2/private/exchange-order/list': 1,
334
+ // linear swap USDT
335
+ 'private/linear/order/list': 5, // 600 per minute = 10 per second => cost = 50 / 10 = 5
336
+ 'private/linear/order/search': 5,
337
+ 'private/linear/stop-order/list': 5,
338
+ 'private/linear/stop-order/search': 5,
339
+ 'private/linear/position/list': 25,
340
+ 'private/linear/trade/execution/list': 25,
341
+ 'private/linear/trade/closed-pnl/list': 25,
342
+ 'public/linear/risk-limit': 1,
343
+ 'private/linear/funding/predicted-funding': 25,
344
+ 'private/linear/funding/prev-funding': 25,
345
+ // inverse futures
346
+ 'futures/private/order/list': 5,
347
+ 'futures/private/order': 5,
348
+ 'futures/private/stop-order/list': 5,
349
+ 'futures/private/stop-order': 5,
350
+ 'futures/private/position/list': 25,
351
+ 'futures/private/execution/list': 25,
352
+ 'futures/private/trade/closed-pnl/list': 1,
353
+ // spot
354
+ 'spot/v1/account': 2.5,
355
+ 'spot/v1/order': 2.5,
356
+ 'spot/v1/open-orders': 2.5,
357
+ 'spot/v1/history-orders': 2.5,
358
+ 'spot/v1/myTrades': 2.5,
359
+ // account
360
+ 'asset/v1/private/transfer/list': 50, // 60 per minute = 1 per second => cost = 50 / 1 = 50
361
+ 'asset/v1/private/sub-member/transfer/list': 50,
362
+ 'asset/v1/private/sub-member/member-ids': 50,
363
+ },
364
+ 'post': {
365
+ // inverse swap
366
+ 'v2/private/order/create': 30,
367
+ 'v2/private/order/cancel': 30,
368
+ 'v2/private/order/cancelAll': 300, // 100 per minute + 'consumes 10 requests'
369
+ 'v2/private/order/replace': 30,
370
+ 'v2/private/stop-order/create': 30,
371
+ 'v2/private/stop-order/cancel': 30,
372
+ 'v2/private/stop-order/cancelAll': 300,
373
+ 'v2/private/stop-order/replace': 30,
374
+ 'v2/private/position/change-position-margin': 40,
375
+ 'v2/private/position/trading-stop': 40,
376
+ 'v2/private/position/leverage/save': 40,
377
+ 'v2/private/tpsl/switch-mode': 40,
378
+ 'v2/private/position/switch-isolated': 2.5,
379
+ 'v2/private/position/risk-limit': 2.5,
380
+ 'v2/private/position/switch-mode': 2.5,
381
+ // linear swap USDT
382
+ 'private/linear/order/create': 30, // 100 per minute = 1.666 per second => cost = 50 / 1.6666 = 30
383
+ 'private/linear/order/cancel': 30,
384
+ 'private/linear/order/cancel-all': 300, // 100 per minute + 'consumes 10 requests'
385
+ 'private/linear/order/replace': 30,
386
+ 'private/linear/stop-order/create': 30,
387
+ 'private/linear/stop-order/cancel': 30,
388
+ 'private/linear/stop-order/cancel-all': 300,
389
+ 'private/linear/stop-order/replace': 30,
390
+ 'private/linear/position/set-auto-add-margin': 40,
391
+ 'private/linear/position/switch-isolated': 40,
392
+ 'private/linear/position/switch-mode': 40,
393
+ 'private/linear/tpsl/switch-mode': 2.5,
394
+ 'private/linear/position/add-margin': 40,
395
+ 'private/linear/position/set-leverage': 40, // 75 per minute = 1.25 per second => cost = 50 / 1.25 = 40
396
+ 'private/linear/position/trading-stop': 40,
397
+ 'private/linear/position/set-risk': 2.5,
398
+ // inverse futures
399
+ 'futures/private/order/create': 30,
400
+ 'futures/private/order/cancel': 30,
401
+ 'futures/private/order/cancelAll': 30,
402
+ 'futures/private/order/replace': 30,
403
+ 'futures/private/stop-order/create': 30,
404
+ 'futures/private/stop-order/cancel': 30,
405
+ 'futures/private/stop-order/cancelAll': 30,
406
+ 'futures/private/stop-order/replace': 30,
407
+ 'futures/private/position/change-position-margin': 40,
408
+ 'futures/private/position/trading-stop': 40,
409
+ 'futures/private/position/leverage/save': 40,
410
+ 'futures/private/position/switch-mode': 40,
411
+ 'futures/private/tpsl/switch-mode': 40,
412
+ 'futures/private/position/switch-isolated': 40,
413
+ 'futures/private/position/risk-limit': 2.5,
414
+ // spot
415
+ 'spot/v1/order': 2.5,
416
+ // account
417
+ 'asset/v1/private/transfer': 150, // 20 per minute = 0.333 per second => cost = 50 / 0.3333 = 150
418
+ 'asset/v1/private/sub-member/transfer': 150,
419
+ // USDC endpoints are testnet only as of 2022 Jan 11 ----------
420
+ // option USDC (testnet only)
421
+ 'option/usdc/openapi/private/v1/place-order': 2.5,
422
+ 'option/usdc/openapi/private/v1/batch-place-order': 2.5,
423
+ 'option/usdc/openapi/private/v1/replace-order': 2.5,
424
+ 'option/usdc/openapi/private/v1/batch-replace-orders': 2.5,
425
+ 'option/usdc/openapi/private/v1/cancel-order': 2.5,
426
+ 'option/usdc/openapi/private/v1/batch-cancel-orders': 2.5,
427
+ 'option/usdc/openapi/private/v1/cancel-all': 2.5,
428
+ 'option/usdc/openapi/private/v1/query-active-orders': 2.5,
429
+ 'option/usdc/openapi/private/v1/query-order-history': 2.5,
430
+ 'option/usdc/openapi/private/v1/execution-list': 2.5,
431
+ 'option/usdc/openapi/private/v1/query-transaction-log': 2.5,
432
+ 'option/usdc/openapi/private/v1/query-wallet-balance': 2.5,
433
+ 'option/usdc/openapi/private/v1/query-asset-info': 2.5,
434
+ 'option/usdc/openapi/private/v1/query-margin-info': 2.5,
435
+ 'option/usdc/openapi/private/v1/query-position': 2.5,
436
+ 'option/usdc/openapi/private/v1/query-delivery-list': 2.5,
437
+ 'option/usdc/openapi/private/v1/query-position-exp-date': 2.5,
438
+ 'option/usdc/openapi/private/v1/mmp-modify': 2.5,
439
+ 'option/usdc/openapi/private/v1/mmp-reset': 2.5,
440
+ // perpetual swap USDC (testnet only)
441
+ 'perpetual/usdc/openapi/private/v1/place-order': 2.5,
442
+ 'perpetual/usdc/openapi/private/v1/replace-order': 2.5,
443
+ 'perpetual/usdc/openapi/private/v1/cancel-order': 2.5,
444
+ 'perpetual/usdc/openapi/private/v1/cancel-all': 2.5,
445
+ 'perpetual/usdc/openapi/private/v1/position/leverage/save': 2.5,
446
+ 'option/usdc/openapi/private/v1/session-settlement': 2.5,
447
+ 'perpetual/usdc/openapi/public/v1/risk-limit/list': 2.5,
448
+ 'perpetual/usdc/openapi/private/v1/position/set-risk-limit': 2.5,
449
+ },
450
+ 'delete': {
451
+ // spot
452
+ 'spot/v1/order': 2.5,
453
+ 'spot/v1/order/fast': 2.5,
454
+ 'spot/order/batch-cancel': 2.5,
455
+ 'spot/order/batch-fast-cancel': 2.5,
456
+ 'spot/order/batch-cancel-by-ids': 2.5,
457
+ },
458
+ // outdated endpoints -------------------------------------
459
+ 'linear': {
460
+ 'get': [
461
+ 'order/list',
462
+ 'order/search',
463
+ 'stop-order/list',
464
+ 'stop-order/search',
465
+ 'position/list',
466
+ 'trade/execution/list',
467
+ 'trade/closed-pnl/list',
468
+ 'funding/predicted-funding',
469
+ 'funding/prev-funding',
470
+ ],
471
+ 'post': [
472
+ 'order/create',
473
+ 'order/cancel',
474
+ 'order/cancel-all',
475
+ 'order/replace',
476
+ 'stop-order/create',
477
+ 'stop-order/cancel',
478
+ 'stop-order/cancel-all',
479
+ 'stop-order/replace',
480
+ 'position/set-auto-add-margin',
481
+ 'position/switch-isolated',
482
+ 'position/switch-mode',
483
+ 'tpsl/switch-mode',
484
+ 'position/add-margin',
485
+ 'position/set-leverage',
486
+ 'position/trading-stop',
487
+ 'position/set-risk',
488
+ ],
489
+ },
490
+ },
491
+ },
492
+ 'httpExceptions': {
493
+ '403': RateLimitExceeded, // Forbidden -- You request too many times
494
+ },
495
+ 'exceptions': {
496
+ 'exact': {
497
+ '-2015': AuthenticationError, // Invalid API-key, IP, or permissions for action.
498
+ '10001': BadRequest, // parameter error
499
+ '10002': InvalidNonce, // request expired, check your timestamp and recv_window
500
+ '10003': AuthenticationError, // Invalid apikey
501
+ '10004': AuthenticationError, // invalid sign
502
+ '10005': PermissionDenied, // permission denied for current apikey
503
+ '10006': RateLimitExceeded, // too many requests
504
+ '10007': AuthenticationError, // api_key not found in your request parameters
505
+ '10010': PermissionDenied, // request ip mismatch
506
+ '10017': BadRequest, // request path not found or request method is invalid
507
+ '10018': RateLimitExceeded, // exceed ip rate limit
508
+ '20001': OrderNotFound, // Order not exists
509
+ '20003': InvalidOrder, // missing parameter side
510
+ '20004': InvalidOrder, // invalid parameter side
511
+ '20005': InvalidOrder, // missing parameter symbol
512
+ '20006': InvalidOrder, // invalid parameter symbol
513
+ '20007': InvalidOrder, // missing parameter order_type
514
+ '20008': InvalidOrder, // invalid parameter order_type
515
+ '20009': InvalidOrder, // missing parameter qty
516
+ '20010': InvalidOrder, // qty must be greater than 0
517
+ '20011': InvalidOrder, // qty must be an integer
518
+ '20012': InvalidOrder, // qty must be greater than zero and less than 1 million
519
+ '20013': InvalidOrder, // missing parameter price
520
+ '20014': InvalidOrder, // price must be greater than 0
521
+ '20015': InvalidOrder, // missing parameter time_in_force
522
+ '20016': InvalidOrder, // invalid value for parameter time_in_force
523
+ '20017': InvalidOrder, // missing parameter order_id
524
+ '20018': InvalidOrder, // invalid date format
525
+ '20019': InvalidOrder, // missing parameter stop_px
526
+ '20020': InvalidOrder, // missing parameter base_price
527
+ '20021': InvalidOrder, // missing parameter stop_order_id
528
+ '20022': BadRequest, // missing parameter leverage
529
+ '20023': BadRequest, // leverage must be a number
530
+ '20031': BadRequest, // leverage must be greater than zero
531
+ '20070': BadRequest, // missing parameter margin
532
+ '20071': BadRequest, // margin must be greater than zero
533
+ '20084': BadRequest, // order_id or order_link_id is required
534
+ '30001': BadRequest, // order_link_id is repeated
535
+ '30003': InvalidOrder, // qty must be more than the minimum allowed
536
+ '30004': InvalidOrder, // qty must be less than the maximum allowed
537
+ '30005': InvalidOrder, // price exceeds maximum allowed
538
+ '30007': InvalidOrder, // price exceeds minimum allowed
539
+ '30008': InvalidOrder, // invalid order_type
540
+ '30009': ExchangeError, // no position found
541
+ '30010': InsufficientFunds, // insufficient wallet balance
542
+ '30011': PermissionDenied, // operation not allowed as position is undergoing liquidation
543
+ '30012': PermissionDenied, // operation not allowed as position is undergoing ADL
544
+ '30013': PermissionDenied, // position is in liq or adl status
545
+ '30014': InvalidOrder, // invalid closing order, qty should not greater than size
546
+ '30015': InvalidOrder, // invalid closing order, side should be opposite
547
+ '30016': ExchangeError, // TS and SL must be cancelled first while closing position
548
+ '30017': InvalidOrder, // estimated fill price cannot be lower than current Buy liq_price
549
+ '30018': InvalidOrder, // estimated fill price cannot be higher than current Sell liq_price
550
+ '30019': InvalidOrder, // cannot attach TP/SL params for non-zero position when placing non-opening position order
551
+ '30020': InvalidOrder, // position already has TP/SL params
552
+ '30021': InvalidOrder, // cannot afford estimated position_margin
553
+ '30022': InvalidOrder, // estimated buy liq_price cannot be higher than current mark_price
554
+ '30023': InvalidOrder, // estimated sell liq_price cannot be lower than current mark_price
555
+ '30024': InvalidOrder, // cannot set TP/SL/TS for zero-position
556
+ '30025': InvalidOrder, // trigger price should bigger than 10% of last price
557
+ '30026': InvalidOrder, // price too high
558
+ '30027': InvalidOrder, // price set for Take profit should be higher than Last Traded Price
559
+ '30028': InvalidOrder, // price set for Stop loss should be between Liquidation price and Last Traded Price
560
+ '30029': InvalidOrder, // price set for Stop loss should be between Last Traded Price and Liquidation price
561
+ '30030': InvalidOrder, // price set for Take profit should be lower than Last Traded Price
562
+ '30031': InsufficientFunds, // insufficient available balance for order cost
563
+ '30032': InvalidOrder, // order has been filled or cancelled
564
+ '30033': RateLimitExceeded, // The number of stop orders exceeds maximum limit allowed
565
+ '30034': OrderNotFound, // no order found
566
+ '30035': RateLimitExceeded, // too fast to cancel
567
+ '30036': ExchangeError, // the expected position value after order execution exceeds the current risk limit
568
+ '30037': InvalidOrder, // order already cancelled
569
+ '30041': ExchangeError, // no position found
570
+ '30042': InsufficientFunds, // insufficient wallet balance
571
+ '30043': InvalidOrder, // operation not allowed as position is undergoing liquidation
572
+ '30044': InvalidOrder, // operation not allowed as position is undergoing AD
573
+ '30045': InvalidOrder, // operation not allowed as position is not normal status
574
+ '30049': InsufficientFunds, // insufficient available balance
575
+ '30050': ExchangeError, // any adjustments made will trigger immediate liquidation
576
+ '30051': ExchangeError, // due to risk limit, cannot adjust leverage
577
+ '30052': ExchangeError, // leverage can not less than 1
578
+ '30054': ExchangeError, // position margin is invalid
579
+ '30057': ExchangeError, // requested quantity of contracts exceeds risk limit
580
+ '30063': ExchangeError, // reduce-only rule not satisfied
581
+ '30067': InsufficientFunds, // insufficient available balance
582
+ '30068': ExchangeError, // exit value must be positive
583
+ '30074': InvalidOrder, // can't create the stop order, because you expect the order will be triggered when the LastPrice(or IndexPrice、 MarkPrice, determined by trigger_by) is raising to stop_px, but the LastPrice(or IndexPrice、 MarkPrice) is already equal to or greater than stop_px, please adjust base_price or stop_px
584
+ '30075': InvalidOrder, // can't create the stop order, because you expect the order will be triggered when the LastPrice(or IndexPrice、 MarkPrice, determined by trigger_by) is falling to stop_px, but the LastPrice(or IndexPrice、 MarkPrice) is already equal to or less than stop_px, please adjust base_price or stop_px
585
+ '30078': ExchangeError, // {"ret_code":30078,"ret_msg":"","ext_code":"","ext_info":"","result":null,"time_now":"1644853040.916000","rate_limit_status":73,"rate_limit_reset_ms":1644853040912,"rate_limit":75}
586
+ // '30084': BadRequest, // Isolated not modified, see handleErrors below
587
+ '33004': AuthenticationError, // apikey already expired
588
+ '34026': ExchangeError, // the limit is no change
589
+ '130021': InsufficientFunds, // {"ret_code":130021,"ret_msg":"orderfix price failed for CannotAffordOrderCost.","ext_code":"","ext_info":"","result":null,"time_now":"1644588250.204878","rate_limit_status":98,"rate_limit_reset_ms":1644588250200,"rate_limit":100}
590
+ },
591
+ 'broad': {
592
+ 'unknown orderInfo': OrderNotFound, // {"ret_code":-1,"ret_msg":"unknown orderInfo","ext_code":"","ext_info":"","result":null,"time_now":"1584030414.005545","rate_limit_status":99,"rate_limit_reset_ms":1584030414003,"rate_limit":100}
593
+ 'invalid api_key': AuthenticationError, // {"ret_code":10003,"ret_msg":"invalid api_key","ext_code":"","ext_info":"","result":null,"time_now":"1599547085.415797"}
594
+ },
595
+ },
596
+ 'precisionMode': TICK_SIZE,
597
+ 'options': {
598
+ 'marketTypes': {
599
+ 'BTC/USDT': 'linear',
600
+ 'ETH/USDT': 'linear',
601
+ 'BNB/USDT': 'linear',
602
+ 'ADA/USDT': 'linear',
603
+ 'DOGE/USDT': 'linear',
604
+ 'XRP/USDT': 'linear',
605
+ 'DOT/USDT': 'linear',
606
+ 'UNI/USDT': 'linear',
607
+ 'BCH/USDT': 'linear',
608
+ 'LTC/USDT': 'linear',
609
+ 'SOL/USDT': 'linear',
610
+ 'LINK/USDT': 'linear',
611
+ 'MATIC/USDT': 'linear',
612
+ 'ETC/USDT': 'linear',
613
+ 'FIL/USDT': 'linear',
614
+ 'EOS/USDT': 'linear',
615
+ 'AAVE/USDT': 'linear',
616
+ 'XTZ/USDT': 'linear',
617
+ 'SUSHI/USDT': 'linear',
618
+ 'XEM/USDT': 'linear',
619
+ 'BTC/USD': 'inverse',
620
+ 'ETH/USD': 'inverse',
621
+ 'EOS/USD': 'inverse',
622
+ 'XRP/USD': 'inverse',
623
+ },
624
+ 'defaultType': 'linear', // linear, inverse, futures
625
+ //
626
+ // ^
627
+ // |
628
+ // | this will be replaced with the following soon |
629
+ // |
630
+ // v
631
+ //
632
+ // 'defaultType': 'swap', // swap, spot, future, option
633
+ 'code': 'BTC',
634
+ 'cancelAllOrders': {
635
+ // 'method': 'v2PrivatePostOrderCancelAll', // v2PrivatePostStopOrderCancelAll
636
+ },
637
+ 'recvWindow': 5 * 1000, // 5 sec default
638
+ 'timeDifference': 0, // the difference between system clock and exchange server clock
639
+ 'adjustForTimeDifference': false, // controls the adjustment logic upon instantiation
640
+ },
641
+ 'fees': {
642
+ 'trading': {
643
+ 'tierBased': false,
644
+ 'percentage': true,
645
+ 'taker': 0.00075,
646
+ 'maker': -0.00025,
647
+ },
648
+ 'funding': {
649
+ 'tierBased': false,
650
+ 'percentage': false,
651
+ 'withdraw': {},
652
+ 'deposit': {},
653
+ },
654
+ },
655
+ });
656
+ }
657
+
658
+ nonce () {
659
+ return this.milliseconds () - this.options['timeDifference'];
660
+ }
661
+
662
+ async fetchTime (params = {}) {
663
+ const response = await this.publicGetV2PublicTime (params);
664
+ //
665
+ // {
666
+ // ret_code: 0,
667
+ // ret_msg: 'OK',
668
+ // ext_code: '',
669
+ // ext_info: '',
670
+ // result: {},
671
+ // time_now: '1583933682.448826'
672
+ // }
673
+ //
674
+ return this.safeTimestamp (response, 'time_now');
675
+ }
676
+
677
+ async fetchMarkets (params = {}) {
678
+ if (this.options['adjustForTimeDifference']) {
679
+ await this.loadTimeDifference ();
680
+ }
681
+ const response = await this.publicGetV2PublicSymbols (params);
682
+ //
683
+ // linear swaps and inverse swaps and futures
684
+ // const swapsResponse = await this.publicGetV2PublicSymbols (params);
685
+ //
686
+ // {
687
+ // "ret_code":0,
688
+ // "ret_msg":"OK",
689
+ // "ext_code":"",
690
+ // "ext_info":"",
691
+ // "result":[
692
+ // // inverse swap
693
+ // {
694
+ // "name":"BTCUSD",
695
+ // "alias":"BTCUSD",
696
+ // "status":"Trading",
697
+ // "base_currency":"BTC",
698
+ // "quote_currency":"USD",
699
+ // "price_scale":2,
700
+ // "taker_fee":"0.00075",
701
+ // "maker_fee":"-0.00025",
702
+ // "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"},
703
+ // "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"},
704
+ // "lot_size_filter":{"max_trading_qty":1000000,"min_trading_qty":1,"qty_step":1}
705
+ // },
706
+ // // linear swap
707
+ // {
708
+ // "name":"BTCUSDT",
709
+ // "alias":"BTCUSDT",
710
+ // "status":"Trading",
711
+ // "base_currency":"BTC",
712
+ // "quote_currency":"USDT",
713
+ // "price_scale":2,
714
+ // "taker_fee":"0.00075",
715
+ // "maker_fee":"-0.00025",
716
+ // "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"},
717
+ // "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"},
718
+ // "lot_size_filter":{"max_trading_qty":100,"min_trading_qty":0.001, "qty_step":0.001}
719
+ // },
720
+ // // inverse futures
721
+ // {
722
+ // "name":"BTCUSDM22",
723
+ // "alias":"BTCUSD0624",
724
+ // "status":"Trading",
725
+ // "base_currency":"BTC",
726
+ // "quote_currency":"USD",
727
+ // "price_scale":2,
728
+ // "taker_fee":"0.00075",
729
+ // "maker_fee":"-0.00025",
730
+ // "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"},
731
+ // "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"},
732
+ // "lot_size_filter":{"max_trading_qty":1000000,"min_trading_qty":1,"qty_step":1}
733
+ // },
734
+ // {
735
+ // "name":"BTCUSDH22",
736
+ // "alias":"BTCUSD0325",
737
+ // "status":"Trading",
738
+ // "base_currency":"BTC",
739
+ // "quote_currency":"USD",
740
+ // "price_scale":2,
741
+ // "taker_fee":"0.00075",
742
+ // "maker_fee":"-0.00025",
743
+ // "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"}
744
+ // "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"},
745
+ // "lot_size_filter":{"max_trading_qty":1000000,"min_trading_qty":1,"qty_step":1}
746
+ // }
747
+ // ],
748
+ // "time_now":"1642369942.072113"
749
+ // }
750
+ //
751
+ // spot markets
752
+ // const spotResponse = await this.publicGetSpotV1Symbols (params);
753
+ //
754
+ // {
755
+ // "ret_code":0,
756
+ // "ret_msg":"",
757
+ // "ext_code":null,
758
+ // "ext_info":null,
759
+ // "result":[
760
+ // {
761
+ // "name":"BTCUSDT",
762
+ // "alias":"BTCUSDT",
763
+ // "baseCurrency":"BTC",
764
+ // "quoteCurrency":"USDT",
765
+ // "basePrecision":"0.000001",
766
+ // "quotePrecision":"0.00000001",
767
+ // "minTradeQuantity":"0.000158",
768
+ // "minTradeAmount":"10",
769
+ // "maxTradeQuantity":"4",
770
+ // "maxTradeAmount":"100000",
771
+ // "minPricePrecision":"0.01",
772
+ // "category":1,
773
+ // "showStatus":true
774
+ // },
775
+ // ]
776
+ // }
777
+ //
778
+ // USDC linear options response
779
+ // const linearOptionsResponse = await this.publicGetOptionUsdcOpenapiPublicV1Symbols (params);
780
+ //
781
+ // {
782
+ // "retCode":0,
783
+ // "retMsg":"success",
784
+ // "result":{
785
+ // "resultTotalSize":424,
786
+ // "cursor":"0%2C500",
787
+ // "dataList":[
788
+ // {
789
+ // "symbol":"BTC-24JUN22-300000-C",
790
+ // "status":"ONLINE",
791
+ // "baseCoin":"BTC",
792
+ // "quoteCoin":"USD",
793
+ // "settleCoin":"USDC",
794
+ // "takerFee":"0.0003",
795
+ // "makerFee":"0.0003",
796
+ // "minLeverage":"",
797
+ // "maxLeverage":"",
798
+ // "leverageStep":"",
799
+ // "minOrderPrice":"0.5",
800
+ // "maxOrderPrice":"10000000",
801
+ // "minOrderSize":"0.01",
802
+ // "maxOrderSize":"200",
803
+ // "tickSize":"0.5",
804
+ // "minOrderSizeIncrement":"0.01",
805
+ // "basicDeliveryFeeRate":"0.00015",
806
+ // "deliveryTime":"1656057600000"
807
+ // },
808
+ // {
809
+ // "symbol":"BTC-24JUN22-300000-P",
810
+ // "status":"ONLINE",
811
+ // "baseCoin":"BTC",
812
+ // "quoteCoin":"USD",
813
+ // "settleCoin":"USDC",
814
+ // "takerFee":"0.0003",
815
+ // "makerFee":"0.0003",
816
+ // "minLeverage":"",
817
+ // "maxLeverage":"",
818
+ // "leverageStep":"",
819
+ // "minOrderPrice":"0.5",
820
+ // "maxOrderPrice":"10000000",
821
+ // "minOrderSize":"0.01",
822
+ // "maxOrderSize":"200",
823
+ // "tickSize":"0.5",
824
+ // "minOrderSizeIncrement":"0.01",
825
+ // "basicDeliveryFeeRate":"0.00015",
826
+ // "deliveryTime":"1656057600000"
827
+ // },
828
+ // ]
829
+ // }
830
+ // }
831
+ //
832
+ // USDC linear perpetual swaps
833
+ // const usdcLinearPerpetualSwaps = await this.publicGetPerpetualUsdcOpenapiPublicV1Symbols (params);
834
+ //
835
+ // {
836
+ // "retCode":0,
837
+ // "retMsg":"",
838
+ // "result":[
839
+ // {
840
+ // "symbol":"BTCPERP",
841
+ // "status":"ONLINE",
842
+ // "baseCoin":"BTC",
843
+ // "quoteCoin":"USD",
844
+ // "takerFeeRate":"0.00075",
845
+ // "makerFeeRate":"-0.00025",
846
+ // "minLeverage":"1",
847
+ // "maxLeverage":"100",
848
+ // "leverageStep":"0.01",
849
+ // "minPrice":"0.50",
850
+ // "maxPrice":"999999.00",
851
+ // "tickSize":"0.50",
852
+ // "maxTradingQty":"5.000",
853
+ // "minTradingQty":"0.001",
854
+ // "qtyStep":"0.001",
855
+ // "deliveryFeeRate":"",
856
+ // "deliveryTime":"0"
857
+ // }
858
+ // ]
859
+ // }
860
+ //
861
+ const markets = this.safeValue (response, 'result', []);
862
+ const options = this.safeValue (this.options, 'fetchMarkets', {});
863
+ const linearQuoteCurrencies = this.safeValue (options, 'linear', { 'USDT': true });
864
+ const result = [];
865
+ for (let i = 0; i < markets.length; i++) {
866
+ const market = markets[i];
867
+ const id = this.safeString2 (market, 'name', 'symbol');
868
+ const baseId = this.safeString2 (market, 'base_currency', 'baseCoin');
869
+ const quoteId = this.safeString2 (market, 'quote_currency', 'quoteCoin');
870
+ let settleId = this.safeString (market, 'settleCoin');
871
+ const base = this.safeCurrencyCode (baseId);
872
+ const quote = this.safeCurrencyCode (quoteId);
873
+ let settle = this.safeCurrencyCode (settleId);
874
+ const linear = (quote in linearQuoteCurrencies);
875
+ let symbol = base + '/' + quote;
876
+ const baseQuote = base + quote;
877
+ let type = 'swap';
878
+ if (baseQuote !== id) {
879
+ type = 'future';
880
+ }
881
+ const lotSizeFilter = this.safeValue (market, 'lot_size_filter', {});
882
+ const priceFilter = this.safeValue (market, 'price_filter', {});
883
+ const leverage = this.safeValue (market, 'leverage_filter', {});
884
+ const status = this.safeString (market, 'status');
885
+ let active = undefined;
886
+ if (status !== undefined) {
887
+ active = (status === 'Trading');
888
+ }
889
+ const swap = (type === 'swap');
890
+ const future = (type === 'future');
891
+ const option = (type === 'option');
892
+ const contract = swap || future || option;
893
+ let expiry = undefined;
894
+ let expiryDatetime = undefined;
895
+ let strike = undefined;
896
+ let optionType = undefined;
897
+ if (contract) {
898
+ if (settle === undefined) {
899
+ settleId = linear ? quoteId : baseId;
900
+ settle = this.safeCurrencyCode (settleId);
901
+ }
902
+ symbol = symbol + ':' + settle;
903
+ if (future) {
904
+ const alias = this.safeString (market, 'alias');
905
+ const shortDate = alias.slice (-4);
906
+ const date = this.iso8601 (this.milliseconds ());
907
+ const splitDate = date.split ('-');
908
+ const year = splitDate[0];
909
+ const expiryMonth = shortDate.slice (0, 2);
910
+ const expiryDay = shortDate.slice (2, 4);
911
+ expiryDatetime = year + '-' + expiryMonth + '-' + expiryDay + 'T00:00:00Z';
912
+ expiry = this.parse8601 (expiryDatetime);
913
+ symbol = symbol + '-' + this.yymmdd (expiry);
914
+ } else if (option) {
915
+ expiry = this.safeInteger (market, 'deliveryTime');
916
+ expiryDatetime = this.iso8601 (expiry);
917
+ const splitId = this.split (id, '-');
918
+ strike = this.safeString (splitId, 2);
919
+ const optionLetter = this.safeString (splitId, 3);
920
+ symbol = symbol + '-' + this.yymmdd (expiry) + ':' + strike + ':' + optionLetter;
921
+ if (optionLetter === 'P') {
922
+ optionType = 'put';
923
+ } else if (optionLetter === 'C') {
924
+ optionType = 'call';
925
+ }
926
+ }
927
+ }
928
+ result.push ({
929
+ 'id': id,
930
+ 'symbol': symbol,
931
+ 'base': base,
932
+ 'quote': quote,
933
+ 'settle': settle,
934
+ 'baseId': baseId,
935
+ 'quoteId': quoteId,
936
+ 'settleId': settleId,
937
+ 'type': type,
938
+ 'spot': (type === 'spot'),
939
+ 'margin': undefined, // todo
940
+ 'swap': swap,
941
+ 'future': future,
942
+ 'futures': future, // Deprecated, use future
943
+ 'option': option,
944
+ 'active': active,
945
+ 'contract': contract,
946
+ 'linear': linear,
947
+ 'inverse': !linear,
948
+ 'taker': this.safeNumber (market, 'taker_fee'),
949
+ 'maker': this.safeNumber (market, 'maker_fee'),
950
+ 'contractSize': undefined, // todo
951
+ 'expiry': expiry,
952
+ 'expiryDatetime': expiryDatetime,
953
+ 'strike': strike,
954
+ 'optionType': optionType,
955
+ 'precision': {
956
+ 'amount': this.safeNumber (lotSizeFilter, 'qty_step'),
957
+ 'price': this.safeNumber (priceFilter, 'tick_size'),
958
+ },
959
+ 'limits': {
960
+ 'leverage': {
961
+ 'min': this.parseNumber ('1'),
962
+ 'max': this.safeNumber (leverage, 'max_leverage', 1),
963
+ },
964
+ 'amount': {
965
+ 'min': this.safeNumber (lotSizeFilter, 'min_trading_qty'),
966
+ 'max': this.safeNumber (lotSizeFilter, 'max_trading_qty'),
967
+ },
968
+ 'price': {
969
+ 'min': this.safeNumber (priceFilter, 'min_price'),
970
+ 'max': this.safeNumber (priceFilter, 'max_price'),
971
+ },
972
+ 'cost': {
973
+ 'min': undefined,
974
+ 'max': undefined,
975
+ },
976
+ },
977
+ 'info': market,
978
+ });
979
+ }
980
+ return result;
981
+ }
982
+
983
+ parseTicker (ticker, market = undefined) {
984
+ //
985
+ // fetchTicker
986
+ //
987
+ // {
988
+ // symbol: 'BTCUSD',
989
+ // bid_price: '7680',
990
+ // ask_price: '7680.5',
991
+ // last_price: '7680.00',
992
+ // last_tick_direction: 'MinusTick',
993
+ // prev_price_24h: '7870.50',
994
+ // price_24h_pcnt: '-0.024204',
995
+ // high_price_24h: '8035.00',
996
+ // low_price_24h: '7671.00',
997
+ // prev_price_1h: '7780.00',
998
+ // price_1h_pcnt: '-0.012853',
999
+ // mark_price: '7683.27',
1000
+ // index_price: '7682.74',
1001
+ // open_interest: 188829147,
1002
+ // open_value: '23670.06',
1003
+ // total_turnover: '25744224.90',
1004
+ // turnover_24h: '102997.83',
1005
+ // total_volume: 225448878806,
1006
+ // volume_24h: 809919408,
1007
+ // funding_rate: '0.0001',
1008
+ // predicted_funding_rate: '0.0001',
1009
+ // next_funding_time: '2020-03-12T00:00:00Z',
1010
+ // countdown_hour: 7
1011
+ // }
1012
+ //
1013
+ const timestamp = undefined;
1014
+ const marketId = this.safeString (ticker, 'symbol');
1015
+ const symbol = this.safeSymbol (marketId, market);
1016
+ const last = this.safeString (ticker, 'last_price');
1017
+ const open = this.safeString (ticker, 'prev_price_24h');
1018
+ let percentage = this.safeString (ticker, 'price_24h_pcnt');
1019
+ percentage = Precise.stringMul (percentage, '100');
1020
+ const baseVolume = this.safeString (ticker, 'turnover_24h');
1021
+ const quoteVolume = this.safeString (ticker, 'volume_24h');
1022
+ return this.safeTicker ({
1023
+ 'symbol': symbol,
1024
+ 'timestamp': timestamp,
1025
+ 'datetime': this.iso8601 (timestamp),
1026
+ 'high': this.safeString (ticker, 'high_price_24h'),
1027
+ 'low': this.safeString (ticker, 'low_price_24h'),
1028
+ 'bid': this.safeString (ticker, 'bid_price'),
1029
+ 'bidVolume': undefined,
1030
+ 'ask': this.safeString (ticker, 'ask_price'),
1031
+ 'askVolume': undefined,
1032
+ 'vwap': undefined,
1033
+ 'open': open,
1034
+ 'close': last,
1035
+ 'last': last,
1036
+ 'previousClose': undefined,
1037
+ 'change': undefined,
1038
+ 'percentage': percentage,
1039
+ 'average': undefined,
1040
+ 'baseVolume': baseVolume,
1041
+ 'quoteVolume': quoteVolume,
1042
+ 'info': ticker,
1043
+ }, market, false);
1044
+ }
1045
+
1046
+ async fetchTicker (symbol, params = {}) {
1047
+ await this.loadMarkets ();
1048
+ const market = this.market (symbol);
1049
+ const request = {
1050
+ 'symbol': market['id'],
1051
+ };
1052
+ const response = await this.publicGetV2PublicTickers (this.extend (request, params));
1053
+ //
1054
+ // {
1055
+ // ret_code: 0,
1056
+ // ret_msg: 'OK',
1057
+ // ext_code: '',
1058
+ // ext_info: '',
1059
+ // result: [
1060
+ // {
1061
+ // symbol: 'BTCUSD',
1062
+ // bid_price: '7680',
1063
+ // ask_price: '7680.5',
1064
+ // last_price: '7680.00',
1065
+ // last_tick_direction: 'MinusTick',
1066
+ // prev_price_24h: '7870.50',
1067
+ // price_24h_pcnt: '-0.024204',
1068
+ // high_price_24h: '8035.00',
1069
+ // low_price_24h: '7671.00',
1070
+ // prev_price_1h: '7780.00',
1071
+ // price_1h_pcnt: '-0.012853',
1072
+ // mark_price: '7683.27',
1073
+ // index_price: '7682.74',
1074
+ // open_interest: 188829147,
1075
+ // open_value: '23670.06',
1076
+ // total_turnover: '25744224.90',
1077
+ // turnover_24h: '102997.83',
1078
+ // total_volume: 225448878806,
1079
+ // volume_24h: 809919408,
1080
+ // funding_rate: '0.0001',
1081
+ // predicted_funding_rate: '0.0001',
1082
+ // next_funding_time: '2020-03-12T00:00:00Z',
1083
+ // countdown_hour: 7
1084
+ // }
1085
+ // ],
1086
+ // time_now: '1583948195.818255'
1087
+ // }
1088
+ //
1089
+ const result = this.safeValue (response, 'result', []);
1090
+ const first = this.safeValue (result, 0);
1091
+ const timestamp = this.safeTimestamp (response, 'time_now');
1092
+ const ticker = this.parseTicker (first, market);
1093
+ ticker['timestamp'] = timestamp;
1094
+ ticker['datetime'] = this.iso8601 (timestamp);
1095
+ return ticker;
1096
+ }
1097
+
1098
+ async fetchTickers (symbols = undefined, params = {}) {
1099
+ await this.loadMarkets ();
1100
+ const response = await this.publicGetV2PublicTickers (params);
1101
+ //
1102
+ // {
1103
+ // ret_code: 0,
1104
+ // ret_msg: 'OK',
1105
+ // ext_code: '',
1106
+ // ext_info: '',
1107
+ // result: [
1108
+ // {
1109
+ // symbol: 'BTCUSD',
1110
+ // bid_price: '7680',
1111
+ // ask_price: '7680.5',
1112
+ // last_price: '7680.00',
1113
+ // last_tick_direction: 'MinusTick',
1114
+ // prev_price_24h: '7870.50',
1115
+ // price_24h_pcnt: '-0.024204',
1116
+ // high_price_24h: '8035.00',
1117
+ // low_price_24h: '7671.00',
1118
+ // prev_price_1h: '7780.00',
1119
+ // price_1h_pcnt: '-0.012853',
1120
+ // mark_price: '7683.27',
1121
+ // index_price: '7682.74',
1122
+ // open_interest: 188829147,
1123
+ // open_value: '23670.06',
1124
+ // total_turnover: '25744224.90',
1125
+ // turnover_24h: '102997.83',
1126
+ // total_volume: 225448878806,
1127
+ // volume_24h: 809919408,
1128
+ // funding_rate: '0.0001',
1129
+ // predicted_funding_rate: '0.0001',
1130
+ // next_funding_time: '2020-03-12T00:00:00Z',
1131
+ // countdown_hour: 7
1132
+ // }
1133
+ // ],
1134
+ // time_now: '1583948195.818255'
1135
+ // }
1136
+ //
1137
+ const result = this.safeValue (response, 'result', []);
1138
+ const tickers = {};
1139
+ for (let i = 0; i < result.length; i++) {
1140
+ const ticker = this.parseTicker (result[i]);
1141
+ const symbol = ticker['symbol'];
1142
+ tickers[symbol] = ticker;
1143
+ }
1144
+ return this.filterByArray (tickers, 'symbol', symbols);
1145
+ }
1146
+
1147
+ parseOHLCV (ohlcv, market = undefined) {
1148
+ //
1149
+ // inverse perpetual BTC/USD
1150
+ //
1151
+ // {
1152
+ // symbol: 'BTCUSD',
1153
+ // interval: '1',
1154
+ // open_time: 1583952540,
1155
+ // open: '7760.5',
1156
+ // high: '7764',
1157
+ // low: '7757',
1158
+ // close: '7763.5',
1159
+ // volume: '1259766',
1160
+ // turnover: '162.32773718999994'
1161
+ // }
1162
+ //
1163
+ // linear perpetual BTC/USDT
1164
+ //
1165
+ // {
1166
+ // "id":143536,
1167
+ // "symbol":"BTCUSDT",
1168
+ // "period":"15",
1169
+ // "start_at":1587883500,
1170
+ // "volume":1.035,
1171
+ // "open":7540.5,
1172
+ // "high":7541,
1173
+ // "low":7540.5,
1174
+ // "close":7541
1175
+ // }
1176
+ //
1177
+ return [
1178
+ this.safeTimestamp2 (ohlcv, 'open_time', 'start_at'),
1179
+ this.safeNumber (ohlcv, 'open'),
1180
+ this.safeNumber (ohlcv, 'high'),
1181
+ this.safeNumber (ohlcv, 'low'),
1182
+ this.safeNumber (ohlcv, 'close'),
1183
+ this.safeNumber2 (ohlcv, 'volume', 'turnover'),
1184
+ ];
1185
+ }
1186
+
1187
+ async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1188
+ await this.loadMarkets ();
1189
+ const market = this.market (symbol);
1190
+ const price = this.safeString (params, 'price');
1191
+ params = this.omit (params, 'price');
1192
+ const request = {
1193
+ 'symbol': market['id'],
1194
+ 'interval': this.timeframes[timeframe],
1195
+ };
1196
+ const duration = this.parseTimeframe (timeframe);
1197
+ const now = this.seconds ();
1198
+ if (since === undefined) {
1199
+ if (limit === undefined) {
1200
+ throw new ArgumentsRequired (this.id + ' fetchOHLCV() requires a since argument or a limit argument');
1201
+ } else {
1202
+ request['from'] = now - limit * duration;
1203
+ }
1204
+ } else {
1205
+ request['from'] = parseInt (since / 1000);
1206
+ }
1207
+ if (limit !== undefined) {
1208
+ request['limit'] = limit; // max 200, default 200
1209
+ }
1210
+ let method = 'publicGetV2PublicKlineList';
1211
+ if (price === 'mark') {
1212
+ method = 'publicGetV2PublicMarkPriceKline';
1213
+ } else if (price === 'index') {
1214
+ method = 'publicGetV2PublicIndexPriceKline';
1215
+ } else if (price === 'premiumIndex') {
1216
+ method = 'publicGetV2PublicPremiumIndexKline';
1217
+ } else if (market['linear']) {
1218
+ method = 'publicGetPublicLinearKline';
1219
+ }
1220
+ const response = await this[method] (this.extend (request, params));
1221
+ //
1222
+ // inverse perpetual BTC/USD
1223
+ //
1224
+ // {
1225
+ // ret_code: 0,
1226
+ // ret_msg: 'OK',
1227
+ // ext_code: '',
1228
+ // ext_info: '',
1229
+ // result: [
1230
+ // {
1231
+ // symbol: 'BTCUSD',
1232
+ // interval: '1',
1233
+ // open_time: 1583952540,
1234
+ // open: '7760.5',
1235
+ // high: '7764',
1236
+ // low: '7757',
1237
+ // close: '7763.5',
1238
+ // volume: '1259766',
1239
+ // turnover: '162.32773718999994'
1240
+ // },
1241
+ // ],
1242
+ // time_now: '1583953082.397330'
1243
+ // }
1244
+ //
1245
+ // linear perpetual BTC/USDT
1246
+ //
1247
+ // {
1248
+ // "ret_code":0,
1249
+ // "ret_msg":"OK",
1250
+ // "ext_code":"",
1251
+ // "ext_info":"",
1252
+ // "result":[
1253
+ // {
1254
+ // "id":143536,
1255
+ // "symbol":"BTCUSDT",
1256
+ // "period":"15",
1257
+ // "start_at":1587883500,
1258
+ // "volume":1.035,
1259
+ // "open":7540.5,
1260
+ // "high":7541,
1261
+ // "low":7540.5,
1262
+ // "close":7541
1263
+ // }
1264
+ // ],
1265
+ // "time_now":"1587884120.168077"
1266
+ // }
1267
+ //
1268
+ const result = this.safeValue (response, 'result', {});
1269
+ return this.parseOHLCVs (result, market, timeframe, since, limit);
1270
+ }
1271
+
1272
+ async fetchFundingRate (symbol, params = {}) {
1273
+ await this.loadMarkets ();
1274
+ const market = this.market (symbol);
1275
+ const request = {
1276
+ 'symbol': market['id'],
1277
+ };
1278
+ const method = market['linear'] ? 'publicLinearGetFundingPrevFundingRate' : 'v2PublicGetFundingPrevFundingRate';
1279
+ // TODO const method = market['linear'] ? 'publicGetPublicLinearFundingPrevFundingRate' : 'publicGetV2PublicFundingRate ???? throws ExchangeError';
1280
+ const response = await this[method] (this.extend (request, params));
1281
+ //
1282
+ // {
1283
+ // "ret_code":0,
1284
+ // "ret_msg":"OK",
1285
+ // "ext_code":"",
1286
+ // "ext_info":"",
1287
+ // "result":{
1288
+ // "symbol":"BTCUSDT",
1289
+ // "funding_rate":0.00006418,
1290
+ // "funding_rate_timestamp":"2022-03-11T16:00:00.000Z"
1291
+ // },
1292
+ // "time_now":"1647040818.724895"
1293
+ // }
1294
+ //
1295
+ // {
1296
+ // "ret_code":0,
1297
+ // "ret_msg":"OK",
1298
+ // "ext_code":"",
1299
+ // "ext_info":"",
1300
+ // "result":{
1301
+ // "symbol":"BTCUSD",
1302
+ // "funding_rate":"0.00009536",
1303
+ // "funding_rate_timestamp":1647014400
1304
+ // },
1305
+ // "time_now":"1647040852.515724"
1306
+ // }
1307
+ //
1308
+ const result = this.safeValue (response, 'result');
1309
+ const fundingRate = this.safeNumber (result, 'funding_rate');
1310
+ let fundingTimestamp = this.parse8601 (this.safeString (result, 'funding_rate_timestamp'));
1311
+ fundingTimestamp = this.safeTimestamp (result, 'funding_rate_timestamp', fundingTimestamp);
1312
+ const currentTime = this.milliseconds ();
1313
+ return {
1314
+ 'info': result,
1315
+ 'symbol': symbol,
1316
+ 'markPrice': undefined,
1317
+ 'indexPrice': undefined,
1318
+ 'interestRate': undefined,
1319
+ 'estimatedSettlePrice': undefined,
1320
+ 'timestamp': currentTime,
1321
+ 'datetime': this.iso8601 (currentTime),
1322
+ 'fundingRate': fundingRate,
1323
+ 'fundingTimestamp': fundingTimestamp,
1324
+ 'fundingDatetime': this.iso8601 (fundingTimestamp),
1325
+ 'nextFundingRate': undefined,
1326
+ 'nextFundingTimestamp': undefined,
1327
+ 'nextFundingDatetime': undefined,
1328
+ 'previousFundingRate': undefined,
1329
+ 'previousFundingTimestamp': undefined,
1330
+ 'previousFundingDatetime': undefined,
1331
+ };
1332
+ }
1333
+
1334
+ async fetchIndexOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1335
+ if (since === undefined && limit === undefined) {
1336
+ throw new ArgumentsRequired (this.id + ' fetchIndexOHLCV() requires a since argument or a limit argument');
1337
+ }
1338
+ const request = {
1339
+ 'price': 'index',
1340
+ };
1341
+ return await this.fetchOHLCV (symbol, timeframe, since, limit, this.extend (request, params));
1342
+ }
1343
+
1344
+ async fetchMarkOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1345
+ if (since === undefined && limit === undefined) {
1346
+ throw new ArgumentsRequired (this.id + ' fetchMarkOHLCV() requires a since argument or a limit argument');
1347
+ }
1348
+ const request = {
1349
+ 'price': 'mark',
1350
+ };
1351
+ return await this.fetchOHLCV (symbol, timeframe, since, limit, this.extend (request, params));
1352
+ }
1353
+
1354
+ async fetchPremiumIndexOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1355
+ if (since === undefined && limit === undefined) {
1356
+ throw new ArgumentsRequired (this.id + ' fetchPremiumIndexOHLCV() requires a since argument or a limit argument');
1357
+ }
1358
+ const request = {
1359
+ 'price': 'premiumIndex',
1360
+ };
1361
+ return await this.fetchOHLCV (symbol, timeframe, since, limit, this.extend (request, params));
1362
+ }
1363
+
1364
+ parseTrade (trade, market = undefined) {
1365
+ //
1366
+ // fetchTrades (public)
1367
+ //
1368
+ // {
1369
+ // "id": "44275042152",
1370
+ // "symbol": "AAVEUSDT",
1371
+ // "price": "256.35",
1372
+ // "qty": "0.1",
1373
+ // "side": "Buy",
1374
+ // "time": "2021-11-30T12:46:14.000Z",
1375
+ // "trade_time_ms": "1638276374312"
1376
+ // }
1377
+ //
1378
+ // fetchMyTrades, fetchOrderTrades (private)
1379
+ //
1380
+ // {
1381
+ // "order_id": "b020b4bc-6fe2-45b5-adbc-dd07794f9746",
1382
+ // "order_link_id": "",
1383
+ // "side": "Buy",
1384
+ // "symbol": "AAVEUSDT",
1385
+ // "exec_id": "09abe8f0-aea6-514e-942b-7da8cb935120",
1386
+ // "price": "269.3",
1387
+ // "order_price": "269.3",
1388
+ // "order_qty": "0.1",
1389
+ // "order_type": "Market",
1390
+ // "fee_rate": "0.00075",
1391
+ // "exec_price": "256.35",
1392
+ // "exec_type": "Trade",
1393
+ // "exec_qty": "0.1",
1394
+ // "exec_fee": "0.01922625",
1395
+ // "exec_value": "25.635",
1396
+ // "leaves_qty": "0",
1397
+ // "closed_size": "0",
1398
+ // "last_liquidity_ind": "RemovedLiquidity",
1399
+ // "trade_time": "1638276374",
1400
+ // "trade_time_ms": "1638276374312"
1401
+ // }
1402
+ //
1403
+ const id = this.safeString2 (trade, 'id', 'exec_id');
1404
+ const marketId = this.safeString (trade, 'symbol');
1405
+ market = this.safeMarket (marketId, market);
1406
+ const symbol = market['symbol'];
1407
+ const amountString = this.safeString2 (trade, 'qty', 'exec_qty');
1408
+ const priceString = this.safeString2 (trade, 'exec_price', 'price');
1409
+ const costString = this.safeString (trade, 'exec_value');
1410
+ let timestamp = this.parse8601 (this.safeString (trade, 'time'));
1411
+ if (timestamp === undefined) {
1412
+ timestamp = this.safeInteger (trade, 'trade_time_ms');
1413
+ }
1414
+ const side = this.safeStringLower (trade, 'side');
1415
+ const lastLiquidityInd = this.safeString (trade, 'last_liquidity_ind');
1416
+ const takerOrMaker = (lastLiquidityInd === 'AddedLiquidity') ? 'maker' : 'taker';
1417
+ const feeCostString = this.safeString (trade, 'exec_fee');
1418
+ let fee = undefined;
1419
+ if (feeCostString !== undefined) {
1420
+ const feeCurrencyCode = market['inverse'] ? market['base'] : market['quote'];
1421
+ fee = {
1422
+ 'cost': feeCostString,
1423
+ 'currency': feeCurrencyCode,
1424
+ 'rate': this.safeString (trade, 'fee_rate'),
1425
+ };
1426
+ }
1427
+ return this.safeTrade ({
1428
+ 'id': id,
1429
+ 'info': trade,
1430
+ 'timestamp': timestamp,
1431
+ 'datetime': this.iso8601 (timestamp),
1432
+ 'symbol': symbol,
1433
+ 'order': this.safeString (trade, 'order_id'),
1434
+ 'type': this.safeStringLower (trade, 'order_type'),
1435
+ 'side': side,
1436
+ 'takerOrMaker': takerOrMaker,
1437
+ 'price': priceString,
1438
+ 'amount': amountString,
1439
+ 'cost': costString,
1440
+ 'fee': fee,
1441
+ }, market);
1442
+ }
1443
+
1444
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
1445
+ await this.loadMarkets ();
1446
+ const market = this.market (symbol);
1447
+ const request = {
1448
+ 'symbol': market['id'],
1449
+ // 'from': 123, // from id
1450
+ };
1451
+ if (limit !== undefined) {
1452
+ request['count'] = limit; // default 500, max 1000
1453
+ }
1454
+ const method = market['linear'] ? 'publicGetPublicLinearRecentTradingRecords' : 'publicGetV2PublicTradingRecords';
1455
+ const response = await this[method] (this.extend (request, params));
1456
+ //
1457
+ // {
1458
+ // ret_code: 0,
1459
+ // ret_msg: 'OK',
1460
+ // ext_code: '',
1461
+ // ext_info: '',
1462
+ // result: [
1463
+ // {
1464
+ // id: 43785688,
1465
+ // symbol: 'BTCUSD',
1466
+ // price: 7786,
1467
+ // qty: 67,
1468
+ // side: 'Sell',
1469
+ // time: '2020-03-11T19:18:30.123Z'
1470
+ // },
1471
+ // ],
1472
+ // time_now: '1583954313.393362'
1473
+ // }
1474
+ //
1475
+ const result = this.safeValue (response, 'result', {});
1476
+ return this.parseTrades (result, market, since, limit);
1477
+ }
1478
+
1479
+ parseOrderBook (orderbook, symbol, timestamp = undefined, bidsKey = 'Buy', asksKey = 'Sell', priceKey = 'price', amountKey = 'size') {
1480
+ const bids = [];
1481
+ const asks = [];
1482
+ for (let i = 0; i < orderbook.length; i++) {
1483
+ const bidask = orderbook[i];
1484
+ const side = this.safeString (bidask, 'side');
1485
+ if (side === 'Buy') {
1486
+ bids.push (this.parseBidAsk (bidask, priceKey, amountKey));
1487
+ } else if (side === 'Sell') {
1488
+ asks.push (this.parseBidAsk (bidask, priceKey, amountKey));
1489
+ } else {
1490
+ throw new ExchangeError (this.id + ' parseOrderBook() encountered an unrecognized bidask format: ' + this.json (bidask));
1491
+ }
1492
+ }
1493
+ return {
1494
+ 'symbol': symbol,
1495
+ 'bids': this.sortBy (bids, 0, true),
1496
+ 'asks': this.sortBy (asks, 0),
1497
+ 'timestamp': timestamp,
1498
+ 'datetime': this.iso8601 (timestamp),
1499
+ 'nonce': undefined,
1500
+ };
1501
+ }
1502
+
1503
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
1504
+ await this.loadMarkets ();
1505
+ const market = this.market (symbol);
1506
+ const request = {
1507
+ 'symbol': market['id'],
1508
+ };
1509
+ const response = await this.publicGetV2PublicOrderBookL2 (this.extend (request, params));
1510
+ //
1511
+ // {
1512
+ // ret_code: 0,
1513
+ // ret_msg: 'OK',
1514
+ // ext_code: '',
1515
+ // ext_info: '',
1516
+ // result: [
1517
+ // { symbol: 'BTCUSD', price: '7767.5', size: 677956, side: 'Buy' },
1518
+ // { symbol: 'BTCUSD', price: '7767', size: 580690, side: 'Buy' },
1519
+ // { symbol: 'BTCUSD', price: '7766.5', size: 475252, side: 'Buy' },
1520
+ // { symbol: 'BTCUSD', price: '7768', size: 330847, side: 'Sell' },
1521
+ // { symbol: 'BTCUSD', price: '7768.5', size: 97159, side: 'Sell' },
1522
+ // { symbol: 'BTCUSD', price: '7769', size: 6508, side: 'Sell' },
1523
+ // ],
1524
+ // time_now: '1583954829.874823'
1525
+ // }
1526
+ //
1527
+ const result = this.safeValue (response, 'result', []);
1528
+ const timestamp = this.safeTimestamp (response, 'time_now');
1529
+ return this.parseOrderBook (result, symbol, timestamp, 'Buy', 'Sell', 'price', 'size');
1530
+ }
1531
+
1532
+ parseBalance (response) {
1533
+ const result = {
1534
+ 'info': response,
1535
+ };
1536
+ const balances = this.safeValue (response, 'result', {});
1537
+ const currencyIds = Object.keys (balances);
1538
+ for (let i = 0; i < currencyIds.length; i++) {
1539
+ const currencyId = currencyIds[i];
1540
+ const balance = balances[currencyId];
1541
+ const code = this.safeCurrencyCode (currencyId);
1542
+ const account = this.account ();
1543
+ account['free'] = this.safeString (balance, 'available_balance');
1544
+ account['used'] = this.safeString (balance, 'used_margin');
1545
+ account['total'] = this.safeString (balance, 'equity');
1546
+ result[code] = account;
1547
+ }
1548
+ return this.safeBalance (result);
1549
+ }
1550
+
1551
+ async fetchBalance (params = {}) {
1552
+ // note: any funds in the 'spot' account will not be returned or visible from this endpoint
1553
+ await this.loadMarkets ();
1554
+ const request = {};
1555
+ const coin = this.safeString (params, 'coin');
1556
+ const code = this.safeString (params, 'code');
1557
+ if (coin !== undefined) {
1558
+ request['coin'] = coin;
1559
+ } else if (code !== undefined) {
1560
+ const currency = this.currency (code);
1561
+ request['coin'] = currency['id'];
1562
+ }
1563
+ const response = await this.v2PrivateGetWalletBalance (this.extend (request, params));
1564
+ //
1565
+ // {
1566
+ // ret_code: 0,
1567
+ // ret_msg: 'OK',
1568
+ // ext_code: '',
1569
+ // ext_info: '',
1570
+ // result: {
1571
+ // BTC: {
1572
+ // equity: 0,
1573
+ // available_balance: 0,
1574
+ // used_margin: 0,
1575
+ // order_margin: 0,
1576
+ // position_margin: 0,
1577
+ // occ_closing_fee: 0,
1578
+ // occ_funding_fee: 0,
1579
+ // wallet_balance: 0,
1580
+ // realised_pnl: 0,
1581
+ // unrealised_pnl: 0,
1582
+ // cum_realised_pnl: 0,
1583
+ // given_cash: 0,
1584
+ // service_cash: 0
1585
+ // }
1586
+ // },
1587
+ // time_now: '1583937810.370020',
1588
+ // rate_limit_status: 119,
1589
+ // rate_limit_reset_ms: 1583937810367,
1590
+ // rate_limit: 120
1591
+ // }
1592
+ //
1593
+ return this.parseBalance (response);
1594
+ }
1595
+
1596
+ parseOrderStatus (status) {
1597
+ const statuses = {
1598
+ // basic orders
1599
+ 'Created': 'open',
1600
+ 'Rejected': 'rejected', // order is triggered but failed upon being placed
1601
+ 'New': 'open',
1602
+ 'PartiallyFilled': 'open',
1603
+ 'Filled': 'closed',
1604
+ 'Cancelled': 'canceled',
1605
+ 'PendingCancel': 'canceling', // the engine has received the cancellation but there is no guarantee that it will be successful
1606
+ // conditional orders
1607
+ 'Active': 'open', // order is triggered and placed successfully
1608
+ 'Untriggered': 'open', // order waits to be triggered
1609
+ 'Triggered': 'closed', // order is triggered
1610
+ // 'Cancelled': 'canceled', // order is cancelled
1611
+ // 'Rejected': 'rejected', // order is triggered but fail to be placed
1612
+ 'Deactivated': 'canceled', // conditional order was cancelled before triggering
1613
+ };
1614
+ return this.safeString (statuses, status, status);
1615
+ }
1616
+
1617
+ parseTimeInForce (timeInForce) {
1618
+ const timeInForces = {
1619
+ 'GoodTillCancel': 'GTC',
1620
+ 'ImmediateOrCancel': 'IOC',
1621
+ 'FillOrKill': 'FOK',
1622
+ 'PostOnly': 'PO',
1623
+ };
1624
+ return this.safeString (timeInForces, timeInForce, timeInForce);
1625
+ }
1626
+
1627
+ parseOrder (order, market = undefined) {
1628
+ //
1629
+ // createOrder
1630
+ //
1631
+ // {
1632
+ // "user_id": 1,
1633
+ // "order_id": "335fd977-e5a5-4781-b6d0-c772d5bfb95b",
1634
+ // "symbol": "BTCUSD",
1635
+ // "side": "Buy",
1636
+ // "order_type": "Limit",
1637
+ // "price": 8800,
1638
+ // "qty": 1,
1639
+ // "time_in_force": "GoodTillCancel",
1640
+ // "order_status": "Created",
1641
+ // "last_exec_time": 0,
1642
+ // "last_exec_price": 0,
1643
+ // "leaves_qty": 1,
1644
+ // "cum_exec_qty": 0, // in contracts, where 1 contract = 1 quote currency unit (USD for inverse contracts)
1645
+ // "cum_exec_value": 0, // in contract's underlying currency (BTC for inverse contracts)
1646
+ // "cum_exec_fee": 0,
1647
+ // "reject_reason": "",
1648
+ // "order_link_id": "",
1649
+ // "created_at": "2019-11-30T11:03:43.452Z",
1650
+ // "updated_at": "2019-11-30T11:03:43.455Z"
1651
+ // }
1652
+ //
1653
+ // fetchOrder
1654
+ //
1655
+ // {
1656
+ // "user_id" : 599946,
1657
+ // "symbol" : "BTCUSD",
1658
+ // "side" : "Buy",
1659
+ // "order_type" : "Limit",
1660
+ // "price" : "7948",
1661
+ // "qty" : 10,
1662
+ // "time_in_force" : "GoodTillCancel",
1663
+ // "order_status" : "Filled",
1664
+ // "ext_fields" : {
1665
+ // "o_req_num" : -1600687220498,
1666
+ // "xreq_type" : "x_create"
1667
+ // },
1668
+ // "last_exec_time" : "1588150113.968422",
1669
+ // "last_exec_price" : "7948",
1670
+ // "leaves_qty" : 0,
1671
+ // "leaves_value" : "0",
1672
+ // "cum_exec_qty" : 10,
1673
+ // "cum_exec_value" : "0.00125817",
1674
+ // "cum_exec_fee" : "-0.00000031",
1675
+ // "reject_reason" : "",
1676
+ // "cancel_type" : "",
1677
+ // "order_link_id" : "",
1678
+ // "created_at" : "2020-04-29T08:45:24.399146Z",
1679
+ // "updated_at" : "2020-04-29T08:48:33.968422Z",
1680
+ // "order_id" : "dd2504b9-0157-406a-99e1-efa522373944"
1681
+ // }
1682
+ //
1683
+ // fetchOrders linear swaps
1684
+ //
1685
+ // {
1686
+ // "order_id":"7917bd70-e7c3-4af5-8147-3285cd99c509",
1687
+ // "user_id":22919890,
1688
+ // "symbol":"GMTUSDT",
1689
+ // "side":"Buy",
1690
+ // "order_type":"Limit",
1691
+ // "price":2.9262,
1692
+ // "qty":50,
1693
+ // "time_in_force":"GoodTillCancel",
1694
+ // "order_status":"Filled",
1695
+ // "last_exec_price":2.9219,
1696
+ // "cum_exec_qty":50,
1697
+ // "cum_exec_value":146.095,
1698
+ // "cum_exec_fee":0.087657,
1699
+ // "reduce_only":false,
1700
+ // "close_on_trigger":false,
1701
+ // "order_link_id":"",
1702
+ // "created_time":"2022-04-18T17:09:54Z",
1703
+ // "updated_time":"2022-04-18T17:09:54Z",
1704
+ // "take_profit":0,
1705
+ // "stop_loss":0,
1706
+ // "tp_trigger_by":"UNKNOWN",
1707
+ // "sl_trigger_by":"UNKNOWN"
1708
+ // }
1709
+ //
1710
+ // conditional order
1711
+ //
1712
+ // {
1713
+ // "user_id":##,
1714
+ // "symbol":"BTCUSD",
1715
+ // "side":"Buy",
1716
+ // "order_type":"Market",
1717
+ // "price":0,
1718
+ // "qty":10,
1719
+ // "time_in_force":"GoodTillCancel",
1720
+ // "stop_order_type":"Stop",
1721
+ // "trigger_by":"LastPrice",
1722
+ // "base_price":11833,
1723
+ // "order_status":"Untriggered",
1724
+ // "ext_fields":{
1725
+ // "stop_order_type":"Stop",
1726
+ // "trigger_by":"LastPrice",
1727
+ // "base_price":11833,
1728
+ // "expected_direction":"Rising",
1729
+ // "trigger_price":12400,
1730
+ // "close_on_trigger":true,
1731
+ // "op_from":"api",
1732
+ // "remark":"x.x.x.x",
1733
+ // "o_req_num":0
1734
+ // },
1735
+ // "leaves_qty":10,
1736
+ // "leaves_value":0.00080645,
1737
+ // "reject_reason":null,
1738
+ // "cross_seq":-1,
1739
+ // "created_at":"2020-08-21T09:18:48.000Z",
1740
+ // "updated_at":"2020-08-21T09:18:48.000Z",
1741
+ // "trigger_price":12400,
1742
+ // "stop_order_id":"3f3b54b1-3379-42c7-8510-44f4d9915be0"
1743
+ // }
1744
+ //
1745
+ const marketId = this.safeString (order, 'symbol');
1746
+ market = this.safeMarket (marketId, market);
1747
+ const symbol = market['symbol'];
1748
+ let feeCurrency = undefined;
1749
+ const timestamp = this.parse8601 (this.safeString2 (order, 'created_at', 'created_time'));
1750
+ const id = this.safeString2 (order, 'order_id', 'stop_order_id');
1751
+ const type = this.safeStringLower (order, 'order_type');
1752
+ let price = undefined;
1753
+ if (type !== 'market') {
1754
+ price = this.safeString (order, 'price');
1755
+ }
1756
+ const average = this.safeString (order, 'average_price');
1757
+ const amount = this.safeString (order, 'qty');
1758
+ const cost = this.safeString (order, 'cum_exec_value');
1759
+ const filled = this.safeString (order, 'cum_exec_qty');
1760
+ const remaining = this.safeString (order, 'leaves_qty');
1761
+ const marketTypes = this.safeValue (this.options, 'marketTypes', {});
1762
+ const marketType = this.safeString (marketTypes, symbol);
1763
+ if (marketType === 'linear') {
1764
+ feeCurrency = market['quote'];
1765
+ } else {
1766
+ feeCurrency = market['base'];
1767
+ }
1768
+ let lastTradeTimestamp = this.safeTimestamp (order, 'last_exec_time');
1769
+ if (lastTradeTimestamp === 0) {
1770
+ lastTradeTimestamp = undefined;
1771
+ }
1772
+ const status = this.parseOrderStatus (this.safeString2 (order, 'order_status', 'stop_order_status'));
1773
+ const side = this.safeStringLower (order, 'side');
1774
+ const feeCostString = this.safeString (order, 'cum_exec_fee');
1775
+ let fee = undefined;
1776
+ if (feeCostString !== undefined) {
1777
+ fee = {
1778
+ 'cost': feeCostString,
1779
+ 'currency': feeCurrency,
1780
+ };
1781
+ }
1782
+ let clientOrderId = this.safeString (order, 'order_link_id');
1783
+ if ((clientOrderId !== undefined) && (clientOrderId.length < 1)) {
1784
+ clientOrderId = undefined;
1785
+ }
1786
+ const timeInForce = this.parseTimeInForce (this.safeString (order, 'time_in_force'));
1787
+ const stopPrice = this.safeNumber2 (order, 'trigger_price', 'stop_px');
1788
+ const postOnly = (timeInForce === 'PO');
1789
+ return this.safeOrder ({
1790
+ 'info': order,
1791
+ 'id': id,
1792
+ 'clientOrderId': clientOrderId,
1793
+ 'timestamp': timestamp,
1794
+ 'datetime': this.iso8601 (timestamp),
1795
+ 'lastTradeTimestamp': lastTradeTimestamp,
1796
+ 'symbol': symbol,
1797
+ 'type': type,
1798
+ 'timeInForce': timeInForce,
1799
+ 'postOnly': postOnly,
1800
+ 'side': side,
1801
+ 'price': price,
1802
+ 'stopPrice': stopPrice,
1803
+ 'amount': amount,
1804
+ 'cost': cost,
1805
+ 'average': average,
1806
+ 'filled': filled,
1807
+ 'remaining': remaining,
1808
+ 'status': status,
1809
+ 'fee': fee,
1810
+ 'trades': undefined,
1811
+ }, market);
1812
+ }
1813
+
1814
+ async fetchOrder (id, symbol = undefined, params = {}) { // TODO
1815
+ if (symbol === undefined) {
1816
+ throw new ArgumentsRequired (this.id + ' fetchOrder() requires a symbol argument');
1817
+ }
1818
+ await this.loadMarkets ();
1819
+ const market = this.market (symbol);
1820
+ const request = {
1821
+ 'symbol': market['id'],
1822
+ // 'order_link_id': 'string', // one of order_id, stop_order_id or order_link_id is required
1823
+ // regular orders ---------------------------------------------
1824
+ // 'order_id': id, // one of order_id or order_link_id is required for regular orders
1825
+ // conditional orders ---------------------------------------------
1826
+ // 'stop_order_id': id, // one of stop_order_id or order_link_id is required for conditional orders
1827
+ };
1828
+ let method = undefined;
1829
+ if (market['swap']) {
1830
+ if (market['linear']) {
1831
+ method = 'privateLinearGetOrderSearch';
1832
+ } else if (market['inverse']) {
1833
+ method = 'v2PrivateGetOrder';
1834
+ }
1835
+ } else if (market['future']) {
1836
+ method = 'futuresPrivateGetOrder';
1837
+ }
1838
+ const stopOrderId = this.safeString (params, 'stop_order_id');
1839
+ if (stopOrderId === undefined) {
1840
+ const orderLinkId = this.safeString (params, 'order_link_id');
1841
+ if (orderLinkId === undefined) {
1842
+ request['order_id'] = id;
1843
+ }
1844
+ } else {
1845
+ if (market['swap']) {
1846
+ if (market['linear']) {
1847
+ method = 'privateLinearGetStopOrderSearch';
1848
+ } else if (market['inverse']) {
1849
+ method = 'v2PrivateGetStopOrder';
1850
+ }
1851
+ } else if (market['future']) {
1852
+ method = 'futuresPrivateGetStopOrder';
1853
+ }
1854
+ }
1855
+ const response = await this[method] (this.extend (request, params));
1856
+ //
1857
+ // {
1858
+ // "ret_code": 0,
1859
+ // "ret_msg": "OK",
1860
+ // "ext_code": "",
1861
+ // "ext_info": "",
1862
+ // "result": {
1863
+ // "user_id": 1,
1864
+ // "symbol": "BTCUSD",
1865
+ // "side": "Sell",
1866
+ // "order_type": "Limit",
1867
+ // "price": "8083",
1868
+ // "qty": 10,
1869
+ // "time_in_force": "GoodTillCancel",
1870
+ // "order_status": "New",
1871
+ // "ext_fields": { "o_req_num": -308787, "xreq_type": "x_create", "xreq_offset": 4154640 },
1872
+ // "leaves_qty": 10,
1873
+ // "leaves_value": "0.00123716",
1874
+ // "cum_exec_qty": 0,
1875
+ // "reject_reason": "",
1876
+ // "order_link_id": "",
1877
+ // "created_at": "2019-10-21T07:28:19.396246Z",
1878
+ // "updated_at": "2019-10-21T07:28:19.396246Z",
1879
+ // "order_id": "efa44157-c355-4a98-b6d6-1d846a936b93"
1880
+ // },
1881
+ // "time_now": "1571651135.291930",
1882
+ // "rate_limit_status": 99, // The remaining number of accesses in one minute
1883
+ // "rate_limit_reset_ms": 1580885703683,
1884
+ // "rate_limit": 100
1885
+ // }
1886
+ //
1887
+ // conditional orders
1888
+ //
1889
+ // {
1890
+ // "ret_code": 0,
1891
+ // "ret_msg": "OK",
1892
+ // "ext_code": "",
1893
+ // "ext_info": "",
1894
+ // "result": {
1895
+ // "user_id": 1,
1896
+ // "symbol": "BTCUSD",
1897
+ // "side": "Buy",
1898
+ // "order_type": "Limit",
1899
+ // "price": "8000",
1900
+ // "qty": 1,
1901
+ // "time_in_force": "GoodTillCancel",
1902
+ // "order_status": "Untriggered",
1903
+ // "ext_fields": {},
1904
+ // "leaves_qty": 1,
1905
+ // "leaves_value": "0.00013333",
1906
+ // "cum_exec_qty": 0,
1907
+ // "cum_exec_value": null,
1908
+ // "cum_exec_fee": null,
1909
+ // "reject_reason": "",
1910
+ // "order_link_id": "",
1911
+ // "created_at": "2019-12-27T19:56:24.052194Z",
1912
+ // "updated_at": "2019-12-27T19:56:24.052194Z",
1913
+ // "order_id": "378a1bbc-a93a-4e75-87f4-502ea754ba36"
1914
+ // },
1915
+ // "time_now": "1577476584.386958",
1916
+ // "rate_limit_status": 99,
1917
+ // "rate_limit_reset_ms": 1580885703683,
1918
+ // "rate_limit": 100
1919
+ // }
1920
+ //
1921
+ const result = this.safeValue (response, 'result');
1922
+ return this.parseOrder (result, market);
1923
+ }
1924
+
1925
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
1926
+ await this.loadMarkets ();
1927
+ const market = this.market (symbol);
1928
+ let qty = this.amountToPrecision (symbol, amount);
1929
+ if (market['inverse']) {
1930
+ qty = parseInt (qty);
1931
+ } else {
1932
+ qty = parseFloat (qty);
1933
+ }
1934
+ const request = {
1935
+ // orders ---------------------------------------------------------
1936
+ 'side': this.capitalize (side),
1937
+ 'symbol': market['id'],
1938
+ 'order_type': this.capitalize (type),
1939
+ 'qty': qty, // order quantity in USD, integer only
1940
+ // 'price': parseFloat (this.priceToPrecision (symbol, price)), // required for limit orders
1941
+ 'time_in_force': 'GoodTillCancel', // ImmediateOrCancel, FillOrKill, PostOnly
1942
+ // 'take_profit': 123.45, // take profit price, only take effect upon opening the position
1943
+ // 'stop_loss': 123.45, // stop loss price, only take effect upon opening the position
1944
+ // 'reduce_only': false, // reduce only, required for linear orders
1945
+ // when creating a closing order, bybit recommends a True value for
1946
+ // close_on_trigger to avoid failing due to insufficient available margin
1947
+ // 'close_on_trigger': false, required for linear orders
1948
+ // 'order_link_id': 'string', // unique client order id, max 36 characters
1949
+ // conditional orders ---------------------------------------------
1950
+ // base_price is used to compare with the value of stop_px, to decide
1951
+ // whether your conditional order will be triggered by crossing trigger
1952
+ // price from upper side or lower side, mainly used to identify the
1953
+ // expected direction of the current conditional order
1954
+ // 'base_price': 123.45, // required for conditional orders
1955
+ // 'stop_px': 123.45, // trigger price, required for conditional orders
1956
+ // 'trigger_by': 'LastPrice', // IndexPrice, MarkPrice
1957
+ };
1958
+ let priceIsRequired = false;
1959
+ if (type === 'limit') {
1960
+ priceIsRequired = true;
1961
+ }
1962
+ if (priceIsRequired) {
1963
+ if (price !== undefined) {
1964
+ request['price'] = parseFloat (this.priceToPrecision (symbol, price));
1965
+ } else {
1966
+ throw new ArgumentsRequired (this.id + ' createOrder() requires a price argument for a ' + type + ' order');
1967
+ }
1968
+ }
1969
+ const clientOrderId = this.safeString2 (params, 'order_link_id', 'clientOrderId');
1970
+ if (clientOrderId !== undefined) {
1971
+ request['order_link_id'] = clientOrderId;
1972
+ params = this.omit (params, [ 'order_link_id', 'clientOrderId' ]);
1973
+ }
1974
+ const stopPx = this.safeValue2 (params, 'stop_px', 'stopPrice');
1975
+ const basePrice = this.safeValue (params, 'base_price');
1976
+ let method = undefined;
1977
+ if (market['swap']) {
1978
+ if (market['linear']) {
1979
+ method = 'privateLinearPostOrderCreate';
1980
+ request['reduce_only'] = false;
1981
+ request['close_on_trigger'] = false;
1982
+ } else if (market['inverse']) {
1983
+ method = 'v2PrivatePostOrderCreate';
1984
+ }
1985
+ } else if (market['future']) {
1986
+ method = 'futuresPrivatePostOrderCreate';
1987
+ }
1988
+ if (stopPx !== undefined) {
1989
+ if (basePrice === undefined) {
1990
+ throw new ArgumentsRequired (this.id + ' createOrder() requires both the stop_px and base_price params for a conditional ' + type + ' order');
1991
+ } else {
1992
+ if (market['swap']) {
1993
+ if (market['linear']) {
1994
+ method = 'privateLinearPostStopOrderCreate';
1995
+ } else if (market['inverse']) {
1996
+ method = 'v2PrivatePostStopOrderCreate';
1997
+ }
1998
+ } else if (market['future']) {
1999
+ method = 'futuresPrivatePostStopOrderCreate';
2000
+ }
2001
+ request['stop_px'] = parseFloat (this.priceToPrecision (symbol, stopPx));
2002
+ request['base_price'] = parseFloat (this.priceToPrecision (symbol, basePrice));
2003
+ request['trigger_by'] = 'LastPrice';
2004
+ params = this.omit (params, [ 'stop_px', 'stopPrice', 'base_price', 'trigger_by' ]);
2005
+ }
2006
+ } else if (basePrice !== undefined) {
2007
+ throw new ArgumentsRequired (this.id + ' createOrder() requires both the stop_px and base_price params for a conditional ' + type + ' order');
2008
+ }
2009
+ const response = await this[method] (this.extend (request, params));
2010
+ //
2011
+ // {
2012
+ // "ret_code": 0,
2013
+ // "ret_msg": "OK",
2014
+ // "ext_code": "",
2015
+ // "ext_info": "",
2016
+ // "result": {
2017
+ // "user_id": 1,
2018
+ // "order_id": "335fd977-e5a5-4781-b6d0-c772d5bfb95b",
2019
+ // "symbol": "BTCUSD",
2020
+ // "side": "Buy",
2021
+ // "order_type": "Limit",
2022
+ // "price": 8800,
2023
+ // "qty": 1,
2024
+ // "time_in_force": "GoodTillCancel",
2025
+ // "order_status": "Created",
2026
+ // "last_exec_time": 0,
2027
+ // "last_exec_price": 0,
2028
+ // "leaves_qty": 1,
2029
+ // "cum_exec_qty": 0,
2030
+ // "cum_exec_value": 0,
2031
+ // "cum_exec_fee": 0,
2032
+ // "reject_reason": "",
2033
+ // "order_link_id": "",
2034
+ // "created_at": "2019-11-30T11:03:43.452Z",
2035
+ // "updated_at": "2019-11-30T11:03:43.455Z"
2036
+ // },
2037
+ // "time_now": "1575111823.458705",
2038
+ // "rate_limit_status": 98,
2039
+ // "rate_limit_reset_ms": 1580885703683,
2040
+ // "rate_limit": 100
2041
+ // }
2042
+ //
2043
+ // conditional orders
2044
+ //
2045
+ // {
2046
+ // "ret_code": 0,
2047
+ // "ret_msg": "ok",
2048
+ // "ext_code": "",
2049
+ // "result": {
2050
+ // "user_id": 1,
2051
+ // "symbol": "BTCUSD",
2052
+ // "side": "Buy",
2053
+ // "order_type": "Limit",
2054
+ // "price": 8000,
2055
+ // "qty": 1,
2056
+ // "time_in_force": "GoodTillCancel",
2057
+ // "stop_order_type": "Stop",
2058
+ // "trigger_by": "LastPrice",
2059
+ // "base_price": 7000,
2060
+ // "order_status": "Untriggered",
2061
+ // "ext_fields": {
2062
+ // "stop_order_type": "Stop",
2063
+ // "trigger_by": "LastPrice",
2064
+ // "base_price": 7000,
2065
+ // "expected_direction": "Rising",
2066
+ // "trigger_price": 7500,
2067
+ // "op_from": "api",
2068
+ // "remark": "127.0.01",
2069
+ // "o_req_num": 0
2070
+ // },
2071
+ // "leaves_qty": 1,
2072
+ // "leaves_value": 0.00013333,
2073
+ // "reject_reason": null,
2074
+ // "cross_seq": -1,
2075
+ // "created_at": "2019-12-27T12:48:24.000Z",
2076
+ // "updated_at": "2019-12-27T12:48:24.000Z",
2077
+ // "stop_px": 7500,
2078
+ // "stop_order_id": "a85cd1c0-a9a4-49d3-a1bd-bab5ebe946d5"
2079
+ // },
2080
+ // "ext_info": null,
2081
+ // "time_now": "1577450904.327654",
2082
+ // "rate_limit_status": 99,
2083
+ // "rate_limit_reset_ms": 1577450904335,
2084
+ // "rate_limit": "100"
2085
+ // }
2086
+ //
2087
+ const result = this.safeValue (response, 'result');
2088
+ return this.parseOrder (result, market);
2089
+ }
2090
+
2091
+ async editOrder (id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
2092
+ if (symbol === undefined) {
2093
+ throw new ArgumentsRequired (this.id + ' editOrder() requires an symbol argument');
2094
+ }
2095
+ await this.loadMarkets ();
2096
+ const market = this.market (symbol);
2097
+ const request = {
2098
+ // 'order_id': id, // only for non-conditional orders
2099
+ 'symbol': market['id'],
2100
+ // 'p_r_qty': this.amountToPrecision (symbol, amount), // new order quantity, optional
2101
+ // 'p_r_price' this.priceToprecision (symbol, price), // new order price, optional
2102
+ // ----------------------------------------------------------------
2103
+ // conditional orders
2104
+ // 'stop_order_id': id, // only for conditional orders
2105
+ // 'p_r_trigger_price': 123.45, // new trigger price also known as stop_px
2106
+ };
2107
+ let method = undefined;
2108
+ if (market['swap']) {
2109
+ if (market['linear']) {
2110
+ method = 'privateLinearPostOrderReplace';
2111
+ } else if (market['inverse']) {
2112
+ method = 'v2PrivatePostOrderReplace';
2113
+ }
2114
+ } else if (market['future']) {
2115
+ method = 'futuresPrivatePostOrderReplace';
2116
+ }
2117
+ const stopOrderId = this.safeString (params, 'stop_order_id');
2118
+ if (stopOrderId !== undefined) {
2119
+ if (market['swap']) {
2120
+ if (market['linear']) {
2121
+ method = 'privateLinearPostStopOrderReplace';
2122
+ } else if (market['inverse']) {
2123
+ method = 'v2PrivatePostStopOrderReplace';
2124
+ }
2125
+ } else if (market['future']) {
2126
+ method = 'futuresPrivatePostStopOrderReplace';
2127
+ }
2128
+ request['stop_order_id'] = stopOrderId;
2129
+ params = this.omit (params, [ 'stop_order_id' ]);
2130
+ } else {
2131
+ request['order_id'] = id;
2132
+ }
2133
+ if (amount !== undefined) {
2134
+ let qty = this.amountToPrecision (symbol, amount);
2135
+ if (market['inverse']) {
2136
+ qty = parseInt (qty);
2137
+ } else {
2138
+ qty = parseFloat (qty);
2139
+ }
2140
+ request['p_r_qty'] = qty;
2141
+ }
2142
+ if (price !== undefined) {
2143
+ request['p_r_price'] = parseFloat (this.priceToPrecision (symbol, price));
2144
+ }
2145
+ const response = await this[method] (this.extend (request, params));
2146
+ //
2147
+ // {
2148
+ // "ret_code": 0,
2149
+ // "ret_msg": "ok",
2150
+ // "ext_code": "",
2151
+ // "result": { "order_id": "efa44157-c355-4a98-b6d6-1d846a936b93" },
2152
+ // "time_now": "1539778407.210858",
2153
+ // "rate_limit_status": 99, // remaining number of accesses in one minute
2154
+ // "rate_limit_reset_ms": 1580885703683,
2155
+ // "rate_limit": 100
2156
+ // }
2157
+ //
2158
+ // conditional orders
2159
+ //
2160
+ // {
2161
+ // "ret_code": 0,
2162
+ // "ret_msg": "ok",
2163
+ // "ext_code": "",
2164
+ // "result": { "stop_order_id": "378a1bbc-a93a-4e75-87f4-502ea754ba36" },
2165
+ // "ext_info": null,
2166
+ // "time_now": "1577475760.604942",
2167
+ // "rate_limit_status": 96,
2168
+ // "rate_limit_reset_ms": 1577475760612,
2169
+ // "rate_limit": "100"
2170
+ // }
2171
+ //
2172
+ const result = this.safeValue (response, 'result', {});
2173
+ return {
2174
+ 'info': response,
2175
+ 'id': this.safeString2 (result, 'order_id', 'stop_order_id'),
2176
+ 'order_id': this.safeString (result, 'order_id'),
2177
+ 'stop_order_id': this.safeString (result, 'stop_order_id'),
2178
+ };
2179
+ }
2180
+
2181
+ async cancelOrder (id, symbol = undefined, params = {}) {
2182
+ if (symbol === undefined) {
2183
+ throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
2184
+ }
2185
+ await this.loadMarkets ();
2186
+ const market = this.market (symbol);
2187
+ const request = {
2188
+ 'symbol': market['id'],
2189
+ // 'order_link_id': 'string', // one of order_id, stop_order_id or order_link_id is required
2190
+ // regular orders ---------------------------------------------
2191
+ // 'order_id': id, // one of order_id or order_link_id is required for regular orders
2192
+ // conditional orders ---------------------------------------------
2193
+ // 'stop_order_id': id, // one of stop_order_id or order_link_id is required for conditional orders
2194
+ };
2195
+ let method = undefined;
2196
+ if (market['swap']) {
2197
+ if (market['linear']) {
2198
+ method = 'privateLinearPostOrderCancel';
2199
+ } else if (market['inverse']) {
2200
+ method = 'v2PrivatePostOrderCancel';
2201
+ }
2202
+ } else if (market['future']) {
2203
+ method = 'futuresPrivatePostOrderCancel';
2204
+ }
2205
+ const stopOrderId = this.safeString (params, 'stop_order_id');
2206
+ if (stopOrderId === undefined) {
2207
+ const orderLinkId = this.safeString (params, 'order_link_id');
2208
+ if (orderLinkId === undefined) {
2209
+ request['order_id'] = id;
2210
+ }
2211
+ } else {
2212
+ if (market['swap']) {
2213
+ if (market['linear']) {
2214
+ method = 'privateLinearPostStopOrderCancel';
2215
+ } else if (market['inverse']) {
2216
+ method = 'v2PrivatePostStopOrderCancel';
2217
+ }
2218
+ } else if (market['future']) {
2219
+ method = 'futuresPrivatePostStopOrderCancel';
2220
+ }
2221
+ }
2222
+ const response = await this[method] (this.extend (request, params));
2223
+ const result = this.safeValue (response, 'result', {});
2224
+ return this.parseOrder (result, market);
2225
+ }
2226
+
2227
+ async cancelAllOrders (symbol = undefined, params = {}) {
2228
+ if (symbol === undefined) {
2229
+ throw new ArgumentsRequired (this.id + ' cancelAllOrders() requires a symbol argument');
2230
+ }
2231
+ await this.loadMarkets ();
2232
+ const market = this.market (symbol);
2233
+ const request = {
2234
+ 'symbol': market['id'],
2235
+ };
2236
+ const options = this.safeValue (this.options, 'cancelAllOrders', {});
2237
+ let defaultMethod = undefined;
2238
+ if (market['swap']) {
2239
+ if (market['linear']) {
2240
+ defaultMethod = 'privateLinearPostOrderCancelAll';
2241
+ } else if (market['inverse']) {
2242
+ defaultMethod = 'v2PrivatePostOrderCancelAll';
2243
+ }
2244
+ } else if (market['future']) {
2245
+ defaultMethod = 'futuresPrivatePostOrderCancelAll';
2246
+ }
2247
+ const stop = this.safeValue (params, 'stop');
2248
+ if (stop) {
2249
+ if (market['swap']) {
2250
+ if (market['linear']) {
2251
+ defaultMethod = 'privateLinearPostStopOrderCancelAll';
2252
+ } else if (market['inverse']) {
2253
+ defaultMethod = 'v2PrivatePostStopOrderCancelAll';
2254
+ }
2255
+ } else if (market['future']) {
2256
+ defaultMethod = 'futuresPrivatePostStopOrderCancelAll';
2257
+ }
2258
+ }
2259
+ const method = this.safeString (options, 'method', defaultMethod);
2260
+ params = this.omit (params, 'stop');
2261
+ const response = await this[method] (this.extend (request, params));
2262
+ const result = this.safeValue (response, 'result', []);
2263
+ return this.parseOrders (result, market);
2264
+ }
2265
+
2266
+ async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
2267
+ await this.loadMarkets ();
2268
+ const request = {
2269
+ // 'order_id': 'string'
2270
+ // 'order_link_id': 'string', // unique client order id, max 36 characters
2271
+ // 'symbol': market['id'], // default BTCUSD
2272
+ // 'order': 'desc', // asc
2273
+ // 'page': 1,
2274
+ // 'limit': 20, // max 50
2275
+ // 'order_status': 'Created,New'
2276
+ // conditional orders ---------------------------------------------
2277
+ // 'stop_order_id': 'string',
2278
+ // 'stop_order_status': 'Untriggered',
2279
+ };
2280
+ let market = undefined;
2281
+ if (symbol !== undefined) {
2282
+ market = this.market (symbol);
2283
+ request['symbol'] = market['id'];
2284
+ }
2285
+ if (limit !== undefined) {
2286
+ request['limit'] = limit;
2287
+ }
2288
+ const options = this.safeValue (this.options, 'fetchOrders', {});
2289
+ const defaultType = this.safeString (this.options, 'defaultType', 'linear');
2290
+ const marketTypes = this.safeValue (this.options, 'marketTypes', {});
2291
+ const marketType = this.safeString (marketTypes, symbol, defaultType);
2292
+ let defaultMethod = undefined;
2293
+ const marketDefined = (market !== undefined);
2294
+ const linear = (marketDefined && market['linear']) || (marketType === 'linear');
2295
+ const inverse = (marketDefined && market['swap'] && market['inverse']) || (marketType === 'inverse');
2296
+ const future = (marketDefined && market['future']) || ((marketType === 'future') || (marketType === 'futures')); // * (marketType === 'futures') deprecated, use (marketType === 'future')
2297
+ if (linear) {
2298
+ defaultMethod = 'privateLinearGetOrderList';
2299
+ } else if (inverse) {
2300
+ defaultMethod = 'v2PrivateGetOrderList';
2301
+ } else if (future) {
2302
+ defaultMethod = 'futuresPrivateGetOrderList';
2303
+ }
2304
+ let query = params;
2305
+ if (('stop_order_id' in params) || ('stop_order_status' in params)) {
2306
+ let stopOrderStatus = this.safeValue (params, 'stop_order_status');
2307
+ if (stopOrderStatus !== undefined) {
2308
+ if (Array.isArray (stopOrderStatus)) {
2309
+ stopOrderStatus = stopOrderStatus.join (',');
2310
+ }
2311
+ request['stop_order_status'] = stopOrderStatus;
2312
+ query = this.omit (params, 'stop_order_status');
2313
+ }
2314
+ if (linear) {
2315
+ defaultMethod = 'privateLinearGetStopOrderList';
2316
+ } else if (inverse) {
2317
+ defaultMethod = 'v2PrivateGetStopOrderList';
2318
+ } else if (future) {
2319
+ defaultMethod = 'futuresPrivateGetStopOrderList';
2320
+ }
2321
+ }
2322
+ const method = this.safeString (options, 'method', defaultMethod);
2323
+ const response = await this[method] (this.extend (request, query));
2324
+ //
2325
+ // {
2326
+ // "ret_code": 0,
2327
+ // "ret_msg": "ok",
2328
+ // "ext_code": "",
2329
+ // "result": {
2330
+ // "current_page": 1,
2331
+ // "last_page": 6,
2332
+ // "data": [
2333
+ // {
2334
+ // "user_id": 1,
2335
+ // "symbol": "BTCUSD",
2336
+ // "side": "Sell",
2337
+ // "order_type": "Market",
2338
+ // "price": 7074,
2339
+ // "qty": 2,
2340
+ // "time_in_force": "ImmediateOrCancel",
2341
+ // "order_status": "Filled",
2342
+ // "ext_fields": {
2343
+ // "close_on_trigger": true,
2344
+ // "orig_order_type": "BLimit",
2345
+ // "prior_x_req_price": 5898.5,
2346
+ // "op_from": "pc",
2347
+ // "remark": "127.0.0.1",
2348
+ // "o_req_num": -34799032763,
2349
+ // "xreq_type": "x_create"
2350
+ // },
2351
+ // "last_exec_time": "1577448481.696421",
2352
+ // "last_exec_price": 7070.5,
2353
+ // "leaves_qty": 0,
2354
+ // "leaves_value": 0,
2355
+ // "cum_exec_qty": 2,
2356
+ // "cum_exec_value": 0.00028283,
2357
+ // "cum_exec_fee": 0.00002,
2358
+ // "reject_reason": "NoError",
2359
+ // "order_link_id": "",
2360
+ // "created_at": "2019-12-27T12:08:01.000Z",
2361
+ // "updated_at": "2019-12-27T12:08:01.000Z",
2362
+ // "order_id": "f185806b-b801-40ff-adec-52289370ed62"
2363
+ // }
2364
+ // ]
2365
+ // },
2366
+ // "ext_info": null,
2367
+ // "time_now": "1577448922.437871",
2368
+ // "rate_limit_status": 98,
2369
+ // "rate_limit_reset_ms": 1580885703683,
2370
+ // "rate_limit": 100
2371
+ // }
2372
+ //
2373
+ // linear swaps
2374
+ //
2375
+ // {
2376
+ // "ret_code":0,
2377
+ // "ret_msg":"OK",
2378
+ // "ext_code":"",
2379
+ // "ext_info":"",
2380
+ // "result":{
2381
+ // "current_page":1,
2382
+ // "data":[
2383
+ // {
2384
+ // "order_id":"7917bd70-e7c3-4af5-8147-3285cd99c509",
2385
+ // "user_id":22919890,
2386
+ // "symbol":"GMTUSDT",
2387
+ // "side":"Buy",
2388
+ // "order_type":"Limit",
2389
+ // "price":2.9262,
2390
+ // "qty":50,
2391
+ // "time_in_force":"GoodTillCancel",
2392
+ // "order_status":"Filled",
2393
+ // "last_exec_price":2.9219,
2394
+ // "cum_exec_qty":50,
2395
+ // "cum_exec_value":146.095,
2396
+ // "cum_exec_fee":0.087657,
2397
+ // "reduce_only":false,
2398
+ // "close_on_trigger":false,
2399
+ // "order_link_id":"",
2400
+ // "created_time":"2022-04-18T17:09:54Z",
2401
+ // "updated_time":"2022-04-18T17:09:54Z",
2402
+ // "take_profit":0,
2403
+ // "stop_loss":0,
2404
+ // "tp_trigger_by":"UNKNOWN",
2405
+ // "sl_trigger_by":"UNKNOWN"
2406
+ // }
2407
+ // ]
2408
+ // },
2409
+ // "time_now":"1650970113.283952",
2410
+ // "rate_limit_status":599,
2411
+ // "rate_limit_reset_ms":1650970113275,
2412
+ // "rate_limit":600
2413
+ // }
2414
+ //
2415
+ // conditional orders
2416
+ //
2417
+ // {
2418
+ // "ret_code": 0,
2419
+ // "ret_msg": "ok",
2420
+ // "ext_code": "",
2421
+ // "result": {
2422
+ // "current_page": 1,
2423
+ // "last_page": 1,
2424
+ // "data": [
2425
+ // {
2426
+ // "user_id": 1,
2427
+ // "stop_order_status": "Untriggered",
2428
+ // "symbol": "BTCUSD",
2429
+ // "side": "Buy",
2430
+ // "order_type": "Limit",
2431
+ // "price": 8000,
2432
+ // "qty": 1,
2433
+ // "time_in_force": "GoodTillCancel",
2434
+ // "stop_order_type": "Stop",
2435
+ // "trigger_by": "LastPrice",
2436
+ // "base_price": 7000,
2437
+ // "order_link_id": "",
2438
+ // "created_at": "2019-12-27T12:48:24.000Z",
2439
+ // "updated_at": "2019-12-27T12:48:24.000Z",
2440
+ // "stop_px": 7500,
2441
+ // "stop_order_id": "a85cd1c0-a9a4-49d3-a1bd-bab5ebe946d5"
2442
+ // },
2443
+ // ]
2444
+ // },
2445
+ // "ext_info": null,
2446
+ // "time_now": "1577451658.755468",
2447
+ // "rate_limit_status": 599,
2448
+ // "rate_limit_reset_ms": 1577451658762,
2449
+ // "rate_limit": 600
2450
+ // }
2451
+ //
2452
+ const result = this.safeValue (response, 'result', {});
2453
+ const data = this.safeValue (result, 'data', []);
2454
+ return this.parseOrders (data, market, since, limit);
2455
+ }
2456
+
2457
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
2458
+ const defaultStatuses = [
2459
+ 'Rejected',
2460
+ 'Filled',
2461
+ 'Cancelled',
2462
+ // conditional orders
2463
+ // 'Active',
2464
+ // 'Triggered',
2465
+ // 'Cancelled',
2466
+ // 'Rejected',
2467
+ // 'Deactivated',
2468
+ ];
2469
+ const options = this.safeValue (this.options, 'fetchClosedOrders', {});
2470
+ let status = this.safeValue (options, 'order_status', defaultStatuses);
2471
+ if (Array.isArray (status)) {
2472
+ status = status.join (',');
2473
+ }
2474
+ const request = {};
2475
+ const stopOrderStatus = this.safeValue (params, 'stop_order_status');
2476
+ if (stopOrderStatus === undefined) {
2477
+ request['order_status'] = status;
2478
+ } else {
2479
+ request['stop_order_status'] = stopOrderStatus;
2480
+ }
2481
+ return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
2482
+ }
2483
+
2484
+ async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
2485
+ const defaultStatuses = [
2486
+ 'Created',
2487
+ 'New',
2488
+ 'PartiallyFilled',
2489
+ 'PendingCancel',
2490
+ // conditional orders
2491
+ // 'Untriggered',
2492
+ ];
2493
+ const options = this.safeValue (this.options, 'fetchOpenOrders', {});
2494
+ let status = this.safeValue (options, 'order_status', defaultStatuses);
2495
+ if (Array.isArray (status)) {
2496
+ status = status.join (',');
2497
+ }
2498
+ const request = {};
2499
+ const stopOrderStatus = this.safeValue (params, 'stop_order_status');
2500
+ if (stopOrderStatus === undefined) {
2501
+ request['order_status'] = status;
2502
+ } else {
2503
+ request['stop_order_status'] = stopOrderStatus;
2504
+ }
2505
+ return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
2506
+ }
2507
+
2508
+ async fetchOrderTrades (id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
2509
+ const request = {
2510
+ 'order_id': id,
2511
+ };
2512
+ return await this.fetchMyTrades (symbol, since, limit, this.extend (request, params));
2513
+ }
2514
+
2515
+ async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
2516
+ if (symbol === undefined) {
2517
+ throw new ArgumentsRequired (this.id + ' fetchMyTrades() requires a symbol argument');
2518
+ }
2519
+ await this.loadMarkets ();
2520
+ const request = {
2521
+ // 'order_id': 'f185806b-b801-40ff-adec-52289370ed62', // if not provided will return user's trading records
2522
+ // 'symbol': market['id'],
2523
+ // 'start_time': parseInt (since / 1000),
2524
+ // 'page': 1,
2525
+ // 'limit' 20, // max 50
2526
+ };
2527
+ let market = undefined;
2528
+ const orderId = this.safeString (params, 'order_id');
2529
+ if (orderId !== undefined) {
2530
+ request['order_id'] = orderId;
2531
+ params = this.omit (params, 'order_id');
2532
+ }
2533
+ market = this.market (symbol);
2534
+ request['symbol'] = market['id'];
2535
+ if (since !== undefined) {
2536
+ request['start_time'] = since;
2537
+ }
2538
+ if (limit !== undefined) {
2539
+ request['limit'] = limit; // default 20, max 50
2540
+ }
2541
+ const [ marketType, query ] = this.handleMarketTypeAndParams ('fetchMyTrades', market, params);
2542
+ const marketDefined = (market !== undefined);
2543
+ const linear = (marketDefined && market['linear']) || (marketType === 'linear');
2544
+ const inverse = (marketDefined && market['swap'] && market['inverse']) || (marketType === 'inverse');
2545
+ const future = (marketDefined && market['future']) || ((marketType === 'future') || (marketType === 'futures')); // * (marketType === 'futures') deprecated, use (marketType === 'future')
2546
+ let method = undefined;
2547
+ if (linear) {
2548
+ method = 'privateLinearGetTradeExecutionList';
2549
+ } else if (inverse) {
2550
+ method = 'v2PrivateGetExecutionList';
2551
+ } else if (future) {
2552
+ method = 'futuresPrivateGetExecutionList';
2553
+ }
2554
+ const response = await this[method] (this.extend (request, query));
2555
+ //
2556
+ // inverse
2557
+ //
2558
+ // {
2559
+ // "ret_code": 0,
2560
+ // "ret_msg": "OK",
2561
+ // "ext_code": "",
2562
+ // "ext_info": "",
2563
+ // "result": {
2564
+ // "order_id": "Abandoned!!", // Abandoned!!
2565
+ // "trade_list": [
2566
+ // {
2567
+ // "closed_size": 0,
2568
+ // "cross_seq": 277136382,
2569
+ // "exec_fee": "0.0000001",
2570
+ // "exec_id": "256e5ef8-abfe-5772-971b-f944e15e0d68",
2571
+ // "exec_price": "8178.5",
2572
+ // "exec_qty": 1,
2573
+ // "exec_time": "1571676941.70682",
2574
+ // "exec_type": "Trade", //Exec Type Enum
2575
+ // "exec_value": "0.00012227",
2576
+ // "fee_rate": "0.00075",
2577
+ // "last_liquidity_ind": "RemovedLiquidity", //Liquidity Enum
2578
+ // "leaves_qty": 0,
2579
+ // "nth_fill": 2,
2580
+ // "order_id": "7ad50cb1-9ad0-4f74-804b-d82a516e1029",
2581
+ // "order_link_id": "",
2582
+ // "order_price": "8178",
2583
+ // "order_qty": 1,
2584
+ // "order_type": "Market", //Order Type Enum
2585
+ // "side": "Buy", //Side Enum
2586
+ // "symbol": "BTCUSD", //Symbol Enum
2587
+ // "user_id": 1
2588
+ // }
2589
+ // ]
2590
+ // },
2591
+ // "time_now": "1577483699.281488",
2592
+ // "rate_limit_status": 118,
2593
+ // "rate_limit_reset_ms": 1577483699244737,
2594
+ // "rate_limit": 120
2595
+ // }
2596
+ //
2597
+ // linear
2598
+ //
2599
+ // {
2600
+ // "ret_code":0,
2601
+ // "ret_msg":"OK",
2602
+ // "ext_code":"",
2603
+ // "ext_info":"",
2604
+ // "result":{
2605
+ // "current_page":1,
2606
+ // "data":[
2607
+ // {
2608
+ // "order_id":"b59418ec-14d4-4ef9-b9f4-721d5d576974",
2609
+ // "order_link_id":"",
2610
+ // "side":"Sell",
2611
+ // "symbol":"BTCUSDT",
2612
+ // "exec_id":"0327284d-faec-5191-bd89-acc5b4fafda9",
2613
+ // "price":0.5,
2614
+ // "order_price":0.5,
2615
+ // "order_qty":0.01,
2616
+ // "order_type":"Market",
2617
+ // "fee_rate":0.00075,
2618
+ // "exec_price":9709.5,
2619
+ // "exec_type":"Trade",
2620
+ // "exec_qty":0.01,
2621
+ // "exec_fee":0.07282125,
2622
+ // "exec_value":97.095,
2623
+ // "leaves_qty":0,
2624
+ // "closed_size":0.01,
2625
+ // "last_liquidity_ind":"RemovedLiquidity",
2626
+ // "trade_time":1591648052,
2627
+ // "trade_time_ms":1591648052861
2628
+ // }
2629
+ // ]
2630
+ // },
2631
+ // "time_now":"1591736501.979264",
2632
+ // "rate_limit_status":119,
2633
+ // "rate_limit_reset_ms":1591736501974,
2634
+ // "rate_limit":120
2635
+ // }
2636
+ //
2637
+ const result = this.safeValue (response, 'result', {});
2638
+ const trades = this.safeValue2 (result, 'trade_list', 'data', []);
2639
+ return this.parseTrades (trades, market, since, limit);
2640
+ }
2641
+
2642
+ async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
2643
+ await this.loadMarkets ();
2644
+ const request = {
2645
+ // 'coin': currency['id'],
2646
+ // 'currency': currency['id'], // alias
2647
+ // 'start_date': this.iso8601 (since),
2648
+ // 'end_date': this.iso8601 (till),
2649
+ 'wallet_fund_type': 'Deposit', // Deposit, Withdraw, RealisedPNL, Commission, Refund, Prize, ExchangeOrderWithdraw, ExchangeOrderDeposit
2650
+ // 'page': 1,
2651
+ // 'limit': 20, // max 50
2652
+ };
2653
+ let currency = undefined;
2654
+ if (code !== undefined) {
2655
+ currency = this.currency (code);
2656
+ request['coin'] = currency['id'];
2657
+ }
2658
+ if (since !== undefined) {
2659
+ request['start_date'] = this.yyyymmdd (since);
2660
+ }
2661
+ if (limit !== undefined) {
2662
+ request['limit'] = limit;
2663
+ }
2664
+ const response = await this.v2PrivateGetWalletFundRecords (this.extend (request, params));
2665
+ //
2666
+ // {
2667
+ // "ret_code": 0,
2668
+ // "ret_msg": "ok",
2669
+ // "ext_code": "",
2670
+ // "result": {
2671
+ // "data": [
2672
+ // {
2673
+ // "id": 234467,
2674
+ // "user_id": 1,
2675
+ // "coin": "BTC",
2676
+ // "wallet_id": 27913,
2677
+ // "type": "Realized P&L",
2678
+ // "amount": "-0.00000006",
2679
+ // "tx_id": "",
2680
+ // "address": "BTCUSD",
2681
+ // "wallet_balance": "0.03000330",
2682
+ // "exec_time": "2019-12-09T00:00:25.000Z",
2683
+ // "cross_seq": 0
2684
+ // }
2685
+ // ]
2686
+ // },
2687
+ // "ext_info": null,
2688
+ // "time_now": "1577481867.115552",
2689
+ // "rate_limit_status": 119,
2690
+ // "rate_limit_reset_ms": 1577481867122,
2691
+ // "rate_limit": 120
2692
+ // }
2693
+ //
2694
+ const result = this.safeValue (response, 'result', {});
2695
+ const data = this.safeValue (result, 'data', []);
2696
+ return this.parseTransactions (data, currency, since, limit, { 'type': 'deposit' });
2697
+ }
2698
+
2699
+ async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
2700
+ await this.loadMarkets ();
2701
+ const request = {
2702
+ // 'coin': currency['id'],
2703
+ // 'start_date': this.iso8601 (since),
2704
+ // 'end_date': this.iso8601 (till),
2705
+ // 'status': 'Pending', // ToBeConfirmed, UnderReview, Pending, Success, CancelByUser, Reject, Expire
2706
+ // 'page': 1,
2707
+ // 'limit': 20, // max 50
2708
+ };
2709
+ let currency = undefined;
2710
+ if (code !== undefined) {
2711
+ currency = this.currency (code);
2712
+ request['coin'] = currency['id'];
2713
+ }
2714
+ if (since !== undefined) {
2715
+ request['start_date'] = this.yyyymmdd (since);
2716
+ }
2717
+ if (limit !== undefined) {
2718
+ request['limit'] = limit;
2719
+ }
2720
+ const response = await this.v2PrivateGetWalletWithdrawList (this.extend (request, params));
2721
+ //
2722
+ // {
2723
+ // "ret_code": 0,
2724
+ // "ret_msg": "ok",
2725
+ // "ext_code": "",
2726
+ // "result": {
2727
+ // "data": [
2728
+ // {
2729
+ // "id": 137,
2730
+ // "user_id": 1,
2731
+ // "coin": "XRP", // Coin Enum
2732
+ // "status": "Pending", // Withdraw Status Enum
2733
+ // "amount": "20.00000000",
2734
+ // "fee": "0.25000000",
2735
+ // "address": "rH7H595XYEVTEHU2FySYsWnmfACBnZS9zM",
2736
+ // "tx_id": "",
2737
+ // "submited_at": "2019-06-11T02:20:24.000Z",
2738
+ // "updated_at": "2019-06-11T02:20:24.000Z"
2739
+ // },
2740
+ // ],
2741
+ // "current_page": 1,
2742
+ // "last_page": 1
2743
+ // },
2744
+ // "ext_info": null,
2745
+ // "time_now": "1577482295.125488",
2746
+ // "rate_limit_status": 119,
2747
+ // "rate_limit_reset_ms": 1577482295132,
2748
+ // "rate_limit": 120
2749
+ // }
2750
+ //
2751
+ const result = this.safeValue (response, 'result', {});
2752
+ const data = this.safeValue (result, 'data', []);
2753
+ return this.parseTransactions (data, currency, since, limit, { 'type': 'withdrawal' });
2754
+ }
2755
+
2756
+ parseTransactionStatus (status) {
2757
+ const statuses = {
2758
+ 'ToBeConfirmed': 'pending',
2759
+ 'UnderReview': 'pending',
2760
+ 'Pending': 'pending',
2761
+ 'Success': 'ok',
2762
+ 'CancelByUser': 'canceled',
2763
+ 'Reject': 'rejected',
2764
+ 'Expire': 'expired',
2765
+ };
2766
+ return this.safeString (statuses, status, status);
2767
+ }
2768
+
2769
+ parseTransaction (transaction, currency = undefined) {
2770
+ //
2771
+ // fetchWithdrawals
2772
+ //
2773
+ // {
2774
+ // "id": 137,
2775
+ // "user_id": 1,
2776
+ // "coin": "XRP", // Coin Enum
2777
+ // "status": "Pending", // Withdraw Status Enum
2778
+ // "amount": "20.00000000",
2779
+ // "fee": "0.25000000",
2780
+ // "address": "rH7H595XYEVTEHU2FySYsWnmfACBnZS9zM",
2781
+ // "tx_id": "",
2782
+ // "submited_at": "2019-06-11T02:20:24.000Z",
2783
+ // "updated_at": "2019-06-11T02:20:24.000Z"
2784
+ // }
2785
+ //
2786
+ // fetchDeposits ledger entries
2787
+ //
2788
+ // {
2789
+ // "id": 234467,
2790
+ // "user_id": 1,
2791
+ // "coin": "BTC",
2792
+ // "wallet_id": 27913,
2793
+ // "type": "Realized P&L",
2794
+ // "amount": "-0.00000006",
2795
+ // "tx_id": "",
2796
+ // "address": "BTCUSD",
2797
+ // "wallet_balance": "0.03000330",
2798
+ // "exec_time": "2019-12-09T00:00:25.000Z",
2799
+ // "cross_seq": 0
2800
+ // }
2801
+ //
2802
+ const currencyId = this.safeString (transaction, 'coin');
2803
+ const code = this.safeCurrencyCode (currencyId, currency);
2804
+ const timestamp = this.parse8601 (this.safeString2 (transaction, 'submited_at', 'exec_time'));
2805
+ const updated = this.parse8601 (this.safeString (transaction, 'updated_at'));
2806
+ const status = this.parseTransactionStatus (this.safeString (transaction, 'status'));
2807
+ const address = this.safeString (transaction, 'address');
2808
+ const feeCost = this.safeNumber (transaction, 'fee');
2809
+ const type = this.safeStringLower (transaction, 'type');
2810
+ let fee = undefined;
2811
+ if (feeCost !== undefined) {
2812
+ fee = {
2813
+ 'cost': feeCost,
2814
+ 'currency': code,
2815
+ };
2816
+ }
2817
+ return {
2818
+ 'info': transaction,
2819
+ 'id': this.safeString (transaction, 'id'),
2820
+ 'txid': this.safeString (transaction, 'tx_id'),
2821
+ 'timestamp': timestamp,
2822
+ 'datetime': this.iso8601 (timestamp),
2823
+ 'network': undefined,
2824
+ 'address': address,
2825
+ 'addressTo': undefined,
2826
+ 'addressFrom': undefined,
2827
+ 'tag': undefined,
2828
+ 'tagTo': undefined,
2829
+ 'tagFrom': undefined,
2830
+ 'type': type,
2831
+ 'amount': this.safeNumber (transaction, 'amount'),
2832
+ 'currency': code,
2833
+ 'status': status,
2834
+ 'updated': updated,
2835
+ 'fee': fee,
2836
+ };
2837
+ }
2838
+
2839
+ async fetchLedger (code = undefined, since = undefined, limit = undefined, params = {}) {
2840
+ await this.loadMarkets ();
2841
+ const request = {
2842
+ // 'coin': currency['id'],
2843
+ // 'currency': currency['id'], // alias
2844
+ // 'start_date': this.iso8601 (since),
2845
+ // 'end_date': this.iso8601 (till),
2846
+ // 'wallet_fund_type': 'Deposit', // Withdraw, RealisedPNL, Commission, Refund, Prize, ExchangeOrderWithdraw, ExchangeOrderDeposit
2847
+ // 'page': 1,
2848
+ // 'limit': 20, // max 50
2849
+ };
2850
+ let currency = undefined;
2851
+ if (code !== undefined) {
2852
+ currency = this.currency (code);
2853
+ request['coin'] = currency['id'];
2854
+ }
2855
+ if (since !== undefined) {
2856
+ request['start_date'] = this.yyyymmdd (since);
2857
+ }
2858
+ if (limit !== undefined) {
2859
+ request['limit'] = limit;
2860
+ }
2861
+ const response = await this.v2PrivateGetWalletFundRecords (this.extend (request, params));
2862
+ //
2863
+ // {
2864
+ // "ret_code": 0,
2865
+ // "ret_msg": "ok",
2866
+ // "ext_code": "",
2867
+ // "result": {
2868
+ // "data": [
2869
+ // {
2870
+ // "id": 234467,
2871
+ // "user_id": 1,
2872
+ // "coin": "BTC",
2873
+ // "wallet_id": 27913,
2874
+ // "type": "Realized P&L",
2875
+ // "amount": "-0.00000006",
2876
+ // "tx_id": "",
2877
+ // "address": "BTCUSD",
2878
+ // "wallet_balance": "0.03000330",
2879
+ // "exec_time": "2019-12-09T00:00:25.000Z",
2880
+ // "cross_seq": 0
2881
+ // }
2882
+ // ]
2883
+ // },
2884
+ // "ext_info": null,
2885
+ // "time_now": "1577481867.115552",
2886
+ // "rate_limit_status": 119,
2887
+ // "rate_limit_reset_ms": 1577481867122,
2888
+ // "rate_limit": 120
2889
+ // }
2890
+ //
2891
+ const result = this.safeValue (response, 'result', {});
2892
+ const data = this.safeValue (result, 'data', []);
2893
+ return this.parseLedger (data, currency, since, limit);
2894
+ }
2895
+
2896
+ parseLedgerEntry (item, currency = undefined) {
2897
+ //
2898
+ // {
2899
+ // "id": 234467,
2900
+ // "user_id": 1,
2901
+ // "coin": "BTC",
2902
+ // "wallet_id": 27913,
2903
+ // "type": "Realized P&L",
2904
+ // "amount": "-0.00000006",
2905
+ // "tx_id": "",
2906
+ // "address": "BTCUSD",
2907
+ // "wallet_balance": "0.03000330",
2908
+ // "exec_time": "2019-12-09T00:00:25.000Z",
2909
+ // "cross_seq": 0
2910
+ // }
2911
+ //
2912
+ const currencyId = this.safeString (item, 'coin');
2913
+ const code = this.safeCurrencyCode (currencyId, currency);
2914
+ const amount = this.safeNumber (item, 'amount');
2915
+ const after = this.safeNumber (item, 'wallet_balance');
2916
+ const direction = (amount < 0) ? 'out' : 'in';
2917
+ let before = undefined;
2918
+ if (after !== undefined && amount !== undefined) {
2919
+ const difference = (direction === 'out') ? amount : -amount;
2920
+ before = this.sum (after, difference);
2921
+ }
2922
+ const timestamp = this.parse8601 (this.safeString (item, 'exec_time'));
2923
+ const type = this.parseLedgerEntryType (this.safeString (item, 'type'));
2924
+ const id = this.safeString (item, 'id');
2925
+ const referenceId = this.safeString (item, 'tx_id');
2926
+ return {
2927
+ 'id': id,
2928
+ 'currency': code,
2929
+ 'account': this.safeString (item, 'wallet_id'),
2930
+ 'referenceAccount': undefined,
2931
+ 'referenceId': referenceId,
2932
+ 'status': undefined,
2933
+ 'amount': amount,
2934
+ 'before': before,
2935
+ 'after': after,
2936
+ 'fee': undefined,
2937
+ 'direction': direction,
2938
+ 'timestamp': timestamp,
2939
+ 'datetime': this.iso8601 (timestamp),
2940
+ 'type': type,
2941
+ 'info': item,
2942
+ };
2943
+ }
2944
+
2945
+ parseLedgerEntryType (type) {
2946
+ const types = {
2947
+ 'Deposit': 'transaction',
2948
+ 'Withdraw': 'transaction',
2949
+ 'RealisedPNL': 'trade',
2950
+ 'Commission': 'fee',
2951
+ 'Refund': 'cashback',
2952
+ 'Prize': 'prize', // ?
2953
+ 'ExchangeOrderWithdraw': 'transaction',
2954
+ 'ExchangeOrderDeposit': 'transaction',
2955
+ };
2956
+ return this.safeString (types, type, type);
2957
+ }
2958
+
2959
+ async fetchPositions (symbols = undefined, params = {}) {
2960
+ await this.loadMarkets ();
2961
+ const request = {};
2962
+ if (Array.isArray (symbols)) {
2963
+ const length = symbols.length;
2964
+ if (length !== 1) {
2965
+ throw new ArgumentsRequired (this.id + ' fetchPositions() takes an array with exactly one symbol');
2966
+ }
2967
+ request['symbol'] = this.marketId (symbols[0]);
2968
+ }
2969
+ const defaultType = this.safeString (this.options, 'defaultType', 'linear');
2970
+ const type = this.safeString (params, 'type', defaultType);
2971
+ params = this.omit (params, 'type');
2972
+ let response = undefined;
2973
+ if (type === 'linear') {
2974
+ response = await this.privateLinearGetPositionList (this.extend (request, params));
2975
+ } else if (type === 'inverse') {
2976
+ response = await this.v2PrivateGetPositionList (this.extend (request, params));
2977
+ } else if (type === 'inverseFuture') {
2978
+ response = await this.futuresPrivateGetPositionList (this.extend (request, params));
2979
+ }
2980
+ if ((typeof response === 'string') && this.isJsonEncodedObject (response)) {
2981
+ response = JSON.parse (response);
2982
+ }
2983
+ //
2984
+ // {
2985
+ // ret_code: 0,
2986
+ // ret_msg: 'OK',
2987
+ // ext_code: '',
2988
+ // ext_info: '',
2989
+ // result: [] or {} depending on the request
2990
+ // }
2991
+ //
2992
+ return this.safeValue (response, 'result');
2993
+ }
2994
+
2995
+ async setMarginMode (marginType, symbol = undefined, params = {}) {
2996
+ //
2997
+ // {
2998
+ // "ret_code": 0,
2999
+ // "ret_msg": "ok",
3000
+ // "ext_code": "",
3001
+ // "result": null,
3002
+ // "ext_info": null,
3003
+ // "time_now": "1577477968.175013",
3004
+ // "rate_limit_status": 74,
3005
+ // "rate_limit_reset_ms": 1577477968183,
3006
+ // "rate_limit": 75
3007
+ // }
3008
+ //
3009
+ const leverage = this.safeValue (params, 'leverage');
3010
+ if (leverage === undefined) {
3011
+ throw new ArgumentsRequired (this.id + ' setMarginMode() requires a leverage parameter');
3012
+ }
3013
+ marginType = marginType.toUpperCase ();
3014
+ if (marginType === 'CROSSED') { // * Deprecated, use 'CROSS' instead
3015
+ marginType = 'CROSS';
3016
+ }
3017
+ if ((marginType !== 'ISOLATED') && (marginType !== 'CROSS')) {
3018
+ throw new BadRequest (this.id + ' setMarginMode() marginType must be either isolated or cross');
3019
+ }
3020
+ await this.loadMarkets ();
3021
+ const market = this.market (symbol);
3022
+ let method = undefined;
3023
+ const defaultType = this.safeString (this.options, 'defaultType', 'linear');
3024
+ const marketTypes = this.safeValue (this.options, 'marketTypes', {});
3025
+ const marketType = this.safeString (marketTypes, symbol, defaultType);
3026
+ const linear = market['linear'] || (marketType === 'linear');
3027
+ const inverse = (market['swap'] && market['inverse']) || (marketType === 'inverse');
3028
+ const future = market['future'] || ((marketType === 'future') || (marketType === 'futures')); // * (marketType === 'futures') deprecated, use (marketType === 'future')
3029
+ if (linear) {
3030
+ method = 'privateLinearPostPositionSwitchIsolated';
3031
+ } else if (inverse) {
3032
+ method = 'v2PrivatePostPositionSwitchIsolated';
3033
+ } else if (future) {
3034
+ method = 'privateFuturesPostPositionSwitchIsolated';
3035
+ }
3036
+ const isIsolated = (marginType === 'ISOLATED');
3037
+ const request = {
3038
+ 'symbol': market['id'],
3039
+ 'is_isolated': isIsolated,
3040
+ 'buy_leverage': leverage,
3041
+ 'sell_leverage': leverage,
3042
+ };
3043
+ const response = await this[method] (this.extend (request, params));
3044
+ //
3045
+ // {
3046
+ // "ret_code": 0,
3047
+ // "ret_msg": "OK",
3048
+ // "ext_code": "",
3049
+ // "ext_info": "",
3050
+ // "result": null,
3051
+ // "time_now": "1585881597.006026",
3052
+ // "rate_limit_status": 74,
3053
+ // "rate_limit_reset_ms": 1585881597004,
3054
+ // "rate_limit": 75
3055
+ // }
3056
+ //
3057
+ return response;
3058
+ }
3059
+
3060
+ async setLeverage (leverage, symbol = undefined, params = {}) {
3061
+ if (symbol === undefined) {
3062
+ throw new ArgumentsRequired (this.id + ' setLeverage() requires a symbol argument');
3063
+ }
3064
+ await this.loadMarkets ();
3065
+ const market = this.market (symbol);
3066
+ // WARNING: THIS WILL INCREASE LIQUIDATION PRICE FOR OPEN ISOLATED LONG POSITIONS
3067
+ // AND DECREASE LIQUIDATION PRICE FOR OPEN ISOLATED SHORT POSITIONS
3068
+ const defaultType = this.safeString (this.options, 'defaultType', 'linear');
3069
+ const marketTypes = this.safeValue (this.options, 'marketTypes', {});
3070
+ const marketType = this.safeString (marketTypes, symbol, defaultType);
3071
+ const linear = market['linear'] || (marketType === 'linear');
3072
+ const inverse = (market['swap'] && market['inverse']) || (marketType === 'inverse');
3073
+ const future = market['future'] || ((marketType === 'future') || (marketType === 'futures')); // * (marketType === 'futures') deprecated, use (marketType === 'future')
3074
+ let method = undefined;
3075
+ if (linear) {
3076
+ method = 'privateLinearPostPositionSetLeverage';
3077
+ } else if (inverse) {
3078
+ method = 'v2PrivatePostPositionLeverageSave';
3079
+ } else if (future) {
3080
+ method = 'privateFuturesPostPositionLeverageSave';
3081
+ }
3082
+ let buy_leverage = leverage;
3083
+ let sell_leverage = leverage;
3084
+ if (params['buy_leverage'] && params['sell_leverage'] && linear) {
3085
+ buy_leverage = params['buy_leverage'];
3086
+ sell_leverage = params['sell_leverage'];
3087
+ } else if (!leverage) {
3088
+ if (linear) {
3089
+ throw new ArgumentsRequired (this.id + ' setLeverage() requires either the parameter leverage or params["buy_leverage"] and params["sell_leverage"] for linear contracts');
3090
+ } else {
3091
+ throw new ArgumentsRequired (this.id + ' setLeverage() requires parameter leverage for inverse and futures contracts');
3092
+ }
3093
+ }
3094
+ if ((buy_leverage < 1) || (buy_leverage > 100) || (sell_leverage < 1) || (sell_leverage > 100)) {
3095
+ throw new BadRequest (this.id + ' setLeverage() leverage should be between 1 and 100');
3096
+ }
3097
+ const request = {
3098
+ 'symbol': market['id'],
3099
+ 'leverage_only': true,
3100
+ };
3101
+ if (!linear) {
3102
+ request['leverage'] = buy_leverage;
3103
+ } else {
3104
+ request['buy_leverage'] = buy_leverage;
3105
+ request['sell_leverage'] = sell_leverage;
3106
+ }
3107
+ return await this[method] (this.extend (request, params));
3108
+ }
3109
+
3110
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3111
+ let url = undefined;
3112
+ if (Array.isArray (api)) {
3113
+ const type = this.safeString (api, 0);
3114
+ let section = this.safeString (api, 1);
3115
+ if (type === 'spot') {
3116
+ if (section === 'public') {
3117
+ section = 'v1';
3118
+ } else {
3119
+ section += '/v1';
3120
+ }
3121
+ }
3122
+ url = this.implodeHostname (this.urls['api'][type]);
3123
+ let request = '/' + type + '/' + section + '/' + path;
3124
+ if ((type === 'spot') || (type === 'quote')) {
3125
+ if (Object.keys (params).length) {
3126
+ request += '?' + this.rawencode (params);
3127
+ }
3128
+ } else if (section === 'public') {
3129
+ if (Object.keys (params).length) {
3130
+ request += '?' + this.rawencode (params);
3131
+ }
3132
+ } else if (type === 'public') {
3133
+ if (Object.keys (params).length) {
3134
+ request += '?' + this.rawencode (params);
3135
+ }
3136
+ } else {
3137
+ this.checkRequiredCredentials ();
3138
+ const timestamp = this.nonce ();
3139
+ const query = this.extend (params, {
3140
+ 'api_key': this.apiKey,
3141
+ 'recv_window': this.options['recvWindow'],
3142
+ 'timestamp': timestamp,
3143
+ });
3144
+ const sortedQuery = this.keysort (query);
3145
+ const auth = this.rawencode (sortedQuery);
3146
+ const signature = this.hmac (this.encode (auth), this.encode (this.secret));
3147
+ if (method === 'POST') {
3148
+ body = this.json (this.extend (query, {
3149
+ 'sign': signature,
3150
+ }));
3151
+ headers = {
3152
+ 'Content-Type': 'application/json',
3153
+ };
3154
+ } else {
3155
+ request += '?' + this.urlencode (sortedQuery) + '&sign=' + signature;
3156
+ }
3157
+ }
3158
+ url += request;
3159
+ } else {
3160
+ url = this.implodeHostname (this.urls['api'][api]) + '/' + path;
3161
+ if (api === 'public') {
3162
+ if (Object.keys (params).length) {
3163
+ url += '?' + this.rawencode (params);
3164
+ }
3165
+ } else if (api === 'private') {
3166
+ this.checkRequiredCredentials ();
3167
+ const timestamp = this.nonce ();
3168
+ const query = this.extend (params, {
3169
+ 'api_key': this.apiKey,
3170
+ 'recv_window': this.options['recvWindow'],
3171
+ 'timestamp': timestamp,
3172
+ });
3173
+ const sortedQuery = this.keysort (query);
3174
+ const auth = this.rawencode (sortedQuery);
3175
+ const signature = this.hmac (this.encode (auth), this.encode (this.secret));
3176
+ if (method === 'POST') {
3177
+ body = this.json (this.extend (query, {
3178
+ 'sign': signature,
3179
+ }));
3180
+ headers = {
3181
+ 'Content-Type': 'application/json',
3182
+ };
3183
+ } else {
3184
+ url += '?' + this.urlencode (sortedQuery) + '&sign=' + signature;
3185
+ }
3186
+ }
3187
+ }
3188
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
3189
+ }
3190
+
3191
+ handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
3192
+ if (!response) {
3193
+ return; // fallback to default error handler
3194
+ }
3195
+ //
3196
+ // {
3197
+ // ret_code: 10001,
3198
+ // ret_msg: 'ReadMapCB: expect { or n, but found \u0000, error ' +
3199
+ // 'found in #0 byte of ...||..., bigger context ' +
3200
+ // '...||...',
3201
+ // ext_code: '',
3202
+ // ext_info: '',
3203
+ // result: null,
3204
+ // time_now: '1583934106.590436'
3205
+ // }
3206
+ //
3207
+ // {
3208
+ // "retCode":10001,
3209
+ // "retMsg":"symbol params err",
3210
+ // "result":{"symbol":"","bid":"","bidIv":"","bidSize":"","ask":"","askIv":"","askSize":"","lastPrice":"","openInterest":"","indexPrice":"","markPrice":"","markPriceIv":"","change24h":"","high24h":"","low24h":"","volume24h":"","turnover24h":"","totalVolume":"","totalTurnover":"","fundingRate":"","predictedFundingRate":"","nextFundingTime":"","countdownHour":"0","predictedDeliveryPrice":"","underlyingPrice":"","delta":"","gamma":"","vega":"","theta":""}
3211
+ // }
3212
+ //
3213
+ const errorCode = this.safeString2 (response, 'ret_code', 'retCode');
3214
+ if (errorCode !== '0') {
3215
+ if (errorCode === '30084') {
3216
+ // not an error
3217
+ // https://github.com/ccxt/ccxt/issues/11268
3218
+ // https://github.com/ccxt/ccxt/pull/11624
3219
+ // POST https://api.bybit.com/v2/private/position/switch-isolated 200 OK
3220
+ // {"ret_code":30084,"ret_msg":"Isolated not modified","ext_code":"","ext_info":"","result":null,"time_now":"1642005219.937988","rate_limit_status":73,"rate_limit_reset_ms":1642005219894,"rate_limit":75}
3221
+ return undefined;
3222
+ }
3223
+ const feedback = this.id + ' ' + body;
3224
+ this.throwExactlyMatchedException (this.exceptions['exact'], errorCode, feedback);
3225
+ this.throwBroadlyMatchedException (this.exceptions['broad'], body, feedback);
3226
+ throw new ExchangeError (feedback); // unknown message
3227
+ }
3228
+ }
3229
+
3230
+ async fetchMarketLeverageTiers (symbol, params = {}) {
3231
+ await this.loadMarkets ();
3232
+ const request = {};
3233
+ let market = undefined;
3234
+ if (symbol !== undefined) {
3235
+ market = this.market (symbol);
3236
+ if (market['spot']) {
3237
+ throw new BadRequest (this.id + ' fetchLeverageTiers() symbol supports contract markets only');
3238
+ }
3239
+ request['symbol'] = market['id'];
3240
+ }
3241
+ const [ type, query ] = this.handleMarketTypeAndParams ('fetchMarketLeverageTiers', market, params);
3242
+ const method = this.getSupportedMapping (type, {
3243
+ 'linear': 'publicLinearGetRiskLimit', // Symbol required
3244
+ 'swap': 'publicLinearGetRiskLimit',
3245
+ 'inverse': 'v2PublicGetRiskLimitList', // Symbol not required, could implement fetchLeverageTiers
3246
+ 'future': 'v2PublicGetRiskLimitList',
3247
+ });
3248
+ const response = await this[method] (this.extend (request, query));
3249
+ //
3250
+ // publicLinearGetRiskLimit
3251
+ // {
3252
+ // ret_code: '0',
3253
+ // ret_msg: 'OK',
3254
+ // ext_code: '',
3255
+ // ext_info: '',
3256
+ // result: [
3257
+ // {
3258
+ // id: '11',
3259
+ // symbol: 'ETHUSDT',
3260
+ // limit: '800000',
3261
+ // maintain_margin: '0.01',
3262
+ // starting_margin: '0.02',
3263
+ // section: [
3264
+ // '1', '2', '3',
3265
+ // '5', '10', '15',
3266
+ // '25'
3267
+ // ],
3268
+ // is_lowest_risk: '1',
3269
+ // created_at: '2022-02-04 23:30:33.555252',
3270
+ // updated_at: '2022-02-04 23:30:33.555254',
3271
+ // max_leverage: '50'
3272
+ // },
3273
+ // ...
3274
+ // ]
3275
+ // }
3276
+ //
3277
+ // v2PublicGetRiskLimitList
3278
+ // {
3279
+ // ret_code: '0',
3280
+ // ret_msg: 'OK',
3281
+ // ext_code: '',
3282
+ // ext_info: '',
3283
+ // result: [
3284
+ // {
3285
+ // id: '180',
3286
+ // is_lowest_risk: '0',
3287
+ // section: [
3288
+ // '1', '2', '3',
3289
+ // '4', '5', '7',
3290
+ // '8', '9'
3291
+ // ],
3292
+ // symbol: 'ETHUSDH22',
3293
+ // limit: '30000',
3294
+ // max_leverage: '9',
3295
+ // starting_margin: '11',
3296
+ // maintain_margin: '5.5',
3297
+ // coin: 'ETH',
3298
+ // created_at: '2021-04-22T15:00:00Z',
3299
+ // updated_at: '2021-04-22T15:00:00Z'
3300
+ // },
3301
+ // ],
3302
+ // time_now: '1644017569.683191'
3303
+ // }
3304
+ //
3305
+ const result = this.safeValue (response, 'result');
3306
+ return this.parseMarketLeverageTiers (result, market);
3307
+ }
3308
+
3309
+ parseMarketLeverageTiers (info, market) {
3310
+ //
3311
+ // Linear
3312
+ // [
3313
+ // {
3314
+ // id: '11',
3315
+ // symbol: 'ETHUSDT',
3316
+ // limit: '800000',
3317
+ // maintain_margin: '0.01',
3318
+ // starting_margin: '0.02',
3319
+ // section: [
3320
+ // '1', '2', '3',
3321
+ // '5', '10', '15',
3322
+ // '25'
3323
+ // ],
3324
+ // is_lowest_risk: '1',
3325
+ // created_at: '2022-02-04 23:30:33.555252',
3326
+ // updated_at: '2022-02-04 23:30:33.555254',
3327
+ // max_leverage: '50'
3328
+ // },
3329
+ // ...
3330
+ // ]
3331
+ //
3332
+ // Inverse
3333
+ // [
3334
+ // {
3335
+ // id: '180',
3336
+ // is_lowest_risk: '0',
3337
+ // section: [
3338
+ // '1', '2', '3',
3339
+ // '4', '5', '7',
3340
+ // '8', '9'
3341
+ // ],
3342
+ // symbol: 'ETHUSDH22',
3343
+ // limit: '30000',
3344
+ // max_leverage: '9',
3345
+ // starting_margin: '11',
3346
+ // maintain_margin: '5.5',
3347
+ // coin: 'ETH',
3348
+ // created_at: '2021-04-22T15:00:00Z',
3349
+ // updated_at: '2021-04-22T15:00:00Z'
3350
+ // }
3351
+ // ...
3352
+ // ]
3353
+ //
3354
+ let minNotional = 0;
3355
+ const tiers = [];
3356
+ for (let i = 0; i < info.length; i++) {
3357
+ const item = info[i];
3358
+ const maxNotional = this.safeNumber (item, 'limit');
3359
+ tiers.push ({
3360
+ 'tier': this.sum (i, 1),
3361
+ 'currency': market['base'],
3362
+ 'minNotional': minNotional,
3363
+ 'maxNotional': maxNotional,
3364
+ 'maintenanceMarginRate': this.safeNumber (item, 'maintain_margin'),
3365
+ 'maxLeverage': this.safeNumber (item, 'max_leverage'),
3366
+ 'info': item,
3367
+ });
3368
+ minNotional = maxNotional;
3369
+ }
3370
+ return tiers;
3371
+ }
3372
+ };